forked from OSchip/llvm-project
[llvm-readobj] - Introduce warnings for cases when unable to read strings from string tables.
Currently we have no dedicated warnings, but we return error message instead of a result. It is generally not consistent with another warnings we have. This change was suggested and discussed here: https://reviews.llvm.org/D77216#1954873 This change refines error messages we report and also I had to update the API to implement it. Differential revision: https://reviews.llvm.org/D77399
This commit is contained in:
parent
e268ec8e0d
commit
7fc599ceb0
|
@ -90,26 +90,54 @@ ProgramHeaders:
|
|||
|
||||
## Test handling of string references pointing past the end of the dynamic string table.
|
||||
# RUN: yaml2obj %s --docnum=3 -o %t.bad-string
|
||||
# RUN: llvm-readobj --dynamic-table %t.bad-string | FileCheck %s --check-prefix BAD-STRING-LLVM
|
||||
# RUN: llvm-readelf --dynamic-table %t.bad-string | FileCheck %s --check-prefix BAD-STRING-GNU
|
||||
# RUN: llvm-readobj --dynamic-table %t.bad-string 2>&1 | \
|
||||
# RUN: FileCheck %s --implicit-check-not=warning: --check-prefix BAD-STRING-LLVM -DFILE=%t.bad-string
|
||||
# RUN: llvm-readelf --dynamic-table %t.bad-string 2>&1 | \
|
||||
# RUN: FileCheck %s --implicit-check-not=warning: --check-prefix BAD-STRING-GNU -DFILE=%t.bad-string
|
||||
|
||||
# BAD-STRING-LLVM: 0x000000000000000A STRSZ 1 (bytes)
|
||||
# BAD-STRING-LLVM: 0x0000000000000001 NEEDED Shared library: [<Invalid offset 0x1>]
|
||||
# BAD-STRING-LLVM: 0x000000007FFFFFFF FILTER Filter library: [<Invalid offset 0x1>]
|
||||
# BAD-STRING-LLVM: 0x000000007FFFFFFD AUXILIARY Auxiliary library: [<Invalid offset 0x1>]
|
||||
# BAD-STRING-LLVM: 0x000000007FFFFFFE USED Not needed object: [<Invalid offset 0x1>]
|
||||
# BAD-STRING-LLVM: 0x000000000000000E SONAME Library soname: [<Invalid offset 0x1>]
|
||||
# BAD-STRING-LLVM: 0x000000000000000F RPATH Library rpath: [<Invalid offset 0x1>]
|
||||
# BAD-STRING-LLVM: 0x000000000000001D RUNPATH Library runpath: [<Invalid offset 0x1>]
|
||||
# BAD-STRING-LLVM: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb6, it goes past the end of the table (0xb1)
|
||||
# BAD-STRING-LLVM: LoadName: <?>
|
||||
# BAD-STRING-LLVM: DynamicSection [ (10 entries)
|
||||
# BAD-STRING-LLVM-NEXT: Tag Type Name/Value
|
||||
# BAD-STRING-LLVM-NEXT: 0x0000000000000005 STRTAB 0x1000
|
||||
# BAD-STRING-LLVM-NEXT: 0x000000000000000A STRSZ 1 (bytes)
|
||||
# BAD-STRING-LLVM-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb2, it goes past the end of the table (0xb1)
|
||||
# BAD-STRING-LLVM-NEXT: 0x0000000000000001 NEEDED Shared library: [<?>]
|
||||
# BAD-STRING-LLVM-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb3, it goes past the end of the table (0xb1)
|
||||
# BAD-STRING-LLVM-NEXT: 0x000000007FFFFFFF FILTER Filter library: [<?>]
|
||||
# BAD-STRING-LLVM-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb4, it goes past the end of the table (0xb1)
|
||||
# BAD-STRING-LLVM-NEXT: 0x000000007FFFFFFD AUXILIARY Auxiliary library: [<?>]
|
||||
# BAD-STRING-LLVM-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb5, it goes past the end of the table (0xb1)
|
||||
# BAD-STRING-LLVM-NEXT: 0x000000007FFFFFFE USED Not needed object: [<?>]
|
||||
## Note: there is no "string table at offset 0xb0..." warning here, because it was printed earlier.
|
||||
# BAD-STRING-LLVM-NEXT: 0x000000000000000E SONAME Library soname: [<?>]
|
||||
# BAD-STRING-LLVM-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb7, it goes past the end of the table (0xb1)
|
||||
# BAD-STRING-LLVM-NEXT: 0x000000000000000F RPATH Library rpath: [<?>]
|
||||
# BAD-STRING-LLVM-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb8, it goes past the end of the table (0xb1)
|
||||
# BAD-STRING-LLVM-NEXT: 0x000000000000001D RUNPATH Library runpath: [<?>]
|
||||
# BAD-STRING-LLVM-NEXT: 0x0000000000000000 NULL 0x0
|
||||
# BAD-STRING-LLVM-NEXT: ]
|
||||
|
||||
# BAD-STRING-GNU: 0x000000000000000a (STRSZ) 1 (bytes)
|
||||
# BAD-STRING-GNU: 0x0000000000000001 (NEEDED) Shared library: [<Invalid offset 0x1>]
|
||||
# BAD-STRING-GNU: 0x000000007fffffff (FILTER) Filter library: [<Invalid offset 0x1>]
|
||||
# BAD-STRING-GNU: 0x000000007ffffffd (AUXILIARY) Auxiliary library: [<Invalid offset 0x1>]
|
||||
# BAD-STRING-GNU: 0x000000007ffffffe (USED) Not needed object: [<Invalid offset 0x1>]
|
||||
# BAD-STRING-GNU: 0x000000000000000e (SONAME) Library soname: [<Invalid offset 0x1>]
|
||||
# BAD-STRING-GNU: 0x000000000000000f (RPATH) Library rpath: [<Invalid offset 0x1>]
|
||||
# BAD-STRING-GNU: 0x000000000000001d (RUNPATH) Library runpath: [<Invalid offset 0x1>]
|
||||
# BAD-STRING-GNU: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb6, it goes past the end of the table (0xb1)
|
||||
# BAD-STRING-GNU-NEXT: Dynamic section at offset 0xb1 contains 10 entries:
|
||||
# BAD-STRING-GNU-NEXT: Tag Type Name/Value
|
||||
# BAD-STRING-GNU-NEXT: 0x0000000000000005 (STRTAB) 0x1000
|
||||
# BAD-STRING-GNU-NEXT: 0x000000000000000a (STRSZ) 1 (bytes)
|
||||
# BAD-STRING-GNU-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb2, it goes past the end of the table (0xb1)
|
||||
# BAD-STRING-GNU-NEXT: 0x0000000000000001 (NEEDED) Shared library: [<?>]
|
||||
# BAD-STRING-GNU-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb3, it goes past the end of the table (0xb1)
|
||||
# BAD-STRING-GNU-NEXT: 0x000000007fffffff (FILTER) Filter library: [<?>]
|
||||
# BAD-STRING-GNU-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb4, it goes past the end of the table (0xb1)
|
||||
# BAD-STRING-GNU-NEXT: 0x000000007ffffffd (AUXILIARY) Auxiliary library: [<?>]
|
||||
# BAD-STRING-GNU-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb5, it goes past the end of the table (0xb1)
|
||||
# BAD-STRING-GNU-NEXT: 0x000000007ffffffe (USED) Not needed object: [<?>]
|
||||
## Note: there is no "string table at offset 0xb6..." warning here, because it was printed earlier.
|
||||
# BAD-STRING-GNU-NEXT: 0x000000000000000e (SONAME) Library soname: [<?>]
|
||||
# BAD-STRING-GNU-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb7, it goes past the end of the table (0xb1)
|
||||
# BAD-STRING-GNU-NEXT: 0x000000000000000f (RPATH) Library rpath: [<?>]
|
||||
# BAD-STRING-GNU-NEXT: warning: '[[FILE]]': string table at offset 0xb0: unable to read the string at 0xb8, it goes past the end of the table (0xb1)
|
||||
# BAD-STRING-GNU-NEXT: 0x000000000000001d (RUNPATH) Library runpath: [<?>]
|
||||
# BAD-STRING-GNU-NEXT: 0x0000000000000000 (NULL) 0x0
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
|
@ -130,19 +158,19 @@ Sections:
|
|||
- Tag: DT_STRSZ
|
||||
Value: 1
|
||||
- Tag: DT_NEEDED
|
||||
Value: 1
|
||||
Value: 2
|
||||
- Tag: DT_FILTER
|
||||
Value: 1
|
||||
Value: 3
|
||||
- Tag: DT_AUXILIARY
|
||||
Value: 1
|
||||
Value: 4
|
||||
- Tag: DT_USED
|
||||
Value: 1
|
||||
Value: 5
|
||||
- Tag: DT_SONAME
|
||||
Value: 1
|
||||
Value: 6
|
||||
- Tag: DT_RPATH
|
||||
Value: 1
|
||||
Value: 7
|
||||
- Tag: DT_RUNPATH
|
||||
Value: 1
|
||||
Value: 8
|
||||
- Tag: DT_NULL
|
||||
Value: 0
|
||||
Symbols: []
|
||||
|
@ -160,17 +188,23 @@ ProgramHeaders:
|
|||
## Test handling of DT_STRTAB pointing outside the file's address space.
|
||||
# RUN: yaml2obj %s --docnum=4 -o %t.bad-strtab
|
||||
|
||||
# RUN: llvm-readobj --dynamic-table %t.bad-strtab 2>&1 >/dev/null | FileCheck -DFILE=%t.bad-strtab %s --check-prefix BAD-STRTAB-ERR
|
||||
# RUN: llvm-readelf --dynamic-table %t.bad-strtab 2>&1 >/dev/null | FileCheck -DFILE=%t.bad-strtab %s --check-prefix BAD-STRTAB-ERR
|
||||
# RUN: llvm-readobj --dynamic-table %t.bad-strtab 2>&1 >/dev/null | \
|
||||
# RUN: FileCheck -DFILE=%t.bad-strtab %s --check-prefix BAD-STRTAB-ERR
|
||||
# RUN: llvm-readelf --dynamic-table %t.bad-strtab 2>&1 >/dev/null | \
|
||||
# RUN: FileCheck -DFILE=%t.bad-strtab %s --check-prefix BAD-STRTAB-ERR
|
||||
# BAD-STRTAB-ERR: warning: '[[FILE]]': Unable to parse DT_STRTAB: virtual address is not in any segment: 0x2000000
|
||||
# BAD-STRTAB-ERR: warning: '[[FILE]]': string table was not found
|
||||
|
||||
# RUN: llvm-readobj --dynamic-table --needed-libs %t.bad-strtab | FileCheck %s --check-prefixes=BAD-STRTAB,BAD-STRTAB-LLVM
|
||||
# RUN: llvm-readelf --dynamic-table --needed-libs %t.bad-strtab | FileCheck %s --check-prefixes=BAD-STRTAB,BAD-STRTAB-GNU
|
||||
# BAD-STRTAB-LLVM: LoadName: <String table is empty or was not found>
|
||||
# BAD-STRTAB-LLVM: 0x0000000000000001 NEEDED Shared library: [<String table is empty or was not found>]
|
||||
# BAD-STRTAB-GNU: 0x0000000000000001 (NEEDED) Shared library: [<String table is empty or was not found>]
|
||||
# RUN: llvm-readobj --dynamic-table --needed-libs %t.bad-strtab 2>&1 | \
|
||||
# RUN: FileCheck -DFILE=%t.bad-strtab %s --check-prefixes=BAD-STRTAB-ERR,BAD-STRTAB,BAD-STRTAB-LLVM
|
||||
# RUN: llvm-readelf --dynamic-table --needed-libs %t.bad-strtab 2>&1 | \
|
||||
# RUN: FileCheck -DFILE=%t.bad-strtab %s --check-prefixes=BAD-STRTAB-ERR,BAD-STRTAB,BAD-STRTAB-GNU
|
||||
|
||||
# BAD-STRTAB-LLVM: LoadName: <?>
|
||||
# BAD-STRTAB-LLVM: 0x0000000000000001 NEEDED Shared library: [<?>]
|
||||
# BAD-STRTAB-GNU: 0x0000000000000001 (NEEDED) Shared library: [<?>]
|
||||
# BAD-STRTAB: NeededLibraries [
|
||||
# BAD-STRTAB: <String table is empty or was not found>
|
||||
# BAD-STRTAB: <?>
|
||||
# BAD-STRTAB: ]
|
||||
|
||||
--- !ELF
|
||||
|
|
|
@ -61,5 +61,6 @@ ProgramHeaders:
|
|||
# RUN: llvm-readelf --dynamic-table %t.err.1.o 2>&1 | FileCheck %s -DFILE=%t.err.1.o --check-prefixes=BROKEN-OFFSET,BROKEN-OFFSET-GNU
|
||||
|
||||
# BROKEN-OFFSET: warning: '[[FILE]]': Unable to parse DT_STRTAB: can't map virtual address 0xfffe to the segment with index 1: the segment ends at 0x10077, which is greater than the file size (0x228)
|
||||
# BROKEN-OFFSET-LLVM: LoadName: <String table is empty or was not found>
|
||||
# BROKEN-OFFSET-GNU: 0x000000000000000e (SONAME) Library soname: [<String table is empty or was not found>]
|
||||
# BROKEN-OFFSET: warning: '[[FILE]]': string table was not found
|
||||
# BROKEN-OFFSET-LLVM: LoadName: <?>
|
||||
# BROKEN-OFFSET-GNU: 0x000000000000000e (SONAME) Library soname: [<?>]
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
## In this test we check the --needed-libs option.
|
||||
|
||||
# RUN: yaml2obj %s --docnum=1 -o %t1
|
||||
# RUN: llvm-readobj --needed-libs %t1 \
|
||||
# RUN: | FileCheck %s --strict-whitespace --match-full-lines --check-prefix=NEEDED-LIBS
|
||||
# RUN: llvm-readelf --needed-libs %t1 \
|
||||
# RUN: | FileCheck %s --strict-whitespace --match-full-lines --check-prefix=NEEDED-LIBS
|
||||
# RUN: llvm-readobj --needed-libs %t1 2>&1 \
|
||||
# RUN: | FileCheck %s -DFILE=%t1 --implicit-check-not=warning: --strict-whitespace --check-prefix=NEEDED-LIBS
|
||||
# RUN: llvm-readelf --needed-libs %t1 2>&1 \
|
||||
# RUN: | FileCheck %s -DFILE=%t1 --implicit-check-not=warning: --strict-whitespace --check-prefix=NEEDED-LIBS
|
||||
|
||||
## Check that library names are sorted when printed.
|
||||
## Document that we also sort error entries.
|
||||
|
||||
# NEEDED-LIBS:NeededLibraries [
|
||||
# NEEDED-LIBS-NEXT: <Invalid offset 0x1111111>
|
||||
# NEEDED-LIBS-NEXT: <Invalid offset 0x9999999>
|
||||
# NEEDED-LIBS-NEXT: aaa
|
||||
# NEEDED-LIBS-NEXT: bbb
|
||||
# NEEDED-LIBS-NEXT: ccc
|
||||
# NEEDED-LIBS-NEXT:]
|
||||
# NEEDED-LIBS:{{^}}NeededLibraries [{{$}}
|
||||
# NEEDED-LIBS-NEXT: warning: '[[FILE]]': string table at offset 0x78: unable to read the string at 0x9999a11, it goes past the end of the table (0x85){{$}}
|
||||
# NEEDED-LIBS-NEXT: warning: '[[FILE]]': string table at offset 0x78: unable to read the string at 0x1111189, it goes past the end of the table (0x85){{$}}
|
||||
# NEEDED-LIBS-NEXT:{{^}} <?>{{$}}
|
||||
# NEEDED-LIBS-NEXT:{{^}} <?>{{$}}
|
||||
# NEEDED-LIBS-NEXT:{{^}} aaa{{$}}
|
||||
# NEEDED-LIBS-NEXT:{{^}} bbb{{$}}
|
||||
# NEEDED-LIBS-NEXT:{{^}} ccc{{$}}
|
||||
# NEEDED-LIBS-NEXT:{{^}}]{{$}}
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
|
@ -56,11 +58,18 @@ ProgramHeaders:
|
|||
|
||||
## Check what we print when the dynamic string table is empty.
|
||||
# RUN: yaml2obj %s --docnum=2 -o %t2
|
||||
# RUN: llvm-readobj --needed-libs %t2 | FileCheck %s --check-prefix=EMPTY-DYNSTR
|
||||
# RUN: llvm-readelf --needed-libs %t2 | FileCheck %s --check-prefix=EMPTY-DYNSTR
|
||||
# RUN: llvm-readobj --needed-libs %t2 2>&1 | \
|
||||
# RUN: FileCheck %s -DFILE=%t2 --implicit-check-not=warning: --check-prefixes=EMPTY-DYNSTR,EMPTY-DYNSTR-LLVM
|
||||
# RUN: llvm-readelf --needed-libs %t2 2>&1 | \
|
||||
# RUN: FileCheck %s -DFILE=%t2 --implicit-check-not=warning: --check-prefix=EMPTY-DYNSTR
|
||||
|
||||
# EMPTY-DYNSTR: warning: '[[FILE]]': string table at offset 0x78: unable to read the string at 0x78, it goes past the end of the table (0x78)
|
||||
# EMPTY-DYNSTR-LLVM: LoadName: <?>
|
||||
# EMPTY-DYNSTR: NeededLibraries [
|
||||
# EMPTY-DYNSTR-NEXT: <String table is empty or was not found>
|
||||
# EMPTY-DYNSTR-NEXT: warning: '[[FILE]]': string table at offset 0x78: unable to read the string at 0x79, it goes past the end of the table (0x78)
|
||||
# EMPTY-DYNSTR-NEXT: warning: '[[FILE]]': string table at offset 0x78: unable to read the string at 0x7a, it goes past the end of the table (0x78)
|
||||
# EMPTY-DYNSTR-NEXT: <?>
|
||||
# EMPTY-DYNSTR-NEXT: <?>
|
||||
# EMPTY-DYNSTR-NEXT: ]
|
||||
|
||||
--- !ELF
|
||||
|
@ -82,6 +91,8 @@ Sections:
|
|||
Value: 0x0000000000000000
|
||||
- Tag: DT_NEEDED
|
||||
Value: 1
|
||||
- Tag: DT_NEEDED
|
||||
Value: 2
|
||||
- Tag: DT_STRSZ
|
||||
Value: 0x0
|
||||
- Tag: DT_NULL
|
||||
|
|
|
@ -288,7 +288,7 @@ private:
|
|||
Optional<DynRegionInfo> DynSymRegion;
|
||||
DynRegionInfo DynamicTable;
|
||||
StringRef DynamicStringTable;
|
||||
std::string SOName = "<Not found>";
|
||||
StringRef SOName = "<Not found>";
|
||||
const Elf_Hash *HashTable = nullptr;
|
||||
const Elf_GnuHash *GnuHashTable = nullptr;
|
||||
const Elf_Shdr *DotSymtabSec = nullptr;
|
||||
|
@ -341,12 +341,12 @@ public:
|
|||
Expected<StringRef> getSymbolSectionName(const Elf_Sym *Symbol,
|
||||
unsigned SectionIndex) const;
|
||||
Expected<std::string> getStaticSymbolName(uint32_t Index) const;
|
||||
std::string getDynamicString(uint64_t Value) const;
|
||||
StringRef getDynamicString(uint64_t Value) const;
|
||||
Expected<StringRef> getSymbolVersionByIndex(uint32_t VersionSymbolIndex,
|
||||
bool &IsDefault) const;
|
||||
|
||||
void printSymbolsHelper(bool IsDynamic) const;
|
||||
void printDynamicEntry(raw_ostream &OS, uint64_t Type, uint64_t Value) const;
|
||||
std::string getDynamicEntry(uint64_t Type, uint64_t Value) const;
|
||||
|
||||
const Elf_Shdr *getDotSymtabSec() const { return DotSymtabSec; }
|
||||
const Elf_Shdr *getDotCGProfileSec() const { return DotCGProfileSec; }
|
||||
|
@ -2387,10 +2387,24 @@ void printFlags(T Value, ArrayRef<EnumEntry<TFlag>> Flags, raw_ostream &OS) {
|
|||
}
|
||||
|
||||
template <class ELFT>
|
||||
void ELFDumper<ELFT>::printDynamicEntry(raw_ostream &OS, uint64_t Type,
|
||||
uint64_t Value) const {
|
||||
const char *ConvChar =
|
||||
(opts::Output == opts::GNU) ? "0x%" PRIx64 : "0x%" PRIX64;
|
||||
std::string ELFDumper<ELFT>::getDynamicEntry(uint64_t Type,
|
||||
uint64_t Value) const {
|
||||
auto FormatHexValue = [](uint64_t V) {
|
||||
std::string Str;
|
||||
raw_string_ostream OS(Str);
|
||||
const char *ConvChar =
|
||||
(opts::Output == opts::GNU) ? "0x%" PRIx64 : "0x%" PRIX64;
|
||||
OS << format(ConvChar, V);
|
||||
return OS.str();
|
||||
};
|
||||
|
||||
auto FormatFlags = [](uint64_t V,
|
||||
llvm::ArrayRef<llvm::EnumEntry<unsigned int>> Array) {
|
||||
std::string Str;
|
||||
raw_string_ostream OS(Str);
|
||||
printFlags(V, Array, OS);
|
||||
return OS.str();
|
||||
};
|
||||
|
||||
// Handle custom printing of architecture specific tags
|
||||
switch (ObjF->getELFFile()->getHeader()->e_machine) {
|
||||
|
@ -2398,8 +2412,7 @@ void ELFDumper<ELFT>::printDynamicEntry(raw_ostream &OS, uint64_t Type,
|
|||
switch (Type) {
|
||||
case DT_AARCH64_BTI_PLT:
|
||||
case DT_AARCH64_PAC_PLT:
|
||||
OS << Value;
|
||||
return;
|
||||
return std::to_string(Value);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2407,12 +2420,10 @@ void ELFDumper<ELFT>::printDynamicEntry(raw_ostream &OS, uint64_t Type,
|
|||
case EM_HEXAGON:
|
||||
switch (Type) {
|
||||
case DT_HEXAGON_VER:
|
||||
OS << Value;
|
||||
return;
|
||||
return std::to_string(Value);
|
||||
case DT_HEXAGON_SYMSZ:
|
||||
case DT_HEXAGON_PLT:
|
||||
OS << format(ConvChar, Value);
|
||||
return;
|
||||
return FormatHexValue(Value);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2423,8 +2434,7 @@ void ELFDumper<ELFT>::printDynamicEntry(raw_ostream &OS, uint64_t Type,
|
|||
case DT_MIPS_LOCAL_GOTNO:
|
||||
case DT_MIPS_SYMTABNO:
|
||||
case DT_MIPS_UNREFEXTNO:
|
||||
OS << Value;
|
||||
return;
|
||||
return std::to_string(Value);
|
||||
case DT_MIPS_TIME_STAMP:
|
||||
case DT_MIPS_ICHECKSUM:
|
||||
case DT_MIPS_IVERSION:
|
||||
|
@ -2465,11 +2475,9 @@ void ELFDumper<ELFT>::printDynamicEntry(raw_ostream &OS, uint64_t Type,
|
|||
case DT_MIPS_PLTGOT:
|
||||
case DT_MIPS_RWPLT:
|
||||
case DT_MIPS_RLD_MAP_REL:
|
||||
OS << format(ConvChar, Value);
|
||||
return;
|
||||
return FormatHexValue(Value);
|
||||
case DT_MIPS_FLAGS:
|
||||
printFlags(Value, makeArrayRef(ElfDynamicDTMipsFlags), OS);
|
||||
return;
|
||||
return FormatFlags(Value, makeArrayRef(ElfDynamicDTMipsFlags));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2480,13 +2488,10 @@ void ELFDumper<ELFT>::printDynamicEntry(raw_ostream &OS, uint64_t Type,
|
|||
|
||||
switch (Type) {
|
||||
case DT_PLTREL:
|
||||
if (Value == DT_REL) {
|
||||
OS << "REL";
|
||||
break;
|
||||
} else if (Value == DT_RELA) {
|
||||
OS << "RELA";
|
||||
break;
|
||||
}
|
||||
if (Value == DT_REL)
|
||||
return "REL";
|
||||
if (Value == DT_RELA)
|
||||
return "RELA";
|
||||
LLVM_FALLTHROUGH;
|
||||
case DT_PLTGOT:
|
||||
case DT_HASH:
|
||||
|
@ -2506,14 +2511,12 @@ void ELFDumper<ELFT>::printDynamicEntry(raw_ostream &OS, uint64_t Type,
|
|||
case DT_VERSYM:
|
||||
case DT_GNU_HASH:
|
||||
case DT_NULL:
|
||||
OS << format(ConvChar, Value);
|
||||
break;
|
||||
return FormatHexValue(Value);
|
||||
case DT_RELACOUNT:
|
||||
case DT_RELCOUNT:
|
||||
case DT_VERDEFNUM:
|
||||
case DT_VERNEEDNUM:
|
||||
OS << Value;
|
||||
break;
|
||||
return std::to_string(Value);
|
||||
case DT_PLTRELSZ:
|
||||
case DT_RELASZ:
|
||||
case DT_RELAENT:
|
||||
|
@ -2526,8 +2529,7 @@ void ELFDumper<ELFT>::printDynamicEntry(raw_ostream &OS, uint64_t Type,
|
|||
case DT_PREINIT_ARRAYSZ:
|
||||
case DT_ANDROID_RELSZ:
|
||||
case DT_ANDROID_RELASZ:
|
||||
OS << Value << " (bytes)";
|
||||
break;
|
||||
return std::to_string(Value) + " (bytes)";
|
||||
case DT_NEEDED:
|
||||
case DT_SONAME:
|
||||
case DT_AUXILIARY:
|
||||
|
@ -2535,37 +2537,45 @@ void ELFDumper<ELFT>::printDynamicEntry(raw_ostream &OS, uint64_t Type,
|
|||
case DT_FILTER:
|
||||
case DT_RPATH:
|
||||
case DT_RUNPATH: {
|
||||
const std::map<uint64_t, const char*> TagNames = {
|
||||
{DT_NEEDED, "Shared library"},
|
||||
{DT_SONAME, "Library soname"},
|
||||
{DT_AUXILIARY, "Auxiliary library"},
|
||||
{DT_USED, "Not needed object"},
|
||||
{DT_FILTER, "Filter library"},
|
||||
{DT_RPATH, "Library rpath"},
|
||||
{DT_RUNPATH, "Library runpath"},
|
||||
const std::map<uint64_t, const char *> TagNames = {
|
||||
{DT_NEEDED, "Shared library"}, {DT_SONAME, "Library soname"},
|
||||
{DT_AUXILIARY, "Auxiliary library"}, {DT_USED, "Not needed object"},
|
||||
{DT_FILTER, "Filter library"}, {DT_RPATH, "Library rpath"},
|
||||
{DT_RUNPATH, "Library runpath"},
|
||||
};
|
||||
OS << TagNames.at(Type) << ": [" << getDynamicString(Value) << "]";
|
||||
break;
|
||||
|
||||
return (Twine(TagNames.at(Type)) + ": [" + getDynamicString(Value) + "]")
|
||||
.str();
|
||||
}
|
||||
case DT_FLAGS:
|
||||
printFlags(Value, makeArrayRef(ElfDynamicDTFlags), OS);
|
||||
break;
|
||||
return FormatFlags(Value, makeArrayRef(ElfDynamicDTFlags));
|
||||
case DT_FLAGS_1:
|
||||
printFlags(Value, makeArrayRef(ElfDynamicDTFlags1), OS);
|
||||
break;
|
||||
return FormatFlags(Value, makeArrayRef(ElfDynamicDTFlags1));
|
||||
default:
|
||||
OS << format(ConvChar, Value);
|
||||
break;
|
||||
return FormatHexValue(Value);
|
||||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
std::string ELFDumper<ELFT>::getDynamicString(uint64_t Value) const {
|
||||
if (DynamicStringTable.empty())
|
||||
return "<String table is empty or was not found>";
|
||||
StringRef ELFDumper<ELFT>::getDynamicString(uint64_t Value) const {
|
||||
auto WarnAndReturn = [this](const Twine &Msg) {
|
||||
reportUniqueWarning(createError(Msg));
|
||||
return "<?>";
|
||||
};
|
||||
|
||||
if (DynamicStringTable.empty() && !DynamicStringTable.data())
|
||||
return WarnAndReturn("string table was not found");
|
||||
|
||||
if (Value < DynamicStringTable.size())
|
||||
return DynamicStringTable.data() + Value;
|
||||
return Twine("<Invalid offset 0x" + utohexstr(Value) + ">").str();
|
||||
|
||||
const uint64_t Offset =
|
||||
(const uint8_t *)DynamicStringTable.data() - ObjF->getELFFile()->base();
|
||||
return WarnAndReturn(
|
||||
"string table at offset 0x" + Twine::utohexstr(Offset) +
|
||||
": unable to read the string at 0x" + Twine::utohexstr(Offset + Value) +
|
||||
", it goes past the end of the table (0x" +
|
||||
Twine::utohexstr(Offset + DynamicStringTable.size()) + ")");
|
||||
}
|
||||
|
||||
template <class ELFT> void ELFDumper<ELFT>::printUnwindInfo() {
|
||||
|
@ -2596,14 +2606,14 @@ template <class ELFT> void ELFDumper<ELFT>::printDynamicTable() {
|
|||
template <class ELFT> void ELFDumper<ELFT>::printNeededLibraries() {
|
||||
ListScope D(W, "NeededLibraries");
|
||||
|
||||
std::vector<std::string> Libs;
|
||||
std::vector<StringRef> Libs;
|
||||
for (const auto &Entry : dynamic_table())
|
||||
if (Entry.d_tag == ELF::DT_NEEDED)
|
||||
Libs.push_back(getDynamicString(Entry.d_un.d_val));
|
||||
|
||||
llvm::sort(Libs);
|
||||
|
||||
for (const std::string &L : Libs)
|
||||
for (StringRef L : Libs)
|
||||
W.startLine() << L << "\n";
|
||||
}
|
||||
|
||||
|
@ -4235,12 +4245,11 @@ template <class ELFT> void GNUStyle<ELFT>::printDynamic(const ELFO *Obj) {
|
|||
std::string ValueFmt = " %-" + std::to_string(MaxTagSize) + "s ";
|
||||
for (auto Entry : Table) {
|
||||
uintX_t Tag = Entry.getTag();
|
||||
std::string TypeString =
|
||||
std::string Type =
|
||||
std::string("(") + Obj->getDynamicTagAsString(Tag).c_str() + ")";
|
||||
std::string Value = this->dumper()->getDynamicEntry(Tag, Entry.getVal());
|
||||
OS << " " << format_hex(Tag, ELFT::Is64Bits ? 18 : 10)
|
||||
<< format(ValueFmt.c_str(), TypeString.c_str());
|
||||
this->dumper()->printDynamicEntry(OS, Tag, Entry.getVal());
|
||||
OS << "\n";
|
||||
<< format(ValueFmt.c_str(), Type.c_str()) << Value << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6051,7 +6060,6 @@ template <class ELFT> void LLVMStyle<ELFT>::printDynamic(const ELFFile<ELFT> *Ob
|
|||
if (Table.empty())
|
||||
return;
|
||||
|
||||
raw_ostream &OS = W.getOStream();
|
||||
W.startLine() << "DynamicSection [ (" << Table.size() << " entries)\n";
|
||||
|
||||
size_t MaxTagSize = getMaxDynamicTagSize(Obj, Table);
|
||||
|
@ -6064,12 +6072,12 @@ template <class ELFT> void LLVMStyle<ELFT>::printDynamic(const ELFFile<ELFT> *Ob
|
|||
std::string ValueFmt = "%-" + std::to_string(MaxTagSize) + "s ";
|
||||
for (auto Entry : Table) {
|
||||
uintX_t Tag = Entry.getTag();
|
||||
std::string Value = this->dumper()->getDynamicEntry(Tag, Entry.getVal());
|
||||
W.startLine() << " " << format_hex(Tag, ELFT::Is64Bits ? 18 : 10, true)
|
||||
<< " "
|
||||
<< format(ValueFmt.c_str(),
|
||||
Obj->getDynamicTagAsString(Tag).c_str());
|
||||
this->dumper()->printDynamicEntry(OS, Tag, Entry.getVal());
|
||||
OS << "\n";
|
||||
Obj->getDynamicTagAsString(Tag).c_str())
|
||||
<< Value << "\n";
|
||||
}
|
||||
W.startLine() << "]\n";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue