aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorgii Rymar <grimar@accesssoftek.com>2020-12-04 13:23:26 +0300
committerGeorgii Rymar <grimar@accesssoftek.com>2020-12-09 12:14:58 +0300
commitabae3c11969defb6537dff99806668eacb6f0057 (patch)
tree8cd8e93d676eb0117f62c408e8ddd66a96eeee12
parent0ef0de65f14ea63a1800c56cbc2faad5b10e828f (diff)
downloadllvm-project-abae3c11969defb6537dff99806668eacb6f0057.tar.gz
[obj2yaml] - Support dumping objects that have multiple SHT_SYMTAB_SHNDX sections.
It is allowed to have multiple `SHT_SYMTAB_SHNDX` sections, though we currently don't implement it. The current implementation assumes that there is a maximum of one SHT_SYMTAB_SHNDX section and that it is always linked with .symtab section. This patch drops this limitations. Differential revision: https://reviews.llvm.org/D92644
-rw-r--r--llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml67
-rw-r--r--llvm/tools/obj2yaml/elf2yaml.cpp47
2 files changed, 58 insertions, 56 deletions
diff --git a/llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml b/llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml
index 2b337538acba..1c1e95e5bacb 100644
--- a/llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml
+++ b/llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml
@@ -94,7 +94,7 @@ Symbols:
# RUN: yaml2obj --docnum=4 %s -o %t4
# RUN: not obj2yaml %t4 2>&1 | FileCheck %s -DFILE=%t4 --check-prefix=CASE4
-## CASE4: Error reading file: [[FILE]]: SHT_SYMTAB_SHNDX has 3 entries, but the symbol table associated has 2
+## CASE4: Error reading file: [[FILE]]: unable to read extended section indexes: SHT_SYMTAB_SHNDX has 3 entries, but the symbol table associated has 2
--- !ELF
FileHeader:
@@ -113,12 +113,14 @@ Symbols:
Index: SHN_XINDEX
## ELF gABI allows having multiple SHT_SYMTAB_SHNDX sections.
-## We only support having one associated with .symtab now.
+## Only one is allowed to be linked with a corresponding symbol table section though.
+## Check we report an error when multiple SHT_SYMTAB_SHNDX sections are linked
+## to the same symbol table.
# RUN: yaml2obj --docnum=5 %s -o %t5
# RUN: not obj2yaml %t5 2>&1 | FileCheck %s -DFILE=%t5 --check-prefix=CASE5
-# CASE5: Error reading file: [[FILE]]: multiple SHT_SYMTAB_SHNDX sections are not supported
+# CASE5: Error reading file: [[FILE]]: multiple SHT_SYMTAB_SHNDX sections are linked to the same symbol table with index 5
--- !ELF
FileHeader:
@@ -128,14 +130,41 @@ FileHeader:
Sections:
- Name: .symtab_shndx1
Type: SHT_SYMTAB_SHNDX
- Entries: [ 0 ]
+ Entries: [ 0, 1 ]
EntSize: 4
Link: .symtab
- Name: .symtab_shndx2
Type: SHT_SYMTAB_SHNDX
- Entries: [ 0 ]
- Link: .symtab
-Symbols: []
+ Entries: [ 0, 2 ]
+ Link: [[LINK=.symtab]]
+Symbols:
+ - Type: STT_SECTION
+ Index: SHN_XINDEX
+DynamicSymbols:
+ - Type: STT_SECTION
+ Index: SHN_XINDEX
+
+## Check it is possible to dump an object that has multiple SHT_SYMTAB_SHNDX sections.
+## Check that yaml2obj can dump the object and dynamic symbols properly when
+## the SHT_SYMTAB_SHNDX section is associated with a SHT_DYNSYM section.
+
+# RUN: yaml2obj --docnum=5 -DLINK=.dynsym %s -o %t5.multiple
+# RUN: obj2yaml %t5.multiple | FileCheck %s --check-prefix=MULTIPLE-SYMTAB
+
+# MULTIPLE-SYMTAB: - Name: .symtab_shndx1
+# MULTIPLE-SYMTAB-NEXT: Type: SHT_SYMTAB_SHNDX
+# MULTIPLE-SYMTAB-NEXT: Link: .symtab
+# MULTIPLE-SYMTAB: - Name: .symtab_shndx2
+# MULTIPLE-SYMTAB-NEXT: Type: SHT_SYMTAB_SHNDX
+# MULTIPLE-SYMTAB-NEXT: Link: .dynsym
+# MULTIPLE-SYMTAB: Symbols:
+# MULTIPLE-SYMTAB-NEXT: - Name: .symtab_shndx1
+# MULTIPLE-SYMTAB-NEXT: Type: STT_SECTION
+# MULTIPLE-SYMTAB-NEXT: Index: SHN_XINDEX
+# MULTIPLE-SYMTAB-NEXT: DynamicSymbols:
+# MULTIPLE-SYMTAB-NEXT: - Name: .symtab_shndx2
+# MULTIPLE-SYMTAB-NEXT: Type: STT_SECTION
+# MULTIPLE-SYMTAB-NEXT: Index: SHN_XINDEX
## Check that yaml2obj can't dump the object if SHT_SYMTAB_SHNDX is
## not associated with a SHT_SYMTAB section (this case is illegal).
@@ -143,7 +172,7 @@ Symbols: []
# RUN: yaml2obj --docnum=6 %s -o %t6
# RUN: not obj2yaml %t6 2>&1 | FileCheck %s -DFILE=%t6 --check-prefix=CASE6
-# CASE6: Error reading file: [[FILE]]: only SHT_SYMTAB_SHNDX associated with SHT_SYMTAB are supported
+# CASE6: Error reading file: [[FILE]]: unable to read extended section indexes: SHT_SYMTAB_SHNDX section is linked with SHT_PROGBITS section (expected SHT_SYMTAB/SHT_DYNSYM)
--- !ELF
FileHeader:
@@ -157,25 +186,3 @@ Sections:
Link: .foo
- Name: .foo
Type: SHT_PROGBITS
-
-## Check that yaml2obj can't dump the object if SHT_SYMTAB_SHNDX is
-## associated with a SHT_DYNSYM section (not implemented yet).
-
-# RUN: yaml2obj --docnum=7 %s -o %t7
-# RUN: not obj2yaml %t7 2>&1 | FileCheck %s -DFILE=%t7 --check-prefix=CASE7
-
-# CASE7: Error reading file: [[FILE]]: only SHT_SYMTAB_SHNDX associated with SHT_SYMTAB are supported
-
---- !ELF
-FileHeader:
- Class: ELFCLASS64
- Data: ELFDATA2LSB
- Type: ET_REL
-Sections:
- - Name: .symtab_shndx
- Type: SHT_SYMTAB_SHNDX
- Entries: [ 0, 1 ]
- Link: .dynsym
-DynamicSymbols:
- - Type: STT_SECTION
- Index: SHN_XINDEX
diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp
index 405e8b17d2fd..0885e92ee28a 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -53,7 +53,8 @@ class ELFDumper {
const object::ELFFile<ELFT> &Obj;
std::unique_ptr<DWARFContext> DWARFCtx;
- ArrayRef<Elf_Word> ShndxTable;
+
+ DenseMap<const Elf_Shdr *, ArrayRef<Elf_Word>> ShndxTables;
Expected<std::vector<ELFYAML::ProgramHeader>>
dumpProgramHeaders(ArrayRef<std::unique_ptr<ELFYAML::Chunk>> Sections);
@@ -157,7 +158,7 @@ ELFDumper<ELFT>::getUniquedSymbolName(const Elf_Sym *Sym, StringRef StrTable,
return SymbolNameOrErr;
StringRef Name = *SymbolNameOrErr;
if (Name.empty() && Sym->getType() == ELF::STT_SECTION) {
- auto ShdrOrErr = Obj.getSection(*Sym, SymTab, ShndxTable);
+ auto ShdrOrErr = Obj.getSection(*Sym, SymTab, ShndxTables.lookup(SymTab));
if (!ShdrOrErr)
return ShdrOrErr.takeError();
return getUniquedSectionName(*ShdrOrErr);
@@ -303,7 +304,6 @@ template <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
// Dump symbols. We need to do this early because other sections might want
// to access the deduplicated symbol names that we also create here.
const Elf_Shdr *SymTab = nullptr;
- const Elf_Shdr *SymTabShndx = nullptr;
const Elf_Shdr *DynSymTab = nullptr;
for (const Elf_Shdr &Sec : Sections) {
@@ -312,31 +312,26 @@ template <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
} else if (Sec.sh_type == ELF::SHT_DYNSYM) {
DynSymTab = &Sec;
} else if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) {
- // ABI allows us to have one SHT_SYMTAB_SHNDX for each symbol table.
- // We only support having the SHT_SYMTAB_SHNDX for SHT_SYMTAB now.
- if (SymTabShndx)
- return createStringError(
- errc::not_supported,
- "multiple SHT_SYMTAB_SHNDX sections are not supported");
- SymTabShndx = &Sec;
+ // We need to locate SHT_SYMTAB_SHNDX sections early, because they
+ // might be needed for dumping symbols.
+ if (Expected<ArrayRef<Elf_Word>> TableOrErr = Obj.getSHNDXTable(Sec)) {
+ // The `getSHNDXTable` calls the `getSection` internally when validates
+ // the symbol table section linked to the SHT_SYMTAB_SHNDX section.
+ const Elf_Shdr *LinkedSymTab = cantFail(Obj.getSection(Sec.sh_link));
+ if (!ShndxTables.insert({LinkedSymTab, *TableOrErr}).second)
+ return createStringError(
+ errc::invalid_argument,
+ "multiple SHT_SYMTAB_SHNDX sections are "
+ "linked to the same symbol table with index " +
+ Twine(Sec.sh_link));
+ } else {
+ return createStringError(errc::invalid_argument,
+ "unable to read extended section indexes: " +
+ toString(TableOrErr.takeError()));
+ }
}
}
- // We need to locate the SHT_SYMTAB_SHNDX section early, because it might be
- // needed for dumping symbols.
- if (SymTabShndx) {
- if (!SymTab ||
- SymTabShndx->sh_link != (unsigned)(SymTab - Sections.begin()))
- return createStringError(
- errc::not_supported,
- "only SHT_SYMTAB_SHNDX associated with SHT_SYMTAB are supported");
-
- auto TableOrErr = Obj.getSHNDXTable(*SymTabShndx);
- if (!TableOrErr)
- return TableOrErr.takeError();
- ShndxTable = *TableOrErr;
- }
-
if (SymTab) {
Y->Symbols.emplace();
if (Error E = dumpSymbols(SymTab, *Y->Symbols))
@@ -682,7 +677,7 @@ Error ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
return Error::success();
}
- auto ShdrOrErr = Obj.getSection(*Sym, SymTab, ShndxTable);
+ auto ShdrOrErr = Obj.getSection(*Sym, SymTab, ShndxTables.lookup(SymTab));
if (!ShdrOrErr)
return ShdrOrErr.takeError();
const Elf_Shdr *Shdr = *ShdrOrErr;