Index: llvm/test/tools/llvm-readobj/ELF/packed-relocs.test =================================================================== --- llvm/test/tools/llvm-readobj/ELF/packed-relocs.test +++ 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 earlier than tries to actually 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 earlier than tries to actually 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 { Index: llvm/test/tools/llvm-readobj/ELF/relocations.test =================================================================== --- llvm/test/tools/llvm-readobj/ELF/relocations.test +++ 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: @@ -199,7 +201,8 @@ ## Check we report a warning when we are unable to dump relocations for a section. ## Check we continue dumping other relocation sections if any. -## Case A: check the case when relocations can't be read from the SHT_REL section. +## Case A: check the case when relocations can't be read from the 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 the 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 \ Index: llvm/test/tools/llvm-readobj/ELF/relr-relocs.test =================================================================== --- llvm/test/tools/llvm-readobj/ELF/relr-relocs.test +++ 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,34 @@ # RUN: not llvm-readelf --relocations %t2.broken.android 2>&1 | \ # RUN: FileCheck -DFILE=%t2.broken.android --check-prefix=BROKEN-GNU %s + +## Document the behavior when the sh_link field of the SHT_RELR/SHT_ANDROID_RELR section is broken. +## Normally, sh_link is set to 0, because such sections contains only relative relocations and +## they do not need a symbol table to be associated with them. Also, with --raw-relr there is no need to +## decode relocations at all, hence we also do not need to locate a symbol table. +## At the same time, the gABI proposal (https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg) +## says that sh_link field of the SHT_RELR section contains the index of the associated symbol table. + +## Case A: check we report a warning when the sh_link field is broken and the --relocations option is requested. +# RUN: yaml2obj --docnum=2 -DLINK=0xff %s -o %t2.broken.link +# RUN: llvm-readobj --relocations %t2.broken.link 2>&1 | \ +# RUN: FileCheck -DFILE=%t2.broken.link --check-prefix=BROKEN-LINK-LLVM %s +# RUN: llvm-readelf --relocations %t2.broken.link 2>&1 | \ +# RUN: FileCheck -DFILE=%t2.broken.link --check-prefix=BROKEN-LINK-GNU %s + +# BROKEN-LINK-LLVM: Relocations [ +# BROKEN-LINK-LLVM-NEXT: Section (1) .relr.dyn { +# BROKEN-LINK-LLVM-NEXT: warning: '[[FILE]]': unable to locate a symbol table for SHT_RELR section with index 1: invalid section index: 255 +# BROKEN-LINK-LLVM-NEXT: } +# BROKEN-LINK-LLVM-NEXT: ] + +# BROKEN-LINK-GNU: Relocation section '.relr.dyn' at offset 0x34 contains 14 entries: +# BROKEN-LINK-GNU-NEXT: Offset Info Type Sym. Value Symbol's Name +# BROKEN-LINK-GNU-NEXT: warning: '[[FILE]]': unable to locate a symbol table for SHT_RELR section with index 1: invalid section index: 255 + +## Case B: check we do not report a warning when the sh_link field is broken and +## the -raw-relr option is also requested. +# RUN: llvm-readobj --relocations -raw-relr %t2.broken.link | \ +# RUN: FileCheck -DFILE=%t2.broken.link --check-prefix=RAW-LLVM2 %s +# RUN: llvm-readelf --relocations %t2.broken.link 2>&1 | \ +# RUN: FileCheck -DFILE=%t2.broken.link --check-prefix=BROKEN-LINK-GNU %s Index: llvm/tools/llvm-readobj/ELFDumper.cpp =================================================================== --- llvm/tools/llvm-readobj/ELFDumper.cpp +++ llvm/tools/llvm-readobj/ELFDumper.cpp @@ -378,7 +378,7 @@ template Expected> - getRelocationTarget(const Elf_Shdr *SymTab, const RelTy &R) const; + getRelocationTarget(const Elf_Shdr &SymTab, const RelTy &R) const; std::function WarningHandler; void reportUniqueWarning(Error Err) const; @@ -770,10 +770,10 @@ function_ref OnSectionEntry); virtual void printRelReloc(const ELFO *Obj, unsigned SecIndex, - const Elf_Shdr *SymTab, const Elf_Rel &R, + const Elf_Shdr &SymTab, const Elf_Rel &R, unsigned RelIndex) = 0; virtual void printRelaReloc(const ELFO *Obj, unsigned SecIndex, - const Elf_Shdr *SymTab, const Elf_Rela &R, + const Elf_Shdr &SymTab, const Elf_Rela &R, unsigned RelIndex) = 0; virtual void printRelrReloc(const Elf_Relr &R) = 0; void printRelocationsHelper(const ELFFile *Obj, const Elf_Shdr &Sec); @@ -893,16 +893,16 @@ StringRef StrTable, uint32_t Bucket); void printRelocHeader(unsigned SType); - void printRelReloc(const ELFO *Obj, unsigned SecIndex, const Elf_Shdr *SymTab, + void printRelReloc(const ELFO *Obj, unsigned SecIndex, const Elf_Shdr &SymTab, const Elf_Rel &R, unsigned RelIndex) override; void printRelaReloc(const ELFO *Obj, unsigned SecIndex, - const Elf_Shdr *SymTab, const Elf_Rela &R, + const Elf_Shdr &SymTab, const Elf_Rela &R, unsigned RelIndex) override; void printRelrReloc(const Elf_Relr &R) override; template void printRelRelaReloc(const ELFO *Obj, unsigned SecIndex, - const Elf_Shdr *SymTab, const RelTy &R, + const Elf_Shdr &SymTab, const RelTy &R, unsigned RelIndex); template void printRelRelaReloc(const ELFO *Obj, const Elf_Sym *Sym, @@ -970,15 +970,15 @@ void printMipsABIFlags(const ELFObjectFile *Obj) override; private: - void printRelReloc(const ELFO *Obj, unsigned SecIndex, const Elf_Shdr *SymTab, + void printRelReloc(const ELFO *Obj, unsigned SecIndex, const Elf_Shdr &SymTab, const Elf_Rel &R, unsigned RelIndex) override; void printRelaReloc(const ELFO *Obj, unsigned SecIndex, - const Elf_Shdr *SymTab, const Elf_Rela &R, + const Elf_Shdr &SymTab, const Elf_Rela &R, unsigned RelIndex) override; void printRelrReloc(const Elf_Relr &R) override; template void printRelRelaReloc(const ELFO *Obj, unsigned SecIndex, const RelTy &Rel, - unsigned RelIndex, const Elf_Shdr *SymTab); + unsigned RelIndex, const Elf_Shdr &SymTab); template void printDynamicRelocation(const ELFO *Obj, const RelTy& Rel); @@ -1100,10 +1100,10 @@ template template Expected> -ELFDumper::getRelocationTarget(const Elf_Shdr *SymTab, +ELFDumper::getRelocationTarget(const Elf_Shdr &SymTab, const RelTy &R) const { const ELFFile *Obj = ObjF->getELFFile(); - Expected SymOrErr = Obj->getRelocationSymbol(&R, SymTab); + Expected SymOrErr = Obj->getRelocationSymbol(&R, &SymTab); if (!SymOrErr) return SymOrErr.takeError(); const Elf_Sym *Sym = *SymOrErr; @@ -1114,7 +1114,7 @@ // This code block returns the section name. if (Sym->getType() == ELF::STT_SECTION) { Expected SecOrErr = - Obj->getSection(Sym, SymTab, ShndxTable); + Obj->getSection(Sym, &SymTab, ShndxTable); if (!SecOrErr) return SecOrErr.takeError(); // A section symbol describes the section at index 0. @@ -1127,12 +1127,12 @@ return std::make_pair(Sym, NameOrErr->str()); } - Expected StrTableOrErr = Obj->getStringTableForSymtab(*SymTab); + Expected StrTableOrErr = Obj->getStringTableForSymtab(SymTab); if (!StrTableOrErr) return StrTableOrErr.takeError(); std::string SymbolName = - getFullSymbolName(Sym, *StrTableOrErr, SymTab->sh_type == SHT_DYNSYM); + getFullSymbolName(Sym, *StrTableOrErr, SymTab.sh_type == SHT_DYNSYM); return std::make_pair(Sym, SymbolName); } @@ -3655,14 +3655,14 @@ template void GNUStyle::printRelReloc(const ELFO *Obj, unsigned SecIndex, - const Elf_Shdr *SymTab, const Elf_Rel &R, + const Elf_Shdr &SymTab, const Elf_Rel &R, unsigned RelIndex) { printRelRelaReloc(Obj, SecIndex, SymTab, R, RelIndex); } template void GNUStyle::printRelaReloc(const ELFO *Obj, unsigned SecIndex, - const Elf_Shdr *SymTab, const Elf_Rela &R, + const Elf_Shdr &SymTab, const Elf_Rela &R, unsigned RelIndex) { printRelRelaReloc(Obj, SecIndex, SymTab, R, RelIndex); } @@ -3674,7 +3674,7 @@ template template void GNUStyle::printRelRelaReloc(const ELFO *Obj, unsigned SecIndex, - const Elf_Shdr *SymTab, const RelTy &R, + const Elf_Shdr &SymTab, const RelTy &R, unsigned RelIndex) { Expected> Target = this->dumper()->getRelocationTarget(SymTab, R); @@ -5510,22 +5510,33 @@ 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)))); }; + const Elf_Shdr *SymTab; + // We do not decode relocations in SHT_RELR/SHT_ANDROID_RELR sections when the + // --raw-relr is specified and hence do not need to locate a symbol table for + // this case. + if (!opts::RawRelr || + (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)) { for (const Elf_Rel &R : *RangeOrErr) - printRelReloc(Obj, SecNdx, SymTab, R, ++RelNdx); + printRelReloc(Obj, SecNdx, *SymTab, R, ++RelNdx); } else { Warn(RangeOrErr.takeError()); } @@ -5533,7 +5544,7 @@ case ELF::SHT_RELA: if (Expected RangeOrErr = Obj->relas(&Sec)) { for (const Elf_Rela &R : *RangeOrErr) - printRelaReloc(Obj, SecNdx, SymTab, R, ++RelNdx); + printRelaReloc(Obj, SecNdx, *SymTab, R, ++RelNdx); } else { Warn(RangeOrErr.takeError()); } @@ -5552,14 +5563,14 @@ } for (const Elf_Rel &R : Obj->decode_relrs(*RangeOrErr)) - printRelReloc(Obj, SecNdx, SymTab, R, ++RelNdx); + printRelReloc(Obj, SecNdx, *SymTab, R, ++RelNdx); break; } case ELF::SHT_ANDROID_REL: case ELF::SHT_ANDROID_RELA: if (Expected> RelasOrErr = Obj->android_relas(&Sec)) { for (const Elf_Rela &R : *RelasOrErr) - printRelaReloc(Obj, SecNdx, SymTab, R, ++RelNdx); + printRelaReloc(Obj, SecNdx, *SymTab, R, ++RelNdx); } else { Warn(RelasOrErr.takeError()); } @@ -6197,14 +6208,14 @@ template void LLVMStyle::printRelReloc(const ELFO *Obj, unsigned SecIndex, - const Elf_Shdr *SymTab, const Elf_Rel &R, + const Elf_Shdr &SymTab, const Elf_Rel &R, unsigned RelIndex) { printRelRelaReloc(Obj, SecIndex, R, RelIndex, SymTab); } template void LLVMStyle::printRelaReloc(const ELFO *Obj, unsigned SecIndex, - const Elf_Shdr *SymTab, const Elf_Rela &R, + const Elf_Shdr &SymTab, const Elf_Rela &R, unsigned RelIndex) { printRelRelaReloc(Obj, SecIndex, R, RelIndex, SymTab); } @@ -6217,7 +6228,7 @@ template void LLVMStyle::printRelRelaReloc(const ELFO *Obj, unsigned SecIndex, const RelTy &Rel, unsigned RelIndex, - const Elf_Shdr *SymTab) { + const Elf_Shdr &SymTab) { Expected> Target = this->dumper()->getRelocationTarget(SymTab, Rel); if (!Target) {