diff --git a/include/llvm/Object/ELFYAML.h b/include/llvm/Object/ELFYAML.h index b6c7556551e..fca965f3dbf 100644 --- a/include/llvm/Object/ELFYAML.h +++ b/include/llvm/Object/ELFYAML.h @@ -72,12 +72,15 @@ struct Section { object::yaml::BinaryRef Content; StringRef Link; llvm::yaml::Hex64 AddressAlign; - // For SHT_SYMTAB; should be empty otherwise. - LocalGlobalWeakSymbols Symbols; }; struct Object { FileHeader Header; std::vector
Sections; + // Although in reality the symbols reside in a section, it is a lot + // cleaner and nicer if we read them from the YAML as a separate + // top-level key, which automatically ensures that invariants like there + // being a single SHT_SYMTAB section are upheld. + LocalGlobalWeakSymbols Symbols; }; } // end namespace ELFYAML diff --git a/lib/Object/ELFYAML.cpp b/lib/Object/ELFYAML.cpp index 107333c708e..a3313022243 100644 --- a/lib/Object/ELFYAML.cpp +++ b/lib/Object/ELFYAML.cpp @@ -244,7 +244,8 @@ void ScalarEnumerationTraits::enumeration( #define ECase(X) IO.enumCase(Value, #X, ELF::X); ECase(SHT_NULL) ECase(SHT_PROGBITS) - ECase(SHT_SYMTAB) + // No SHT_SYMTAB. Use the top-level `Symbols` key instead. + // FIXME: Issue a diagnostic with this information. ECase(SHT_STRTAB) ECase(SHT_RELA) ECase(SHT_HASH) @@ -326,17 +327,12 @@ void MappingTraits::mapping(IO &IO, IO.mapOptional("Content", Section.Content); IO.mapOptional("Link", Section.Link); IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0)); - // TODO: Error if `Type` is SHT_SYMTAB and this is not present, or if - // `Type` is *not* SHT_SYMTAB and this *is* present. (By SHT_SYMTAB I - // also mean SHT_DYNSYM, but for simplicity right now we just do - // SHT_SYMTAB). Want to be able to share the predicate with consumers of - // this structure. - IO.mapOptional("Symbols", Section.Symbols); } void MappingTraits::mapping(IO &IO, ELFYAML::Object &Object) { IO.mapRequired("FileHeader", Object.Header); IO.mapOptional("Sections", Object.Sections); + IO.mapOptional("Symbols", Object.Symbols); } } // end namespace yaml diff --git a/test/Object/yaml2obj-elf-symbol-LocalGlobalWeak.yaml b/test/Object/yaml2obj-elf-symbol-LocalGlobalWeak.yaml index 44479dce7dc..3c4e830c0df 100644 --- a/test/Object/yaml2obj-elf-symbol-LocalGlobalWeak.yaml +++ b/test/Object/yaml2obj-elf-symbol-LocalGlobalWeak.yaml @@ -10,21 +10,19 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_ALLOC, SHF_WRITE ] Content: "DEADBEEF" - - Name: .symtab - Type: SHT_SYMTAB - Symbols: - Local: - - Name: local_symbol - Type: STT_OBJECT - Section: .data - Global: - - Name: global_symbol - Type: STT_OBJECT - Section: .data - Weak: - - Name: weak_symbol - Type: STT_OBJECT - Section: .data +Symbols: + Local: + - Name: local_symbol + Type: STT_OBJECT + Section: .data + Global: + - Name: global_symbol + Type: STT_OBJECT + Section: .data + Weak: + - Name: weak_symbol + Type: STT_OBJECT + Section: .data # CHECK: Symbol { # CHECK: Name: (0) diff --git a/test/Object/yaml2obj-elf-symbol-basic.yaml b/test/Object/yaml2obj-elf-symbol-basic.yaml index d54e2f05c3c..3fb9b17655f 100644 --- a/test/Object/yaml2obj-elf-symbol-basic.yaml +++ b/test/Object/yaml2obj-elf-symbol-basic.yaml @@ -16,16 +16,14 @@ Sections: # This YAML file is a valid relocatable object that, # when linked and run on x86_64, will go into an # infloop. - - Name: .symtab - Type: SHT_SYMTAB - Symbols: - Global: - - Name: main - Type: STT_FUNC - Section: .text - Value: 0x1 - Size: 2 - - Name: undefined_symbol +Symbols: + Global: + - Name: main + Type: STT_FUNC + Section: .text + Value: 0x1 + Size: 2 + - Name: undefined_symbol # CHECK: Symbols [ # CHECK-NEXT: Symbol { diff --git a/tools/yaml2obj/yaml2elf.cpp b/tools/yaml2obj/yaml2elf.cpp index 82ff78756ea..61252a4a28d 100644 --- a/tools/yaml2obj/yaml2elf.cpp +++ b/tools/yaml2obj/yaml2elf.cpp @@ -216,8 +216,7 @@ static void handleSymtabSectionHeader( typename object::ELFObjectFile::Elf_Shdr &SHeader) { typedef typename object::ELFObjectFile::Elf_Sym Elf_Sym; - // TODO: Ensure that a manually specified `Link` field is diagnosed as an - // error for SHT_SYMTAB. + SHeader.sh_type = ELF::SHT_SYMTAB; SHeader.sh_link = State.getDotStrTabSecNo(); // One greater than symbol table index of the last local symbol. SHeader.sh_info = Symbols.Local.size() + 1; @@ -272,11 +271,12 @@ static int writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) { // Immediately following the ELF header. Header.e_shoff = sizeof(Header); const std::vector &Sections = Doc.Sections; - // "+ 3" for + // "+ 4" for // - SHT_NULL entry (placed first, i.e. 0'th entry) + // - symbol table (.symtab) (placed third to last) // - string table (.strtab) (placed second to last) // - section header string table. (placed last) - Header.e_shnum = Sections.size() + 3; + Header.e_shnum = Sections.size() + 4; // Place section header string table last. Header.e_shstrndx = Header.e_shnum - 1; const unsigned DotStrtabSecNo = Header.e_shnum - 2; @@ -334,14 +334,16 @@ static int writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) { SHeader.sh_info = 0; SHeader.sh_addralign = Sec.AddressAlign; SHeader.sh_entsize = 0; - // XXX: Really ugly right now. Should not be writing to `CBA` above - // (and setting sh_offset and sh_size) when going through this branch - // here. - if (Sec.Type == ELFYAML::ELF_SHT(SHT_SYMTAB)) - handleSymtabSectionHeader(Sec.Symbols, State, SHeader); SHeaders.push_back(SHeader); } + // .symtab section. + Elf_Shdr SymtabSHeader; + zero(SymtabSHeader); + SymtabSHeader.sh_name = SHStrTab.addString(StringRef(".symtab")); + handleSymtabSectionHeader(Doc.Symbols, State, SymtabSHeader); + SHeaders.push_back(SymtabSHeader); + // .strtab string table header. Elf_Shdr DotStrTabSHeader; zero(DotStrTabSHeader);