diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h index e12e512d68b..de0f48e7f4f 100644 --- a/include/llvm/Object/Binary.h +++ b/include/llvm/Object/Binary.h @@ -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> createBinary(MemoryBufferRef Source, - LLVMContext *Context = nullptr, - bool InitContent = true); + LLVMContext *Context = nullptr); template class OwningBinary { std::unique_ptr Bin; @@ -232,8 +229,7 @@ template const T* OwningBinary::getBinary() const { } Expected> createBinary(StringRef Path, - LLVMContext *Context = nullptr, - bool InitContent = true); + LLVMContext *Context = nullptr); } // end namespace object diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index abb065a0408..0f6604bd510 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -246,15 +246,11 @@ public: return SectionRef(toDRI(Sec), this); } - bool IsContentValid() const { return ContentValid; } - private: ELFObjectFile(MemoryBufferRef Object, ELFFile EF, const Elf_Shdr *DotDynSymSec, const Elf_Shdr *DotSymtabSec, const Elf_Shdr *DotSymtabShndxSec); - bool ContentValid = false; - protected: ELFFile 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 getSymbolName(DataRefImpl Symb) const override; Expected getSymbolAddress(DataRefImpl Symb) const override; @@ -406,8 +400,7 @@ protected: public: ELFObjectFile(ELFObjectFile &&Other); - static Expected> create(MemoryBufferRef Object, - bool InitContent = true); + static Expected> create(MemoryBufferRef Object); const Elf_Rel *getRel(DataRefImpl Rel) const; const Elf_Rela *getRela(DataRefImpl Rela) const; @@ -464,35 +457,6 @@ void ELFObjectFile::moveSymbolNext(DataRefImpl &Sym) const { ++Sym.d.b; } -template Error ELFObjectFile::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 Expected ELFObjectFile::getSymbolName(DataRefImpl Sym) const { const Elf_Sym *ESym = getSymbol(Sym); @@ -1028,17 +992,40 @@ ELFObjectFile::getRela(DataRefImpl Rela) const { template Expected> -ELFObjectFile::create(MemoryBufferRef Object, bool InitContent) { +ELFObjectFile::create(MemoryBufferRef Object) { auto EFOrErr = ELFFile::create(Object.getBuffer()); if (Error E = EFOrErr.takeError()) return std::move(E); + auto EF = std::move(*EFOrErr); - ELFObjectFile 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(Object, EF, DotDynSymSec, DotSymtabSec, + DotSymtabShndxSec); } template diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 27e40cbdbec..744e33d2d9f 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -350,8 +350,7 @@ public: createObjectFile(StringRef ObjectPath); static Expected> - createObjectFile(MemoryBufferRef Object, llvm::file_magic Type, - bool InitContent = true); + createObjectFile(MemoryBufferRef Object, llvm::file_magic Type); static Expected> createObjectFile(MemoryBufferRef Object) { return createObjectFile(Object, llvm::file_magic::unknown); @@ -368,7 +367,7 @@ public: createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType); static Expected> - createELFObjectFile(MemoryBufferRef Object, bool InitContent = true); + createELFObjectFile(MemoryBufferRef Object); static Expected> createMachOObjectFile(MemoryBufferRef Object, diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h index 012f9f7fad0..5c964615e9d 100644 --- a/include/llvm/Object/SymbolicFile.h +++ b/include/llvm/Object/SymbolicFile.h @@ -161,12 +161,14 @@ public: // construction aux. static Expected> createSymbolicFile(MemoryBufferRef Object, llvm::file_magic Type, - LLVMContext *Context, bool InitContent = true); + LLVMContext *Context); static Expected> createSymbolicFile(MemoryBufferRef Object) { return createSymbolicFile(Object, llvm::file_magic::unknown, nullptr); } + static Expected> + createSymbolicFile(StringRef ObjectPath); static bool classof(const Binary *v) { return v->isSymbolic(); diff --git a/lib/Object/Binary.cpp b/lib/Object/Binary.cpp index e741cbba288..384df4b8435 100644 --- a/lib/Object/Binary.cpp +++ b/lib/Object/Binary.cpp @@ -44,8 +44,7 @@ StringRef Binary::getFileName() const { return Data.getBufferIdentifier(); } MemoryBufferRef Binary::getMemoryBufferRef() const { return Data; } Expected> object::createBinary(MemoryBufferRef Buffer, - LLVMContext *Context, - bool InitContent) { + LLVMContext *Context) { file_magic Type = identify_magic(Buffer.getBuffer()); switch (Type) { @@ -74,7 +73,7 @@ Expected> 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> object::createBinary(MemoryBufferRef Buffer, llvm_unreachable("Unexpected Binary File Type"); } -Expected> -object::createBinary(StringRef Path, LLVMContext *Context, bool InitContent) { +Expected> object::createBinary(StringRef Path, + LLVMContext *Context) { ErrorOr> FileOrErr = MemoryBuffer::getFileOrSTDIN(Path, /*FileSize=*/-1, /*RequiresNullTerminator=*/false); @@ -104,7 +103,7 @@ object::createBinary(StringRef Path, LLVMContext *Context, bool InitContent) { std::unique_ptr &Buffer = FileOrErr.get(); Expected> BinOrErr = - createBinary(Buffer->getMemBufferRef(), Context, InitContent); + createBinary(Buffer->getMemBufferRef(), Context); if (!BinOrErr) return BinOrErr.takeError(); std::unique_ptr &Bin = BinOrErr.get(); diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp index c654c3fd3d6..6dee3ab81b6 100644 --- a/lib/Object/ELFObjectFile.cpp +++ b/lib/Object/ELFObjectFile.cpp @@ -61,15 +61,15 @@ ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source) template static Expected>> -createPtr(MemoryBufferRef Object, bool InitContent) { - auto Ret = ELFObjectFile::create(Object, InitContent); +createPtr(MemoryBufferRef Object) { + auto Ret = ELFObjectFile::create(Object); if (Error E = Ret.takeError()) return std::move(E); return std::make_unique>(std::move(*Ret)); } Expected> -ObjectFile::createELFObjectFile(MemoryBufferRef Obj, bool InitContent) { +ObjectFile::createELFObjectFile(MemoryBufferRef Obj) { std::pair 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(Obj, InitContent); + return createPtr(Obj); else if (Ident.second == ELF::ELFDATA2MSB) - return createPtr(Obj, InitContent); + return createPtr(Obj); else return createError("Invalid ELF data"); } else if (Ident.first == ELF::ELFCLASS64) { if (Ident.second == ELF::ELFDATA2LSB) - return createPtr(Obj, InitContent); + return createPtr(Obj); else if (Ident.second == ELF::ELFDATA2MSB) - return createPtr(Obj, InitContent); + return createPtr(Obj); else return createError("Invalid ELF data"); } diff --git a/lib/Object/ObjectFile.cpp b/lib/Object/ObjectFile.cpp index cf09a66d9c7..61b36ea0f44 100644 --- a/lib/Object/ObjectFile.cpp +++ b/lib/Object/ObjectFile.cpp @@ -132,8 +132,7 @@ Triple ObjectFile::makeTriple() const { } Expected> -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: diff --git a/lib/Object/SymbolicFile.cpp b/lib/Object/SymbolicFile.cpp index 34a2c5e1c12..72014fd34a4 100644 --- a/lib/Object/SymbolicFile.cpp +++ b/lib/Object/SymbolicFile.cpp @@ -36,7 +36,7 @@ SymbolicFile::~SymbolicFile() = default; Expected> 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(new COFFImportFile(Object)); case file_magic::elf_relocatable: case file_magic::macho_object: case file_magic::coff_object: { Expected> Obj = - ObjectFile::createObjectFile(Object, Type, InitContent); + ObjectFile::createObjectFile(Object, Type); if (!Obj || !Context) return std::move(Obj); diff --git a/test/Object/invalid.test b/test/Object/invalid.test index 881145a8d8c..b6bee98681b 100644 --- a/test/Object/invalid.test +++ b/test/Object/invalid.test @@ -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: -# 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: -# 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 diff --git a/test/tools/llvm-readobj/ELF/file-headers.test b/test/tools/llvm-readobj/ELF/file-headers.test index 9cd431878d3..99cbfdf5e8c 100644 --- a/test/tools/llvm-readobj/ELF/file-headers.test +++ b/test/tools/llvm-readobj/ELF/file-headers.test @@ -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: -# 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 diff --git a/test/tools/yaml2obj/ELF/section-headers.yaml b/test/tools/yaml2obj/ELF/section-headers.yaml index 7eadb4a881b..c90ffe38122 100644 --- a/test/tools/yaml2obj/ELF/section-headers.yaml +++ b/test/tools/yaml2obj/ELF/section-headers.yaml @@ -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 diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 255e633ec2e..1214f0b14e7 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -1998,9 +1998,6 @@ ELFDumper::ELFDumper(const object::ELFObjectFile &O, else ELFDumperStyle.reset(new LLVMStyle(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 &Obj, if (ElfHeader.e_shnum != 0) return to_string(ElfHeader.e_shnum); - Expected> 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 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 @@ -3470,18 +3460,11 @@ static std::string getSectionHeaderTableIndexString(const ELFFile &Obj, if (ElfHeader.e_shstrndx != SHN_XINDEX) return to_string(ElfHeader.e_shstrndx); - Expected> 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 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 void GNUStyle::printFileHeaders() { diff --git a/tools/llvm-readobj/ObjDumper.h b/tools/llvm-readobj/ObjDumper.h index fa1767fe890..ea549dcca21 100644 --- a/tools/llvm-readobj/ObjDumper.h +++ b/tools/llvm-readobj/ObjDumper.h @@ -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; diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index 41cd4414d05..a30773525c1 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -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> 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> BinaryOrErr = - createBinary(File, /*Context=*/nullptr, /*InitContent=*/false); + Expected> BinaryOrErr = createBinary(File); if (!BinaryOrErr) reportError(BinaryOrErr.takeError(), File); Binary &Binary = *BinaryOrErr.get().getBinary();