1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 10:32:48 +02:00

[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:
Georgii Rymar 2020-11-19 18:23:27 +03:00
parent 55fbb7e6c9
commit 78b3f55aa0
2 changed files with 86 additions and 30 deletions

View File

@ -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

View File

@ -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,29 +3569,21 @@ 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;
};
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;
// 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;
};
std::vector<GroupSection> Ret;
uint64_t I = 0;
@ -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");