private:
ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
const Elf_Shdr *DotDynSymSec, const Elf_Shdr *DotSymtabSec,
- ArrayRef<Elf_Word> ShndxTable);
+ const Elf_Shdr *DotSymtabShndxSec);
protected:
ELFFile<ELFT> EF;
const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section.
const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section.
- ArrayRef<Elf_Word> ShndxTable;
+ const Elf_Shdr *DotSymtabShndxSec = nullptr; // SHT_SYMTAB_SHNDX section.
void moveSymbolNext(DataRefImpl &Symb) const override;
Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
return SymTabOrErr.takeError();
if (EF.getHeader().e_type == ELF::ET_REL) {
+ ArrayRef<Elf_Word> ShndxTable;
+ if (DotSymtabShndxSec) {
+ // TODO: Test this error.
+ if (Expected<ArrayRef<Elf_Word>> ShndxTableOrErr =
+ EF.getSHNDXTable(*DotSymtabShndxSec))
+ ShndxTable = *ShndxTableOrErr;
+ else
+ return ShndxTableOrErr.takeError();
+ }
+
Expected<const Elf_Shdr *> SectionOrErr =
EF.getSection(*ESym, *SymTabOrErr, ShndxTable);
if (!SectionOrErr)
Expected<section_iterator>
ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym,
const Elf_Shdr *SymTab) const {
+ ArrayRef<Elf_Word> ShndxTable;
+ if (DotSymtabShndxSec) {
+ // TODO: Test this error.
+ Expected<ArrayRef<Elf_Word>> ShndxTableOrErr =
+ EF.getSHNDXTable(*DotSymtabShndxSec);
+ if (!ShndxTableOrErr)
+ return ShndxTableOrErr.takeError();
+ ShndxTable = *ShndxTableOrErr;
+ }
+
auto ESecOrErr = EF.getSection(*ESym, SymTab, ShndxTable);
if (!ESecOrErr)
return ESecOrErr.takeError();
const Elf_Shdr *DotDynSymSec = nullptr;
const Elf_Shdr *DotSymtabSec = nullptr;
- ArrayRef<Elf_Word> ShndxTable;
+ const Elf_Shdr *DotSymtabShndxSec = nullptr;
for (const Elf_Shdr &Sec : *SectionsOrErr) {
switch (Sec.sh_type) {
case ELF::SHT_DYNSYM: {
break;
}
case ELF::SHT_SYMTAB_SHNDX: {
- auto TableOrErr = EF.getSHNDXTable(Sec);
- if (!TableOrErr)
- return TableOrErr.takeError();
- ShndxTable = *TableOrErr;
+ if (!DotSymtabShndxSec)
+ DotSymtabShndxSec = &Sec;
break;
}
}
}
return ELFObjectFile<ELFT>(Object, EF, DotDynSymSec, DotSymtabSec,
- ShndxTable);
+ DotSymtabShndxSec);
}
template <class ELFT>
ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
const Elf_Shdr *DotDynSymSec,
const Elf_Shdr *DotSymtabSec,
- ArrayRef<Elf_Word> ShndxTable)
+ const Elf_Shdr *DotSymtabShndx)
: ELFObjectFileBase(
getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits),
Object),
EF(EF), DotDynSymSec(DotDynSymSec), DotSymtabSec(DotSymtabSec),
- ShndxTable(ShndxTable) {}
+ DotSymtabShndxSec(DotSymtabShndx) {}
template <class ELFT>
ELFObjectFile<ELFT>::ELFObjectFile(ELFObjectFile<ELFT> &&Other)
: ELFObjectFile(Other.Data, Other.EF, Other.DotDynSymSec,
- Other.DotSymtabSec, Other.ShndxTable) {}
+ Other.DotSymtabSec, Other.DotSymtabShndxSec) {}
template <class ELFT>
basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin() const {
## sizeof(.symtab_shndx) = (sizeof(.symtab) / entsize(.symtab)) * entsize(.symtab_shndx)
# RUN: yaml2obj %s --docnum=11 -o %t11
-# RUN: not llvm-readobj --symbols %t11 2>&1 | FileCheck --check-prefix=INVALID-XINDEX-SIZE %s
+# RUN: llvm-readobj --symbols %t11 2>&1 | FileCheck --check-prefix=INVALID-XINDEX-SIZE %s
-# INVALID-XINDEX-SIZE: error: {{.*}}: SHT_SYMTAB_SHNDX has 2 entries, but the symbol table associated has 1
+# INVALID-XINDEX-SIZE: warning: {{.*}}: SHT_SYMTAB_SHNDX has 2 entries, but the symbol table associated has 1
--- !ELF
FileHeader:
Index: SHN_XINDEX
- Name: no_shndx2
Index: SHN_XINDEX
+
+## Check we can dump symbols even when the number of entries in the
+## SHT_SYMTAB_SHNDX section doesn't match the number of symbols in the symbol table.
+
+# RUN: yaml2obj --docnum=4 %s -o %t4
+# RUN: llvm-readelf --symbols %t4 2>&1 | FileCheck %s -DFILE=%t4 --check-prefix=SHNDX-ERR-GNU
+# RUN: llvm-readobj --symbols %t4 2>&1 | FileCheck %s -DFILE=%t4 --check-prefix=SHNDX-ERR-LLVM
+
+# SHNDX-ERR-GNU: warning: '[[FILE]]': SHT_SYMTAB_SHNDX has 3 entries, but the symbol table associated has 2
+# SHNDX-ERR-GNU-EMPTY:
+# SHNDX-ERR-GNU-NEXT: Symbol table '.symtab' contains 2 entries:
+# SHNDX-ERR-GNU-NEXT: Num: Value Size Type Bind Vis Ndx Name
+# SHNDX-ERR-GNU-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+# SHNDX-ERR-GNU-NEXT: warning: '[[FILE]]': extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0
+# SHNDX-ERR-GNU-NEXT: 1: 0000000000000000 0 NOTYPE LOCAL DEFAULT RSV[0xffff]
+# SHNDX-ERR-GNU-EMPTY:
+# SHNDX-ERR-GNU-NOT:{{.}}
+
+# SHNDX-ERR-LLVM: warning: '[[FILE]]': SHT_SYMTAB_SHNDX has 3 entries, but the symbol table associated has 2
+# SHNDX-ERR-LLVM: Format: elf64-unknown
+# SHNDX-ERR-LLVM-NEXT: Arch: unknown
+# SHNDX-ERR-LLVM-NEXT: AddressSize: 64bit
+# SHNDX-ERR-LLVM-NEXT: LoadName: <Not found>
+# SHNDX-ERR-LLVM-NEXT: Symbols [
+# SHNDX-ERR-LLVM-NEXT: Symbol {
+# SHNDX-ERR-LLVM-NEXT: Name: (0)
+# SHNDX-ERR-LLVM-NEXT: Value: 0x0
+# SHNDX-ERR-LLVM-NEXT: Size: 0
+# SHNDX-ERR-LLVM-NEXT: Binding: Local (0x0)
+# SHNDX-ERR-LLVM-NEXT: Type: None (0x0)
+# SHNDX-ERR-LLVM-NEXT: Other: 0
+# SHNDX-ERR-LLVM-NEXT: Section: Undefined (0x0)
+# SHNDX-ERR-LLVM-NEXT: }
+# SHNDX-ERR-LLVM-NEXT: Symbol {
+# SHNDX-ERR-LLVM-NEXT: Name: (0)
+# SHNDX-ERR-LLVM-NEXT: Value: 0x0
+# SHNDX-ERR-LLVM-NEXT: Size: 0
+# SHNDX-ERR-LLVM-NEXT: Binding: Local (0x0)
+# SHNDX-ERR-LLVM-NEXT: Type: None (0x0)
+# SHNDX-ERR-LLVM-NEXT: Other: 0
+# SHNDX-ERR-LLVM-NEXT: warning: '[[FILE]]': extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0
+# SHNDX-ERR-LLVM-NEXT: Section: Reserved (0xFFFF)
+# SHNDX-ERR-LLVM-NEXT: }
+# SHNDX-ERR-LLVM-NEXT: ]
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+Sections:
+ - Name: .symtab_shndx
+ Type: SHT_SYMTAB_SHNDX
+ Entries: [ 0, 1, 2 ]
+ Link: .symtab
+Symbols:
+ - Index: SHN_XINDEX
# 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]]: SHT_SYMTAB_SHNDX section is linked with SHT_PROGBITS section (expected SHT_SYMTAB/SHT_DYNSYM)
+# CASE6: Error reading file: [[FILE]]: only SHT_SYMTAB_SHNDX associated with SHT_SYMTAB are supported
--- !ELF
FileHeader:
## Check we can set a custom sh_entsize for SHT_SYMTAB_SHNDX section.
# RUN: yaml2obj --docnum=5 %s -o %t5
-# RUN: not llvm-readelf -S 2>&1 %t5 | FileCheck %s -DFILE=%t5 --check-prefix=CASE5
+# RUN: llvm-readelf -S 2>&1 %t5 | FileCheck %s -DFILE=%t5 --check-prefix=CASE5
-# CASE5: error: '[[FILE]]': section [index 1] has an invalid sh_entsize: 2
+# CASE5: warning: '[[FILE]]': section [index 1] has an invalid sh_entsize: 2
--- !ELF
FileHeader:
}
break;
case ELF::SHT_SYMTAB_SHNDX:
- ShndxTable = unwrapOrError(ObjF.getFileName(), Obj.getSHNDXTable(Sec));
+ if (Expected<ArrayRef<Elf_Word>> ShndxTableOrErr = Obj.getSHNDXTable(Sec))
+ ShndxTable = *ShndxTableOrErr;
+ else
+ this->reportUniqueWarning(ShndxTableOrErr.takeError());
break;
case ELF::SHT_GNU_versym:
if (!SymbolVersionSection)
set(LLVM_LINK_COMPONENTS
BinaryFormat
Object
+ ObjectYAML
)
add_llvm_unittest(ObjectTests
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/ObjectYAML/yaml2obj.h"
+#include "llvm/Support/YAMLTraits.h"
#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
checkFormatAndArch(D, Formats[I++], Triple::csky);
}
-
-
// ELF relative relocation type test.
TEST(ELFObjectFileTest, RelativeRelocationTypeTest) {
EXPECT_EQ(ELF::R_CKCORE_RELATIVE, getELFRelativeRelocationType(ELF::EM_CSKY));
}
+
+template <class ELFT>
+static Expected<ELFObjectFile<ELFT>> toBinary(SmallVectorImpl<char> &Storage,
+ StringRef Yaml) {
+ raw_svector_ostream OS(Storage);
+ yaml::Input YIn(Yaml);
+ if (!yaml::convertYAML(YIn, OS, [](const Twine &Msg) {}))
+ return createStringError(std::errc::invalid_argument,
+ "unable to convert YAML");
+ return ELFObjectFile<ELFT>::create(MemoryBufferRef(OS.str(), "dummyELF"));
+}
+
+// Check we are able to create an ELFObjectFile even when the content of the
+// SHT_SYMTAB_SHNDX section can't be read properly.
+TEST(ELFObjectFileTest, InvalidSymtabShndxTest) {
+ SmallString<0> Storage;
+ Expected<ELFObjectFile<ELF64LE>> ExpectedFile = toBinary<ELF64LE>(Storage, R"(
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+Sections:
+ - Name: .symtab_shndx
+ Type: SHT_SYMTAB_SHNDX
+ Entries: [ 0 ]
+ ShSize: 0xFFFFFFFF
+)");
+
+ ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded());
+}