diff --git a/llvm/test/tools/llvm-readobj/ELF/packed-relocs.test b/llvm/test/tools/llvm-readobj/ELF/packed-relocs.test --- a/llvm/test/tools/llvm-readobj/ELF/packed-relocs.test +++ b/llvm/test/tools/llvm-readobj/ELF/packed-relocs.test @@ -49,7 +49,7 @@ # RUN: yaml2obj --docnum=1 -DSHOFFSET=0xffffffff %s -o %t1.broken # RUN: llvm-readobj --relocations %t1.broken 2>&1 | FileCheck -DFILE=%t1.broken --check-prefix=BROKEN-RELA-LLVM %s -# RUN: not llvm-readelf --relocations %t1.broken 2>&1 | FileCheck -DFILE=%t1.broken --check-prefix=BROKEN-RELA-GNU %s +# RUN: llvm-readelf --relocations %t1.broken 2>&1 | FileCheck -DFILE=%t1.broken --check-prefix=BROKEN-RELA-GNU %s # BROKEN-RELA-LLVM: Relocations [ # BROKEN-RELA-LLVM-NEXT: Section (1) .rela.dyn { @@ -57,8 +57,10 @@ # BROKEN-RELA-LLVM-NEXT: } # BROKEN-RELA-LLVM-NEXT: ] -## FIXME: GNU still reports an error before trying to dump relocations. -# BROKEN-RELA-GNU: error: '[[FILE]]': section [index 1] has a sh_offset (0xffffffff) + sh_size (0x3a) that is greater than the file size (0x238) +# BROKEN-RELA-GNU: warning: '[[FILE]]': unable to get the number of relocations in SHT_ANDROID_RELA section with index 1: section [index 1] has a sh_offset (0xffffffff) + sh_size (0x3a) that is greater than the file size (0x238) +# BROKEN-RELA-GNU: Relocation section '.rela.dyn' at offset 0xffffffff contains entries: +# BROKEN-RELA-GNU-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend +# BROKEN-RELA-GNU-NEXT: warning: '[[FILE]]': unable to read relocations from SHT_ANDROID_RELA section with index 1: section [index 1] has a sh_offset (0xffffffff) + sh_size (0x3a) that is greater than the file size (0x238) ## Check we report a warning when the sh_link field of the SHT_ANDROID_RELA section is broken. @@ -130,7 +132,7 @@ # RUN: yaml2obj --docnum=2 -DSHOFFSET=0xffffffff %s -o %t2.broken # RUN: llvm-readobj --relocations %t2.broken 2>&1 | FileCheck -DFILE=%t2.broken --check-prefix=BROKEN-REL-LLVM %s -# RUN: not llvm-readelf --relocations %t2.broken 2>&1 | FileCheck -DFILE=%t2.broken --check-prefix=BROKEN-REL-GNU %s +# RUN: llvm-readelf --relocations %t2.broken 2>&1 | FileCheck -DFILE=%t2.broken --check-prefix=BROKEN-REL-GNU %s # BROKEN-REL-LLVM: Relocations [ # BROKEN-REL-LLVM-NEXT: Section (1) .rel.dyn { @@ -138,8 +140,10 @@ # BROKEN-REL-LLVM-NEXT: } # BROKEN-REL-LLVM-NEXT: ] -## FIXME: GNU still reports an error before trying to dump relocations. -# BROKEN-REL-GNU: error: '[[FILE]]': section [index 1] has a sh_offset (0xffffffff) + sh_size (0x12) that cannot be represented +# BROKEN-REL-GNU: warning: '[[FILE]]': unable to get the number of relocations in SHT_ANDROID_REL section with index 1: section [index 1] has a sh_offset (0xffffffff) + sh_size (0x12) that cannot be represented +# BROKEN-REL-GNU: Relocation section '.rel.dyn' at offset 0xffffffff contains entries: +# BROKEN-REL-GNU-NEXT: Offset Info Type Sym. Value Symbol's Name +# BROKEN-REL-GNU-NEXT: warning: '[[FILE]]': unable to read relocations from SHT_ANDROID_REL section with index 1: section [index 1] has a sh_offset (0xffffffff) + sh_size (0x12) that cannot be represented ## Check we report a warning when the sh_link field of the SHT_ANDROID_REL section is broken. diff --git a/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test b/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test --- a/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test +++ b/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test @@ -160,8 +160,8 @@ # RUN: yaml2obj --docnum=2 -DENTSIZE=1 %s -o %t2.broken # RUN: llvm-readobj --relocations %t2.broken 2>&1 | \ # RUN: FileCheck -DFILE=%t2.broken --check-prefix=BROKEN-LLVM %s -DSECNAME=SHT_RELR -# RUN: not llvm-readelf --relocations %t2.broken 2>&1 | \ -# RUN: FileCheck -DFILE=%t2.broken --check-prefix=BROKEN-GNU %s +# RUN: llvm-readelf --relocations %t2.broken 2>&1 | \ +# RUN: FileCheck -DFILE=%t2.broken --check-prefix=BROKEN-GNU %s -DSECNAME=SHT_RELR # BROKEN-LLVM: Relocations [ # BROKEN-LLVM-NEXT: Section (1) .relr.dyn { @@ -169,17 +169,18 @@ # BROKEN-LLVM-NEXT: } # BROKEN-LLVM-NEXT: ] -## FIXME: GNU still reports an error before trying to dump relocations. -# BROKEN-GNU: error: '[[FILE]]': section [index 1] has an invalid sh_entsize: 1 +# BROKEN-GNU: warning: '[[FILE]]': unable to get the number of relocations in [[SECNAME]] section with index 1: section [index 1] has an invalid sh_entsize: 1 +# BROKEN-GNU: Relocation section '.relr.dyn' at offset 0x34 contains entries: +# BROKEN-GNU-NEXT: Offset Info Type Sym. Value Symbol's Name +# BROKEN-GNU-NEXT: warning: '[[FILE]]': unable to read relocations from [[SECNAME]] section with index 1: section [index 1] has an invalid sh_entsize: 1 ## Case B: check the case when relocations can't be read from an SHT_ANDROID_RELR section. ## SHT_ANDROID_RELR = 0x6fffff00. # RUN: yaml2obj --docnum=2 -DENTSIZE=1 -DSHTYPE=0x6fffff00 %s -o %t2.broken.android # RUN: llvm-readobj --relocations %t2.broken.android 2>&1 | \ # RUN: FileCheck -DFILE=%t2.broken.android --check-prefix=BROKEN-LLVM %s -DSECNAME=SHT_ANDROID_RELR - -# RUN: not llvm-readelf --relocations %t2.broken.android 2>&1 | \ -# RUN: FileCheck -DFILE=%t2.broken.android --check-prefix=BROKEN-GNU %s +# RUN: llvm-readelf --relocations %t2.broken.android 2>&1 | \ +# RUN: FileCheck -DFILE=%t2.broken.android --check-prefix=BROKEN-GNU %s -DSECNAME=SHT_ANDROID_RELR ## Check the behavior when the sh_link field of the SHT_RELR/SHT_ANDROID_RELR section ## is set to an arbitrary value. Normally, it is set to 0, because such sections contains diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -3749,30 +3749,47 @@ } template void GNUStyle::printRelocations(const ELFO *Obj) { + auto GetEntriesNum = [&](const Elf_Shdr &Sec) -> Expected { + // Android's packed relocation section needs to be unpacked first + // to get the actual number of entries. + if (Sec.sh_type == ELF::SHT_ANDROID_REL || + Sec.sh_type == ELF::SHT_ANDROID_RELA) { + Expected> RelasOrErr = + Obj->android_relas(&Sec); + if (!RelasOrErr) + return RelasOrErr.takeError(); + return RelasOrErr->size(); + } + + if (!opts::RawRelr && (Sec.sh_type == ELF::SHT_RELR || + Sec.sh_type == ELF::SHT_ANDROID_RELR)) { + Expected RelrsOrErr = Obj->relrs(&Sec); + if (!RelrsOrErr) + return RelrsOrErr.takeError(); + return Obj->decode_relrs(*RelrsOrErr).size(); + } + + return Sec.getEntityCount(); + }; + bool HasRelocSections = false; for (const Elf_Shdr &Sec : cantFail(Obj->sections())) { if (!isRelocationSec(Sec)) continue; HasRelocSections = true; - unsigned Entries; - // Android's packed relocation section needs to be unpacked first - // to get the actual number of entries. - if (Sec.sh_type == ELF::SHT_ANDROID_REL || - Sec.sh_type == ELF::SHT_ANDROID_RELA) { - Entries = unwrapOrError(this->FileName, Obj->android_relas(&Sec)).size(); - } else if (!opts::RawRelr && (Sec.sh_type == ELF::SHT_RELR || - Sec.sh_type == ELF::SHT_ANDROID_RELR)) { - Elf_Relr_Range Relrs = unwrapOrError(this->FileName, Obj->relrs(&Sec)); - Entries = Obj->decode_relrs(Relrs).size(); - } else { - Entries = Sec.getEntityCount(); - } + std::string EntriesNum = ""; + if (Expected NumOrErr = GetEntriesNum(Sec)) + EntriesNum = std::to_string(*NumOrErr); + else + this->reportUniqueWarning(createError( + "unable to get the number of relocations in " + describe(Obj, Sec) + + ": " + toString(NumOrErr.takeError()))); uintX_t Offset = Sec.sh_offset; StringRef Name = this->getPrintableSectionName(Obj, Sec); OS << "\nRelocation section '" << Name << "' at offset 0x" - << to_hexString(Offset, false) << " contains " << Entries + << to_hexString(Offset, false) << " contains " << EntriesNum << " entries:\n"; printRelocHeader(Sec.sh_type); this->printRelocationsHelper(Obj, Sec);