mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[yaml2obj][obj2yaml] Support custom ELF section header string table name
This patch adds support for a new field in the FileHeader, which states the name to use for the section header string table. This also allows combining the string table with another string table in the object, e.g. the symbol name string table. The field is optional. By default, .shstrtab will continue to be used. This partially fixes https://bugs.llvm.org/show_bug.cgi?id=50506. Reviewed by: Higuoxing Differential Revision: https://reviews.llvm.org/D104035
This commit is contained in:
parent
5506e18140
commit
a516a14043
@ -118,6 +118,7 @@ struct FileHeader {
|
||||
Optional<ELF_EM> Machine;
|
||||
ELF_EF Flags;
|
||||
llvm::yaml::Hex64 Entry;
|
||||
Optional<StringRef> SectionHeaderStringTable;
|
||||
|
||||
Optional<llvm::yaml::Hex64> EPhOff;
|
||||
Optional<llvm::yaml::Hex16> EPhEntSize;
|
||||
|
@ -177,15 +177,24 @@ template <class ELFT> class ELFState {
|
||||
|
||||
enum class SymtabType { Static, Dynamic };
|
||||
|
||||
/// The future ".strtab" section.
|
||||
/// The future symbol table string section.
|
||||
StringTableBuilder DotStrtab{StringTableBuilder::ELF};
|
||||
|
||||
/// The future ".shstrtab" section.
|
||||
/// The future section header string table section, if a unique string table
|
||||
/// is needed. Don't reference this variable direectly: use the
|
||||
/// ShStrtabStrings member instead.
|
||||
StringTableBuilder DotShStrtab{StringTableBuilder::ELF};
|
||||
|
||||
/// The future ".dynstr" section.
|
||||
/// The future dynamic symbol string section.
|
||||
StringTableBuilder DotDynstr{StringTableBuilder::ELF};
|
||||
|
||||
/// The name of the section header string table section. If it is .strtab or
|
||||
/// .dynstr, the section header strings will be written to the same string
|
||||
/// table as the static/dynamic symbols respectively. Otherwise a dedicated
|
||||
/// section will be created with that name.
|
||||
StringRef SectionHeaderStringTableName = ".shstrtab";
|
||||
StringTableBuilder *ShStrtabStrings = &DotShStrtab;
|
||||
|
||||
NameToIdxMap SN2I;
|
||||
NameToIdxMap SymN2I;
|
||||
NameToIdxMap DynSymN2I;
|
||||
@ -327,6 +336,18 @@ template <class T> static void zero(T &Obj) { memset(&Obj, 0, sizeof(Obj)); }
|
||||
template <class ELFT>
|
||||
ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH)
|
||||
: Doc(D), ErrHandler(EH) {
|
||||
// The input may explicitly request to store the section header table strings
|
||||
// in the same string table as dynamic or static symbol names. Set the
|
||||
// ShStrtabStrings member accordingly.
|
||||
if (Doc.Header.SectionHeaderStringTable) {
|
||||
SectionHeaderStringTableName = *Doc.Header.SectionHeaderStringTable;
|
||||
if (*Doc.Header.SectionHeaderStringTable == ".strtab")
|
||||
ShStrtabStrings = &DotStrtab;
|
||||
else if (*Doc.Header.SectionHeaderStringTable == ".dynstr")
|
||||
ShStrtabStrings = &DotDynstr;
|
||||
// Otherwise, the unique table will be used.
|
||||
}
|
||||
|
||||
std::vector<ELFYAML::Section *> Sections = Doc.getSections();
|
||||
// Insert SHT_NULL section implicitly when it is not defined in YAML.
|
||||
if (Sections.empty() || Sections.front()->Type != ELF::SHT_NULL)
|
||||
@ -363,19 +384,35 @@ ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH)
|
||||
"' at YAML section/fill number " + Twine(I));
|
||||
}
|
||||
|
||||
std::vector<StringRef> ImplicitSections;
|
||||
if (Doc.DynamicSymbols)
|
||||
ImplicitSections.insert(ImplicitSections.end(), {".dynsym", ".dynstr"});
|
||||
if (Doc.Symbols)
|
||||
ImplicitSections.push_back(".symtab");
|
||||
SmallSetVector<StringRef, 8> ImplicitSections;
|
||||
if (Doc.DynamicSymbols) {
|
||||
if (SectionHeaderStringTableName == ".dynsym")
|
||||
reportError("cannot use '.dynsym' as the section header name table when "
|
||||
"there are dynamic symbols");
|
||||
ImplicitSections.insert(".dynsym");
|
||||
ImplicitSections.insert(".dynstr");
|
||||
}
|
||||
if (Doc.Symbols) {
|
||||
if (SectionHeaderStringTableName == ".symtab")
|
||||
reportError("cannot use '.symtab' as the section header name table when "
|
||||
"there are symbols");
|
||||
ImplicitSections.insert(".symtab");
|
||||
}
|
||||
if (Doc.DWARF)
|
||||
for (StringRef DebugSecName : Doc.DWARF->getNonEmptySectionNames()) {
|
||||
std::string SecName = ("." + DebugSecName).str();
|
||||
ImplicitSections.push_back(StringRef(SecName).copy(StringAlloc));
|
||||
// TODO: For .debug_str it should be possible to share the string table,
|
||||
// in the same manner as the symbol string tables.
|
||||
if (SectionHeaderStringTableName == SecName)
|
||||
reportError("cannot use '" + SecName +
|
||||
"' as the section header name table when it is needed for "
|
||||
"DWARF output");
|
||||
ImplicitSections.insert(StringRef(SecName).copy(StringAlloc));
|
||||
}
|
||||
ImplicitSections.insert(ImplicitSections.end(), {".strtab"});
|
||||
// TODO: Only create the .strtab here if any symbols have been requested.
|
||||
ImplicitSections.insert(".strtab");
|
||||
if (!SecHdrTable || !SecHdrTable->NoHeaders.getValueOr(false))
|
||||
ImplicitSections.insert(ImplicitSections.end(), {".shstrtab"});
|
||||
ImplicitSections.insert(SectionHeaderStringTableName);
|
||||
|
||||
// Insert placeholders for implicit sections that are not
|
||||
// defined explicitly in YAML.
|
||||
@ -387,7 +424,9 @@ ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH)
|
||||
ELFYAML::Chunk::ChunkKind::RawContent, true /*IsImplicit*/);
|
||||
Sec->Name = SecName;
|
||||
|
||||
if (SecName == ".dynsym")
|
||||
if (SecName == SectionHeaderStringTableName)
|
||||
Sec->Type = ELF::SHT_STRTAB;
|
||||
else if (SecName == ".dynsym")
|
||||
Sec->Type = ELF::SHT_DYNSYM;
|
||||
else if (SecName == ".symtab")
|
||||
Sec->Type = ELF::SHT_SYMTAB;
|
||||
@ -480,8 +519,9 @@ void ELFState<ELFT>::writeELFHeader(raw_ostream &OS) {
|
||||
|
||||
if (Doc.Header.EShStrNdx)
|
||||
Header.e_shstrndx = *Doc.Header.EShStrNdx;
|
||||
else if (SectionHeaders.Offset && !ExcludedSectionHeaders.count(".shstrtab"))
|
||||
Header.e_shstrndx = SN2I.get(".shstrtab");
|
||||
else if (SectionHeaders.Offset &&
|
||||
!ExcludedSectionHeaders.count(SectionHeaderStringTableName))
|
||||
Header.e_shstrndx = SN2I.get(SectionHeaderStringTableName);
|
||||
else
|
||||
Header.e_shstrndx = 0;
|
||||
|
||||
@ -615,16 +655,16 @@ bool ELFState<ELFT>::initImplicitHeader(ContiguousBlobAccumulator &CBA,
|
||||
if (Header.sh_offset)
|
||||
return false;
|
||||
|
||||
if (SecName == ".symtab")
|
||||
initSymtabSectionHeader(Header, SymtabType::Static, CBA, YAMLSec);
|
||||
else if (SecName == ".strtab")
|
||||
if (SecName == ".strtab")
|
||||
initStrtabSectionHeader(Header, SecName, DotStrtab, CBA, YAMLSec);
|
||||
else if (SecName == ".shstrtab")
|
||||
initStrtabSectionHeader(Header, SecName, DotShStrtab, CBA, YAMLSec);
|
||||
else if (SecName == ".dynsym")
|
||||
initSymtabSectionHeader(Header, SymtabType::Dynamic, CBA, YAMLSec);
|
||||
else if (SecName == ".dynstr")
|
||||
initStrtabSectionHeader(Header, SecName, DotDynstr, CBA, YAMLSec);
|
||||
else if (SecName == SectionHeaderStringTableName)
|
||||
initStrtabSectionHeader(Header, SecName, *ShStrtabStrings, CBA, YAMLSec);
|
||||
else if (SecName == ".symtab")
|
||||
initSymtabSectionHeader(Header, SymtabType::Static, CBA, YAMLSec);
|
||||
else if (SecName == ".dynsym")
|
||||
initSymtabSectionHeader(Header, SymtabType::Dynamic, CBA, YAMLSec);
|
||||
else if (SecName.startswith(".debug_")) {
|
||||
// If a ".debug_*" section's type is a preserved one, e.g., SHT_DYNAMIC, we
|
||||
// will not treat it as a debug section.
|
||||
@ -671,7 +711,7 @@ uint64_t ELFState<ELFT>::getSectionNameOffset(StringRef Name) {
|
||||
// the string table.
|
||||
if (ExcludedSectionHeaders.count(Name))
|
||||
return 0;
|
||||
return DotShStrtab.getOffset(Name);
|
||||
return ShStrtabStrings->getOffset(Name);
|
||||
}
|
||||
|
||||
static uint64_t writeContent(ContiguousBlobAccumulator &CBA,
|
||||
@ -995,7 +1035,7 @@ void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,
|
||||
StringTableBuilder &STB,
|
||||
ContiguousBlobAccumulator &CBA,
|
||||
ELFYAML::Section *YAMLSec) {
|
||||
SHeader.sh_name = getSectionNameOffset(Name);
|
||||
SHeader.sh_name = getSectionNameOffset(ELFYAML::dropUniqueSuffix(Name));
|
||||
SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_STRTAB;
|
||||
SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1;
|
||||
|
||||
@ -1817,10 +1857,8 @@ template <class ELFT> void ELFState<ELFT>::buildSectionIndex() {
|
||||
llvm_unreachable("buildSectionIndex() failed");
|
||||
|
||||
if (!ExcludedSectionHeaders.count(S->Name))
|
||||
DotShStrtab.add(ELFYAML::dropUniqueSuffix(S->Name));
|
||||
ShStrtabStrings->add(ELFYAML::dropUniqueSuffix(S->Name));
|
||||
}
|
||||
|
||||
DotShStrtab.finalize();
|
||||
}
|
||||
|
||||
template <class ELFT> void ELFState<ELFT>::buildSymbolIndexes() {
|
||||
@ -1870,6 +1908,11 @@ template <class ELFT> void ELFState<ELFT>::finalizeStrings() {
|
||||
}
|
||||
|
||||
DotDynstr.finalize();
|
||||
|
||||
// Don't finalize the section header string table a second time if it has
|
||||
// already been finalized due to being one of the symbol string tables.
|
||||
if (ShStrtabStrings != &DotStrtab && ShStrtabStrings != &DotDynstr)
|
||||
ShStrtabStrings->finalize();
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
@ -1879,14 +1922,16 @@ bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc,
|
||||
if (State.HasError)
|
||||
return false;
|
||||
|
||||
// Finalize .strtab and .dynstr sections. We do that early because want to
|
||||
// finalize the string table builders before writing the content of the
|
||||
// sections that might want to use them.
|
||||
State.finalizeStrings();
|
||||
|
||||
// Build the section index, which adds sections to the section header string
|
||||
// table first, so that we can finalise the section header string table.
|
||||
State.buildSectionIndex();
|
||||
State.buildSymbolIndexes();
|
||||
|
||||
// Finalize section header string table and the .strtab and .dynstr sections.
|
||||
// We do this early because we want to finalize the string table builders
|
||||
// before writing the content of the sections that might want to use them.
|
||||
State.finalizeStrings();
|
||||
|
||||
if (State.HasError)
|
||||
return false;
|
||||
|
||||
|
@ -1007,6 +1007,7 @@ void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
|
||||
IO.mapOptional("Machine", FileHdr.Machine);
|
||||
IO.mapOptional("Flags", FileHdr.Flags, ELFYAML::ELF_EF(0));
|
||||
IO.mapOptional("Entry", FileHdr.Entry, Hex64(0));
|
||||
IO.mapOptional("SectionHeaderStringTable", FileHdr.SectionHeaderStringTable);
|
||||
|
||||
// obj2yaml does not dump these fields.
|
||||
assert(!IO.outputting() ||
|
||||
|
@ -11,6 +11,7 @@
|
||||
# CHECK-NEXT: Class: ELFCLASS64
|
||||
# CHECK-NEXT: Data: ELFDATA2LSB
|
||||
# CHECK-NEXT: Type: ET_REL
|
||||
# CHECK-NEXT: SectionHeaderStringTable: {{.*}}
|
||||
# CHECK-NEXT: Sections:
|
||||
# CHECK-NEXT: - Name: "{{.*}}"
|
||||
# CHECK-NEXT: Type: SHT_PROGBITS
|
||||
|
447
test/tools/obj2yaml/ELF/shstrtab.yaml
Normal file
447
test/tools/obj2yaml/ELF/shstrtab.yaml
Normal file
@ -0,0 +1,447 @@
|
||||
## Show that the SectionHeaderStringTable field in the document header is set,
|
||||
## iff the section name is not ".shstrtab".
|
||||
## Also show that no section appears in the Sections table for this section,
|
||||
## unless some property is different to the default.
|
||||
|
||||
## Show the case when the name is a custom string (the key should be set).
|
||||
# RUN: yaml2obj --docnum=1 %s -o %t1.o
|
||||
# RUN: obj2yaml %t1.o > %t1.yaml
|
||||
# RUN: FileCheck %s --input-file=%t1.yaml --check-prefix=CUSTOM
|
||||
|
||||
# CUSTOM: --- !ELF
|
||||
# CUSTOM-NEXT: FileHeader:
|
||||
# CUSTOM-NEXT: Class: ELFCLASS64
|
||||
# CUSTOM-NEXT: Data: ELFDATA2LSB
|
||||
# CUSTOM-NEXT: Type: ET_EXEC
|
||||
# CUSTOM-NEXT: SectionHeaderStringTable: .foo
|
||||
# CUSTOM-NEXT: ...
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: .foo
|
||||
|
||||
## Show the case when the e_shstrndx value is 0 and the name is not ".shstrtab"
|
||||
## (the key should be set).
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t2.o
|
||||
# RUN: obj2yaml %t2.o > %t2.yaml
|
||||
# RUN: FileCheck %s --input-file=%t2.yaml --check-prefix=XINDEX
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
EShStrNdx: 0xffff
|
||||
SectionHeaderStringTable: .foo
|
||||
Sections:
|
||||
- Type: SHT_NULL
|
||||
Link: .foo
|
||||
|
||||
# XINDEX: --- !ELF
|
||||
# XINDEX-NEXT: FileHeader:
|
||||
# XINDEX-NEXT: Class: ELFCLASS64
|
||||
# XINDEX-NEXT: Data: ELFDATA2LSB
|
||||
# XINDEX-NEXT: Type: ET_EXEC
|
||||
# XINDEX-NEXT: SectionHeaderStringTable: .foo
|
||||
# XINDEX-NEXT: Sections:
|
||||
# XINDEX-NEXT: - Type: SHT_NULL
|
||||
# XINDEX-NEXT: Link: .foo
|
||||
# XINDEX-NEXT: Size: 0x0
|
||||
# XINDEX-NEXT: ...
|
||||
|
||||
## Show the case when the string table section is also the symbol table's string
|
||||
## table (the key should be set).
|
||||
# RUN: yaml2obj --docnum=3 %s -o %t3.o
|
||||
# RUN: obj2yaml %t3.o > %t3.yaml
|
||||
# RUN: FileCheck %s --input-file=%t3.yaml --check-prefix=STRTAB
|
||||
|
||||
# STRTAB: --- !ELF
|
||||
# STRTAB-NEXT: FileHeader:
|
||||
# STRTAB-NEXT: Class: ELFCLASS64
|
||||
# STRTAB-NEXT: Data: ELFDATA2LSB
|
||||
# STRTAB-NEXT: Type: ET_EXEC
|
||||
# STRTAB-NEXT: SectionHeaderStringTable: .strtab
|
||||
# STRTAB-NEXT: Symbols:
|
||||
# STRTAB-NEXT: - Name: boz
|
||||
# STRTAB-NEXT: ...
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: ".strtab"
|
||||
Symbols:
|
||||
- Name: boz
|
||||
|
||||
## Document the case when the string table section is also the symbol table's
|
||||
## dynamic string table (the key should be set).
|
||||
## FIXME: Regardless of whether it is shared with the section header string
|
||||
## table or not, the dynstr (and also the dynsym) should be omitted if
|
||||
## they match the default behaviour.
|
||||
# RUN: yaml2obj --docnum=4 %s -o %t4.o
|
||||
# RUN: obj2yaml %t4.o > %t4.yaml
|
||||
# RUN: FileCheck %s --input-file=%t4.yaml --check-prefix=DYNSTR
|
||||
|
||||
# DYNSTR: --- !ELF
|
||||
# DYNSTR-NEXT: FileHeader:
|
||||
# DYNSTR-NEXT: Class: ELFCLASS64
|
||||
# DYNSTR-NEXT: Data: ELFDATA2LSB
|
||||
# DYNSTR-NEXT: Type: ET_EXEC
|
||||
# DYNSTR-NEXT: SectionHeaderStringTable: .dynstr
|
||||
# DYNSTR-NEXT: Sections:
|
||||
# DYNSTR-NEXT: - Name: .dynsym
|
||||
# DYNSTR-NEXT: Type: SHT_DYNSYM
|
||||
# DYNSTR-NEXT: Flags: [ SHF_ALLOC ]
|
||||
# DYNSTR-NEXT: Link: .dynstr
|
||||
# DYNSTR-NEXT: AddressAlign: 0x8
|
||||
# DYNSTR-NEXT: - Name: .dynstr
|
||||
# DYNSTR-NEXT: Type: SHT_STRTAB
|
||||
# DYNSTR-NEXT: Flags: [ SHF_ALLOC ]
|
||||
# DYNSTR-NEXT: Address: 0x30
|
||||
# DYNSTR-NEXT: AddressAlign: 0x1
|
||||
# DYNSTR-NEXT: DynamicSymbols:
|
||||
# DYNSTR-NEXT: - Name: boz
|
||||
# DYNSTR-NEXT: ...
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: ".dynstr"
|
||||
DynamicSymbols:
|
||||
- Name: boz
|
||||
|
||||
## Show the case when the name is the default ".shstrtab" (the key should not be
|
||||
## set).
|
||||
# RUN: yaml2obj --docnum=5 %s -o %t5.o
|
||||
# RUN: obj2yaml %t5.o > %t5.yaml
|
||||
# RUN: FileCheck %s --input-file=%t5.yaml --check-prefix=DEFAULT
|
||||
|
||||
# DEFAULT: --- !ELF
|
||||
# DEFAULT-NEXT: FileHeader:
|
||||
# DEFAULT-NEXT: Class: ELFCLASS64
|
||||
# DEFAULT-NEXT: Data: ELFDATA2LSB
|
||||
# DEFAULT-NEXT: Type: ET_EXEC
|
||||
# DEFAULT-NEXT: ...
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
|
||||
## Show the case when the e_shstrndx value is 0 and the name is ".shstrtab" (the
|
||||
## key should not be set).
|
||||
# RUN: yaml2obj --docnum=6 %s -o %t6.o
|
||||
# RUN: obj2yaml %t6.o > %t6.yaml
|
||||
# RUN: FileCheck %s --input-file=%t6.yaml --check-prefix=DEFXINDEX
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
EShStrNdx: 0xffff
|
||||
Sections:
|
||||
- Type: SHT_NULL
|
||||
Link: .shstrtab
|
||||
|
||||
# DEFXINDEX: --- !ELF
|
||||
# DEFXINDEX-NEXT: FileHeader:
|
||||
# DEFXINDEX-NEXT: Class: ELFCLASS64
|
||||
# DEFXINDEX-NEXT: Data: ELFDATA2LSB
|
||||
# DEFXINDEX-NEXT: Type: ET_EXEC
|
||||
# DEFXINDEX-NEXT: Sections:
|
||||
# DEFXINDEX-NEXT: - Type: SHT_NULL
|
||||
# DEFXINDEX-NEXT: Link: .shstrtab
|
||||
# DEFXINDEX-NEXT: Size: 0x0
|
||||
# DEFXINDEX-NEXT: ...
|
||||
|
||||
## Show that if there are no section headers, the key is not set.
|
||||
# RUN: yaml2obj --docnum=7 %s -o %t7.o
|
||||
# RUN: obj2yaml %t7.o > %t7.yaml
|
||||
# RUN: FileCheck %s --input-file=%t7.yaml --check-prefix=NOHDRS
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
Sections:
|
||||
- Type: SectionHeaderTable
|
||||
NoHeaders: true
|
||||
|
||||
# NOHDRS: --- !ELF
|
||||
# NOHDRS-NEXT: FileHeader:
|
||||
# NOHDRS-NEXT: Class: ELFCLASS64
|
||||
# NOHDRS-NEXT: Data: ELFDATA2LSB
|
||||
# NOHDRS-NEXT: Type: ET_EXEC
|
||||
## FIXME: There should be a SectionHeaderTable key as per the input.
|
||||
# NOHDRS-NEXT: ...
|
||||
|
||||
## Show that a custom-named section header string table can be in a reordered
|
||||
## section header table.
|
||||
# RUN: yaml2obj --docnum=8 %s -o %t8.o
|
||||
# RUN: obj2yaml %t8.o > %t8.yaml
|
||||
# RUN: FileCheck %s --input-file=%t8.yaml --check-prefix=REORDER
|
||||
|
||||
# REORDER: --- !ELF
|
||||
# REORDER-NEXT: FileHeader:
|
||||
# REORDER-NEXT: Class: ELFCLASS64
|
||||
# REORDER-NEXT: Data: ELFDATA2LSB
|
||||
# REORDER-NEXT: Type: ET_EXEC
|
||||
# REORDER-NEXT: SectionHeaderStringTable: .foo
|
||||
# REORDER-NEXT: Sections:
|
||||
# REORDER-NEXT: - Name: .baz
|
||||
# REORDER-NEXT: Type: SHT_PROGBITS
|
||||
# REORDER-NEXT: Offset: 0x180
|
||||
# REORDER-NEXT: - Name: .bar
|
||||
# REORDER-NEXT: Type: SHT_PROGBITS
|
||||
## FIXME: This should be at the start of the sections list.
|
||||
# REORDER-NEXT: - Type: SectionHeaderTable
|
||||
# REORDER-NEXT: Sections:
|
||||
# REORDER-NEXT: - Name: .baz
|
||||
# REORDER-NEXT: - Name: .foo
|
||||
# REORDER-NEXT: - Name: .bar
|
||||
# REORDER-NEXT: - Name: .strtab
|
||||
# REORDER-NEXT: ...
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: .foo
|
||||
Sections:
|
||||
- Type: SectionHeaderTable
|
||||
Sections:
|
||||
- Name: .baz
|
||||
- Name: .foo
|
||||
- Name: .bar
|
||||
## FIXME: we shouldn't need a .strtab section if there are no symbols.
|
||||
- Name: .strtab
|
||||
- Name: .baz
|
||||
Type: SHT_PROGBITS
|
||||
- Name: .bar
|
||||
Type: SHT_PROGBITS
|
||||
|
||||
## Document what happens when a custom-named section header string table is
|
||||
## placed in between other sections.
|
||||
## FIXME: obj2yaml should preserve the ordering in the Sections list, but it
|
||||
## doesn't for custom or default named tables.
|
||||
# RUN: yaml2obj --docnum=9 %s -o %t9.o
|
||||
# RUN: obj2yaml %t9.o > %t9.yaml
|
||||
# RUN: FileCheck %s --input-file=%t9.yaml --check-prefix=PLACED
|
||||
|
||||
# PLACED: --- !ELF
|
||||
# PLACED-NEXT: FileHeader:
|
||||
# PLACED-NEXT: Class: ELFCLASS64
|
||||
# PLACED-NEXT: Data: ELFDATA2LSB
|
||||
# PLACED-NEXT: Type: ET_EXEC
|
||||
# PLACED-NEXT: SectionHeaderStringTable: .foo
|
||||
# PLACED-NEXT: Sections:
|
||||
# PLACED-NEXT: - Name: .baz
|
||||
# PLACED-NEXT: Type: SHT_PROGBITS
|
||||
# PLACED-NEXT: - Name: .bar
|
||||
# PLACED-NEXT: Type: SHT_PROGBITS
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: .foo
|
||||
Sections:
|
||||
- Name: .baz
|
||||
Type: SHT_PROGBITS
|
||||
- Name: .foo
|
||||
Type: SHT_STRTAB
|
||||
- Name: .bar
|
||||
Type: SHT_PROGBITS
|
||||
|
||||
## Show that a custom-named section header string table can be given different
|
||||
## properties.
|
||||
# RUN: yaml2obj --docnum=10 %s -o %t10.o
|
||||
# RUN: obj2yaml %t10.o > %t10.yaml
|
||||
# RUN: FileCheck %s --input-file=%t10.yaml --check-prefix=PROPS
|
||||
|
||||
# PROPS: --- !ELF
|
||||
# PROPS-NEXT: FileHeader:
|
||||
# PROPS-NEXT: Class: ELFCLASS64
|
||||
# PROPS-NEXT: Data: ELFDATA2LSB
|
||||
# PROPS-NEXT: Type: ET_EXEC
|
||||
# PROPS-NEXT: SectionHeaderStringTable: .foo
|
||||
# PROPS-NEXT: Sections:
|
||||
# PROPS-NEXT: - Name: .foo
|
||||
# PROPS-NEXT: Type: SHT_STRTAB
|
||||
# PROPS-NEXT: Flags: [ SHF_ALLOC ]
|
||||
# PROPS-NEXT: ...
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: .foo
|
||||
Sections:
|
||||
- Name: .foo
|
||||
Type: SHT_STRTAB
|
||||
Flags: [ SHF_ALLOC ]
|
||||
|
||||
## Show that an error is reported if the section header string table name cannot
|
||||
## be read.
|
||||
# RUN: yaml2obj --docnum=11 %s -o %t11.o
|
||||
# RUNasda: not obj2yaml %t11.o 2>&1 | FileCheck %s --check-prefix=ERR -DFILE=%t11.o
|
||||
|
||||
# ERR: Error reading file: [[FILE]]: unable to read section header string table name: a section [index 1] has an invalid sh_name (0x10000) offset which goes past the end of the section name string table
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
Sections:
|
||||
- Name: .shstrtab
|
||||
Type: SHT_STRTAB
|
||||
ShName: 0x10000
|
||||
|
||||
## Show that the name is uniquified if necessary.
|
||||
|
||||
## Case 1: generic name.
|
||||
# RUN: yaml2obj --docnum=12 %s -o %t12.o
|
||||
# RUN: obj2yaml %t12.o > %t12.yaml
|
||||
# RUN: FileCheck %s --input-file=%t12.yaml --check-prefix=UNIQUIFY1
|
||||
|
||||
# UNIQUIFY1: --- !ELF
|
||||
# UNIQUIFY1-NEXT: FileHeader:
|
||||
# UNIQUIFY1-NEXT: Class: ELFCLASS64
|
||||
# UNIQUIFY1-NEXT: Data: ELFDATA2LSB
|
||||
# UNIQUIFY1-NEXT: Type: ET_EXEC
|
||||
# UNIQUIFY1-NEXT: SectionHeaderStringTable: '.strings (1)'
|
||||
# UNIQUIFY1-NEXT: Sections:
|
||||
# UNIQUIFY1-NEXT: - Name: .strings
|
||||
# UNIQUIFY1-NEXT: Type: SHT_PROGBITS
|
||||
# UNIQUIFY1-NEXT: ...
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: '.strings (1)'
|
||||
Sections:
|
||||
- Name: '.strings (2)'
|
||||
Type: SHT_PROGBITS
|
||||
|
||||
## Case 2: '.strtab' when symbols are present.
|
||||
# RUN: yaml2obj --docnum=13 %s -o %t13.o '-DNAME=".strtab (1)"'
|
||||
# RUN: obj2yaml %t13.o > %t13.yaml
|
||||
# RUN: FileCheck %s --input-file=%t13.yaml --check-prefix=UNIQUIFY2 \
|
||||
# RUN: -DNAME=.strtab
|
||||
|
||||
# UNIQUIFY2: --- !ELF
|
||||
# UNIQUIFY2-NEXT: FileHeader:
|
||||
# UNIQUIFY2-NEXT: Class: ELFCLASS64
|
||||
# UNIQUIFY2-NEXT: Data: ELFDATA2LSB
|
||||
# UNIQUIFY2-NEXT: Type: ET_EXEC
|
||||
# UNIQUIFY2-NEXT: SectionHeaderStringTable: '[[NAME]] (1)'
|
||||
# UNIQUIFY2-NEXT: Symbols:
|
||||
# UNIQUIFY2-NEXT: - Name: foo
|
||||
# UNIQUIFY2-NEXT: ...
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: [[NAME]]
|
||||
Symbols:
|
||||
- Name: foo
|
||||
|
||||
## Case 3: '.symtab' when symbols are present.
|
||||
# RUN: yaml2obj --docnum=13 %s -o %t14.o '-DNAME=".symtab (1)"'
|
||||
# RUN: obj2yaml %t14.o > %t14.yaml
|
||||
# RUN: FileCheck %s --input-file=%t14.yaml --check-prefix=UNIQUIFY2 \
|
||||
# RUN: -DNAME=.symtab
|
||||
|
||||
## Case 4: '.dynstr' when dynamic symbols are present.
|
||||
# RUN: yaml2obj --docnum=14 %s -o %t15.o '-DNAME=".dynstr (1)"'
|
||||
# RUN: obj2yaml %t15.o > %t15.yaml
|
||||
# RUN: FileCheck %s --input-file=%t15.yaml --check-prefix=UNIQUIFY3 \
|
||||
# RUN: -DNAME=.dynstr
|
||||
|
||||
# UNIQUIFY3: --- !ELF
|
||||
# UNIQUIFY3-NEXT: FileHeader:
|
||||
# UNIQUIFY3-NEXT: Class: ELFCLASS64
|
||||
# UNIQUIFY3-NEXT: Data: ELFDATA2LSB
|
||||
# UNIQUIFY3-NEXT: Type: ET_EXEC
|
||||
# UNIQUIFY3-NEXT: SectionHeaderStringTable: '[[NAME]] (1)'
|
||||
## FIXME: The .dynsym and .dynstr sections shouldn't need to be emitted, since
|
||||
## their values are the default produced by yaml2obj.
|
||||
# UNIQUIFY3-NEXT: Sections:
|
||||
# UNIQUIFY3-NEXT: - Name: .dynsym
|
||||
# UNIQUIFY3-NEXT: Type: SHT_DYNSYM
|
||||
# UNIQUIFY3-NEXT: Flags: [ SHF_ALLOC ]
|
||||
# UNIQUIFY3-NEXT: Link: .dynstr
|
||||
# UNIQUIFY3-NEXT: AddressAlign: 0x8
|
||||
# UNIQUIFY3-NEXT: - Name: .dynstr
|
||||
# UNIQUIFY3-NEXT: Type: SHT_STRTAB
|
||||
# UNIQUIFY3-NEXT: Flags: [ SHF_ALLOC ]
|
||||
# UNIQUIFY3-NEXT: Address: 0x30
|
||||
# UNIQUIFY3-NEXT: AddressAlign: 0x1
|
||||
# UNIQUIFY3-NEXT: DynamicSymbols:
|
||||
# UNIQUIFY3-NEXT: - Name: foo
|
||||
# UNIQUIFY3-NEXT: ...
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: [[NAME]]
|
||||
DynamicSymbols:
|
||||
- Name: foo
|
||||
|
||||
## Case 5: '.dynsym' when dynamic symbols are present.
|
||||
# RUN: yaml2obj --docnum=14 %s -o %t16.o '-DNAME=".dynsym (1)"'
|
||||
# RUN: obj2yaml %t16.o > %t16.yaml
|
||||
# RUN: FileCheck %s --input-file=%t16.yaml --check-prefix=UNIQUIFY3 \
|
||||
# RUN: -DNAME=.dynsym
|
||||
|
||||
## Case 6: Document what happens for '.debug_str' when DWARF debug strings are
|
||||
## requested. The dwarf2yaml code uses the last .debug_* named section
|
||||
## to populate the corresponding DWARF block. As a result, the original
|
||||
## .debug_str content is lost.
|
||||
## TODO: We should prevent the dwarf2yaml code from using the section header
|
||||
## string table to populate the DWARF block.
|
||||
# RUN: yaml2obj --docnum=15 %s -o %t17.o
|
||||
# RUN: obj2yaml %t17.o > %t17.yaml
|
||||
# RUN: FileCheck %s --input-file=%t17.yaml --check-prefix=UNIQUIFY6
|
||||
|
||||
# UNIQUIFY6: --- !ELF
|
||||
# UNIQUIFY6-NEXT: FileHeader:
|
||||
# UNIQUIFY6-NEXT: Class: ELFCLASS64
|
||||
# UNIQUIFY6-NEXT: Data: ELFDATA2LSB
|
||||
# UNIQUIFY6-NEXT: Type: ET_EXEC
|
||||
# UNIQUIFY6-NEXT: SectionHeaderStringTable: '.debug_str (1)'
|
||||
# UNIQUIFY6-NEXT: DWARF:
|
||||
# UNIQUIFY6-NEXT: debug_str:
|
||||
# UNIQUIFY6-NEXT: - ''
|
||||
# UNIQUIFY6-NEXT: - .debug_str
|
||||
# UNIQUIFY6-NEXT: - .strtab
|
||||
# UNIQUIFY6-NEXT: ...
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: '.debug_str (1)'
|
||||
DWARF:
|
||||
debug_str:
|
||||
- string
|
545
test/tools/yaml2obj/ELF/shstrtab.yaml
Normal file
545
test/tools/yaml2obj/ELF/shstrtab.yaml
Normal file
@ -0,0 +1,545 @@
|
||||
## A user should be able to specify any arbitrary string table as the section
|
||||
## header string table, including the symbol string table. This test covers
|
||||
## various cases to do with this.
|
||||
|
||||
## Case 1: custom name specified for string table.
|
||||
# RUN: yaml2obj --docnum=1 %s -o %t1 -DSHSTRTAB=.strings
|
||||
# RUN: llvm-readelf -S -p=.strings %t1 | FileCheck %s --check-prefix=CASE1
|
||||
|
||||
# CASE1: There are 5 section headers
|
||||
# CASE1-EMPTY:
|
||||
# CASE1-NEXT: Section Headers:
|
||||
# CASE1-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
|
||||
# CASE1-NEXT: [ 0] NULL
|
||||
# CASE1-NEXT: [ 1] .foo{{ }}
|
||||
# CASE1-NEXT: [ 2] .bar{{ }}
|
||||
# CASE1-NEXT: [ 3] .strtab{{ }}
|
||||
# CASE1-NEXT: [ 4] .strings STRTAB 0000000000000000 [[#%x,]] 00001c 00 0 0 1
|
||||
|
||||
# CASE1: String dump of section '.strings':
|
||||
# CASE1-NEXT: [ 1] .strings{{$}}
|
||||
# CASE1-NEXT: [ a] .bar{{$}}
|
||||
# CASE1-NEXT: [ f] .foo{{$}}
|
||||
# CASE1-NEXT: [ 14] .strtab{{$}}
|
||||
# CASE1-EMPTY:
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: [[SHSTRTAB=<none>]]
|
||||
Sections:
|
||||
- Name: .foo
|
||||
Type: SHT_PROGBITS
|
||||
- Name: [[OTHER=.bar]]
|
||||
Type: SHT_PROGBITS
|
||||
|
||||
## Case 2: reuse symbol string table.
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t2 -DSHSTRTAB=.strtab
|
||||
# RUN: llvm-readelf -S -s -p=.strtab %t2 | FileCheck %s --check-prefix=CASE2
|
||||
|
||||
# CASE2: There are 5 section headers
|
||||
# CASE2-EMPTY:
|
||||
# CASE2-NEXT: Section Headers:
|
||||
# CASE2-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
|
||||
# CASE2-NEXT: [ 0] NULL
|
||||
# CASE2-NEXT: [ 1] .foo{{ }}
|
||||
# CASE2-NEXT: [ 2] .bar{{ }}
|
||||
# CASE2-NEXT: [ 3] .symtab{{ }}
|
||||
# CASE2-NEXT: [ 4] .strtab STRTAB 0000000000000000 [[#%x,]] 000023 00 0 0 1
|
||||
|
||||
# CASE2: Symbol table '.symtab' contains 3 entries:
|
||||
# CASE2-NEXT: Num: {{.*}} Ndx Name
|
||||
# CASE2-NEXT: 0: {{.*}} UND {{$}}
|
||||
# CASE2-NEXT: 1: {{.*}} baz{{$}}
|
||||
# CASE2-NEXT: 2: {{.*}} bob{{$}}
|
||||
|
||||
# CASE2: String dump of section '.strtab':
|
||||
# CASE2-NEXT: [ 1] baz{{$}}
|
||||
# CASE2-NEXT: [ 5] .bar{{$}}
|
||||
# CASE2-NEXT: [ a] .foo{{$}}
|
||||
# CASE2-NEXT: [ f] bob{{$}}
|
||||
# CASE2-NEXT: [ 13] .strtab{{$}}
|
||||
# CASE2-NEXT: [ 1b] .symtab{{$}}
|
||||
# CASE2-EMPTY:
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: [[SHSTRTAB]]
|
||||
Sections:
|
||||
- Name: .foo
|
||||
Type: SHT_PROGBITS
|
||||
- Name: .bar
|
||||
Type: SHT_PROGBITS
|
||||
Symbols:
|
||||
- Name: baz
|
||||
- Name: bob
|
||||
|
||||
## Case 3: reuse dynamic string table.
|
||||
# RUN: yaml2obj --docnum=3 %s -o %t3 -DSHSTRTAB=.dynstr
|
||||
# RUN: llvm-readelf -S --dyn-syms -p=.dynstr %t3 | FileCheck %s --check-prefix=CASE3
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: [[SHSTRTAB]]
|
||||
Sections:
|
||||
- Name: .foo
|
||||
Type: SHT_PROGBITS
|
||||
- Name: .bar
|
||||
Type: SHT_PROGBITS
|
||||
DynamicSymbols:
|
||||
- Name: baz
|
||||
- Name: bob
|
||||
|
||||
# CASE3: There are 6 section headers
|
||||
# CASE3-EMPTY:
|
||||
# CASE3-NEXT: Section Headers:
|
||||
# CASE3-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
|
||||
# CASE3-NEXT: [ 0] NULL
|
||||
# CASE3-NEXT: [ 1] .foo{{ }}
|
||||
# CASE3-NEXT: [ 2] .bar{{ }}
|
||||
# CASE3-NEXT: [ 3] .dynsym{{ }}
|
||||
# CASE3-NEXT: [ 4] .dynstr STRTAB 0000000000000048 [[#%x,]] 00002b 00 A 0 0 1
|
||||
# CASE3-NEXT: [ 5] .strtab{{ }}
|
||||
|
||||
# CASE3: Symbol table '.dynsym' contains 3 entries:
|
||||
# CASE3-NEXT: Num: {{.*}} Ndx Name
|
||||
# CASE3-NEXT: 0: {{.*}} UND {{$}}
|
||||
# CASE3-NEXT: 1: {{.*}} baz{{$}}
|
||||
# CASE3-NEXT: 2: {{.*}} bob{{$}}
|
||||
|
||||
# CASE3: String dump of section '.dynstr':
|
||||
# CASE3-NEXT: [ 1] baz{{$}}
|
||||
# CASE3-NEXT: [ 5] .dynstr{{$}}
|
||||
# CASE3-NEXT: [ d] .bar{{$}}
|
||||
# CASE3-NEXT: [ 12] .foo{{$}}
|
||||
# CASE3-NEXT: [ 17] .dynsym{{$}}
|
||||
# CASE3-NEXT: [ 1f] bob{{$}}
|
||||
# CASE3-NEXT: [ 23] .strtab{{$}}
|
||||
# CASE3-EMPTY:
|
||||
|
||||
## Case 4: shstrtab specified to be otherwise ungenerated non-strtab implicit
|
||||
## section.
|
||||
# RUN: yaml2obj --docnum=1 %s -o %t4 -DSHSTRTAB=.symtab
|
||||
# RUN: llvm-readelf -S -p=.symtab %t4 | FileCheck %s --check-prefix=CASE4
|
||||
|
||||
# CASE4: There are 5 section headers
|
||||
# CASE4-EMPTY:
|
||||
# CASE4-NEXT: Section Headers:
|
||||
# CASE4-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
|
||||
# CASE4-NEXT: [ 0] NULL
|
||||
# CASE4-NEXT: [ 1] .foo{{ }}
|
||||
# CASE4-NEXT: [ 2] .bar{{ }}
|
||||
# CASE4-NEXT: [ 3] .strtab{{ }}
|
||||
# CASE4-NEXT: [ 4] .symtab STRTAB 0000000000000000 [[#%x,]] 00001b 00 0 0 1
|
||||
|
||||
# CASE4: String dump of section '.symtab':
|
||||
# CASE4-NEXT: [ 1] .bar{{$}}
|
||||
# CASE4-NEXT: [ 6] .foo{{$}}
|
||||
# CASE4-NEXT: [ b] .strtab{{$}}
|
||||
# CASE4-NEXT: [ 13] .symtab{{$}}
|
||||
|
||||
## Case 5: shstrtab specified to be otherwise ungenerated .dynstr section. In
|
||||
## this case, the SHF_ALLOC flag will be set.
|
||||
# RUN: yaml2obj --docnum=1 %s -o %t5 -DSHSTRTAB=.dynstr
|
||||
# RUN: llvm-readelf -S -p=.dynstr %t5 | FileCheck %s --check-prefix=CASE5
|
||||
|
||||
# CASE5: There are 5 section headers
|
||||
# CASE5-EMPTY:
|
||||
# CASE5-NEXT: Section Headers:
|
||||
# CASE5-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
|
||||
# CASE5-NEXT: [ 0] NULL
|
||||
# CASE5-NEXT: [ 1] .foo{{ }}
|
||||
# CASE5-NEXT: [ 2] .bar{{ }}
|
||||
# CASE5-NEXT: [ 3] .strtab{{ }}
|
||||
# CASE5-NEXT: [ 4] .dynstr STRTAB 0000000000000001 [[#%x,]] 00001b 00 A 0 0 1
|
||||
|
||||
# CASE5: String dump of section '.dynstr':
|
||||
# CASE5-NEXT: [ 1] .dynstr{{$}}
|
||||
# CASE5-NEXT: [ 9] .bar{{$}}
|
||||
# CASE5-NEXT: [ e] .foo{{$}}
|
||||
# CASE5-NEXT: [ 13] .strtab{{$}}
|
||||
|
||||
## Case 6: shstrtab specified to be otherwise ungenerated .debug_str section. In
|
||||
## this case, the sh_entsize will be set to 1.
|
||||
# RUN: yaml2obj --docnum=1 %s -o %t6 -DSHSTRTAB=.debug_str
|
||||
# RUN: llvm-readelf -S -p=.debug_str %t6 | FileCheck %s --check-prefix=CASE6
|
||||
|
||||
# CASE6: There are 5 section headers
|
||||
# CASE6-EMPTY:
|
||||
# CASE6-NEXT: Section Headers:
|
||||
# CASE6-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
|
||||
# CASE6-NEXT: [ 0] NULL
|
||||
# CASE6-NEXT: [ 1] .foo{{ }}
|
||||
# CASE6-NEXT: [ 2] .bar{{ }}
|
||||
# CASE6-NEXT: [ 3] .strtab{{ }}
|
||||
# CASE6-NEXT: [ 4] .debug_str STRTAB 0000000000000000 [[#%x,]] 00001e 01 0 0 1
|
||||
|
||||
# CASE6: String dump of section '.debug_str':
|
||||
# CASE6-NEXT: [ 1] .debug_str{{$}}
|
||||
# CASE6-NEXT: [ c] .bar{{$}}
|
||||
# CASE6-NEXT: [ 11] .foo{{$}}
|
||||
# CASE6-NEXT: [ 16] .strtab{{$}}
|
||||
|
||||
## Case 7: shstrtab specified to be the .symtab section, when there are symbols.
|
||||
## This triggers an error (since the symbols cannot be represented in the
|
||||
## section as section names).
|
||||
# RUN: not yaml2obj --docnum=2 %s -o %t7 -DSHSTRTAB=.symtab 2>&1 | FileCheck %s --check-prefix=ERR1
|
||||
|
||||
# ERR1: error: cannot use '.symtab' as the section header name table when there are symbols
|
||||
|
||||
## Case 8: shstrtab specified to be the .dynsym section, when there are dynamic
|
||||
## symbols. This triggers an error (since the symbols cannot be represented in
|
||||
## the section as section names).
|
||||
# RUN: not yaml2obj --docnum=3 %s -o %t8 -DSHSTRTAB=.dynsym 2>&1 | FileCheck %s --check-prefix=ERR2
|
||||
|
||||
# ERR2: error: cannot use '.dynsym' as the section header name table when there are dynamic symbols
|
||||
|
||||
## Case 9: shstrtab specified to be the .debug_str section, when there are DWARF
|
||||
## debug strings. This triggers an error.
|
||||
# RUN: not yaml2obj --docnum=4 %s -o %t9 2>&1 | FileCheck %s --check-prefix=ERR3
|
||||
|
||||
# ERR3: error: cannot use '.debug_str' as the section header name table when it is needed for DWARF output
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: .debug_str
|
||||
DWARF:
|
||||
debug_str:
|
||||
- a
|
||||
|
||||
## Case 10: can explicitly specifiy ".shstrtab" as shstrtab. Output will be the
|
||||
## same as if it wasn't sepcified at all.
|
||||
# RUN: yaml2obj --docnum=1 %s -o %t10 -DSHSTRTAB=.shstrtab
|
||||
# RUN: llvm-readelf -S -p=.shstrtab %t10 | FileCheck %s --check-prefix=CASE10
|
||||
# RUN: yaml2obj --docnum=1 %s -o %t10.default
|
||||
# RUN: cmp %t10 %t10.default
|
||||
|
||||
# CASE10: There are 5 section headers
|
||||
# CASE10-EMPTY:
|
||||
# CASE10-NEXT: Section Headers:
|
||||
# CASE10-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
|
||||
# CASE10-NEXT: [ 0] NULL
|
||||
# CASE10-NEXT: [ 1] .foo{{ }}
|
||||
# CASE10-NEXT: [ 2] .bar{{ }}
|
||||
# CASE10-NEXT: [ 3] .strtab{{ }}
|
||||
# CASE10-NEXT: [ 4] .shstrtab STRTAB 0000000000000000 [[#%x,]] 00001d 00 0 0 1
|
||||
|
||||
# CASE10: String dump of section '.shstrtab':
|
||||
# CASE10-NEXT: [ 1] .bar{{$}}
|
||||
# CASE10-NEXT: [ 6] .foo{{$}}
|
||||
# CASE10-NEXT: [ b] .shstrtab{{$}}
|
||||
# CASE10-NEXT: [ 15] .strtab{{$}}
|
||||
# CASE10-EMPTY:
|
||||
|
||||
## Case 11: can specify custom shstrtab properties.
|
||||
## FIXME: when the section is listed explicitly, the sh_addralign value is 0 if
|
||||
## not overwritten, which is inconsistent with when the section is not
|
||||
## specified at all.
|
||||
# RUN: yaml2obj --docnum=5 %s -o %t11 -DENTSIZE=2
|
||||
# RUN: llvm-readelf -S -p=.strings %t11 | FileCheck %s --check-prefix=CASE11
|
||||
|
||||
# CASE11: There are 5 section headers
|
||||
# CASE11-EMPTY:
|
||||
# CASE11-NEXT: Section Headers:
|
||||
# CASE11-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
|
||||
# CASE11-NEXT: [ 0] NULL
|
||||
# CASE11-NEXT: [ 1] .foo{{ }}
|
||||
# CASE11-NEXT: [ 2] .strings STRTAB 0000000000000000 [[#%x,]] 00001c 02 0 0 0
|
||||
# CASE11-NEXT: [ 3] .bar{{ }}
|
||||
# CASE11-NEXT: [ 4] .strtab{{ }}
|
||||
|
||||
# CASE11: String dump of section '.strings':
|
||||
# CASE11-NEXT: [ 1] .strings{{$}}
|
||||
# CASE11-NEXT: [ a] .bar{{$}}
|
||||
# CASE11-NEXT: [ f] .foo{{$}}
|
||||
# CASE11-NEXT: [ 14] .strtab{{$}}
|
||||
# CASE11-EMPTY:
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: .strings
|
||||
Sections:
|
||||
- Name: .foo
|
||||
Type: SHT_PROGBITS
|
||||
- Name: .strings
|
||||
Type: [[TYPE=SHT_STRTAB]]
|
||||
EntSize: [[ENTSIZE=<none>]]
|
||||
Size: [[SIZE=<none>]]
|
||||
Content: [[CONTENT=<none>]]
|
||||
- Name: .bar
|
||||
Type: SHT_PROGBITS
|
||||
|
||||
## Case 12: shstrtab does not have SHT_STRTAB type. Default properties will be
|
||||
## derived from the specified section type.
|
||||
# RUN: yaml2obj --docnum=5 %s -o %t12 -DTYPE=SHT_RELA
|
||||
# RUN: llvm-readelf -S %t12 | FileCheck %s --check-prefix=CASE12
|
||||
|
||||
# CASE12: There are 5 section headers
|
||||
# CASE12-EMPTY:
|
||||
# CASE12-NEXT: Section Headers:
|
||||
# CASE12-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
|
||||
# CASE12-NEXT: [ 0] NULL
|
||||
# CASE12-NEXT: [ 1] .foo{{ }}
|
||||
# CASE12-NEXT: [ 2] .strings RELA 0000000000000000 [[#%x,]] 00001c 18 0 0 0
|
||||
# CASE12-NEXT: [ 3] .bar{{ }}
|
||||
# CASE12-NEXT: [ 4] .strtab{{ }}
|
||||
|
||||
## Case 13: shstrtab has specified Content. The specified content overrides the
|
||||
## implicitly generated content.
|
||||
# RUN: yaml2obj --docnum=5 %s -o %t13 -DCONTENT="00616263646566676800696a6b6c006d6e6f70007172737475767700787a7b7c00"
|
||||
# RUN: llvm-readelf -S %t13 | FileCheck %s --check-prefix=CASE13
|
||||
|
||||
# CASE13: There are 5 section headers
|
||||
# CASE13-EMPTY:
|
||||
# CASE13-NEXT: Section Headers:
|
||||
# CASE13-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
|
||||
# CASE13-NEXT: [ 0] NULL
|
||||
# CASE13-NEXT: [ 1] mnop{{ }}
|
||||
# CASE13-NEXT: [ 2] abcdefgh STRTAB 0000000000000000 [[#%x,]] 000021 00 0 0 0
|
||||
# CASE13-NEXT: [ 3] ijkl{{ }}
|
||||
# CASE13-NEXT: [ 4] qrstuvw{{ }}
|
||||
|
||||
## Case 14: shstrtab has specified Size. The section will be filled with zeros
|
||||
## to the requested size.
|
||||
# RUN: yaml2obj --docnum=5 %s -o %t14 -DSIZE=32
|
||||
# RUN: llvm-readelf -S -p=2 %t14 | FileCheck %s --check-prefix=CASE14
|
||||
|
||||
# CASE14: There are 5 section headers
|
||||
# CASE14-EMPTY:
|
||||
# CASE14-NEXT: Section Headers:
|
||||
# CASE14-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
|
||||
# CASE14-NEXT: [ 0] NULL
|
||||
# CASE14-NEXT: [ 1] PROGBITS
|
||||
# CASE14-NEXT: [ 2] STRTAB 0000000000000000 [[#%x,]] 000020 00 0 0 0
|
||||
# CASE14-NEXT: [ 3] PROGBITS
|
||||
# CASE14-NEXT: [ 4] STRTAB
|
||||
|
||||
# CASE14: String dump of section '':
|
||||
# CASE14-EMPTY:
|
||||
|
||||
## Case 15: custom shstrtab and no section header table. The section header
|
||||
## names shouldn't appear anywhere in the output file.
|
||||
# RUN: yaml2obj --docnum=6 %s -o %t15
|
||||
# RUN: FileCheck %s --input-file=%t15 \
|
||||
# RUN: --implicit-check-not=.strings --implicit-check-not=.foo \
|
||||
# RUN: --implicit-check-not=.bar
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: .strings
|
||||
Sections:
|
||||
- Name: .foo
|
||||
Type: SHT_PROGBITS
|
||||
- Name: .bar
|
||||
Type: SHT_PROGBITS
|
||||
- Type: SectionHeaderTable
|
||||
NoHeaders: true
|
||||
|
||||
## Case 16: custom shstrtab can be reordered in the section header table.
|
||||
# RUN: yaml2obj --docnum=7 %s -o %t16
|
||||
# RUN: llvm-readelf -S %t16 | FileCheck %s --check-prefix=CASE16
|
||||
|
||||
# CASE16: There are 5 section headers
|
||||
# CASE16-EMPTY:
|
||||
# CASE16-NEXT: Section Headers:
|
||||
# CASE16-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
|
||||
# CASE16-NEXT: [ 0] NULL
|
||||
# CASE16-NEXT: [ 1] .foo{{ }}
|
||||
# CASE16-NEXT: [ 2] .strings STRTAB 0000000000000000 [[#%x,]] 00001c 00 0 0 1
|
||||
# CASE16-NEXT: [ 3] .bar{{ }}
|
||||
# CASE16-NEXT: [ 4] .strtab{{ }}
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: .strings
|
||||
Sections:
|
||||
- Name: .foo
|
||||
Type: SHT_PROGBITS
|
||||
- Name: .bar
|
||||
Type: SHT_PROGBITS
|
||||
- Type: SectionHeaderTable
|
||||
Sections:
|
||||
- Name: .foo
|
||||
- Name: .strings
|
||||
- Name: .bar
|
||||
- Name: .strtab
|
||||
|
||||
## Case 17: custom shstrtab section header can be excluded.
|
||||
# RUN: yaml2obj --docnum=8 %s -o %t17
|
||||
# RUN: llvm-readelf -h -S %t17 | FileCheck %s --check-prefix=CASE17
|
||||
|
||||
# CASE17: Section header string table index: 0
|
||||
# CASE17: There are 4 section headers
|
||||
# CASE17-EMPTY:
|
||||
# CASE17-NEXT: Section Headers:
|
||||
# CASE17-NEXT: [Nr] Name Type
|
||||
# CASE17-NEXT: [ 0] <no-strings> NULL
|
||||
# CASE17-NEXT: [ 1] <no-strings> PROGBITS
|
||||
# CASE17-NEXT: [ 2] <no-strings> PROGBITS
|
||||
# CASE17-NEXT: [ 3] <no-strings> STRTAB
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: .strings
|
||||
Sections:
|
||||
- Name: .foo
|
||||
Type: SHT_PROGBITS
|
||||
- Name: .bar
|
||||
Type: SHT_PROGBITS
|
||||
- Type: SectionHeaderTable
|
||||
Sections:
|
||||
- Name: .foo
|
||||
- Name: .bar
|
||||
- Name: .strtab
|
||||
Excluded:
|
||||
- Name: .strings
|
||||
|
||||
## Case 18: section name for excluded section does not appear in custom
|
||||
## shstrtab.
|
||||
# RUN: yaml2obj --docnum=9 %s -o %t18
|
||||
# RUN: llvm-readelf -S -p=.strings %t18 | FileCheck %s --check-prefix=CASE18
|
||||
|
||||
# CASE18: There are 4 section headers
|
||||
# CASE18-EMPTY:
|
||||
# CASE18-NEXT: Section Headers:
|
||||
# CASE18-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
|
||||
# CASE18-NEXT: [ 0] NULL
|
||||
# CASE18-NEXT: [ 1] .foo{{ }}
|
||||
# CASE18-NEXT: [ 2] .strings STRTAB 0000000000000000 [[#%x,]] 000017 00 0 0 1
|
||||
# CASE18-NEXT: [ 3] .strtab{{ }}
|
||||
|
||||
# CASE18: String dump of section '.strings':
|
||||
# CASE18-NEXT: [ 1] .strings
|
||||
# CASE18-NEXT: [ a] .foo
|
||||
# CASE18-NEXT: [ f] .strtab
|
||||
# CASE18-EMPTY:
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
SectionHeaderStringTable: .strings
|
||||
Sections:
|
||||
- Name: .foo
|
||||
Type: SHT_PROGBITS
|
||||
- Name: .bar
|
||||
Type: SHT_PROGBITS
|
||||
- Type: SectionHeaderTable
|
||||
Sections:
|
||||
- Name: .foo
|
||||
- Name: .strings
|
||||
- Name: .strtab
|
||||
Excluded:
|
||||
- Name: .bar
|
||||
|
||||
## Case 19: custom shstrtab can have a uniqued name.
|
||||
# RUN: yaml2obj --docnum=1 %s -o %t19 '-DSHSTRTAB=.strings (1)' '-DOTHER=.strings (0)'
|
||||
# RUN: llvm-readelf -S -p=4 %t19 | FileCheck %s --check-prefix=CASE19
|
||||
|
||||
# CASE19: There are 5 section headers
|
||||
# CASE19-EMPTY:
|
||||
# CASE19-NEXT: Section Headers:
|
||||
# CASE19-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
|
||||
# CASE19-NEXT: [ 0] NULL
|
||||
# CASE19-NEXT: [ 1] .foo{{ }}
|
||||
# CASE19-NEXT: [ 2] .strings PROGBITS
|
||||
# CASE19-NEXT: [ 3] .strtab{{ }}
|
||||
# CASE19-NEXT: [ 4] .strings STRTAB 0000000000000000 [[#%x,]] 000017 00 0 0 1
|
||||
|
||||
# CASE19: String dump of section '.strings':
|
||||
# CASE19-NEXT: [ 1] .strings{{$}}
|
||||
# CASE19-NEXT: [ a] .foo{{$}}
|
||||
# CASE19-NEXT: [ f] .strtab{{$}}
|
||||
# CASE19-EMPTY:
|
||||
|
||||
## Case 20: custom shstrtab named ".strtab" with uniquifying ID.
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t20 '-DSHSTRTAB=.strtab (1)'
|
||||
# RUN: llvm-readelf -S -s -p=4 -p=5 %t20 | FileCheck %s --check-prefix=CASE20
|
||||
|
||||
# CASE20: There are 6 section headers
|
||||
# CASE20-EMPTY:
|
||||
# CASE20-NEXT: Section Headers:
|
||||
# CASE20-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
|
||||
# CASE20-NEXT: [ 0] NULL
|
||||
# CASE20-NEXT: [ 1] .foo{{ }}
|
||||
# CASE20-NEXT: [ 2] .bar{{ }}
|
||||
# CASE20-NEXT: [ 3] .symtab{{ }}
|
||||
# CASE20-NEXT: [ 4] .strtab STRTAB [[#%x,]] [[#%x,]] 000009 00 0 0 1
|
||||
# CASE20-NEXT: [ 5] .strtab STRTAB 0000000000000000 [[#%x,]] 00001b 00 0 0 1
|
||||
|
||||
# CASE20: Symbol table '.symtab' contains 3 entries:
|
||||
# CASE20-NEXT: Num: {{.*}} Ndx Name
|
||||
# CASE20-NEXT: 0: {{.*}} UND {{$}}
|
||||
# CASE20-NEXT: 1: {{.*}} baz{{$}}
|
||||
# CASE20-NEXT: 2: {{.*}} bob{{$}}
|
||||
|
||||
# CASE20: String dump of section '.strtab':
|
||||
# CASE20-NEXT: [ 1] baz
|
||||
# CASE20-NEXT: [ 5] bob
|
||||
# CASE20-EMPTY:
|
||||
|
||||
# CASE20: String dump of section '.strtab':
|
||||
# CASE20-NEXT: [ 1] .bar{{$}}
|
||||
# CASE20-NEXT: [ 6] .foo{{$}}
|
||||
# CASE20-NEXT: [ b] .strtab{{$}}
|
||||
# CASE20-NEXT: [ 13] .symtab{{$}}
|
||||
# CASE20-EMPTY:
|
||||
|
||||
## Case 21: custom shstrtab named ".dynstr" with uniquifying ID.
|
||||
# RUN: yaml2obj --docnum=3 %s -o %t21 '-DSHSTRTAB=.dynstr (1)'
|
||||
# RUN: llvm-readelf -S --dyn-syms -p=4 -p=6 %t21 | FileCheck %s --check-prefix=CASE21
|
||||
|
||||
# CASE21: There are 7 section headers
|
||||
# CASE21-EMPTY:
|
||||
# CASE21-NEXT: Section Headers:
|
||||
# CASE21-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
|
||||
# CASE21-NEXT: [ 0] NULL
|
||||
# CASE21-NEXT: [ 1] .foo{{ }}
|
||||
# CASE21-NEXT: [ 2] .bar{{ }}
|
||||
# CASE21-NEXT: [ 3] .dynsym{{ }}
|
||||
# CASE21-NEXT: [ 4] .dynstr STRTAB [[#%x,]] [[#%x,]] 000009 00 A 0 0 1
|
||||
# CASE21-NEXT: [ 5] .strtab{{ }}
|
||||
# CASE21-NEXT: [ 6] .dynstr STRTAB 0000000000000000 [[#%x,]] 000023 00 0 0 1
|
||||
|
||||
# CASE21: Symbol table '.dynsym' contains 3 entries:
|
||||
# CASE21-NEXT: Num: {{.*}} Ndx Name
|
||||
# CASE21-NEXT: 0: {{.*}} UND {{$}}
|
||||
# CASE21-NEXT: 1: {{.*}} baz{{$}}
|
||||
# CASE21-NEXT: 2: {{.*}} bob{{$}}
|
||||
|
||||
# CASE21: String dump of section '.dynstr':
|
||||
# CASE21-NEXT: [ 1] baz
|
||||
# CASE21-NEXT: [ 5] bob
|
||||
# CASE21-EMPTY:
|
||||
|
||||
# CASE21: String dump of section '.dynstr':
|
||||
# CASE21-NEXT: [ 1] .dynstr{{$}}
|
||||
# CASE21-NEXT: [ 9] .bar{{$}}
|
||||
# CASE21-NEXT: [ e] .foo{{$}}
|
||||
# CASE21-NEXT: [ 13] .dynsym{{$}}
|
||||
# CASE21-NEXT: [ 1b] .strtab{{$}}
|
||||
# CASE21-EMPTY:
|
@ -31,6 +31,7 @@ class ELFDumper {
|
||||
|
||||
DenseMap<StringRef, uint32_t> UsedSectionNames;
|
||||
std::vector<std::string> SectionNames;
|
||||
Optional<uint32_t> ShStrTabIndex;
|
||||
|
||||
DenseMap<StringRef, uint32_t> UsedSymbolNames;
|
||||
std::vector<std::string> SymbolNames;
|
||||
@ -289,6 +290,13 @@ template <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
|
||||
Sections = *SectionsOrErr;
|
||||
SectionNames.resize(Sections.size());
|
||||
|
||||
if (Sections.size() > 0) {
|
||||
ShStrTabIndex = Obj.getHeader().e_shstrndx;
|
||||
if (*ShStrTabIndex == ELF::SHN_XINDEX)
|
||||
ShStrTabIndex = Sections[0].sh_link;
|
||||
// TODO: Set EShStrndx if the value doesn't represent a real section.
|
||||
}
|
||||
|
||||
// Normally an object that does not have sections has e_shnum == 0.
|
||||
// Also, e_shnum might be 0, when the the number of entries in the section
|
||||
// header table is larger than or equal to SHN_LORESERVE (0xff00). In this
|
||||
@ -398,6 +406,29 @@ template <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
|
||||
return !shouldPrintSection(S, Sections[S.OriginalSecNdx], Y->DWARF);
|
||||
});
|
||||
|
||||
// The section header string table by default is assumed to be called
|
||||
// ".shstrtab" and be in its own unique section. However, it's possible for it
|
||||
// to be called something else and shared with another section. If the name
|
||||
// isn't the default, provide this in the YAML.
|
||||
if (ShStrTabIndex && *ShStrTabIndex != ELF::SHN_UNDEF &&
|
||||
*ShStrTabIndex < Sections.size()) {
|
||||
StringRef ShStrtabName;
|
||||
if (SymTab && SymTab->sh_link == *ShStrTabIndex) {
|
||||
// Section header string table is shared with the symbol table. Use that
|
||||
// section's name (usually .strtab).
|
||||
ShStrtabName = cantFail(Obj.getSectionName(Sections[SymTab->sh_link]));
|
||||
} else if (DynSymTab && DynSymTab->sh_link == *ShStrTabIndex) {
|
||||
// Section header string table is shared with the dynamic symbol table.
|
||||
// Use that section's name (usually .dynstr).
|
||||
ShStrtabName = cantFail(Obj.getSectionName(Sections[DynSymTab->sh_link]));
|
||||
} else {
|
||||
// Otherwise, the section name potentially needs uniquifying.
|
||||
ShStrtabName = cantFail(getUniquedSectionName(Sections[*ShStrTabIndex]));
|
||||
}
|
||||
if (ShStrtabName != ".shstrtab")
|
||||
Y->Header.SectionHeaderStringTable = ShStrtabName;
|
||||
}
|
||||
|
||||
Y->Chunks = std::move(Chunks);
|
||||
return Y.release();
|
||||
}
|
||||
@ -486,6 +517,12 @@ Optional<DWARFYAML::Data> ELFDumper<ELFT>::dumpDWARFSections(
|
||||
|
||||
if (ELFYAML::RawContentSection *RawSec =
|
||||
dyn_cast<ELFYAML::RawContentSection>(C.get())) {
|
||||
// FIXME: The debugDebug* functions should take the content as stored in
|
||||
// RawSec. Currently, they just use the last section with the matching
|
||||
// name, which defeats this attempt to skip reading a section header
|
||||
// string table with the same name as a DWARF section.
|
||||
if (ShStrTabIndex && RawSec->OriginalSecNdx == *ShStrTabIndex)
|
||||
continue;
|
||||
Error Err = Error::success();
|
||||
cantFail(std::move(Err));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user