Index: llvm/include/llvm/ObjectYAML/ELFYAML.h =================================================================== --- llvm/include/llvm/ObjectYAML/ELFYAML.h +++ llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -101,13 +101,13 @@ }; struct Symbol { - StringRef Name; - ELF_STT Type; - StringRef Section; + Optional Name; + Optional Type; + Optional Section; Optional Index; - ELF_STB Binding; - llvm::yaml::Hex64 Value; - llvm::yaml::Hex64 Size; + Optional Binding; + Optional Value; + Optional Size; Optional Other; Optional StName; Index: llvm/lib/ObjectYAML/ELFEmitter.cpp =================================================================== --- llvm/lib/ObjectYAML/ELFEmitter.cpp +++ llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -807,7 +807,7 @@ static size_t findFirstNonGlobal(ArrayRef Symbols) { for (size_t I = 0; I < Symbols.size(); ++I) - if (Symbols[I].Binding.value != ELF::STB_LOCAL) + if (Symbols[I].Binding.getValueOr(ELF::STB_LOCAL) != ELF::STB_LOCAL) return I; return Symbols.size(); } @@ -828,18 +828,20 @@ // the specified Name to the string table builder to get its offset. if (Sym.StName) Symbol.st_name = *Sym.StName; - else if (!Sym.Name.empty()) - Symbol.st_name = Strtab.getOffset(ELFYAML::dropUniqueSuffix(Sym.Name)); - - Symbol.setBindingAndType(Sym.Binding, Sym.Type); - if (!Sym.Section.empty()) - Symbol.st_shndx = toSectionIndex(Sym.Section, "", Sym.Name); + else if (Sym.Name) + Symbol.st_name = Strtab.getOffset(ELFYAML::dropUniqueSuffix(*Sym.Name)); + + Symbol.setBindingAndType(Sym.Binding.getValueOr(ELF::STB_LOCAL), + Sym.Type.getValueOr(ELF::STT_NOTYPE)); + if (Sym.Section) + Symbol.st_shndx = + toSectionIndex(*Sym.Section, "", Sym.Name.getValueOr("")); else if (Sym.Index) Symbol.st_shndx = *Sym.Index; - Symbol.st_value = Sym.Value; - Symbol.st_other = Sym.Other ? *Sym.Other : 0; - Symbol.st_size = Sym.Size; + Symbol.st_value = Sym.Value.getValueOr(yaml::Hex64(0)); + Symbol.st_other = Sym.Other.getValueOr(yaml::Hex64(0)); + Symbol.st_size = Sym.Size.getValueOr(yaml::Hex64(0)); } return Ret; @@ -1842,8 +1844,8 @@ auto Build = [this](ArrayRef V, NameToIdxMap &Map) { for (size_t I = 0, S = V.size(); I < S; ++I) { const ELFYAML::Symbol &Sym = V[I]; - if (!Sym.Name.empty() && !Map.addName(Sym.Name, I + 1)) - reportError("repeated symbol name: '" + Sym.Name + "'"); + if (Sym.Name && !Sym.Name->empty() && !Map.addName(*Sym.Name, I + 1)) + reportError("repeated symbol name: '" + *Sym.Name + "'"); } }; @@ -1857,13 +1859,13 @@ // Add the regular symbol names to .strtab section. if (Doc.Symbols) for (const ELFYAML::Symbol &Sym : *Doc.Symbols) - DotStrtab.add(ELFYAML::dropUniqueSuffix(Sym.Name)); + DotStrtab.add(ELFYAML::dropUniqueSuffix(Sym.Name.getValueOr(""))); DotStrtab.finalize(); // Add the dynamic symbol names to .dynstr section. if (Doc.DynamicSymbols) for (const ELFYAML::Symbol &Sym : *Doc.DynamicSymbols) - DotDynstr.add(ELFYAML::dropUniqueSuffix(Sym.Name)); + DotDynstr.add(ELFYAML::dropUniqueSuffix(Sym.Name.getValueOr(""))); // SHT_GNU_verdef and SHT_GNU_verneed sections might also // add strings to .dynstr section. Index: llvm/lib/ObjectYAML/ELFYAML.cpp =================================================================== --- llvm/lib/ObjectYAML/ELFYAML.cpp +++ llvm/lib/ObjectYAML/ELFYAML.cpp @@ -1083,14 +1083,14 @@ } void MappingTraits::mapping(IO &IO, ELFYAML::Symbol &Symbol) { - IO.mapOptional("Name", Symbol.Name, StringRef()); + IO.mapOptional("Name", Symbol.Name); IO.mapOptional("StName", Symbol.StName); - IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0)); - IO.mapOptional("Section", Symbol.Section, StringRef()); + IO.mapOptional("Type", Symbol.Type); + IO.mapOptional("Section", Symbol.Section); IO.mapOptional("Index", Symbol.Index); - IO.mapOptional("Binding", Symbol.Binding, ELFYAML::ELF_STB(0)); - IO.mapOptional("Value", Symbol.Value, Hex64(0)); - IO.mapOptional("Size", Symbol.Size, Hex64(0)); + IO.mapOptional("Binding", Symbol.Binding); + IO.mapOptional("Value", Symbol.Value); + IO.mapOptional("Size", Symbol.Size); // Symbol's Other field is a bit special. It is usually a field that // represents st_other and holds the symbol visibility. However, on some @@ -1104,7 +1104,7 @@ std::string MappingTraits::validate(IO &IO, ELFYAML::Symbol &Symbol) { - if (Symbol.Index && Symbol.Section.data()) + if (Symbol.Index && Symbol.Section) return "Index and Section cannot both be specified for Symbol"; return ""; } Index: llvm/test/tools/yaml2obj/ELF/dynamic-symbols.yaml =================================================================== --- llvm/test/tools/yaml2obj/ELF/dynamic-symbols.yaml +++ llvm/test/tools/yaml2obj/ELF/dynamic-symbols.yaml @@ -42,7 +42,7 @@ ## Check we can use numeric values to refer to sections. -# RUN: yaml2obj --docnum=2 %s -o %t2 +# RUN: yaml2obj --docnum=2 -DSEC=0xff %s -o %t2 # RUN: llvm-readobj --dyn-symbols %t2 2>&1 | FileCheck -DFILE=%t2 %s --check-prefix=NUM # NUM: Name: foo @@ -67,12 +67,24 @@ - Name: .data Type: SHT_PROGBITS DynamicSymbols: - - Name: foo + - Name: foo Section: 1 - - Name: bar + - Name: bar Section: 2 - - Name: zed - Section: 0xff + - Name: zed + Section: [[SEC=]] + +## Check that by default no section is set. + +# RUN: yaml2obj --docnum=2 %s -o %t2.none +# RUN: llvm-readobj --dyn-symbols %t2.none 2>&1 | \ +# RUN: FileCheck -DFILE=%t2.none %s --check-prefix=NONE + +# NONE: Symbol { +# NONE: Name: zed +# NONE-NOT: } +# NONE: Section: Undefined (0x0) +# NONE-NEXT: } ## Check we report errors when unknown sections are referenced by dynamic symbols. Index: llvm/test/tools/yaml2obj/ELF/symbol-binding.yaml =================================================================== --- llvm/test/tools/yaml2obj/ELF/symbol-binding.yaml +++ llvm/test/tools/yaml2obj/ELF/symbol-binding.yaml @@ -1,6 +1,12 @@ ## Check we can set different bindings for symbols. -# RUN: yaml2obj %s | llvm-readobj --symbols - | FileCheck %s +# RUN: yaml2obj %s -o %t1 +# RUN: llvm-readobj --symbols %t1 | FileCheck %s + +## Check that STB_LOCAL is the default value for binding. + +# RUN: yaml2obj %s -DBINDING=STB_LOCAL -o %t2 +# RUN: cmp %t1 %t2 !ELF FileHeader: @@ -10,7 +16,7 @@ Symbols: - Name: local_symbol Type: STT_OBJECT - Binding: STB_LOCAL + Binding: [[BINDING=]] - Name: global_symbol Type: STT_OBJECT Binding: STB_GLOBAL Index: llvm/test/tools/yaml2obj/ELF/symbol-index.yaml =================================================================== --- llvm/test/tools/yaml2obj/ELF/symbol-index.yaml +++ llvm/test/tools/yaml2obj/ELF/symbol-index.yaml @@ -1,5 +1,11 @@ -# RUN: yaml2obj %s -o %t -# RUN: llvm-readelf -s %t | FileCheck %s +## Here we test that we can set the index of a symbol using the "Index" key. +## Check that we set the index of a symbol to STN_UNDEF by default. + +# RUN: yaml2obj %s -o %t1 +# RUN: llvm-readelf -s %t1 | FileCheck %s + +# RUN: yaml2obj %s -DUNDEFINDEX=0 -o %t2 +# RUN: cmp %t1 %t2 !ELF FileHeader: @@ -34,7 +40,7 @@ Index: SHN_UNDEF Binding: STB_GLOBAL - Name: undef2 - Index: 0 + Index: [[UNDEFINDEX=]] Binding: STB_GLOBAL # CHECK: Symbol table '.symtab' contains 9 entries Index: llvm/test/tools/yaml2obj/ELF/symbol-name.yaml =================================================================== --- llvm/test/tools/yaml2obj/ELF/symbol-name.yaml +++ llvm/test/tools/yaml2obj/ELF/symbol-name.yaml @@ -8,6 +8,7 @@ # CHECK: Name: est (2) # CHECK: Name: 1 (8) # CHECK: Name: 2 (6) +# CHECK: Name: (0) --- !ELF FileHeader: @@ -20,6 +21,9 @@ - StName: 2 - Name: 1 - Name: 2 +## Test that we can use '=' syntax. +## Test that we set sh_name to 0 by default. + - Name: [[NAME=]] ## Check we allow specifying both Name and StName at once. ## In this case StName has priority, but the symbol Name is still added Index: llvm/test/tools/yaml2obj/ELF/symbol-type.yaml =================================================================== --- llvm/test/tools/yaml2obj/ELF/symbol-type.yaml +++ llvm/test/tools/yaml2obj/ELF/symbol-type.yaml @@ -1,5 +1,8 @@ -# RUN: yaml2obj %s -o %t -# RUN: llvm-readobj --symbols %t | FileCheck %s +# RUN: yaml2obj %s -o %t1 +# RUN: llvm-readobj --symbols %t1 | FileCheck %s + +# RUN: yaml2obj %s -DTYPE=STT_NOTYPE -o %t2 +# RUN: cmp %t1 %t2 # CHECK: Name: notype # CHECK: Type: None @@ -28,7 +31,9 @@ Type: SHT_PROGBITS Symbols: - Name: notype - Type: STT_NOTYPE +## Test that we can use '=' syntax. +## Test that we set the type to STT_NOTYPE by default. + Type: [[TYPE=]] Binding: STB_GLOBAL - Name: normal_type Type: STT_OBJECT Index: llvm/tools/obj2yaml/elf2yaml.cpp =================================================================== --- llvm/tools/obj2yaml/elf2yaml.cpp +++ llvm/tools/obj2yaml/elf2yaml.cpp @@ -665,11 +665,15 @@ template Error ELFDumper::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab, StringRef StrTable, ELFYAML::Symbol &S) { - S.Type = Sym->getType(); - S.Value = Sym->st_value; - S.Size = Sym->st_size; + if (Sym->getType() != ELF::STT_NOTYPE) + S.Type = (ELFYAML::ELF_STT)Sym->getType(); + if (Sym->st_value) + S.Value = (yaml::Hex64)Sym->st_value; + if (Sym->st_size) + S.Size = (yaml::Hex64)Sym->st_size; S.Other = Sym->st_other; - S.Binding = Sym->getBinding(); + if (Sym->getBinding() != ELF::STB_LOCAL) + S.Binding = Sym->getBinding(); Expected SymbolNameOrErr = getUniquedSymbolName(Sym, StrTable, SymTab);