diff --git a/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-corrupt-xz.yaml b/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-corrupt-xz.yaml --- a/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-corrupt-xz.yaml +++ b/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-corrupt-xz.yaml @@ -5,11 +5,6 @@ # RUN: yaml2obj %s > %t.obj -# TODO(kwk): once yaml2obj doesn't auto-generate a .symtab section -# when there's none in YAML, remove the following line: - -# RUN: llvm-objcopy --remove-section=.symtab %t.obj - # RUN: %lldb -b -o 'image dump symtab' %t.obj 2>&1 | FileCheck %s # CHECK: warning: (x86_64) {{.*}}.obj An error occurred while decompression the section .gnu_debugdata: lzma_stream_buffer_decode()=lzma error: LZMA_DATA_ERROR diff --git a/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-find-symbols.yaml b/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-find-symbols.yaml --- a/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-find-symbols.yaml +++ b/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-find-symbols.yaml @@ -2,11 +2,6 @@ # RUN: yaml2obj %s > %t.obj -# TODO(kwk): once yaml2obj doesn't auto-generate a .symtab section -# when there's none in YAML, remove the following line: - -# RUN: llvm-objcopy --remove-section=.symtab %t.obj - # RUN: %lldb -b -o 'image dump symtab' %t.obj | FileCheck %s # CHECK: [ 0] 1 X Code 0x00000000004005b0 0x000000000000000f 0x00000012 multiplyByFour diff --git a/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-no-lzma.yaml b/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-no-lzma.yaml --- a/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-no-lzma.yaml +++ b/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-no-lzma.yaml @@ -5,11 +5,6 @@ # RUN: yaml2obj %s > %t.obj -# TODO(kwk): once yaml2obj doesn't auto-generate a .symtab section -# when there's none in YAML, remove the following line: - -# RUN: llvm-objcopy --remove-section=.symtab %t.obj - # RUN: %lldb -b -o 'image dump symtab' %t.obj 2>&1 | FileCheck %s # CHECK: warning: (x86_64) {{.*}}.obj No LZMA support found for reading .gnu_debugdata section diff --git a/lldb/test/Shell/ObjectFile/ELF/no-symtab-generated.yaml b/lldb/test/Shell/ObjectFile/ELF/no-symtab-generated.yaml new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/ObjectFile/ELF/no-symtab-generated.yaml @@ -0,0 +1,21 @@ +# In this test we don't explicitly define a "Symbols" entry in the YAML and +# expect no .symtab section to be generated. + +# RUN: yaml2obj %s > %t.obj +# RUN: %lldb -b -o "image dump sections" %t.obj | FileCheck %s + +# CHECK: SectID Type File Address Perm File Off. File Size Flags Section Name +# CHECK-NEXT: ---------- ---------------- --------------------------------------- ---- ---------- ---------- ---------- ---------------------------- +# CHECK-NEXT: {{.*}}.strtab +# CHECK-NEXT: {{.*}}.shstrtab +# CHECK-EMPTY: + + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 + Entry: 0x00000000004004C0 +... diff --git a/lldb/test/Shell/ObjectFile/ELF/symtab-generated.yaml b/lldb/test/Shell/ObjectFile/ELF/symtab-generated.yaml new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/ObjectFile/ELF/symtab-generated.yaml @@ -0,0 +1,37 @@ +# In this test we define a "Symbols" entry in the YAML and expect a .symtab +# section to be generated. Notice that this is automatically added even though +# we don't have .symtab listed in the "Sections" entry. + +# RUN: yaml2obj %s > %t.obj +# RUN: %lldb -b -o "image dump sections" %t.obj | FileCheck -v --color --dump-input=always %s + +# CHECK: SectID Type File Address Perm File Off. File Size Flags Section Name +# CHECK-NEXT: ---------- ---------------- --------------------------------------- ---- ---------- ---------- ---------- ---------------------------- +# CHECK-NEXT: {{.*}}.text +# CHECK-NEXT: {{.*}}.strtab +# CHECK-NEXT: {{.*}}.shstrtab +# CHECK-NEXT: {{.*}}.symtab +# CHECK-EMPTY: + + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 + Entry: 0x00000000004004C0 +Sections: +- Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x00000000004003D0 + AddressAlign: 0x0000000000000010 + Content: DEADBEEFBAADF00D +Symbols: +- Name: main + Type: STT_FUNC + Section: .text + Value: 0x00000000004003D0 + Size: 0x0000000000000008 +... diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -376,7 +376,7 @@ // 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. - std::vector Symbols; + Optional> Symbols; std::vector DynamicSymbols; }; diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -210,8 +210,10 @@ Doc.Sections.begin(), std::make_unique( ELFYAML::Section::SectionKind::RawContent, /*IsImplicit=*/true)); - - std::vector ImplicitSections = {".symtab", ".strtab", ".shstrtab"}; + + std::vector ImplicitSections = {".strtab", ".shstrtab"}; + if (Doc.Symbols) + ImplicitSections.push_back(".symtab"); if (!Doc.DynamicSymbols.empty()) ImplicitSections.insert(ImplicitSections.end(), {".dynsym", ".dynstr"}); @@ -508,7 +510,7 @@ ELFYAML::Section *YAMLSec) { bool IsStatic = STType == SymtabType::Static; - const auto &Symbols = IsStatic ? Doc.Symbols : Doc.DynamicSymbols; + const auto &Symbols = (IsStatic && Doc.Symbols) ? *Doc.Symbols : Doc.DynamicSymbols; ELFYAML::RawContentSection *RawSec = dyn_cast_or_null(YAMLSec); @@ -556,8 +558,9 @@ // If the symbol table section is explicitly described in the YAML // then we should set the fields requested. - SHeader.sh_info = (RawSec && RawSec->Info) ? (unsigned)(*RawSec->Info) - : findFirstNonGlobal(Symbols) + 1; + SHeader.sh_info = (RawSec && RawSec->Info) + ? (unsigned)(*RawSec->Info) + : findFirstNonGlobal(Symbols) + 1; SHeader.sh_entsize = (YAMLSec && YAMLSec->EntSize) ? (uint64_t)(*YAMLSec->EntSize) : sizeof(Elf_Sym); @@ -1044,14 +1047,16 @@ } }; - Build(Doc.Symbols, SymN2I); + if (Doc.Symbols) + Build(*Doc.Symbols, SymN2I); Build(Doc.DynamicSymbols, DynSymN2I); } template void ELFState::finalizeStrings() { // Add the regular symbol names to .strtab section. - for (const ELFYAML::Symbol &Sym : Doc.Symbols) - DotStrtab.add(ELFYAML::dropUniqueSuffix(Sym.Name)); + if (Doc.Symbols) + for (const ELFYAML::Symbol &Sym : *Doc.Symbols) + DotStrtab.add(ELFYAML::dropUniqueSuffix(Sym.Name)); DotStrtab.finalize(); // Add the dynamic symbol names to .dynstr section. diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -200,8 +200,8 @@ return TableOrErr.takeError(); ShndxTable = *TableOrErr; } - if (SymTab) - if (Error E = dumpSymbols(SymTab, Y->Symbols)) + if (SymTab && Y->Symbols) + if (Error E = dumpSymbols(SymTab, *Y->Symbols)) return std::move(E); if (DynSymTab) if (Error E = dumpSymbols(DynSymTab, Y->DynamicSymbols))