forked from OSchip/llvm-project
[llvm-objdump] Change printSymbolVersionDependency to use ELFFile API
When .gnu.version_r is empty (allowed by readelf but warned by objdump), llvm-objdump -p may decode the next section as .gnu.version_r and may crash due to out-of-bounds C string reference. ELFFile<ELFT>::getVersionDependencies handles 0-entry .gnu.version_r gracefully. Just use it. Fix https://github.com/llvm/llvm-project/issues/57707 Differential Revision: https://reviews.llvm.org/D133751
This commit is contained in:
parent
55a72dae1f
commit
25394c9d10
|
@ -1038,7 +1038,7 @@ ELFFile<ELFT>::getVersionDependencies(const Elf_Shdr &Sec,
|
|||
VN.Offset = VerneedBuf - Start;
|
||||
|
||||
if (Verneed->vn_file < StrTab.size())
|
||||
VN.File = std::string(StrTab.drop_front(Verneed->vn_file));
|
||||
VN.File = std::string(StrTab.data() + Verneed->vn_file);
|
||||
else
|
||||
VN.File = ("<corrupt vn_file: " + Twine(Verneed->vn_file) + ">").str();
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
# RUN: llvm-objdump -p %t 2>&1 | FileCheck %s --check-prefix=BROKEN-AUX -DFILE=%t
|
||||
|
||||
# BROKEN-AUX: Version References:
|
||||
# BROKEN-AUX-NEXT: required from :
|
||||
# BROKEN-AUX-NEXT: 0x00000000 0x00 00
|
||||
# BROKEN-AUX-NEXT: warning: '[[FILE]]': invalid SHT_GNU_verneed section with index 2: found a misaligned auxiliary entry at offset 0x11
|
||||
# BROKEN-AUX-NOT: {{.}}
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
|
|
|
@ -46,3 +46,23 @@ Sections:
|
|||
DynamicSymbols:
|
||||
- Name: f1
|
||||
Binding: STB_GLOBAL
|
||||
|
||||
# RUN: yaml2obj --docnum=2 %s -o %t.empty
|
||||
# RUN: llvm-objdump -p %t.empty 2>&1 | FileCheck %s --check-prefix=EMPTY --implicit-check-not=warning:
|
||||
|
||||
# EMPTY: Version References:
|
||||
# EMPTY-NOT: {{.}}
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
- Name: .gnu.version_r
|
||||
Type: SHT_GNU_verneed
|
||||
Flags: [ SHF_ALLOC ]
|
||||
DynamicSymbols:
|
||||
- Name: f1
|
||||
Binding: STB_GLOBAL
|
||||
|
|
|
@ -282,27 +282,28 @@ static void printProgramHeaders(const ELFFile<ELFT> &Obj, StringRef FileName) {
|
|||
}
|
||||
|
||||
template <class ELFT>
|
||||
static void printSymbolVersionDependency(ArrayRef<uint8_t> Contents,
|
||||
StringRef StrTab) {
|
||||
static void printSymbolVersionDependency(StringRef FileName,
|
||||
const ELFFile<ELFT> &Obj,
|
||||
const typename ELFT::Shdr &Sec) {
|
||||
outs() << "\nVersion References:\n";
|
||||
|
||||
const uint8_t *Buf = Contents.data();
|
||||
while (Buf) {
|
||||
auto *Verneed = reinterpret_cast<const typename ELFT::Verneed *>(Buf);
|
||||
outs() << " required from "
|
||||
<< StringRef(StrTab.drop_front(Verneed->vn_file).data()) << ":\n";
|
||||
auto WarningHandler = [&](const Twine &Msg) {
|
||||
reportWarning(Msg, FileName);
|
||||
return Error::success();
|
||||
};
|
||||
Expected<std::vector<VerNeed>> V =
|
||||
Obj.getVersionDependencies(Sec, WarningHandler);
|
||||
if (!V) {
|
||||
reportWarning(toString(V.takeError()), FileName);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8_t *BufAux = Buf + Verneed->vn_aux;
|
||||
while (BufAux) {
|
||||
auto *Vernaux = reinterpret_cast<const typename ELFT::Vernaux *>(BufAux);
|
||||
outs() << " "
|
||||
<< format("0x%08" PRIx32 " ", (uint32_t)Vernaux->vna_hash)
|
||||
<< format("0x%02" PRIx16 " ", (uint16_t)Vernaux->vna_flags)
|
||||
<< format("%02" PRIu16 " ", (uint16_t)Vernaux->vna_other)
|
||||
<< StringRef(StrTab.drop_front(Vernaux->vna_name).data()) << '\n';
|
||||
BufAux = Vernaux->vna_next ? BufAux + Vernaux->vna_next : nullptr;
|
||||
}
|
||||
Buf = Verneed->vn_next ? Buf + Verneed->vn_next : nullptr;
|
||||
raw_fd_ostream &OS = outs();
|
||||
for (const VerNeed &VN : *V) {
|
||||
OS << " required from " << VN.File << ":\n";
|
||||
for (const VernAux &Aux : VN.AuxV)
|
||||
OS << format(" 0x%08x 0x%02x %02u %s\n", Aux.Hash, Aux.Flags,
|
||||
Aux.Other, Aux.Name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -355,7 +356,7 @@ static void printSymbolVersionInfo(const ELFFile<ELFT> &Elf,
|
|||
StringRef StrTab = unwrapOrError(Elf.getStringTable(*StrTabSec), FileName);
|
||||
|
||||
if (Shdr.sh_type == ELF::SHT_GNU_verneed)
|
||||
printSymbolVersionDependency<ELFT>(Contents, StrTab);
|
||||
printSymbolVersionDependency<ELFT>(FileName, Elf, Shdr);
|
||||
else
|
||||
printSymbolVersionDefinition<ELFT>(Shdr, Contents, StrTab);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue