mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-27 13:40:43 +00:00
Recommit r366052 "[obj2yaml] - Rework tool's error reporting logic for ELF target."
No changes, LLD code was updated in r366057. Original commit message: ELF.h contains two getSymbol methods which seems to be used only from obj2yaml. One of these methods calls another, which in turn contains untested error message which doesn't provide enough information. Problem is that after improving only just that message, obj2yaml will not show it, ("Error reading file: yaml: Invalid data was encountered while parsing the file" message will be shown instead), because internal errors handling of tool is based on ErrorOr<> class which stores a error code and as a result can only show a predefined error string, what actually isn't very useful. In this patch, I rework obj2yaml's error reporting system for ELF targets to use Error Expected<> classes. Also, I improve the error message produced by getSymbol for demonstration of the new functionality. Differential revision: https://reviews.llvm.org/D64631 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366058 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
da0d3e1755
commit
70b7545abc
@ -354,22 +354,19 @@ ELFFile<ELFT>::getSection(const Elf_Sym *Sym, Elf_Sym_Range Symbols,
|
||||
return getSection(Index);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
inline Expected<const typename ELFT::Sym *>
|
||||
getSymbol(typename ELFT::SymRange Symbols, uint32_t Index) {
|
||||
if (Index >= Symbols.size())
|
||||
// TODO: this error is untested.
|
||||
return createError("invalid symbol index");
|
||||
return &Symbols[Index];
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
Expected<const typename ELFT::Sym *>
|
||||
ELFFile<ELFT>::getSymbol(const Elf_Shdr *Sec, uint32_t Index) const {
|
||||
auto SymtabOrErr = symbols(Sec);
|
||||
if (!SymtabOrErr)
|
||||
return SymtabOrErr.takeError();
|
||||
return object::getSymbol<ELFT>(*SymtabOrErr, Index);
|
||||
auto SymsOrErr = symbols(Sec);
|
||||
if (!SymsOrErr)
|
||||
return SymsOrErr.takeError();
|
||||
|
||||
Elf_Sym_Range Symbols = *SymsOrErr;
|
||||
if (Index >= Symbols.size())
|
||||
return createError("unable to get symbol from section " +
|
||||
getSecIndexForError(this, Sec) +
|
||||
": invalid symbol index (" + Twine(Index) + ")");
|
||||
return &Symbols[Index];
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
|
@ -1,6 +1,6 @@
|
||||
## Checks that the tool is able to read section groups from ELF.
|
||||
|
||||
# RUN: yaml2obj %s > %t1.o
|
||||
# RUN: yaml2obj --docnum=1 %s > %t1.o
|
||||
# RUN: llvm-readobj --elf-section-groups %t1.o | FileCheck %s -check-prefix=OBJ
|
||||
# RUN: obj2yaml %t1.o | FileCheck %s --check-prefix YAML
|
||||
|
||||
@ -46,3 +46,25 @@ Symbols:
|
||||
- Name: signature
|
||||
Type: STT_OBJECT
|
||||
Section: .rodata
|
||||
|
||||
## Check obj2yaml report an error when sh_info field of
|
||||
## group section contains invalid (too large) signature symbol index.
|
||||
|
||||
# RUN: yaml2obj --docnum=2 %s > %t2.o
|
||||
# RUN: not obj2yaml %t2.o 2>&1 | FileCheck %s --check-prefix ERR
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
- Name: .group
|
||||
Type: SHT_GROUP
|
||||
Link: .symtab
|
||||
Info: 0xFF
|
||||
Members:
|
||||
- SectionOrType: GRP_COMDAT
|
||||
|
||||
# ERR: Error reading file: {{.*}}2.o: unable to get symbol from section [index 2]: invalid symbol index (255)
|
||||
|
@ -51,4 +51,4 @@ Symbols:
|
||||
## shn_xindex.o contains a symbol with st_shndx == SHN_XINDEX.
|
||||
## We do not support it at this moment.
|
||||
# RUN: not obj2yaml %S/Inputs/shn_xindex.o 2>&1 | FileCheck %s --check-prefix=ERR
|
||||
# ERR: Error reading file: {{.*}}shn_xindex.o: Feature not yet implemented.
|
||||
# ERR: Error reading file: {{.*}}shn_xindex.o: SHN_XINDEX symbols are not supported
|
||||
|
@ -44,31 +44,31 @@ class ELFDumper {
|
||||
const object::ELFFile<ELFT> &Obj;
|
||||
ArrayRef<Elf_Word> ShndxTable;
|
||||
|
||||
std::error_code dumpSymbols(const Elf_Shdr *Symtab,
|
||||
std::vector<ELFYAML::Symbol> &Symbols);
|
||||
std::error_code dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
|
||||
StringRef StrTable, ELFYAML::Symbol &S);
|
||||
std::error_code dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S);
|
||||
std::error_code dumpCommonRelocationSection(const Elf_Shdr *Shdr,
|
||||
ELFYAML::RelocationSection &S);
|
||||
Error dumpSymbols(const Elf_Shdr *Symtab,
|
||||
std::vector<ELFYAML::Symbol> &Symbols);
|
||||
Error dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
|
||||
StringRef StrTable, ELFYAML::Symbol &S);
|
||||
Error dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S);
|
||||
Error dumpCommonRelocationSection(const Elf_Shdr *Shdr,
|
||||
ELFYAML::RelocationSection &S);
|
||||
template <class RelT>
|
||||
std::error_code dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
|
||||
ELFYAML::Relocation &R);
|
||||
|
||||
ErrorOr<ELFYAML::DynamicSection *> dumpDynamicSection(const Elf_Shdr *Shdr);
|
||||
ErrorOr<ELFYAML::RelocationSection *> dumpRelocSection(const Elf_Shdr *Shdr);
|
||||
ErrorOr<ELFYAML::RawContentSection *>
|
||||
Error dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
|
||||
ELFYAML::Relocation &R);
|
||||
|
||||
Expected<ELFYAML::DynamicSection *> dumpDynamicSection(const Elf_Shdr *Shdr);
|
||||
Expected<ELFYAML::RelocationSection *> dumpRelocSection(const Elf_Shdr *Shdr);
|
||||
Expected<ELFYAML::RawContentSection *>
|
||||
dumpContentSection(const Elf_Shdr *Shdr);
|
||||
ErrorOr<ELFYAML::NoBitsSection *> dumpNoBitsSection(const Elf_Shdr *Shdr);
|
||||
ErrorOr<ELFYAML::VerdefSection *> dumpVerdefSection(const Elf_Shdr *Shdr);
|
||||
ErrorOr<ELFYAML::SymverSection *> dumpSymverSection(const Elf_Shdr *Shdr);
|
||||
ErrorOr<ELFYAML::VerneedSection *> dumpVerneedSection(const Elf_Shdr *Shdr);
|
||||
ErrorOr<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr);
|
||||
ErrorOr<ELFYAML::MipsABIFlags *> dumpMipsABIFlags(const Elf_Shdr *Shdr);
|
||||
Expected<ELFYAML::NoBitsSection *> dumpNoBitsSection(const Elf_Shdr *Shdr);
|
||||
Expected<ELFYAML::VerdefSection *> dumpVerdefSection(const Elf_Shdr *Shdr);
|
||||
Expected<ELFYAML::SymverSection *> dumpSymverSection(const Elf_Shdr *Shdr);
|
||||
Expected<ELFYAML::VerneedSection *> dumpVerneedSection(const Elf_Shdr *Shdr);
|
||||
Expected<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr);
|
||||
Expected<ELFYAML::MipsABIFlags *> dumpMipsABIFlags(const Elf_Shdr *Shdr);
|
||||
|
||||
public:
|
||||
ELFDumper(const object::ELFFile<ELFT> &O);
|
||||
ErrorOr<ELFYAML::Object *> dump();
|
||||
Expected<ELFYAML::Object *> dump();
|
||||
};
|
||||
|
||||
}
|
||||
@ -134,7 +134,7 @@ ELFDumper<ELFT>::getUniquedSymbolName(const Elf_Sym *Sym, StringRef StrTable,
|
||||
return Name;
|
||||
}
|
||||
|
||||
template <class ELFT> ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
|
||||
template <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
|
||||
auto Y = make_unique<ELFYAML::Object>();
|
||||
|
||||
// Dump header. We do not dump SHEntSize, SHOffset, SHNum and SHStrNdx field.
|
||||
@ -152,7 +152,7 @@ template <class ELFT> ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
|
||||
// Dump sections
|
||||
auto SectionsOrErr = Obj.sections();
|
||||
if (!SectionsOrErr)
|
||||
return errorToErrorCode(SectionsOrErr.takeError());
|
||||
return SectionsOrErr.takeError();
|
||||
Sections = *SectionsOrErr;
|
||||
SectionNames.resize(Sections.size());
|
||||
|
||||
@ -160,20 +160,20 @@ template <class ELFT> ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
|
||||
// to access the deduplicated symbol names that we also create here.
|
||||
for (const Elf_Shdr &Sec : Sections) {
|
||||
if (Sec.sh_type == ELF::SHT_SYMTAB)
|
||||
if (auto EC = dumpSymbols(&Sec, Y->Symbols))
|
||||
return EC;
|
||||
if (Error E = dumpSymbols(&Sec, Y->Symbols))
|
||||
return std::move(E);
|
||||
if (Sec.sh_type == ELF::SHT_DYNSYM)
|
||||
if (auto EC = dumpSymbols(&Sec, Y->DynamicSymbols))
|
||||
return EC;
|
||||
if (Error E = dumpSymbols(&Sec, Y->DynamicSymbols))
|
||||
return std::move(E);
|
||||
}
|
||||
|
||||
for (const Elf_Shdr &Sec : Sections) {
|
||||
switch (Sec.sh_type) {
|
||||
case ELF::SHT_DYNAMIC: {
|
||||
ErrorOr<ELFYAML::DynamicSection *> S = dumpDynamicSection(&Sec);
|
||||
if (std::error_code EC = S.getError())
|
||||
return EC;
|
||||
Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
|
||||
Expected<ELFYAML::DynamicSection *> SecOrErr = dumpDynamicSection(&Sec);
|
||||
if (!SecOrErr)
|
||||
return SecOrErr.takeError();
|
||||
Y->Sections.emplace_back(*SecOrErr);
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_NULL:
|
||||
@ -185,65 +185,66 @@ template <class ELFT> ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
|
||||
case ELF::SHT_SYMTAB_SHNDX: {
|
||||
auto TableOrErr = Obj.getSHNDXTable(Sec);
|
||||
if (!TableOrErr)
|
||||
return errorToErrorCode(TableOrErr.takeError());
|
||||
return TableOrErr.takeError();
|
||||
ShndxTable = *TableOrErr;
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_REL:
|
||||
case ELF::SHT_RELA: {
|
||||
ErrorOr<ELFYAML::RelocationSection *> S = dumpRelocSection(&Sec);
|
||||
if (std::error_code EC = S.getError())
|
||||
return EC;
|
||||
Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
|
||||
Expected<ELFYAML::RelocationSection *> SecOrErr = dumpRelocSection(&Sec);
|
||||
if (!SecOrErr)
|
||||
return SecOrErr.takeError();
|
||||
Y->Sections.emplace_back(*SecOrErr);
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_GROUP: {
|
||||
ErrorOr<ELFYAML::Group *> G = dumpGroup(&Sec);
|
||||
if (std::error_code EC = G.getError())
|
||||
return EC;
|
||||
Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(G.get()));
|
||||
Expected<ELFYAML::Group *> GroupOrErr = dumpGroup(&Sec);
|
||||
if (!GroupOrErr)
|
||||
return GroupOrErr.takeError();
|
||||
Y->Sections.emplace_back(*GroupOrErr);
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_MIPS_ABIFLAGS: {
|
||||
ErrorOr<ELFYAML::MipsABIFlags *> G = dumpMipsABIFlags(&Sec);
|
||||
if (std::error_code EC = G.getError())
|
||||
return EC;
|
||||
Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(G.get()));
|
||||
Expected<ELFYAML::MipsABIFlags *> SecOrErr = dumpMipsABIFlags(&Sec);
|
||||
if (!SecOrErr)
|
||||
return SecOrErr.takeError();
|
||||
Y->Sections.emplace_back(*SecOrErr);
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_NOBITS: {
|
||||
ErrorOr<ELFYAML::NoBitsSection *> S = dumpNoBitsSection(&Sec);
|
||||
if (std::error_code EC = S.getError())
|
||||
return EC;
|
||||
Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
|
||||
Expected<ELFYAML::NoBitsSection *> SecOrErr = dumpNoBitsSection(&Sec);
|
||||
if (!SecOrErr)
|
||||
return SecOrErr.takeError();
|
||||
Y->Sections.emplace_back(*SecOrErr);
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_GNU_verdef: {
|
||||
ErrorOr<ELFYAML::VerdefSection *> S = dumpVerdefSection(&Sec);
|
||||
if (std::error_code EC = S.getError())
|
||||
return EC;
|
||||
Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
|
||||
Expected<ELFYAML::VerdefSection *> SecOrErr = dumpVerdefSection(&Sec);
|
||||
if (!SecOrErr)
|
||||
return SecOrErr.takeError();
|
||||
Y->Sections.emplace_back(*SecOrErr);
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_GNU_versym: {
|
||||
ErrorOr<ELFYAML::SymverSection *> S = dumpSymverSection(&Sec);
|
||||
if (std::error_code EC = S.getError())
|
||||
return EC;
|
||||
Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
|
||||
Expected<ELFYAML::SymverSection *> SecOrErr = dumpSymverSection(&Sec);
|
||||
if (!SecOrErr)
|
||||
return SecOrErr.takeError();
|
||||
Y->Sections.emplace_back(*SecOrErr);
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_GNU_verneed: {
|
||||
ErrorOr<ELFYAML::VerneedSection *> S = dumpVerneedSection(&Sec);
|
||||
if (std::error_code EC = S.getError())
|
||||
return EC;
|
||||
Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
|
||||
Expected<ELFYAML::VerneedSection *> SecOrErr = dumpVerneedSection(&Sec);
|
||||
if (!SecOrErr)
|
||||
return SecOrErr.takeError();
|
||||
Y->Sections.emplace_back(*SecOrErr);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
ErrorOr<ELFYAML::RawContentSection *> S = dumpContentSection(&Sec);
|
||||
if (std::error_code EC = S.getError())
|
||||
return EC;
|
||||
Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
|
||||
Expected<ELFYAML::RawContentSection *> SecOrErr =
|
||||
dumpContentSection(&Sec);
|
||||
if (!SecOrErr)
|
||||
return SecOrErr.takeError();
|
||||
Y->Sections.emplace_back(*SecOrErr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -252,20 +253,19 @@ template <class ELFT> ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
std::error_code
|
||||
ELFDumper<ELFT>::dumpSymbols(const Elf_Shdr *Symtab,
|
||||
Error ELFDumper<ELFT>::dumpSymbols(const Elf_Shdr *Symtab,
|
||||
std::vector<ELFYAML::Symbol> &Symbols) {
|
||||
if (!Symtab)
|
||||
return std::error_code();
|
||||
return Error::success();
|
||||
|
||||
auto StrTableOrErr = Obj.getStringTableForSymtab(*Symtab);
|
||||
if (!StrTableOrErr)
|
||||
return errorToErrorCode(StrTableOrErr.takeError());
|
||||
return StrTableOrErr.takeError();
|
||||
StringRef StrTable = *StrTableOrErr;
|
||||
|
||||
auto SymtabOrErr = Obj.symbols(Symtab);
|
||||
if (!SymtabOrErr)
|
||||
return errorToErrorCode(SymtabOrErr.takeError());
|
||||
return SymtabOrErr.takeError();
|
||||
|
||||
if (Symtab->sh_type == ELF::SHT_SYMTAB) {
|
||||
SymTable = *SymtabOrErr;
|
||||
@ -279,13 +279,12 @@ ELFDumper<ELFT>::dumpSymbols(const Elf_Shdr *Symtab,
|
||||
Symbols.push_back(S);
|
||||
}
|
||||
|
||||
return std::error_code();
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
std::error_code
|
||||
ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
|
||||
StringRef StrTable, ELFYAML::Symbol &S) {
|
||||
Error ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
|
||||
StringRef StrTable, ELFYAML::Symbol &S) {
|
||||
S.Type = Sym->getType();
|
||||
S.Value = Sym->st_value;
|
||||
S.Size = Sym->st_size;
|
||||
@ -295,56 +294,56 @@ ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
|
||||
Expected<StringRef> SymbolNameOrErr =
|
||||
getUniquedSymbolName(Sym, StrTable, SymTab);
|
||||
if (!SymbolNameOrErr)
|
||||
return errorToErrorCode(SymbolNameOrErr.takeError());
|
||||
return SymbolNameOrErr.takeError();
|
||||
S.Name = SymbolNameOrErr.get();
|
||||
|
||||
if (Sym->st_shndx >= ELF::SHN_LORESERVE) {
|
||||
if (Sym->st_shndx == ELF::SHN_XINDEX)
|
||||
return obj2yaml_error::not_implemented;
|
||||
return createStringError(obj2yaml_error::not_implemented,
|
||||
"SHN_XINDEX symbols are not supported");
|
||||
S.Index = (ELFYAML::ELF_SHN)Sym->st_shndx;
|
||||
return obj2yaml_error::success;
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable);
|
||||
if (!ShdrOrErr)
|
||||
return errorToErrorCode(ShdrOrErr.takeError());
|
||||
return ShdrOrErr.takeError();
|
||||
const Elf_Shdr *Shdr = *ShdrOrErr;
|
||||
if (!Shdr)
|
||||
return obj2yaml_error::success;
|
||||
return Error::success();
|
||||
|
||||
auto NameOrErr = getUniquedSectionName(Shdr);
|
||||
if (!NameOrErr)
|
||||
return errorToErrorCode(NameOrErr.takeError());
|
||||
return NameOrErr.takeError();
|
||||
S.Section = NameOrErr.get();
|
||||
|
||||
return obj2yaml_error::success;
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
template <class RelT>
|
||||
std::error_code ELFDumper<ELFT>::dumpRelocation(const RelT *Rel,
|
||||
const Elf_Shdr *SymTab,
|
||||
ELFYAML::Relocation &R) {
|
||||
Error ELFDumper<ELFT>::dumpRelocation(const RelT *Rel, const Elf_Shdr *SymTab,
|
||||
ELFYAML::Relocation &R) {
|
||||
R.Type = Rel->getType(Obj.isMips64EL());
|
||||
R.Offset = Rel->r_offset;
|
||||
R.Addend = 0;
|
||||
|
||||
auto SymOrErr = Obj.getRelocationSymbol(Rel, SymTab);
|
||||
if (!SymOrErr)
|
||||
return errorToErrorCode(SymOrErr.takeError());
|
||||
return SymOrErr.takeError();
|
||||
const Elf_Sym *Sym = *SymOrErr;
|
||||
auto StrTabSec = Obj.getSection(SymTab->sh_link);
|
||||
if (!StrTabSec)
|
||||
return errorToErrorCode(StrTabSec.takeError());
|
||||
return StrTabSec.takeError();
|
||||
auto StrTabOrErr = Obj.getStringTable(*StrTabSec);
|
||||
if (!StrTabOrErr)
|
||||
return errorToErrorCode(StrTabOrErr.takeError());
|
||||
return StrTabOrErr.takeError();
|
||||
StringRef StrTab = *StrTabOrErr;
|
||||
|
||||
if (Sym) {
|
||||
Expected<StringRef> NameOrErr = getUniquedSymbolName(Sym, StrTab, SymTab);
|
||||
if (!NameOrErr)
|
||||
return errorToErrorCode(NameOrErr.takeError());
|
||||
return NameOrErr.takeError();
|
||||
R.Symbol = NameOrErr.get();
|
||||
} else {
|
||||
// We have some edge cases of relocations without a symbol associated,
|
||||
@ -354,12 +353,12 @@ std::error_code ELFDumper<ELFT>::dumpRelocation(const RelT *Rel,
|
||||
R.Symbol = "";
|
||||
}
|
||||
|
||||
return obj2yaml_error::success;
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
std::error_code ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,
|
||||
ELFYAML::Section &S) {
|
||||
Error ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,
|
||||
ELFYAML::Section &S) {
|
||||
// Dump fields. We do not dump the ShOffset field. When not explicitly
|
||||
// set, the value is set by yaml2obj automatically.
|
||||
S.Type = Shdr->sh_type;
|
||||
@ -372,51 +371,50 @@ std::error_code ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,
|
||||
|
||||
auto NameOrErr = getUniquedSectionName(Shdr);
|
||||
if (!NameOrErr)
|
||||
return errorToErrorCode(NameOrErr.takeError());
|
||||
return NameOrErr.takeError();
|
||||
S.Name = NameOrErr.get();
|
||||
|
||||
if (Shdr->sh_link != ELF::SHN_UNDEF) {
|
||||
auto LinkSection = Obj.getSection(Shdr->sh_link);
|
||||
if (LinkSection.takeError())
|
||||
return errorToErrorCode(LinkSection.takeError());
|
||||
return LinkSection.takeError();
|
||||
NameOrErr = getUniquedSectionName(*LinkSection);
|
||||
if (!NameOrErr)
|
||||
return errorToErrorCode(NameOrErr.takeError());
|
||||
return NameOrErr.takeError();
|
||||
S.Link = NameOrErr.get();
|
||||
}
|
||||
|
||||
return obj2yaml_error::success;
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
std::error_code
|
||||
ELFDumper<ELFT>::dumpCommonRelocationSection(const Elf_Shdr *Shdr,
|
||||
ELFYAML::RelocationSection &S) {
|
||||
if (std::error_code EC = dumpCommonSection(Shdr, S))
|
||||
return EC;
|
||||
Error ELFDumper<ELFT>::dumpCommonRelocationSection(
|
||||
const Elf_Shdr *Shdr, ELFYAML::RelocationSection &S) {
|
||||
if (Error E = dumpCommonSection(Shdr, S))
|
||||
return E;
|
||||
|
||||
auto InfoSection = Obj.getSection(Shdr->sh_info);
|
||||
if (!InfoSection)
|
||||
return errorToErrorCode(InfoSection.takeError());
|
||||
return InfoSection.takeError();
|
||||
|
||||
auto NameOrErr = getUniquedSectionName(*InfoSection);
|
||||
if (!NameOrErr)
|
||||
return errorToErrorCode(NameOrErr.takeError());
|
||||
return NameOrErr.takeError();
|
||||
S.RelocatableSec = NameOrErr.get();
|
||||
|
||||
return obj2yaml_error::success;
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<ELFYAML::DynamicSection *>
|
||||
Expected<ELFYAML::DynamicSection *>
|
||||
ELFDumper<ELFT>::dumpDynamicSection(const Elf_Shdr *Shdr) {
|
||||
auto S = make_unique<ELFYAML::DynamicSection>();
|
||||
if (std::error_code EC = dumpCommonSection(Shdr, *S))
|
||||
return EC;
|
||||
if (Error E = dumpCommonSection(Shdr, *S))
|
||||
return std::move(E);
|
||||
|
||||
auto DynTagsOrErr = Obj.template getSectionContentsAsArray<Elf_Dyn>(Shdr);
|
||||
if (!DynTagsOrErr)
|
||||
return errorToErrorCode(DynTagsOrErr.takeError());
|
||||
return DynTagsOrErr.takeError();
|
||||
|
||||
for (const Elf_Dyn &Dyn : *DynTagsOrErr)
|
||||
S->Entries.push_back({(ELFYAML::ELF_DYNTAG)Dyn.getTag(), Dyn.getVal()});
|
||||
@ -425,35 +423,35 @@ ELFDumper<ELFT>::dumpDynamicSection(const Elf_Shdr *Shdr) {
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<ELFYAML::RelocationSection *>
|
||||
Expected<ELFYAML::RelocationSection *>
|
||||
ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) {
|
||||
auto S = make_unique<ELFYAML::RelocationSection>();
|
||||
if (std::error_code EC = dumpCommonRelocationSection(Shdr, *S))
|
||||
return EC;
|
||||
if (auto E = dumpCommonRelocationSection(Shdr, *S))
|
||||
return std::move(E);
|
||||
|
||||
auto SymTabOrErr = Obj.getSection(Shdr->sh_link);
|
||||
if (!SymTabOrErr)
|
||||
return errorToErrorCode(SymTabOrErr.takeError());
|
||||
return SymTabOrErr.takeError();
|
||||
const Elf_Shdr *SymTab = *SymTabOrErr;
|
||||
|
||||
if (Shdr->sh_type == ELF::SHT_REL) {
|
||||
auto Rels = Obj.rels(Shdr);
|
||||
if (!Rels)
|
||||
return errorToErrorCode(Rels.takeError());
|
||||
return Rels.takeError();
|
||||
for (const Elf_Rel &Rel : *Rels) {
|
||||
ELFYAML::Relocation R;
|
||||
if (std::error_code EC = dumpRelocation(&Rel, SymTab, R))
|
||||
return EC;
|
||||
if (Error E = dumpRelocation(&Rel, SymTab, R))
|
||||
return std::move(E);
|
||||
S->Relocations.push_back(R);
|
||||
}
|
||||
} else {
|
||||
auto Rels = Obj.relas(Shdr);
|
||||
if (!Rels)
|
||||
return errorToErrorCode(Rels.takeError());
|
||||
return Rels.takeError();
|
||||
for (const Elf_Rela &Rel : *Rels) {
|
||||
ELFYAML::Relocation R;
|
||||
if (std::error_code EC = dumpRelocation(&Rel, SymTab, R))
|
||||
return EC;
|
||||
if (Error E = dumpRelocation(&Rel, SymTab, R))
|
||||
return std::move(E);
|
||||
R.Addend = Rel.r_addend;
|
||||
S->Relocations.push_back(R);
|
||||
}
|
||||
@ -463,16 +461,15 @@ ELFDumper<ELFT>::dumpRelocSection(const Elf_Shdr *Shdr) {
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<ELFYAML::RawContentSection *>
|
||||
Expected<ELFYAML::RawContentSection *>
|
||||
ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) {
|
||||
auto S = make_unique<ELFYAML::RawContentSection>();
|
||||
|
||||
if (std::error_code EC = dumpCommonSection(Shdr, *S))
|
||||
return EC;
|
||||
if (Error E = dumpCommonSection(Shdr, *S))
|
||||
return std::move(E);
|
||||
|
||||
auto ContentOrErr = Obj.getSectionContents(Shdr);
|
||||
if (!ContentOrErr)
|
||||
return errorToErrorCode(ContentOrErr.takeError());
|
||||
return ContentOrErr.takeError();
|
||||
ArrayRef<uint8_t> Content = *ContentOrErr;
|
||||
if (!Content.empty())
|
||||
S->Content = yaml::BinaryRef(Content);
|
||||
@ -482,40 +479,39 @@ ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) {
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<ELFYAML::NoBitsSection *>
|
||||
Expected<ELFYAML::NoBitsSection *>
|
||||
ELFDumper<ELFT>::dumpNoBitsSection(const Elf_Shdr *Shdr) {
|
||||
auto S = make_unique<ELFYAML::NoBitsSection>();
|
||||
|
||||
if (std::error_code EC = dumpCommonSection(Shdr, *S))
|
||||
return EC;
|
||||
if (Error E = dumpCommonSection(Shdr, *S))
|
||||
return std::move(E);
|
||||
S->Size = Shdr->sh_size;
|
||||
|
||||
return S.release();
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<ELFYAML::VerdefSection *>
|
||||
Expected<ELFYAML::VerdefSection *>
|
||||
ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) {
|
||||
typedef typename ELFT::Verdef Elf_Verdef;
|
||||
typedef typename ELFT::Verdaux Elf_Verdaux;
|
||||
|
||||
auto S = make_unique<ELFYAML::VerdefSection>();
|
||||
if (std::error_code EC = dumpCommonSection(Shdr, *S))
|
||||
return EC;
|
||||
if (Error E = dumpCommonSection(Shdr, *S))
|
||||
return std::move(E);
|
||||
|
||||
S->Info = Shdr->sh_info;
|
||||
|
||||
auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);
|
||||
if (!StringTableShdrOrErr)
|
||||
return errorToErrorCode(StringTableShdrOrErr.takeError());
|
||||
return StringTableShdrOrErr.takeError();
|
||||
|
||||
auto StringTableOrErr = Obj.getStringTable(*StringTableShdrOrErr);
|
||||
if (!StringTableOrErr)
|
||||
return errorToErrorCode(StringTableOrErr.takeError());
|
||||
return StringTableOrErr.takeError();
|
||||
|
||||
auto Contents = Obj.getSectionContents(Shdr);
|
||||
if (!Contents)
|
||||
return errorToErrorCode(Contents.takeError());
|
||||
return Contents.takeError();
|
||||
|
||||
llvm::ArrayRef<uint8_t> Data = *Contents;
|
||||
const uint8_t *Buf = Data.data();
|
||||
@ -544,17 +540,17 @@ ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) {
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<ELFYAML::SymverSection *>
|
||||
Expected<ELFYAML::SymverSection *>
|
||||
ELFDumper<ELFT>::dumpSymverSection(const Elf_Shdr *Shdr) {
|
||||
typedef typename ELFT::Half Elf_Half;
|
||||
|
||||
auto S = make_unique<ELFYAML::SymverSection>();
|
||||
if (std::error_code EC = dumpCommonSection(Shdr, *S))
|
||||
return EC;
|
||||
if (Error E = dumpCommonSection(Shdr, *S))
|
||||
return std::move(E);
|
||||
|
||||
auto VersionsOrErr = Obj.template getSectionContentsAsArray<Elf_Half>(Shdr);
|
||||
if (!VersionsOrErr)
|
||||
return errorToErrorCode(VersionsOrErr.takeError());
|
||||
return VersionsOrErr.takeError();
|
||||
for (const Elf_Half &E : *VersionsOrErr)
|
||||
S->Entries.push_back(E);
|
||||
|
||||
@ -562,28 +558,28 @@ ELFDumper<ELFT>::dumpSymverSection(const Elf_Shdr *Shdr) {
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<ELFYAML::VerneedSection *>
|
||||
Expected<ELFYAML::VerneedSection *>
|
||||
ELFDumper<ELFT>::dumpVerneedSection(const Elf_Shdr *Shdr) {
|
||||
typedef typename ELFT::Verneed Elf_Verneed;
|
||||
typedef typename ELFT::Vernaux Elf_Vernaux;
|
||||
|
||||
auto S = make_unique<ELFYAML::VerneedSection>();
|
||||
if (std::error_code EC = dumpCommonSection(Shdr, *S))
|
||||
return EC;
|
||||
if (Error E = dumpCommonSection(Shdr, *S))
|
||||
return std::move(E);
|
||||
|
||||
S->Info = Shdr->sh_info;
|
||||
|
||||
auto Contents = Obj.getSectionContents(Shdr);
|
||||
if (!Contents)
|
||||
return errorToErrorCode(Contents.takeError());
|
||||
return Contents.takeError();
|
||||
|
||||
auto StringTableShdrOrErr = Obj.getSection(Shdr->sh_link);
|
||||
if (!StringTableShdrOrErr)
|
||||
return errorToErrorCode(StringTableShdrOrErr.takeError());
|
||||
return StringTableShdrOrErr.takeError();
|
||||
|
||||
auto StringTableOrErr = Obj.getStringTable(*StringTableShdrOrErr);
|
||||
if (!StringTableOrErr)
|
||||
return errorToErrorCode(StringTableOrErr.takeError());
|
||||
return StringTableOrErr.takeError();
|
||||
|
||||
llvm::ArrayRef<uint8_t> Data = *Contents;
|
||||
const uint8_t *Buf = Data.data();
|
||||
@ -619,32 +615,32 @@ ELFDumper<ELFT>::dumpVerneedSection(const Elf_Shdr *Shdr) {
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) {
|
||||
Expected<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) {
|
||||
auto S = make_unique<ELFYAML::Group>();
|
||||
if (std::error_code EC = dumpCommonSection(Shdr, *S))
|
||||
return EC;
|
||||
if (Error E = dumpCommonSection(Shdr, *S))
|
||||
return std::move(E);
|
||||
|
||||
auto SymtabOrErr = Obj.getSection(Shdr->sh_link);
|
||||
if (!SymtabOrErr)
|
||||
return errorToErrorCode(SymtabOrErr.takeError());
|
||||
return SymtabOrErr.takeError();
|
||||
// Get symbol with index sh_info which name is the signature of the group.
|
||||
const Elf_Shdr *Symtab = *SymtabOrErr;
|
||||
auto SymOrErr = Obj.getSymbol(Symtab, Shdr->sh_info);
|
||||
if (!SymOrErr)
|
||||
return errorToErrorCode(SymOrErr.takeError());
|
||||
return SymOrErr.takeError();
|
||||
auto StrTabOrErr = Obj.getStringTableForSymtab(*Symtab);
|
||||
if (!StrTabOrErr)
|
||||
return errorToErrorCode(StrTabOrErr.takeError());
|
||||
return StrTabOrErr.takeError();
|
||||
|
||||
Expected<StringRef> SymbolName =
|
||||
getUniquedSymbolName(*SymOrErr, *StrTabOrErr, Symtab);
|
||||
if (!SymbolName)
|
||||
return errorToErrorCode(SymbolName.takeError());
|
||||
return SymbolName.takeError();
|
||||
S->Signature = *SymbolName;
|
||||
|
||||
auto MembersOrErr = Obj.template getSectionContentsAsArray<Elf_Word>(Shdr);
|
||||
if (!MembersOrErr)
|
||||
return errorToErrorCode(MembersOrErr.takeError());
|
||||
return MembersOrErr.takeError();
|
||||
|
||||
for (Elf_Word Member : *MembersOrErr) {
|
||||
if (Member == llvm::ELF::GRP_COMDAT) {
|
||||
@ -654,27 +650,27 @@ ErrorOr<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) {
|
||||
|
||||
auto SHdrOrErr = Obj.getSection(Member);
|
||||
if (!SHdrOrErr)
|
||||
return errorToErrorCode(SHdrOrErr.takeError());
|
||||
return SHdrOrErr.takeError();
|
||||
auto NameOrErr = getUniquedSectionName(*SHdrOrErr);
|
||||
if (!NameOrErr)
|
||||
return errorToErrorCode(NameOrErr.takeError());
|
||||
return NameOrErr.takeError();
|
||||
S->Members.push_back({*NameOrErr});
|
||||
}
|
||||
return S.release();
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<ELFYAML::MipsABIFlags *>
|
||||
Expected<ELFYAML::MipsABIFlags *>
|
||||
ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) {
|
||||
assert(Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS &&
|
||||
"Section type is not SHT_MIPS_ABIFLAGS");
|
||||
auto S = make_unique<ELFYAML::MipsABIFlags>();
|
||||
if (std::error_code EC = dumpCommonSection(Shdr, *S))
|
||||
return EC;
|
||||
if (Error E = dumpCommonSection(Shdr, *S))
|
||||
return std::move(E);
|
||||
|
||||
auto ContentOrErr = Obj.getSectionContents(Shdr);
|
||||
if (!ContentOrErr)
|
||||
return errorToErrorCode(ContentOrErr.takeError());
|
||||
return ContentOrErr.takeError();
|
||||
|
||||
auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>(
|
||||
ContentOrErr.get().data());
|
||||
@ -693,21 +689,20 @@ ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) {
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
static std::error_code elf2yaml(raw_ostream &Out,
|
||||
const object::ELFFile<ELFT> &Obj) {
|
||||
static Error elf2yaml(raw_ostream &Out, const object::ELFFile<ELFT> &Obj) {
|
||||
ELFDumper<ELFT> Dumper(Obj);
|
||||
ErrorOr<ELFYAML::Object *> YAMLOrErr = Dumper.dump();
|
||||
if (std::error_code EC = YAMLOrErr.getError())
|
||||
return EC;
|
||||
Expected<ELFYAML::Object *> YAMLOrErr = Dumper.dump();
|
||||
if (!YAMLOrErr)
|
||||
return YAMLOrErr.takeError();
|
||||
|
||||
std::unique_ptr<ELFYAML::Object> YAML(YAMLOrErr.get());
|
||||
yaml::Output Yout(Out);
|
||||
Yout << *YAML;
|
||||
|
||||
return std::error_code();
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
std::error_code elf2yaml(raw_ostream &Out, const object::ObjectFile &Obj) {
|
||||
Error elf2yaml(raw_ostream &Out, const object::ObjectFile &Obj) {
|
||||
if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(&Obj))
|
||||
return elf2yaml(Out, *ELFObj->getELFFile());
|
||||
|
||||
@ -720,5 +715,5 @@ std::error_code elf2yaml(raw_ostream &Out, const object::ObjectFile &Obj) {
|
||||
if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(&Obj))
|
||||
return elf2yaml(Out, *ELFObj->getELFFile());
|
||||
|
||||
return obj2yaml_error::unsupported_obj_file_format;
|
||||
llvm_unreachable("unknown ELF file format");
|
||||
}
|
||||
|
@ -17,19 +17,20 @@
|
||||
using namespace llvm;
|
||||
using namespace llvm::object;
|
||||
|
||||
static std::error_code dumpObject(const ObjectFile &Obj) {
|
||||
static Error dumpObject(const ObjectFile &Obj) {
|
||||
if (Obj.isCOFF())
|
||||
return coff2yaml(outs(), cast<COFFObjectFile>(Obj));
|
||||
return errorCodeToError(coff2yaml(outs(), cast<COFFObjectFile>(Obj)));
|
||||
|
||||
if (Obj.isXCOFF())
|
||||
return xcoff2yaml(outs(), cast<XCOFFObjectFile>(Obj));
|
||||
return errorCodeToError(xcoff2yaml(outs(), cast<XCOFFObjectFile>(Obj)));
|
||||
|
||||
if (Obj.isELF())
|
||||
return elf2yaml(outs(), Obj);
|
||||
if (Obj.isWasm())
|
||||
return wasm2yaml(outs(), cast<WasmObjectFile>(Obj));
|
||||
|
||||
return obj2yaml_error::unsupported_obj_file_format;
|
||||
if (Obj.isWasm())
|
||||
return errorCodeToError(wasm2yaml(outs(), cast<WasmObjectFile>(Obj)));
|
||||
|
||||
return errorCodeToError(obj2yaml_error::unsupported_obj_file_format);
|
||||
}
|
||||
|
||||
static Error dumpInput(StringRef File) {
|
||||
@ -44,7 +45,7 @@ static Error dumpInput(StringRef File) {
|
||||
return errorCodeToError(macho2yaml(outs(), Binary));
|
||||
// TODO: If this is an archive, then burst it and dump each entry
|
||||
if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary))
|
||||
return errorCodeToError(dumpObject(*Obj));
|
||||
return dumpObject(*Obj);
|
||||
if (MinidumpFile *Minidump = dyn_cast<MinidumpFile>(&Binary))
|
||||
return minidump2yaml(outs(), *Minidump);
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
std::error_code coff2yaml(llvm::raw_ostream &Out,
|
||||
const llvm::object::COFFObjectFile &Obj);
|
||||
std::error_code elf2yaml(llvm::raw_ostream &Out,
|
||||
llvm::Error elf2yaml(llvm::raw_ostream &Out,
|
||||
const llvm::object::ObjectFile &Obj);
|
||||
std::error_code macho2yaml(llvm::raw_ostream &Out,
|
||||
const llvm::object::Binary &Obj);
|
||||
|
Loading…
Reference in New Issue
Block a user