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 @@ -36,7 +36,7 @@ - Name: .rela.dyn Type: SHT_ANDROID_RELA Flags: [ SHF_ALLOC ] - Link: .symtab + Link: [[LINK=.symtab]] Content: 41505332088020020108800280010202088180808010818080802002080181808080100802818080802004020C7E048180808010088180808020 ShOffset: [[SHOFFSET=]] Symbols: @@ -60,6 +60,24 @@ ## 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) +## Check we report a warning when the sh_link field of the SHT_ANDROID_RELA section is broken. + +# RUN: yaml2obj --docnum=1 -DLINK=0xffffffff %s -o %t1.broken.link +# RUN: llvm-readobj --relocations %t1.broken.link 2>&1 | \ +# RUN: FileCheck -DFILE=%t1.broken.link --check-prefix=BROKEN-RELA-LINK-LLVM %s +# RUN: llvm-readelf --relocations %t1.broken.link 2>&1 | \ +# RUN: FileCheck -DFILE=%t1.broken.link --check-prefix=BROKEN-RELA-LINK-GNU %s + +# BROKEN-RELA-LINK-LLVM: Relocations [ +# BROKEN-RELA-LINK-LLVM-NEXT: Section (1) .rela.dyn { +# BROKEN-RELA-LINK-LLVM-NEXT: warning: '[[FILE]]': unable to locate a symbol table for SHT_ANDROID_RELA section with index 1: invalid section index: 4294967295 +# BROKEN-RELA-LINK-LLVM-NEXT: } +# BROKEN-RELA-LINK-LLVM-NEXT: ] + +# BROKEN-RELA-LINK-GNU: Relocation section '.rela.dyn' at offset 0x40 contains 8 entries: +# BROKEN-RELA-LINK-GNU-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend +# BROKEN-RELA-LINK-GNU-NEXT: warning: '[[FILE]]': unable to locate a symbol table for SHT_ANDROID_RELA section with index 1: invalid section index: 4294967295 + # RUN: yaml2obj --docnum=2 %s -o %t2 # RUN: llvm-readobj --relocations %t2 | FileCheck --check-prefix=LLVM2 %s # LLVM2: Section (1) .rel.dyn { @@ -99,7 +117,7 @@ - Name: .rel.dyn Type: SHT_ANDROID_REL Flags: [ SHF_ALLOC ] - Link: .symtab + Link: [[LINK=.symtab]] Content: 415053320A80200202088102830408037C08 ShOffset: [[SHOFFSET=]] Symbols: @@ -123,6 +141,24 @@ ## 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 +## Check we report a warning when the sh_link field of the SHT_ANDROID_REL section is broken. + +# RUN: yaml2obj --docnum=2 -DLINK=0xffffffff %s -o %t2.broken.link +# RUN: llvm-readobj --relocations %t2.broken.link 2>&1 | \ +# RUN: FileCheck -DFILE=%t2.broken.link --check-prefix=BROKEN-REL-LINK-LLVM %s +# RUN: llvm-readelf --relocations %t2.broken.link 2>&1 | \ +# RUN: FileCheck -DFILE=%t2.broken.link --check-prefix=BROKEN-REL-LINK-GNU %s + +# BROKEN-REL-LINK-LLVM: Relocations [ +# BROKEN-REL-LINK-LLVM-NEXT: Section (1) .rel.dyn { +# BROKEN-REL-LINK-LLVM-NEXT: warning: '[[FILE]]': unable to locate a symbol table for SHT_ANDROID_REL section with index 1: invalid section index: 4294967295 +# BROKEN-REL-LINK-LLVM-NEXT: } +# BROKEN-REL-LINK-LLVM-NEXT: ] + +# BROKEN-REL-LINK-GNU: Relocation section '.rel.dyn' at offset 0x34 contains 10 entries: +# BROKEN-REL-LINK-GNU-NEXT: Offset Info Type Sym. Value Symbol's Name +# BROKEN-REL-LINK-GNU-NEXT: warning: '[[FILE]]': unable to locate a symbol table for SHT_ANDROID_REL section with index 1: invalid section index: 4294967295 + # RUN: yaml2obj --docnum=3 %s | llvm-readobj --relocations - | FileCheck --check-prefix=LLVM3 %s # # LLVM3: Section (1) .rela.dyn { diff --git a/llvm/test/tools/llvm-readobj/ELF/relocations.test b/llvm/test/tools/llvm-readobj/ELF/relocations.test --- a/llvm/test/tools/llvm-readobj/ELF/relocations.test +++ b/llvm/test/tools/llvm-readobj/ELF/relocations.test @@ -128,6 +128,7 @@ - Name: .rel.text Type: SHT_REL Info: .text + Link: [[LINK=.symtab]] ShName: [[SHNAME=]] EntSize: [[ENTSIZEREL=]] Relocations: @@ -145,6 +146,7 @@ - Name: .rela.text Type: SHT_RELA Info: .text + Link: [[LINK=.symtab]] ShName: [[SHNAME=]] EntSize: [[ENTSIZERELA=]] Relocations: @@ -200,6 +202,7 @@ ## Check we continue dumping other relocation sections if any. ## Case A: check the case when relocations can't be read from an SHT_REL section. +## because of broken sh_entsize field. # RUN: yaml2obj %s --docnum=1 -DENTSIZEREL=1 -o %t.broken.rel # RUN: llvm-readobj --relocations %t.broken.rel 2>&1 \ # RUN: | FileCheck %s -DFILE=%t.broken.rel --check-prefix=BROKEN-REL-LLVM @@ -231,6 +234,7 @@ # BROKEN-REL-GNU-NEXT: 0000000000000009 000000090000000b R_X86_64_32S ffffffffffffffff rela_maxpos + 7fffffffffffffff ## Case B: check the case when relocations can't be read from an SHT_RELA section. +## because of broken sh_entsize field. # RUN: yaml2obj %s --docnum=1 -DENTSIZERELA=1 -o %t.broken.rela # RUN: llvm-readobj --relocations %t.broken.rela 2>&1 \ # RUN: | FileCheck %s -DFILE=%t.broken.rela --check-prefix=BROKEN-RELA-LLVM @@ -260,6 +264,31 @@ # 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_RELA section with index 3: section [index 3] has an invalid sh_entsize: 1 +## Case C: check the case when relocations can't be read from SHT_REL/SHT_RELA sections +## because of broken sh_link fields. +# RUN: yaml2obj %s --docnum=1 -DLINK=0xffff -o %t.broken.link +# RUN: llvm-readobj --relocations %t.broken.link 2>&1 \ +# RUN: | FileCheck %s -DFILE=%t.broken.link --check-prefix=BROKEN-LINK-LLVM +# RUN: llvm-readelf --relocations %t.broken.link 2>&1 \ +# RUN: | FileCheck %s -DFILE=%t.broken.link --check-prefix=BROKEN-LINK-GNU + +# BROKEN-LINK-LLVM: Relocations [ +# BROKEN-LINK-LLVM-NEXT: Section (2) .rel.text { +# BROKEN-LINK-LLVM-NEXT: warning: '[[FILE]]': unable to locate a symbol table for SHT_REL section with index 2: invalid section index: 65535 +# BROKEN-LINK-LLVM-NEXT: } +# BROKEN-LINK-LLVM-NEXT: Section (3) .rela.text { +# BROKEN-LINK-LLVM-NEXT: warning: '[[FILE]]': unable to locate a symbol table for SHT_RELA section with index 3: invalid section index: 65535 +# BROKEN-LINK-LLVM-NEXT: } +# BROKEN-LINK-LLVM-NEXT: ] + +# BROKEN-LINK-GNU: Relocation section '.rel.text' at offset 0x51 contains 4 entries: +# BROKEN-LINK-GNU-NEXT: Offset Info Type Symbol's Value Symbol's Name +# BROKEN-LINK-GNU-NEXT: warning: '[[FILE]]': unable to locate a symbol table for SHT_REL section with index 2: invalid section index: 65535 +# BROKEN-LINK-GNU-EMPTY: +# BROKEN-LINK-GNU-NEXT: Relocation section '.rela.text' at offset 0x91 contains 5 entries: +# BROKEN-LINK-GNU-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend +# BROKEN-LINK-GNU-NEXT: warning: '[[FILE]]': unable to locate a symbol table for SHT_RELA section with index 3: invalid section index: 65535 + ## Show that ELF32 is dumped correctly. # RUN: yaml2obj %s --docnum=2 -o %t32 # RUN: llvm-readobj -r %t32 \ 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 @@ -151,6 +151,7 @@ 0x000F0501, 0x50400009 ] EntSize: [[ENTSIZE=]] ShType: [[SHTYPE=]] + Link: [[LINK=""]] ## Check we report a warning when we are unable to dump relocations ## for a SHT_RELR/SHT_ANDROID_RELR section. @@ -179,3 +180,23 @@ # RUN: not llvm-readelf --relocations %t2.broken.android 2>&1 | \ # RUN: FileCheck -DFILE=%t2.broken.android --check-prefix=BROKEN-GNU %s + +## 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 +## only relative relocations and do not have an associated symbol table, like other +## relocation sections. + +## Case A: check we do not report warnings when the sh_link field is set to an arbitrary value +## and the --relocations option is requested. +# RUN: yaml2obj --docnum=2 -DLINK=0xff %s -o %t2.has.link +# RUN: llvm-readobj --relocations %t2.has.link 2>&1 | \ +# RUN: FileCheck -DFILE=%t2.has.link --check-prefix=LLVM2 %s --implicit-check-not=warning: +# RUN: llvm-readelf --relocations %t2.has.link 2>&1 | \ +# RUN: FileCheck -DFILE=%t2.has.link --check-prefix=GNU2 %s --implicit-check-not=warning: + +## Case B: check we do not report warnings when the sh_link field is set to an arbitrary value +## and --relocations and --raw-relr options are requested. +# RUN: llvm-readobj --relocations --raw-relr %t2.has.link | \ +# RUN: FileCheck -DFILE=%t2.has.link --check-prefix=RAW-LLVM2 %s +# RUN: llvm-readelf --relocations --raw-relr %t2.has.link 2>&1 | \ +# RUN: FileCheck -DFILE=%t2.has.link --check-prefix=RAW-GNU2 %s 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 @@ -5519,17 +5519,27 @@ template void DumpStyle::printRelocationsHelper(const ELFFile *Obj, const Elf_Shdr &Sec) { - const Elf_Shdr *SymTab = - unwrapOrError(this->FileName, Obj->getSection(Sec.sh_link)); - unsigned SecNdx = &Sec - &cantFail(Obj->sections()).front(); - unsigned RelNdx = 0; - - auto Warn = [&](Error &&E) { - this->reportUniqueWarning(createError("unable to read relocations from " + - describe(Obj, Sec) + ": " + - toString(std::move(E)))); + auto Warn = [&](Error &&E, + const Twine &Prefix = "unable to read relocations from") { + this->reportUniqueWarning(createError(Prefix + " " + describe(Obj, Sec) + + ": " + toString(std::move(E)))); }; + // SHT_RELR/SHT_ANDROID_RELR sections do not have an associated symbol table. + // For them we should not treat the value of the sh_link field as an index of + // a symbol table. + const Elf_Shdr *SymTab; + if (Sec.sh_type != ELF::SHT_RELR && Sec.sh_type != ELF::SHT_ANDROID_RELR) { + Expected SymTabOrErr = Obj->getSection(Sec.sh_link); + if (!SymTabOrErr) { + Warn(SymTabOrErr.takeError(), "unable to locate a symbol table for"); + return; + } + SymTab = *SymTabOrErr; + } + + unsigned SecNdx = &Sec - &cantFail(Obj->sections()).front(); + unsigned RelNdx = 0; switch (Sec.sh_type) { case ELF::SHT_REL: if (Expected RangeOrErr = Obj->rels(&Sec)) { @@ -5561,7 +5571,7 @@ } for (const Elf_Rel &R : Obj->decode_relrs(*RangeOrErr)) - printRelReloc(Obj, SecNdx, SymTab, R, ++RelNdx); + printRelReloc(Obj, SecNdx, /*SymTab=*/nullptr, R, ++RelNdx); break; } case ELF::SHT_ANDROID_REL: