diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-05-27 18:44:32 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-05-27 18:44:32 +0000 |
| commit | 5a5ac124e1efaf208671f01c46edb15f29ed2a0b (patch) | |
| tree | a6140557876943cdd800ee997c9317283394b22c /tools/yaml2obj | |
| parent | f03b5bed27d0d2eafd68562ce14f8b5e3f1f0801 (diff) | |
Notes
Diffstat (limited to 'tools/yaml2obj')
| -rw-r--r-- | tools/yaml2obj/yaml2coff.cpp | 7 | ||||
| -rw-r--r-- | tools/yaml2obj/yaml2elf.cpp | 106 | ||||
| -rw-r--r-- | tools/yaml2obj/yaml2obj.cpp | 3 |
3 files changed, 97 insertions, 19 deletions
diff --git a/tools/yaml2obj/yaml2coff.cpp b/tools/yaml2obj/yaml2coff.cpp index 8322b2ff0a0de..61d985192552b 100644 --- a/tools/yaml2obj/yaml2coff.cpp +++ b/tools/yaml2obj/yaml2coff.cpp @@ -253,10 +253,7 @@ binary_le_impl<value_type> binary_le(value_type V) { return binary_le_impl<value_type>(V); } -template <size_t NumBytes> -struct zeros_impl { - zeros_impl() {} -}; +template <size_t NumBytes> struct zeros_impl {}; template <size_t NumBytes> raw_ostream &operator<<(raw_ostream &OS, const zeros_impl<NumBytes> &) { @@ -282,7 +279,7 @@ raw_ostream &operator<<(raw_ostream &OS, const num_zeros_impl &NZI) { return OS; } -num_zeros_impl num_zeros(size_t N) { +static num_zeros_impl num_zeros(size_t N) { num_zeros_impl NZI(N); return NZI; } diff --git a/tools/yaml2obj/yaml2elf.cpp b/tools/yaml2obj/yaml2elf.cpp index 44c8c12da89df..3386588056384 100644 --- a/tools/yaml2obj/yaml2elf.cpp +++ b/tools/yaml2obj/yaml2elf.cpp @@ -131,6 +131,11 @@ class ELFState { bool writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::RelocationSection &Section, ContiguousBlobAccumulator &CBA); + bool writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::Group &Group, + ContiguousBlobAccumulator &CBA); + bool writeSectionContent(Elf_Shdr &SHeader, + const ELFYAML::MipsABIFlags &Section, + ContiguousBlobAccumulator &CBA); // - SHT_NULL entry (placed first, i.e. 0'th entry) // - symbol table (.symtab) (placed third to last) @@ -223,6 +228,19 @@ bool ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders, if (!writeSectionContent(SHeader, *S, CBA)) return false; + } else if (auto S = dyn_cast<ELFYAML::Group>(Sec.get())) { + unsigned SymIdx; + if (SymN2I.lookup(S->Info, SymIdx)) { + errs() << "error: Unknown symbol referenced: '" << S->Info + << "' at YAML section '" << S->Name << "'.\n"; + return false; + } + SHeader.sh_info = SymIdx; + if (!writeSectionContent(SHeader, *S, CBA)) + return false; + } else if (auto S = dyn_cast<ELFYAML::MipsABIFlags>(Sec.get())) { + if (!writeSectionContent(SHeader, *S, CBA)) + return false; } else llvm_unreachable("Unknown section type"); @@ -321,16 +339,20 @@ ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, SHeader.sh_size = Section.Size; } +static bool isMips64EL(const ELFYAML::Object &Doc) { + return Doc.Header.Machine == ELFYAML::ELF_EM(llvm::ELF::EM_MIPS) && + Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64) && + Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB); +} + template <class ELFT> bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::RelocationSection &Section, ContiguousBlobAccumulator &CBA) { - if (Section.Type != llvm::ELF::SHT_REL && - Section.Type != llvm::ELF::SHT_RELA) { - errs() << "error: Invalid relocation section type.\n"; - return false; - } + assert((Section.Type == llvm::ELF::SHT_REL || + Section.Type == llvm::ELF::SHT_RELA) && + "Section type is not SHT_REL nor SHT_RELA"); bool IsRela = Section.Type == llvm::ELF::SHT_RELA; SHeader.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); @@ -339,31 +361,89 @@ ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset); for (const auto &Rel : Section.Relocations) { - unsigned SymIdx; - if (SymN2I.lookup(Rel.Symbol, SymIdx)) { - errs() << "error: Unknown symbol referenced: '" << Rel.Symbol - << "' at YAML relocation.\n"; - return false; - } + unsigned SymIdx = 0; + // Some special relocation, R_ARM_v4BX for instance, does not have + // an external reference. So it ignores the return value of lookup() + // here. + SymN2I.lookup(Rel.Symbol, SymIdx); if (IsRela) { Elf_Rela REntry; zero(REntry); REntry.r_offset = Rel.Offset; REntry.r_addend = Rel.Addend; - REntry.setSymbolAndType(SymIdx, Rel.Type); + REntry.setSymbolAndType(SymIdx, Rel.Type, isMips64EL(Doc)); OS.write((const char *)&REntry, sizeof(REntry)); } else { Elf_Rel REntry; zero(REntry); REntry.r_offset = Rel.Offset; - REntry.setSymbolAndType(SymIdx, Rel.Type); + REntry.setSymbolAndType(SymIdx, Rel.Type, isMips64EL(Doc)); OS.write((const char *)&REntry, sizeof(REntry)); } } return true; } +template <class ELFT> +bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, + const ELFYAML::Group &Section, + ContiguousBlobAccumulator &CBA) { + typedef typename object::ELFFile<ELFT>::Elf_Word Elf_Word; + assert(Section.Type == llvm::ELF::SHT_GROUP && + "Section type is not SHT_GROUP"); + + SHeader.sh_entsize = sizeof(Elf_Word); + SHeader.sh_size = SHeader.sh_entsize * Section.Members.size(); + + auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset); + + for (auto member : Section.Members) { + Elf_Word SIdx; + unsigned int sectionIndex = 0; + if (member.sectionNameOrType == "GRP_COMDAT") + sectionIndex = llvm::ELF::GRP_COMDAT; + else if (SN2I.lookup(member.sectionNameOrType, sectionIndex)) { + errs() << "error: Unknown section referenced: '" + << member.sectionNameOrType << "' at YAML section' " + << Section.Name << "\n"; + return false; + } + SIdx = sectionIndex; + OS.write((const char *)&SIdx, sizeof(SIdx)); + } + return true; +} + +template <class ELFT> +bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, + const ELFYAML::MipsABIFlags &Section, + ContiguousBlobAccumulator &CBA) { + assert(Section.Type == llvm::ELF::SHT_MIPS_ABIFLAGS && + "Section type is not SHT_MIPS_ABIFLAGS"); + + object::Elf_Mips_ABIFlags<ELFT> Flags; + zero(Flags); + SHeader.sh_entsize = sizeof(Flags); + SHeader.sh_size = SHeader.sh_entsize; + + auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset); + Flags.version = Section.Version; + Flags.isa_level = Section.ISALevel; + Flags.isa_rev = Section.ISARevision; + Flags.gpr_size = Section.GPRSize; + Flags.cpr1_size = Section.CPR1Size; + Flags.cpr2_size = Section.CPR2Size; + Flags.fp_abi = Section.FpABI; + Flags.isa_ext = Section.ISAExtension; + Flags.ases = Section.ASEs; + Flags.flags1 = Section.Flags1; + Flags.flags2 = Section.Flags2; + OS.write((const char *)&Flags, sizeof(Flags)); + + return true; +} + template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() { SN2I.addName(".symtab", getDotSymTabSecNo()); SN2I.addName(".strtab", getDotStrTabSecNo()); diff --git a/tools/yaml2obj/yaml2obj.cpp b/tools/yaml2obj/yaml2obj.cpp index 375cd89849c30..af4d868906724 100644 --- a/tools/yaml2obj/yaml2obj.cpp +++ b/tools/yaml2obj/yaml2obj.cpp @@ -62,7 +62,8 @@ static cl::opt<std::string> OutputFilename("o", cl::desc("Output filename"), typedef int (*ConvertFuncPtr)(yaml::Input & YIn, raw_ostream &Out); -int convertYAML(yaml::Input & YIn, raw_ostream &Out, ConvertFuncPtr Convert) { +static int convertYAML(yaml::Input &YIn, raw_ostream &Out, + ConvertFuncPtr Convert) { unsigned CurDocNum = 0; do { if (++CurDocNum == DocNum) |
