From 14d1db9019cae7c07f142e5106b17ffa02c57a10 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 30 Apr 2014 19:38:09 +0000 Subject: [PATCH] Use the new StringTableBuilder in yaml2elf http://reviews.llvm.org/D3574 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207694 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/Object/yaml2obj-elf-rel.yaml | 10 +-- test/Object/yaml2obj-elf-section-basic.yaml | 6 +- tools/yaml2obj/yaml2elf.cpp | 72 ++++++++------------- 3 files changed, 35 insertions(+), 53 deletions(-) diff --git a/test/Object/yaml2obj-elf-rel.yaml b/test/Object/yaml2obj-elf-rel.yaml index 121a533b8cb..6a7ed459eff 100644 --- a/test/Object/yaml2obj-elf-rel.yaml +++ b/test/Object/yaml2obj-elf-rel.yaml @@ -66,11 +66,11 @@ Symbols: # CHECK: } # CHECK: Section { # CHECK-NEXT: Index: 1 -# CHECK-NEXT: Name: .text (1) +# CHECK-NEXT: Name: .text (16) # CHECK: } # CHECK-NEXT: Section { # CHECK-NEXT: Index: 2 -# CHECK-NEXT: Name: .rel.text (7) +# CHECK-NEXT: Name: .rel.text (1) # CHECK-NEXT: Type: SHT_REL (0x9) # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] @@ -84,7 +84,7 @@ Symbols: # CHECK-NEXT: } # CHECK-NEXT: Section { # CHECK-NEXT: Index: 3 -# CHECK-NEXT: Name: .rela.text (17) +# CHECK-NEXT: Name: .rela.text (11) # CHECK-NEXT: Type: SHT_RELA (0x4) # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] @@ -98,11 +98,11 @@ Symbols: # CHECK-NEXT: } # CHECK-NEXT: Section { # CHECK-NEXT: Index: 4 -# CHECK-NEXT: Name: .symtab (28) +# CHECK-NEXT: Name: .symtab (40) # CHECK: } # CHECK-NEXT: Section { # CHECK-NEXT: Index: 5 -# CHECK-NEXT: Name: .strtab (36) +# CHECK-NEXT: Name: .strtab (32) # CHECK: } # CHECK: Relocations [ # CHECK-NEXT: Section (2) .rel.text { diff --git a/test/Object/yaml2obj-elf-section-basic.yaml b/test/Object/yaml2obj-elf-section-basic.yaml index c1f69351855..7264b7a5761 100644 --- a/test/Object/yaml2obj-elf-section-basic.yaml +++ b/test/Object/yaml2obj-elf-section-basic.yaml @@ -35,14 +35,14 @@ Sections: # CHECK-NEXT: ) # # CHECK: Section { -# CHECK: Name: .symtab (7) +# CHECK: Name: .symtab (25) # CHECK: Type: SHT_SYMTAB (0x2) # CHECK: } # CHECK: Section { -# CHECK: Name: .strtab (15) +# CHECK: Name: .strtab (17) # CHECK: Type: SHT_STRTAB (0x3) # CHECK: } # CHECK: Section { -# CHECK: Name: .shstrtab (23) +# CHECK: Name: .shstrtab (7) # CHECK: Type: SHT_STRTAB (0x3) # CHECK: } diff --git a/tools/yaml2obj/yaml2elf.cpp b/tools/yaml2obj/yaml2elf.cpp index c78e1dbe774..1d2beda7136 100644 --- a/tools/yaml2obj/yaml2elf.cpp +++ b/tools/yaml2obj/yaml2elf.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/ELFYAML.h" +#include "llvm/Object/StringTableBuilder.h" #include "llvm/Support/ELF.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/YAMLTraits.h" @@ -23,45 +24,6 @@ using namespace llvm; -// There is similar code in yaml2coff, but with some slight COFF-specific -// variations like different initial state. Might be able to deduplicate -// some day, but also want to make sure that the Mach-O use case is served. -// -// This class has a deliberately small interface, since a lot of -// implementation variation is possible. -// -// TODO: Use the StringTable builder from lib/Object instead, since it -// will deduplicate suffixes. -namespace { -class StringTableBuilder { - /// \brief Indices of strings currently present in `Buf`. - StringMap StringIndices; - /// \brief The contents of the string table as we build it. - std::string Buf; -public: - StringTableBuilder() { - Buf.push_back('\0'); - } - /// \returns Index of string in string table. - unsigned addString(StringRef S) { - StringMapEntry &Entry = StringIndices.GetOrCreateValue(S); - unsigned &I = Entry.getValue(); - if (I != 0) - return I; - I = Buf.size(); - Buf.append(S.begin(), S.end()); - Buf.push_back('\0'); - return I; - } - size_t size() const { - return Buf.size(); - } - void writeToStream(raw_ostream &OS) { - OS.write(Buf.data(), Buf.size()); - } -}; -} // end anonymous namespace - // This class is used to build up a contiguous binary blob while keeping // track of an offset in the output (which notionally begins at // `InitialOffset`). @@ -226,9 +188,13 @@ bool ELFState::initSectionHeaders(std::vector &SHeaders, zero(SHeader); SHeaders.push_back(SHeader); + for (const auto &Sec : Doc.Sections) + DotShStrtab.add(Sec->Name); + DotShStrtab.finalize(); + for (const auto &Sec : Doc.Sections) { zero(SHeader); - SHeader.sh_name = DotShStrtab.addString(Sec->Name); + SHeader.sh_name = DotShStrtab.getOffset(Sec->Name); SHeader.sh_type = Sec->Type; SHeader.sh_flags = Sec->Flags; SHeader.sh_addr = Sec->Address; @@ -273,7 +239,7 @@ template void ELFState::initSymtabSectionHeader(Elf_Shdr &SHeader, ContiguousBlobAccumulator &CBA) { zero(SHeader); - SHeader.sh_name = DotShStrtab.addString(StringRef(".symtab")); + SHeader.sh_name = DotShStrtab.getOffset(".symtab"); SHeader.sh_type = ELF::SHT_SYMTAB; SHeader.sh_link = getDotStrTabSecNo(); // One greater than symbol table index of the last local symbol. @@ -287,6 +253,16 @@ void ELFState::initSymtabSectionHeader(Elf_Shdr &SHeader, zero(Sym); Syms.push_back(Sym); } + + // Add symbol names to .strtab. + for (const auto &Sym : Doc.Symbols.Local) + DotStrtab.add(Sym.Name); + for (const auto &Sym : Doc.Symbols.Global) + DotStrtab.add(Sym.Name); + for (const auto &Sym : Doc.Symbols.Weak) + DotStrtab.add(Sym.Name); + DotStrtab.finalize(); + addSymbols(Doc.Symbols.Local, Syms, ELF::STB_LOCAL); addSymbols(Doc.Symbols.Global, Syms, ELF::STB_GLOBAL); addSymbols(Doc.Symbols.Weak, Syms, ELF::STB_WEAK); @@ -301,10 +277,10 @@ void ELFState::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name, StringTableBuilder &STB, ContiguousBlobAccumulator &CBA) { zero(SHeader); - SHeader.sh_name = DotShStrtab.addString(Name); + SHeader.sh_name = DotShStrtab.getOffset(Name); SHeader.sh_type = ELF::SHT_STRTAB; - STB.writeToStream(CBA.getOSAndAlignedOffset(SHeader.sh_offset)); - SHeader.sh_size = STB.size(); + CBA.getOSAndAlignedOffset(SHeader.sh_offset) << STB.data(); + SHeader.sh_size = STB.data().size(); SHeader.sh_addralign = 1; } @@ -316,7 +292,7 @@ void ELFState::addSymbols(const std::vector &Symbols, Elf_Sym Symbol; zero(Symbol); if (!Sym.Name.empty()) - Symbol.st_name = DotStrtab.addString(Sym.Name); + Symbol.st_name = DotStrtab.getOffset(Sym.Name); Symbol.setBindingAndType(SymbolBinding, Sym.Type); if (!Sym.Section.empty()) { unsigned Index; @@ -445,6 +421,12 @@ int ELFState::writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) { Header.e_ehsize + Header.e_shentsize * Header.e_shnum; ContiguousBlobAccumulator CBA(SectionContentBeginOffset); + // Doc might not contain .symtab, .strtab and .shstrtab sections, + // but we will emit them, so make sure to add them to ShStrTabSHeader. + State.DotShStrtab.add(".symtab"); + State.DotShStrtab.add(".strtab"); + State.DotShStrtab.add(".shstrtab"); + std::vector SHeaders; if(!State.initSectionHeaders(SHeaders, CBA)) return 1;