From fe57e347a57d643bbbcc9c19c8267a3e8c06b5a6 Mon Sep 17 00:00:00 2001 From: Sean Silva Date: Sat, 15 Jun 2013 00:25:26 +0000 Subject: [PATCH] [yaml2obj] Add support for sh_link via `Link` key. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184022 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/ELFYAML.h | 1 + lib/Object/ELFYAML.cpp | 1 + test/Object/yaml2obj-elf-section-basic.yaml | 3 ++ tools/yaml2obj/yaml2elf.cpp | 45 ++++++++++++++++++++- 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/include/llvm/Object/ELFYAML.h b/include/llvm/Object/ELFYAML.h index 124af7a936f..04ba0a66225 100644 --- a/include/llvm/Object/ELFYAML.h +++ b/include/llvm/Object/ELFYAML.h @@ -55,6 +55,7 @@ struct Section { ELF_SHF Flags; llvm::yaml::Hex64 Address; object::yaml::BinaryRef Content; + StringRef Link; llvm::yaml::Hex64 AddressAlign; }; struct Object { diff --git a/lib/Object/ELFYAML.cpp b/lib/Object/ELFYAML.cpp index 6e99767f87f..e0e95bee934 100644 --- a/lib/Object/ELFYAML.cpp +++ b/lib/Object/ELFYAML.cpp @@ -267,6 +267,7 @@ void MappingTraits::mapping(IO &IO, IO.mapOptional("Flags", Section.Flags, ELFYAML::ELF_SHF(0)); IO.mapOptional("Address", Section.Address, Hex64(0)); IO.mapOptional("Content", Section.Content); + IO.mapOptional("Link", Section.Link); IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0)); } diff --git a/test/Object/yaml2obj-elf-section-basic.yaml b/test/Object/yaml2obj-elf-section-basic.yaml index e3749868053..34be11d3658 100644 --- a/test/Object/yaml2obj-elf-section-basic.yaml +++ b/test/Object/yaml2obj-elf-section-basic.yaml @@ -10,6 +10,7 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_ALLOC, SHF_EXECINSTR ] Address: 0xCAFEBABE + Link: .text # Doesn't make sense for SHT_PROGBITS, but good enough for test. Content: EBFE AddressAlign: 2 @@ -26,6 +27,8 @@ Sections: # CHECK-NEXT: ] # CHECK-NEXT: Address: 0xCAFEBABE # CHECK: Size: 2 +# Check that Link != 0. +# CHECK: Link: {{[1-9][0-9]*}} # CHECK: AddressAlignment: 2 # CHECK: SectionData ( # CHECK-NEXT: 0000: EBFE diff --git a/tools/yaml2obj/yaml2elf.cpp b/tools/yaml2obj/yaml2elf.cpp index e5988be3293..e6a157cfd88 100644 --- a/tools/yaml2obj/yaml2elf.cpp +++ b/tools/yaml2obj/yaml2elf.cpp @@ -76,6 +76,29 @@ public: void writeBlobToStream(raw_ostream &Out) { Out << OS.str(); } }; +// Used to keep track of section names, so that in the YAML file sections +// can be referenced by name instead of by index. +class SectionNameToIdxMap { + StringMap Map; +public: + /// \returns true if name is already present in the map. + bool addName(StringRef SecName, unsigned i) { + StringMapEntry &Entry = Map.GetOrCreateValue(SecName, -1); + if (Entry.getValue() != -1) + return true; + Entry.setValue((int)i); + return false; + } + /// \returns true if name is not present in the map + bool lookupSection(StringRef SecName, unsigned &Idx) const { + StringMap::const_iterator I = Map.find(SecName); + if (I == Map.end()) + return true; + Idx = I->getValue(); + return false; + } +}; + template static size_t vectorDataSize(const std::vector &Vec) { return Vec.size() * sizeof(T); @@ -138,6 +161,18 @@ static void writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) { // Place section header string table last. Header.e_shstrndx = Sections.size(); + SectionNameToIdxMap SN2I; + for (unsigned i = 0, e = Sections.size(); i != e; ++i) { + StringRef Name = Sections[i].Name; + if (Name.empty()) + continue; + if (SN2I.addName(Name, i)) { + errs() << "error: Repeated section name: '" << Name + << "' at YAML section number " << i << ".\n"; + return; + } + } + StringTableBuilder StrTab; SmallVector Buf; // XXX: This offset is tightly coupled with the order that we write @@ -159,7 +194,15 @@ static void writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) { SHeader.sh_size = Sec.Content.binary_size(); Sec.Content.writeAsBinary(CBA.getOS()); - SHeader.sh_link = 0; + if (!Sec.Link.empty()) { + unsigned Index; + if (SN2I.lookupSection(Sec.Link, Index)) { + errs() << "error: Unknown section referenced: '" << Sec.Link + << "' at YAML section number " << i << ".\n"; + return; + } + SHeader.sh_link = Index; + } SHeader.sh_info = 0; SHeader.sh_addralign = Sec.AddressAlign; SHeader.sh_entsize = 0;