mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +01:00
Revert "[llvm-readelf/obj] - Allow dumping of ELF header even if some elements are corrupt."
This reverts commit ea8a0b8b29eb08d3f0f6ac40942a2d8e98ab57ee. It broke BBots. http://lab.llvm.org:8011/#/builders/14/builds/1439 http://lab.llvm.org:8011/#/builders/112/builds/913
This commit is contained in:
parent
0e596f45f4
commit
aaa86f8a5c
@ -91,8 +91,6 @@ public:
|
||||
Binary(const Binary &other) = delete;
|
||||
virtual ~Binary();
|
||||
|
||||
virtual Error initContent() { return Error::success(); };
|
||||
|
||||
StringRef getData() const;
|
||||
StringRef getFileName() const;
|
||||
MemoryBufferRef getMemoryBufferRef() const;
|
||||
@ -180,8 +178,7 @@ DEFINE_ISA_CONVERSION_FUNCTIONS(Binary, LLVMBinaryRef)
|
||||
///
|
||||
/// @param Source The data to create the Binary from.
|
||||
Expected<std::unique_ptr<Binary>> createBinary(MemoryBufferRef Source,
|
||||
LLVMContext *Context = nullptr,
|
||||
bool InitContent = true);
|
||||
LLVMContext *Context = nullptr);
|
||||
|
||||
template <typename T> class OwningBinary {
|
||||
std::unique_ptr<T> Bin;
|
||||
@ -232,8 +229,7 @@ template <typename T> const T* OwningBinary<T>::getBinary() const {
|
||||
}
|
||||
|
||||
Expected<OwningBinary<Binary>> createBinary(StringRef Path,
|
||||
LLVMContext *Context = nullptr,
|
||||
bool InitContent = true);
|
||||
LLVMContext *Context = nullptr);
|
||||
|
||||
} // end namespace object
|
||||
|
||||
|
@ -246,15 +246,11 @@ public:
|
||||
return SectionRef(toDRI(Sec), this);
|
||||
}
|
||||
|
||||
bool IsContentValid() const { return ContentValid; }
|
||||
|
||||
private:
|
||||
ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
|
||||
const Elf_Shdr *DotDynSymSec, const Elf_Shdr *DotSymtabSec,
|
||||
const Elf_Shdr *DotSymtabShndxSec);
|
||||
|
||||
bool ContentValid = false;
|
||||
|
||||
protected:
|
||||
ELFFile<ELFT> EF;
|
||||
|
||||
@ -262,8 +258,6 @@ protected:
|
||||
const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section.
|
||||
const Elf_Shdr *DotSymtabShndxSec = nullptr; // SHT_SYMTAB_SHNDX section.
|
||||
|
||||
Error initContent() override;
|
||||
|
||||
void moveSymbolNext(DataRefImpl &Symb) const override;
|
||||
Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
|
||||
Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
|
||||
@ -406,8 +400,7 @@ protected:
|
||||
|
||||
public:
|
||||
ELFObjectFile(ELFObjectFile<ELFT> &&Other);
|
||||
static Expected<ELFObjectFile<ELFT>> create(MemoryBufferRef Object,
|
||||
bool InitContent = true);
|
||||
static Expected<ELFObjectFile<ELFT>> create(MemoryBufferRef Object);
|
||||
|
||||
const Elf_Rel *getRel(DataRefImpl Rel) const;
|
||||
const Elf_Rela *getRela(DataRefImpl Rela) const;
|
||||
@ -464,35 +457,6 @@ void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
|
||||
++Sym.d.b;
|
||||
}
|
||||
|
||||
template <class ELFT> Error ELFObjectFile<ELFT>::initContent() {
|
||||
auto SectionsOrErr = EF.sections();
|
||||
if (!SectionsOrErr)
|
||||
return SectionsOrErr.takeError();
|
||||
|
||||
for (const Elf_Shdr &Sec : *SectionsOrErr) {
|
||||
switch (Sec.sh_type) {
|
||||
case ELF::SHT_DYNSYM: {
|
||||
if (!DotDynSymSec)
|
||||
DotDynSymSec = &Sec;
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_SYMTAB: {
|
||||
if (!DotSymtabSec)
|
||||
DotSymtabSec = &Sec;
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_SYMTAB_SHNDX: {
|
||||
if (!DotSymtabShndxSec)
|
||||
DotSymtabShndxSec = &Sec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ContentValid = true;
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
Expected<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const {
|
||||
const Elf_Sym *ESym = getSymbol(Sym);
|
||||
@ -1028,17 +992,40 @@ ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
|
||||
|
||||
template <class ELFT>
|
||||
Expected<ELFObjectFile<ELFT>>
|
||||
ELFObjectFile<ELFT>::create(MemoryBufferRef Object, bool InitContent) {
|
||||
ELFObjectFile<ELFT>::create(MemoryBufferRef Object) {
|
||||
auto EFOrErr = ELFFile<ELFT>::create(Object.getBuffer());
|
||||
if (Error E = EFOrErr.takeError())
|
||||
return std::move(E);
|
||||
auto EF = std::move(*EFOrErr);
|
||||
|
||||
ELFObjectFile<ELFT> Obj = {Object, std::move(*EFOrErr), nullptr, nullptr,
|
||||
nullptr};
|
||||
if (InitContent)
|
||||
if (Error E = Obj.initContent())
|
||||
return std::move(E);
|
||||
return Obj;
|
||||
auto SectionsOrErr = EF.sections();
|
||||
if (!SectionsOrErr)
|
||||
return SectionsOrErr.takeError();
|
||||
|
||||
const Elf_Shdr *DotDynSymSec = nullptr;
|
||||
const Elf_Shdr *DotSymtabSec = nullptr;
|
||||
const Elf_Shdr *DotSymtabShndxSec = nullptr;
|
||||
for (const Elf_Shdr &Sec : *SectionsOrErr) {
|
||||
switch (Sec.sh_type) {
|
||||
case ELF::SHT_DYNSYM: {
|
||||
if (!DotDynSymSec)
|
||||
DotDynSymSec = &Sec;
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_SYMTAB: {
|
||||
if (!DotSymtabSec)
|
||||
DotSymtabSec = &Sec;
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_SYMTAB_SHNDX: {
|
||||
if (!DotSymtabShndxSec)
|
||||
DotSymtabShndxSec = &Sec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ELFObjectFile<ELFT>(Object, EF, DotDynSymSec, DotSymtabSec,
|
||||
DotSymtabShndxSec);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
|
@ -350,8 +350,7 @@ public:
|
||||
createObjectFile(StringRef ObjectPath);
|
||||
|
||||
static Expected<std::unique_ptr<ObjectFile>>
|
||||
createObjectFile(MemoryBufferRef Object, llvm::file_magic Type,
|
||||
bool InitContent = true);
|
||||
createObjectFile(MemoryBufferRef Object, llvm::file_magic Type);
|
||||
static Expected<std::unique_ptr<ObjectFile>>
|
||||
createObjectFile(MemoryBufferRef Object) {
|
||||
return createObjectFile(Object, llvm::file_magic::unknown);
|
||||
@ -368,7 +367,7 @@ public:
|
||||
createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
|
||||
|
||||
static Expected<std::unique_ptr<ObjectFile>>
|
||||
createELFObjectFile(MemoryBufferRef Object, bool InitContent = true);
|
||||
createELFObjectFile(MemoryBufferRef Object);
|
||||
|
||||
static Expected<std::unique_ptr<MachOObjectFile>>
|
||||
createMachOObjectFile(MemoryBufferRef Object,
|
||||
|
@ -161,12 +161,14 @@ public:
|
||||
// construction aux.
|
||||
static Expected<std::unique_ptr<SymbolicFile>>
|
||||
createSymbolicFile(MemoryBufferRef Object, llvm::file_magic Type,
|
||||
LLVMContext *Context, bool InitContent = true);
|
||||
LLVMContext *Context);
|
||||
|
||||
static Expected<std::unique_ptr<SymbolicFile>>
|
||||
createSymbolicFile(MemoryBufferRef Object) {
|
||||
return createSymbolicFile(Object, llvm::file_magic::unknown, nullptr);
|
||||
}
|
||||
static Expected<OwningBinary<SymbolicFile>>
|
||||
createSymbolicFile(StringRef ObjectPath);
|
||||
|
||||
static bool classof(const Binary *v) {
|
||||
return v->isSymbolic();
|
||||
|
@ -44,8 +44,7 @@ StringRef Binary::getFileName() const { return Data.getBufferIdentifier(); }
|
||||
MemoryBufferRef Binary::getMemoryBufferRef() const { return Data; }
|
||||
|
||||
Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
|
||||
LLVMContext *Context,
|
||||
bool InitContent) {
|
||||
LLVMContext *Context) {
|
||||
file_magic Type = identify_magic(Buffer.getBuffer());
|
||||
|
||||
switch (Type) {
|
||||
@ -74,7 +73,7 @@ Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
|
||||
case file_magic::xcoff_object_32:
|
||||
case file_magic::xcoff_object_64:
|
||||
case file_magic::wasm_object:
|
||||
return ObjectFile::createSymbolicFile(Buffer, Type, Context, InitContent);
|
||||
return ObjectFile::createSymbolicFile(Buffer, Type, Context);
|
||||
case file_magic::macho_universal_binary:
|
||||
return MachOUniversalBinary::create(Buffer);
|
||||
case file_magic::windows_resource:
|
||||
@ -94,8 +93,8 @@ Expected<std::unique_ptr<Binary>> object::createBinary(MemoryBufferRef Buffer,
|
||||
llvm_unreachable("Unexpected Binary File Type");
|
||||
}
|
||||
|
||||
Expected<OwningBinary<Binary>>
|
||||
object::createBinary(StringRef Path, LLVMContext *Context, bool InitContent) {
|
||||
Expected<OwningBinary<Binary>> object::createBinary(StringRef Path,
|
||||
LLVMContext *Context) {
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
|
||||
MemoryBuffer::getFileOrSTDIN(Path, /*FileSize=*/-1,
|
||||
/*RequiresNullTerminator=*/false);
|
||||
@ -104,7 +103,7 @@ object::createBinary(StringRef Path, LLVMContext *Context, bool InitContent) {
|
||||
std::unique_ptr<MemoryBuffer> &Buffer = FileOrErr.get();
|
||||
|
||||
Expected<std::unique_ptr<Binary>> BinOrErr =
|
||||
createBinary(Buffer->getMemBufferRef(), Context, InitContent);
|
||||
createBinary(Buffer->getMemBufferRef(), Context);
|
||||
if (!BinOrErr)
|
||||
return BinOrErr.takeError();
|
||||
std::unique_ptr<Binary> &Bin = BinOrErr.get();
|
||||
|
@ -61,15 +61,15 @@ ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
|
||||
|
||||
template <class ELFT>
|
||||
static Expected<std::unique_ptr<ELFObjectFile<ELFT>>>
|
||||
createPtr(MemoryBufferRef Object, bool InitContent) {
|
||||
auto Ret = ELFObjectFile<ELFT>::create(Object, InitContent);
|
||||
createPtr(MemoryBufferRef Object) {
|
||||
auto Ret = ELFObjectFile<ELFT>::create(Object);
|
||||
if (Error E = Ret.takeError())
|
||||
return std::move(E);
|
||||
return std::make_unique<ELFObjectFile<ELFT>>(std::move(*Ret));
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<ObjectFile>>
|
||||
ObjectFile::createELFObjectFile(MemoryBufferRef Obj, bool InitContent) {
|
||||
ObjectFile::createELFObjectFile(MemoryBufferRef Obj) {
|
||||
std::pair<unsigned char, unsigned char> Ident =
|
||||
getElfArchType(Obj.getBuffer());
|
||||
std::size_t MaxAlignment =
|
||||
@ -80,16 +80,16 @@ ObjectFile::createELFObjectFile(MemoryBufferRef Obj, bool InitContent) {
|
||||
|
||||
if (Ident.first == ELF::ELFCLASS32) {
|
||||
if (Ident.second == ELF::ELFDATA2LSB)
|
||||
return createPtr<ELF32LE>(Obj, InitContent);
|
||||
return createPtr<ELF32LE>(Obj);
|
||||
else if (Ident.second == ELF::ELFDATA2MSB)
|
||||
return createPtr<ELF32BE>(Obj, InitContent);
|
||||
return createPtr<ELF32BE>(Obj);
|
||||
else
|
||||
return createError("Invalid ELF data");
|
||||
} else if (Ident.first == ELF::ELFCLASS64) {
|
||||
if (Ident.second == ELF::ELFDATA2LSB)
|
||||
return createPtr<ELF64LE>(Obj, InitContent);
|
||||
return createPtr<ELF64LE>(Obj);
|
||||
else if (Ident.second == ELF::ELFDATA2MSB)
|
||||
return createPtr<ELF64BE>(Obj, InitContent);
|
||||
return createPtr<ELF64BE>(Obj);
|
||||
else
|
||||
return createError("Invalid ELF data");
|
||||
}
|
||||
|
@ -132,8 +132,7 @@ Triple ObjectFile::makeTriple() const {
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<ObjectFile>>
|
||||
ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type,
|
||||
bool InitContent) {
|
||||
ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type) {
|
||||
StringRef Data = Object.getBuffer();
|
||||
if (Type == file_magic::unknown)
|
||||
Type = identify_magic(Data);
|
||||
@ -155,7 +154,7 @@ ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type,
|
||||
case file_magic::elf_executable:
|
||||
case file_magic::elf_shared_object:
|
||||
case file_magic::elf_core:
|
||||
return createELFObjectFile(Object, InitContent);
|
||||
return createELFObjectFile(Object);
|
||||
case file_magic::macho_object:
|
||||
case file_magic::macho_executable:
|
||||
case file_magic::macho_fixed_virtual_memory_shared_lib:
|
||||
|
@ -36,7 +36,7 @@ SymbolicFile::~SymbolicFile() = default;
|
||||
|
||||
Expected<std::unique_ptr<SymbolicFile>>
|
||||
SymbolicFile::createSymbolicFile(MemoryBufferRef Object, file_magic Type,
|
||||
LLVMContext *Context, bool InitContent) {
|
||||
LLVMContext *Context) {
|
||||
StringRef Data = Object.getBuffer();
|
||||
if (Type == file_magic::unknown)
|
||||
Type = identify_magic(Data);
|
||||
@ -67,14 +67,14 @@ SymbolicFile::createSymbolicFile(MemoryBufferRef Object, file_magic Type,
|
||||
case file_magic::xcoff_object_32:
|
||||
case file_magic::xcoff_object_64:
|
||||
case file_magic::wasm_object:
|
||||
return ObjectFile::createObjectFile(Object, Type, InitContent);
|
||||
return ObjectFile::createObjectFile(Object, Type);
|
||||
case file_magic::coff_import_library:
|
||||
return std::unique_ptr<SymbolicFile>(new COFFImportFile(Object));
|
||||
case file_magic::elf_relocatable:
|
||||
case file_magic::macho_object:
|
||||
case file_magic::coff_object: {
|
||||
Expected<std::unique_ptr<ObjectFile>> Obj =
|
||||
ObjectFile::createObjectFile(Object, Type, InitContent);
|
||||
ObjectFile::createObjectFile(Object, Type);
|
||||
if (!Obj || !Context)
|
||||
return std::move(Obj);
|
||||
|
||||
|
@ -175,11 +175,9 @@ Sections:
|
||||
## when the e_shentsize field is broken.
|
||||
|
||||
# RUN: yaml2obj %s --docnum=9 -o %t9
|
||||
# RUN: not llvm-readobj -S %t9 2>&1 | \
|
||||
# RUN: FileCheck -DFILE=%t9 --implicit-check-not=warning: --check-prefix=INVALID-SH-ENTSIZE %s
|
||||
# RUN: not llvm-readobj -S %t9 2>&1 | FileCheck --check-prefix=INVALID-SH-ENTSIZE %s
|
||||
|
||||
# INVALID-SH-ENTSIZE: LoadName: <Not found>
|
||||
# INVALID-SH-ENTSIZE-NEXT: error: '[[FILE]]': unable to continue dumping, the file is corrupt: invalid e_shentsize in ELF header: 1
|
||||
# INVALID-SH-ENTSIZE: error: {{.*}}: invalid e_shentsize in ELF header: 1
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
@ -314,12 +312,10 @@ Symbols:
|
||||
## when the e_shnum field is broken (is greater than the actual number of sections).
|
||||
|
||||
# RUN: yaml2obj %s --docnum=15 -o %t15
|
||||
# RUN: not llvm-readobj -S %t15 2>&1 | \
|
||||
# RUN: FileCheck -DFILE=%t15 --implicit-check-not=warning: --check-prefix=INVALID-SECTION-NUM %s
|
||||
|
||||
# INVALID-SECTION-NUM: LoadName: <Not found>
|
||||
# INVALID-SECTION-NUM-NEXT: error: '[[FILE]]': unable to continue dumping, the file is corrupt: section table goes past the end of file
|
||||
# RUN: not llvm-readobj -S %t15 2>&1 | FileCheck --check-prefix=INVALID-SECTION-NUM %s
|
||||
|
||||
# INVALID-SECTION-NUM: error: {{.*}}: section table goes past the end of file
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
@ -555,7 +551,7 @@ Sections:
|
||||
# RUN: yaml2obj --docnum=25 %s -o %t25
|
||||
# RUN: not llvm-readobj -h %t25 2>&1 | FileCheck -DFILE=%t25 --check-prefix=INVALID-SEC-NUM1 %s
|
||||
|
||||
# INVALID-SEC-NUM1: error: '[[FILE]]': unable to continue dumping, the file is corrupt: invalid section header table offset (e_shoff = 0x58) or invalid number of sections specified in the first section header's sh_size field (0x3ffffffffffffff)
|
||||
# INVALID-SEC-NUM1: error: '[[FILE]]': invalid section header table offset (e_shoff = 0x58) or invalid number of sections specified in the first section header's sh_size field (0x3ffffffffffffff)
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
@ -574,7 +570,7 @@ Sections:
|
||||
# RUN: yaml2obj --docnum=26 %s -o %t26
|
||||
# RUN: not llvm-readobj -h %t26 2>&1 | FileCheck -DFILE=%t26 --check-prefix=INVALID-SEC-NUM2 %s
|
||||
|
||||
# INVALID-SEC-NUM2: error: '[[FILE]]': unable to continue dumping, the file is corrupt: invalid number of sections specified in the NULL section's sh_size field (288230376151711744)
|
||||
# INVALID-SEC-NUM2: error: '[[FILE]]': invalid number of sections specified in the NULL section's sh_size field (288230376151711744)
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
@ -592,8 +588,8 @@ Sections:
|
||||
# RUN: yaml2obj --docnum=27 %s -o %t27
|
||||
# RUN: not llvm-readobj -h %t27 2>&1 | FileCheck -DFILE=%t27 --check-prefix=INVALID-SEC-NUM3 %s
|
||||
|
||||
# INVALID-SEC-NUM3: error: '[[FILE]]': unable to continue dumping, the file is corrupt: section header table goes past the end of the file: e_shoff = 0xffffffffffffffff
|
||||
|
||||
# INVALID-SEC-NUM3: error: '[[FILE]]': section header table goes past the end of the file: e_shoff = 0xffffffffffffffff
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
|
@ -137,98 +137,3 @@ FileHeader:
|
||||
# LANAI-NEXT: StringTableSectionIndex: 2
|
||||
# LANAI-NEXT:}
|
||||
# LANAI-NOT:{{.}}
|
||||
|
||||
## Check we are able to dump the file header when the section header table can't be read.
|
||||
|
||||
# RUN: yaml2obj %s --docnum=4 -o %t.invalid1
|
||||
# RUN: not llvm-readobj --file-headers %t.invalid1 2>&1 \
|
||||
# RUN: | FileCheck %s --implicit-check-not=warning: -DFILE=%t.invalid1 \
|
||||
# RUN: -DSECHDRCOUNT=8192 -DSECHDRSTRTABINDEX=12288 --check-prefix=INVALID-LLVM
|
||||
# RUN: not llvm-readelf --file-headers %t.invalid1 2>&1 \
|
||||
# RUN: | FileCheck %s --implicit-check-not=warning: -DFILE=%t.invalid1 \
|
||||
# RUN: -DSECHDRCOUNT=8192 -DSECHDRSTRTABINDEX=12288 --check-prefix=INVALID-GNU
|
||||
|
||||
# INVALID-LLVM: File: [[FILE]]
|
||||
# INVALID-LLVM-NEXT: Format: elf64-unknown
|
||||
# INVALID-LLVM-NEXT: Arch: unknown
|
||||
# INVALID-LLVM-NEXT: AddressSize: 64bit
|
||||
# INVALID-LLVM-NEXT: LoadName: <Not found>
|
||||
# INVALID-LLVM-NEXT: ElfHeader {
|
||||
# INVALID-LLVM-NEXT: Ident {
|
||||
# INVALID-LLVM-NEXT: Magic: (7F 45 4C 46)
|
||||
# INVALID-LLVM-NEXT: Class: 64-bit (0x2)
|
||||
# INVALID-LLVM-NEXT: DataEncoding: LittleEndian (0x1)
|
||||
# INVALID-LLVM-NEXT: FileVersion: 1
|
||||
# INVALID-LLVM-NEXT: OS/ABI: SystemV (0x0)
|
||||
# INVALID-LLVM-NEXT: ABIVersion: 0
|
||||
# INVALID-LLVM-NEXT: Unused: (00 00 00 00 00 00 00)
|
||||
# INVALID-LLVM-NEXT: }
|
||||
# INVALID-LLVM-NEXT: Type: Relocatable (0x1)
|
||||
# INVALID-LLVM-NEXT: Machine: EM_NONE (0x0)
|
||||
# INVALID-LLVM-NEXT: Version: 1
|
||||
# INVALID-LLVM-NEXT: Entry: 0x0
|
||||
# INVALID-LLVM-NEXT: ProgramHeaderOffset: 0x0
|
||||
# INVALID-LLVM-NEXT: SectionHeaderOffset: 0x1000
|
||||
# INVALID-LLVM-NEXT: Flags [ (0x0)
|
||||
# INVALID-LLVM-NEXT: ]
|
||||
# INVALID-LLVM-NEXT: HeaderSize: 64
|
||||
# INVALID-LLVM-NEXT: ProgramHeaderEntrySize: 0
|
||||
# INVALID-LLVM-NEXT: ProgramHeaderCount: 0
|
||||
# INVALID-LLVM-NEXT: SectionHeaderEntrySize: 64
|
||||
# INVALID-LLVM-NEXT: SectionHeaderCount: [[SECHDRCOUNT]]
|
||||
# INVALID-LLVM-NEXT: StringTableSectionIndex: [[SECHDRSTRTABINDEX]]
|
||||
# INVALID-LLVM-NEXT: }
|
||||
# INVALID-LLVM-NEXT: error: '[[FILE]]': unable to continue dumping, the file is corrupt: section header table goes past the end of the file: e_shoff = 0x1000
|
||||
|
||||
# INVALID-GNU: ELF Header:
|
||||
# INVALID-GNU-NEXT: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
|
||||
# INVALID-GNU-NEXT: Class: ELF64
|
||||
# INVALID-GNU-NEXT: Data: 2's complement, little endian
|
||||
# INVALID-GNU-NEXT: Version: 1 (current)
|
||||
# INVALID-GNU-NEXT: OS/ABI: UNIX - System V
|
||||
# INVALID-GNU-NEXT: ABI Version: 0
|
||||
# INVALID-GNU-NEXT: Type: REL (Relocatable file)
|
||||
# INVALID-GNU-NEXT: Machine: None
|
||||
# INVALID-GNU-NEXT: Version: 0x1
|
||||
# INVALID-GNU-NEXT: Entry point address: 0x0
|
||||
# INVALID-GNU-NEXT: Start of program headers: 0 (bytes into file)
|
||||
# INVALID-GNU-NEXT: Start of section headers: 4096 (bytes into file)
|
||||
# INVALID-GNU-NEXT: Flags: 0x0
|
||||
# INVALID-GNU-NEXT: Size of this header: 64 (bytes)
|
||||
# INVALID-GNU-NEXT: Size of program headers: 0 (bytes)
|
||||
# INVALID-GNU-NEXT: Number of program headers: 0
|
||||
# INVALID-GNU-NEXT: Size of section headers: 64 (bytes)
|
||||
# INVALID-GNU-NEXT: Number of section headers: [[SECHDRCOUNT]]
|
||||
# INVALID-GNU-NEXT: Section header string table index: [[SECHDRSTRTABINDEX]]
|
||||
# INVALID-GNU-NEXT: error: '[[FILE]]': unable to continue dumping, the file is corrupt: section header table goes past the end of the file: e_shoff = 0x1000
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
## The section header table offset goes past the EOF.
|
||||
EShOff: 0x1000
|
||||
## The number of section headers is too large, the file is
|
||||
## too little to contain so many sections.
|
||||
EShNum: [[SHNUM=0x2000]]
|
||||
## The index of the section name string table is too large.
|
||||
## The section would be past the EOF.
|
||||
EShStrNdx: [[SHSTRNDX=0x3000]]
|
||||
SectionHeaderTable:
|
||||
NoHeaders: true
|
||||
|
||||
## Check we don't dump anything except the file header when the section header table can't be read.
|
||||
|
||||
# RUN: not llvm-readobj -a %t.invalid 2>&1 \
|
||||
# RUN: | FileCheck %s -DFILE=%t.invalid -DSECHDRCOUNT=8192 -DSECHDRSTRTABINDEX=12288 --check-prefix=INVALID-LLVM
|
||||
# RUN: not llvm-readelf -a %t.invalid 2>&1 \
|
||||
# RUN: | FileCheck %s -DFILE=%t.invalid -DSECHDRCOUNT=8192 -DSECHDRSTRTABINDEX=12288 --check-prefix=INVALID-GNU
|
||||
|
||||
## Check what we print when e_shnum == 0, e_shstrndx == SHN_XINDEX and the section header table can't be read.
|
||||
|
||||
# RUN: yaml2obj %s -DSHNUM=0 -DSHSTRNDX=0xffff --docnum=4 -o %t.invalid2
|
||||
# RUN: not llvm-readobj --file-headers %t.invalid2 2>&1 \
|
||||
# RUN: | FileCheck %s -DFILE=%t.invalid2 -DSECHDRCOUNT="<?>" -DSECHDRSTRTABINDEX="<?>" --check-prefix=INVALID-LLVM
|
||||
# RUN: not llvm-readelf --file-headers %t.invalid2 2>&1 \
|
||||
# RUN: | FileCheck %s -DFILE=%t.invalid2 -DSECHDRCOUNT="<?>" -DSECHDRSTRTABINDEX="<?>" --check-prefix=INVALID-GNU
|
||||
|
@ -174,7 +174,7 @@ SectionHeaderTable: [[VAL]]
|
||||
## Test that we are still able to override e_shoff, e_shnum and e_shstrndx
|
||||
## fields even when we do not produce section headers.
|
||||
# RUN: yaml2obj %s --docnum=6 -o %t4
|
||||
# RUN: not llvm-readelf --file-headers %t4 | FileCheck %s --check-prefix=NO-HEADERS-OVERRIDE
|
||||
# RUN: llvm-readelf --file-headers %t4 | FileCheck %s --check-prefix=NO-HEADERS-OVERRIDE
|
||||
|
||||
# NO-HEADERS-OVERRIDE: Start of section headers: 2 (bytes into file)
|
||||
# NO-HEADERS-OVERRIDE: Number of section headers: 3
|
||||
@ -188,6 +188,13 @@ FileHeader:
|
||||
EShOff: 0x2
|
||||
EShNum: 0x3
|
||||
EShStrNdx: 0x4
|
||||
Sections:
|
||||
- Name: .foo
|
||||
Type: SHT_PROGBITS
|
||||
## FIXME: we have to set an arbitrary size to create a
|
||||
## piece of dummy data to make llvm-readelf happy.
|
||||
## See: https://bugs.llvm.org/show_bug.cgi?id=40804
|
||||
Size: 0x100
|
||||
SectionHeaderTable:
|
||||
NoHeaders: true
|
||||
|
||||
|
@ -1998,9 +1998,6 @@ ELFDumper<ELFT>::ELFDumper(const object::ELFObjectFile<ELFT> &O,
|
||||
else
|
||||
ELFDumperStyle.reset(new LLVMStyle<ELFT>(Writer, *this));
|
||||
|
||||
if (!O.IsContentValid())
|
||||
return;
|
||||
|
||||
typename ELFT::ShdrRange Sections = cantFail(Obj.sections());
|
||||
for (const Elf_Shdr &Sec : Sections) {
|
||||
switch (Sec.sh_type) {
|
||||
@ -3450,17 +3447,10 @@ static std::string getSectionHeadersNumString(const ELFFile<ELFT> &Obj,
|
||||
if (ElfHeader.e_shnum != 0)
|
||||
return to_string(ElfHeader.e_shnum);
|
||||
|
||||
Expected<ArrayRef<typename ELFT::Shdr>> ArrOrErr = Obj.sections();
|
||||
if (!ArrOrErr) {
|
||||
// In this case we can ignore an error, because we have already reported a
|
||||
// warning about the broken section header table earlier.
|
||||
consumeError(ArrOrErr.takeError());
|
||||
return "<?>";
|
||||
}
|
||||
|
||||
if (ArrOrErr->empty())
|
||||
ArrayRef<typename ELFT::Shdr> Arr = cantFail(Obj.sections());
|
||||
if (Arr.empty())
|
||||
return "0";
|
||||
return "0 (" + to_string((*ArrOrErr)[0].sh_size) + ")";
|
||||
return "0 (" + to_string(Arr[0].sh_size) + ")";
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
@ -3470,18 +3460,11 @@ static std::string getSectionHeaderTableIndexString(const ELFFile<ELFT> &Obj,
|
||||
if (ElfHeader.e_shstrndx != SHN_XINDEX)
|
||||
return to_string(ElfHeader.e_shstrndx);
|
||||
|
||||
Expected<ArrayRef<typename ELFT::Shdr>> ArrOrErr = Obj.sections();
|
||||
if (!ArrOrErr) {
|
||||
// In this case we can ignore an error, because we have already reported a
|
||||
// warning about the broken section header table earlier.
|
||||
consumeError(ArrOrErr.takeError());
|
||||
return "<?>";
|
||||
}
|
||||
|
||||
if (ArrOrErr->empty())
|
||||
ArrayRef<typename ELFT::Shdr> Arr = cantFail(Obj.sections());
|
||||
if (Arr.empty())
|
||||
return "65535 (corrupt: out of range)";
|
||||
return to_string(ElfHeader.e_shstrndx) + " (" +
|
||||
to_string((*ArrOrErr)[0].sh_link) + ")";
|
||||
return to_string(ElfHeader.e_shstrndx) + " (" + to_string(Arr[0].sh_link) +
|
||||
")";
|
||||
}
|
||||
|
||||
template <class ELFT> void GNUStyle<ELFT>::printFileHeaders() {
|
||||
|
@ -35,8 +35,6 @@ public:
|
||||
ObjDumper(ScopedPrinter &Writer);
|
||||
virtual ~ObjDumper();
|
||||
|
||||
virtual bool canDumpContent() { return true; }
|
||||
|
||||
virtual void printFileHeaders() = 0;
|
||||
virtual void printSectionHeaders() = 0;
|
||||
virtual void printRelocations() = 0;
|
||||
|
@ -458,17 +458,12 @@ createDumper(const ObjectFile &Obj, ScopedPrinter &Writer) {
|
||||
}
|
||||
|
||||
/// Dumps the specified object file.
|
||||
static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer,
|
||||
static void dumpObject(const ObjectFile &Obj, ScopedPrinter &Writer,
|
||||
const Archive *A = nullptr) {
|
||||
std::string FileStr =
|
||||
A ? Twine(A->getFileName() + "(" + Obj.getFileName() + ")").str()
|
||||
: Obj.getFileName().str();
|
||||
|
||||
std::string ContentErrString;
|
||||
if (Error ContentErr = Obj.initContent())
|
||||
ContentErrString = "unable to continue dumping, the file is corrupt: " +
|
||||
toString(std::move(ContentErr));
|
||||
|
||||
ObjDumper *Dumper;
|
||||
Expected<std::unique_ptr<ObjDumper>> DumperOrErr = createDumper(Obj, Writer);
|
||||
if (!DumperOrErr)
|
||||
@ -491,11 +486,6 @@ static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer,
|
||||
if (opts::FileHeaders)
|
||||
Dumper->printFileHeaders();
|
||||
|
||||
// This is only used for ELF currently. In some cases, when an object is
|
||||
// corrupt (e.g. truncated), we can't dump anything except the file header.
|
||||
if (!ContentErrString.empty())
|
||||
reportError(createError(ContentErrString), FileStr);
|
||||
|
||||
if (opts::SectionDetails || opts::SectionHeaders) {
|
||||
if (opts::Output == opts::GNU && opts::SectionDetails)
|
||||
Dumper->printSectionDetails();
|
||||
@ -647,8 +637,7 @@ static void dumpWindowsResourceFile(WindowsResource *WinRes,
|
||||
/// Opens \a File and dumps it.
|
||||
static void dumpInput(StringRef File, ScopedPrinter &Writer) {
|
||||
// Attempt to open the binary.
|
||||
Expected<OwningBinary<Binary>> BinaryOrErr =
|
||||
createBinary(File, /*Context=*/nullptr, /*InitContent=*/false);
|
||||
Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(File);
|
||||
if (!BinaryOrErr)
|
||||
reportError(BinaryOrErr.takeError(), File);
|
||||
Binary &Binary = *BinaryOrErr.get().getBinary();
|
||||
|
Loading…
Reference in New Issue
Block a user