forked from OSchip/llvm-project
[llvm-readelf/obj] - Improve error reporting when dumping group sections.
Our code that dumps groups has 3 noticeable issues: 1) It uses `unwrapOrError` in many places. 2) It doesn't allow reporting unique warnings, because the `getGroups` helper is not a member of `DumpStyle<ELFT>`. 3) It might just crash. See the comment for `StrTableOrErr->data() + Sym.st_name` line. In this patch I am starting addressing these points. For start I've converted one of `unwrapOrError` calls to a unique warning. Differential revision: https://reviews.llvm.org/D91798
This commit is contained in:
parent
da14ae23a5
commit
343dceb831
|
@ -74,6 +74,9 @@ Sections:
|
|||
Type: SHT_RELA
|
||||
Link: .symtab
|
||||
Info: .text.bar
|
||||
- Name: .symtab
|
||||
Type: SHT_SYMTAB
|
||||
Link: [[SYMTABLINK=.strtab]]
|
||||
Symbols:
|
||||
- Name: foo
|
||||
Section: .text.foo
|
||||
|
@ -123,3 +126,49 @@ Symbols:
|
|||
# DUP-GNU-NEXT: warning: '[[FILE]]': section with index 3, included in the group section with index 1, was also found in the group section with index 2
|
||||
# DUP-GNU-NEXT: [ 3] .text.foo
|
||||
# DUP-GNU-NEXT: [ 6] .rela.text.bar
|
||||
|
||||
# RUN: yaml2obj %s -DSYMTABLINK=0xFF -o %t.symtab.o
|
||||
# RUN: llvm-readobj --elf-section-groups %t.symtab.o 2>&1 | \
|
||||
# RUN: FileCheck -DFILE=%t.symtab.o %s --check-prefix=SYMTAB-LLVM --implicit-check-not=warning:
|
||||
# RUN: llvm-readelf --elf-section-groups %t.symtab.o 2>&1 | \
|
||||
# RUN: FileCheck -DFILE=%t.symtab.o %s --check-prefix=SYMTAB-GNU --implicit-check-not=warning:
|
||||
|
||||
# SYMTAB-LLVM: Groups {
|
||||
# SYMTAB-LLVM-NEXT: warning: '[[FILE]]': unable to get the string table for SHT_SYMTAB section with index 7: invalid section index: 255
|
||||
# SYMTAB-LLVM-NEXT: Group {
|
||||
# SYMTAB-LLVM-NEXT: Name: .group (16)
|
||||
# SYMTAB-LLVM-NEXT: Index: 1
|
||||
# SYMTAB-LLVM-NEXT: Link: 7
|
||||
# SYMTAB-LLVM-NEXT: Info: 1
|
||||
# SYMTAB-LLVM-NEXT: Type: COMDAT (0x1)
|
||||
# SYMTAB-LLVM-NEXT: Signature: <?>
|
||||
# SYMTAB-LLVM-NEXT: Section(s) in group [
|
||||
# SYMTAB-LLVM-NEXT: .text.foo (3)
|
||||
# SYMTAB-LLVM-NEXT: .rela.text.foo (4)
|
||||
# SYMTAB-LLVM-NEXT: ]
|
||||
# SYMTAB-LLVM-NEXT: }
|
||||
# SYMTAB-LLVM-NEXT: Group {
|
||||
# SYMTAB-LLVM-NEXT: Name: .group1 (64)
|
||||
# SYMTAB-LLVM-NEXT: Index: 2
|
||||
# SYMTAB-LLVM-NEXT: Link: 7
|
||||
# SYMTAB-LLVM-NEXT: Info: 2
|
||||
# SYMTAB-LLVM-NEXT: Type: COMDAT (0x1)
|
||||
# SYMTAB-LLVM-NEXT: Signature: <?>
|
||||
# SYMTAB-LLVM-NEXT: Section(s) in group [
|
||||
# SYMTAB-LLVM-NEXT: .text.bar (5)
|
||||
# SYMTAB-LLVM-NEXT: .rela.text.bar (6)
|
||||
# SYMTAB-LLVM-NEXT: ]
|
||||
# SYMTAB-LLVM-NEXT: }
|
||||
# SYMTAB-LLVM-NEXT: }
|
||||
|
||||
# SYMTAB-GNU: warning: '[[FILE]]': unable to get the string table for SHT_SYMTAB section with index 7: invalid section index: 255
|
||||
# SYMTAB-GNU-EMPTY:
|
||||
# SYMTAB-GNU-NEXT: COMDAT group section [ 1] `.group' [<?>] contains 2 sections:
|
||||
# SYMTAB-GNU-NEXT: [Index] Name
|
||||
# SYMTAB-GNU-NEXT: [ 3] .text.foo
|
||||
# SYMTAB-GNU-NEXT: [ 4] .rela.text.foo
|
||||
# SYMTAB-GNU-EMPTY:
|
||||
# SYMTAB-GNU-NEXT: COMDAT group section [ 2] `.group1' [<?>] contains 2 sections:
|
||||
# SYMTAB-GNU-NEXT: [Index] Name
|
||||
# SYMTAB-GNU-NEXT: [ 5] .text.bar
|
||||
# SYMTAB-GNU-NEXT: [ 6] .rela.text.bar
|
||||
|
|
|
@ -170,6 +170,22 @@ struct DynRegionInfo {
|
|||
}
|
||||
};
|
||||
|
||||
struct GroupMember {
|
||||
StringRef Name;
|
||||
uint64_t Index;
|
||||
};
|
||||
|
||||
struct GroupSection {
|
||||
StringRef Name;
|
||||
std::string Signature;
|
||||
uint64_t ShName;
|
||||
uint64_t Index;
|
||||
uint32_t Link;
|
||||
uint32_t Info;
|
||||
uint32_t Type;
|
||||
std::vector<GroupMember> Members;
|
||||
};
|
||||
|
||||
namespace {
|
||||
struct VerdAux {
|
||||
unsigned Offset;
|
||||
|
@ -773,6 +789,8 @@ public:
|
|||
const ELFDumper<ELFT> &dumper() const { return Dumper; }
|
||||
|
||||
protected:
|
||||
std::vector<GroupSection> getGroups();
|
||||
|
||||
void printDependentLibsHelper(
|
||||
function_ref<void(const Elf_Shdr &)> OnSectionStart,
|
||||
function_ref<void(StringRef, uint64_t)> OnSectionEntry);
|
||||
|
@ -3551,30 +3569,22 @@ template <class ELFT> void GNUStyle<ELFT>::printFileHeaders() {
|
|||
printFields(OS, "Section header string table index:", Str);
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct GroupMember {
|
||||
StringRef Name;
|
||||
uint64_t Index;
|
||||
};
|
||||
template <class ELFT> std::vector<GroupSection> DumpStyle<ELFT>::getGroups() {
|
||||
auto GetSignature = [&](const Elf_Sym &Sym,
|
||||
const Elf_Shdr &Symtab) -> StringRef {
|
||||
Expected<StringRef> StrTableOrErr = Obj.getStringTableForSymtab(Symtab);
|
||||
if (!StrTableOrErr) {
|
||||
reportUniqueWarning(createError("unable to get the string table for " +
|
||||
describe(Obj, Symtab) + ": " +
|
||||
toString(StrTableOrErr.takeError())));
|
||||
return "<?>";
|
||||
}
|
||||
|
||||
struct GroupSection {
|
||||
StringRef Name;
|
||||
std::string Signature;
|
||||
uint64_t ShName;
|
||||
uint64_t Index;
|
||||
uint32_t Link;
|
||||
uint32_t Info;
|
||||
uint32_t Type;
|
||||
std::vector<GroupMember> Members;
|
||||
// TODO: this might lead to a crash or produce a wrong result, when the
|
||||
// st_name goes past the end of the string table.
|
||||
return StrTableOrErr->data() + Sym.st_name;
|
||||
};
|
||||
|
||||
template <class ELFT>
|
||||
std::vector<GroupSection> getGroups(const ELFFile<ELFT> &Obj,
|
||||
StringRef FileName) {
|
||||
using Elf_Shdr = typename ELFT::Shdr;
|
||||
using Elf_Sym = typename ELFT::Sym;
|
||||
using Elf_Word = typename ELFT::Word;
|
||||
|
||||
std::vector<GroupSection> Ret;
|
||||
uint64_t I = 0;
|
||||
for (const Elf_Shdr &Sec : cantFail(Obj.sections())) {
|
||||
|
@ -3584,15 +3594,14 @@ std::vector<GroupSection> getGroups(const ELFFile<ELFT> &Obj,
|
|||
|
||||
const Elf_Shdr *Symtab =
|
||||
unwrapOrError(FileName, Obj.getSection(Sec.sh_link));
|
||||
StringRef StrTable =
|
||||
unwrapOrError(FileName, Obj.getStringTableForSymtab(*Symtab));
|
||||
|
||||
const Elf_Sym *Sym = unwrapOrError(
|
||||
FileName, Obj.template getEntry<Elf_Sym>(*Symtab, Sec.sh_info));
|
||||
auto Data = unwrapOrError(
|
||||
FileName, Obj.template getSectionContentsAsArray<Elf_Word>(Sec));
|
||||
|
||||
StringRef Name = unwrapOrError(FileName, Obj.getSectionName(Sec));
|
||||
StringRef Signature = StrTable.data() + Sym->st_name;
|
||||
StringRef Signature = GetSignature(*Sym, *Symtab);
|
||||
Ret.push_back({Name,
|
||||
maybeDemangle(Signature),
|
||||
Sec.sh_name,
|
||||
|
@ -3612,7 +3621,7 @@ std::vector<GroupSection> getGroups(const ELFFile<ELFT> &Obj,
|
|||
return Ret;
|
||||
}
|
||||
|
||||
DenseMap<uint64_t, const GroupSection *>
|
||||
static DenseMap<uint64_t, const GroupSection *>
|
||||
mapSectionsToGroups(ArrayRef<GroupSection> Groups) {
|
||||
DenseMap<uint64_t, const GroupSection *> Ret;
|
||||
for (const GroupSection &G : Groups)
|
||||
|
@ -3621,10 +3630,8 @@ mapSectionsToGroups(ArrayRef<GroupSection> Groups) {
|
|||
return Ret;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
template <class ELFT> void GNUStyle<ELFT>::printGroupSections() {
|
||||
std::vector<GroupSection> V = getGroups<ELFT>(this->Obj, this->FileName);
|
||||
std::vector<GroupSection> V = this->getGroups();
|
||||
DenseMap<uint64_t, const GroupSection *> Map = mapSectionsToGroups(V);
|
||||
for (const GroupSection &G : V) {
|
||||
OS << "\n"
|
||||
|
@ -6256,7 +6263,7 @@ template <class ELFT> void LLVMStyle<ELFT>::printFileHeaders() {
|
|||
|
||||
template <class ELFT> void LLVMStyle<ELFT>::printGroupSections() {
|
||||
DictScope Lists(W, "Groups");
|
||||
std::vector<GroupSection> V = getGroups<ELFT>(this->Obj, this->FileName);
|
||||
std::vector<GroupSection> V = this->getGroups();
|
||||
DenseMap<uint64_t, const GroupSection *> Map = mapSectionsToGroups(V);
|
||||
for (const GroupSection &G : V) {
|
||||
DictScope D(W, "Group");
|
||||
|
|
Loading…
Reference in New Issue