Expected<std::vector<VerNeed>>
getVersionDependencies(const Elf_Shdr *Sec) const;
+ template <class RelTy>
Expected<std::pair<const Elf_Sym *, std::string>>
- getRelocationTarget(const Elf_Shdr *SymTab, const Elf_Rela &R) const;
+ getRelocationTarget(const Elf_Shdr *SymTab, const RelTy &R) const;
std::function<Error(const Twine &Msg)> WarningHandler;
void reportUniqueWarning(Error Err) const;
void printHashedSymbol(const ELFO *Obj, const Elf_Sym *FirstSym, uint32_t Sym,
StringRef StrTable, uint32_t Bucket);
void printRelocHeader(unsigned SType);
+ template <class RelTy>
void printRelocation(const ELFO *Obj, unsigned SecIndex,
- const Elf_Shdr *SymTab, const Elf_Rela &R,
- unsigned RelIndex, bool IsRela);
+ const Elf_Shdr *SymTab, const RelTy &R,
+ unsigned RelIndex);
+ template <class RelTy>
void printRelocation(const ELFO *Obj, const Elf_Sym *Sym,
- StringRef SymbolName, const Elf_Rela &R, bool IsRela);
+ StringRef SymbolName, const RelTy &R);
void printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, const Elf_Sym *First,
Optional<StringRef> StrTable, bool IsDynamic,
bool NonVisibilityBitsUsed) override;
std::string getSymbolSectionNdx(const ELFO *Obj, const Elf_Sym *Symbol,
const Elf_Sym *FirstSym);
- void printDynamicRelocation(const ELFO *Obj, Elf_Rela R, bool IsRela);
+ template <class RelTy>
+ void printDynamicRelocation(const ELFO *Obj, const RelTy &R);
void printProgramHeaders(const ELFO *Obj);
void printSectionMapping(const ELFO *Obj);
void printGNUVersionSectionProlog(const ELFFile<ELFT> *Obj,
void printMipsABIFlags(const ELFObjectFile<ELFT> *Obj) override;
private:
- void printRelocation(const ELFO *Obj, unsigned SecIndex, Elf_Rela Rel,
+ template <class RelTy>
+ void printRelocation(const ELFO *Obj, unsigned SecIndex, const RelTy &Rel,
unsigned RelIndex, const Elf_Shdr *SymTab);
- void printDynamicRelocation(const ELFO *Obj, Elf_Rela Rel);
+ template <class RelTy>
+ void printDynamicRelocation(const ELFO *Obj, const RelTy& Rel);
+
void printSymbols(const ELFO *Obj);
void printDynamicSymbols(const ELFO *Obj);
void printSymbolSection(const Elf_Sym *Symbol, const Elf_Sym *First);
}
template <typename ELFT>
+template <class RelTy>
Expected<std::pair<const typename ELFT::Sym *, std::string>>
ELFDumper<ELFT>::getRelocationTarget(const Elf_Shdr *SymTab,
- const Elf_Rela &R) const {
+ const RelTy &R) const {
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
Expected<const Elf_Sym *> SymOrErr = Obj->getRelocationSymbol(&R, SymTab);
if (!SymOrErr)
}
template <class ELFT>
+template <class RelTy>
void GNUStyle<ELFT>::printRelocation(const ELFO *Obj, unsigned SecIndex,
- const Elf_Shdr *SymTab, const Elf_Rela &R,
- unsigned RelIndex, bool IsRela) {
+ const Elf_Shdr *SymTab, const RelTy &R,
+ unsigned RelIndex) {
Expected<std::pair<const typename ELFT::Sym *, std::string>> Target =
this->dumper()->getRelocationTarget(SymTab, R);
if (!Target)
"unable to print relocation " + Twine(RelIndex) + " in section " +
Twine(SecIndex) + ": " + toString(Target.takeError())));
else
- printRelocation(Obj, /*Sym=*/Target->first, /*Name=*/Target->second, R,
- IsRela);
+ printRelocation(Obj, /*Sym=*/Target->first, /*Name=*/Target->second, R);
+}
+
+template <class ELFT>
+static Optional<int64_t> getAddend(const typename ELFT::Rela &R) {
+ return (int64_t)R.r_addend;
+}
+
+template <class ELFT>
+static Optional<int64_t> getAddend(const typename ELFT::Rel &) {
+ return None;
}
template <class ELFT>
+template <class RelTy>
void GNUStyle<ELFT>::printRelocation(const ELFO *Obj, const Elf_Sym *Sym,
- StringRef SymbolName, const Elf_Rela &R,
- bool IsRela) {
+ StringRef SymbolName, const RelTy &R) {
// First two fields are bit width dependent. The rest of them are fixed width.
unsigned Bias = ELFT::Is64Bits ? 8 : 0;
Field Fields[5] = {0, 10 + Bias, 19 + 2 * Bias, 42 + 2 * Bias, 53 + 2 * Bias};
printField(F);
std::string Addend;
- if (IsRela) {
- int64_t RelAddend = R.r_addend;
+ if (Optional<int64_t> A = getAddend<ELFT>(R)) {
+ int64_t RelAddend = *A;
if (!SymbolName.empty()) {
- if (R.r_addend < 0) {
+ if (RelAddend < 0) {
Addend = " - ";
RelAddend = std::abs(RelAddend);
- } else
+ } else {
Addend = " + ";
+ }
}
-
Addend += to_hexString(RelAddend, false);
}
OS << Addend << "\n";
AndroidRelas = unwrapOrError(this->FileName, Obj->android_relas(&Sec));
Entries = AndroidRelas.size();
}
- std::vector<Elf_Rela> RelrRelas;
+ std::vector<Elf_Rel> RelrRels;
if (!opts::RawRelr && (Sec.sh_type == ELF::SHT_RELR ||
Sec.sh_type == ELF::SHT_ANDROID_RELR)) {
// .relr.dyn relative relocation section needs to be unpacked first
// to get the actual number of entries.
Elf_Relr_Range Relrs = unwrapOrError(this->FileName, Obj->relrs(&Sec));
- RelrRelas = unwrapOrError(this->FileName, Obj->decode_relrs(Relrs));
- Entries = RelrRelas.size();
+ RelrRels = unwrapOrError(this->FileName, Obj->decode_relrs(Relrs));
+ Entries = RelrRels.size();
}
uintX_t Offset = Sec.sh_offset;
OS << "\nRelocation section '" << Name << "' at offset 0x"
switch (Sec.sh_type) {
case ELF::SHT_REL:
- for (const auto &R : unwrapOrError(this->FileName, Obj->rels(&Sec))) {
- Elf_Rela Rela;
- Rela.r_offset = R.r_offset;
- Rela.r_info = R.r_info;
- Rela.r_addend = 0;
- printRelocation(Obj, SecNdx, SymTab, Rela, ++RelNdx, false);
- }
+ for (const Elf_Rel &R : unwrapOrError(this->FileName, Obj->rels(&Sec)))
+ printRelocation(Obj, SecNdx, SymTab, R, ++RelNdx);
break;
case ELF::SHT_RELA:
- for (const auto &R : unwrapOrError(this->FileName, Obj->relas(&Sec)))
- printRelocation(Obj, SecNdx, SymTab, R, ++RelNdx, true);
+ for (const Elf_Rela &R : unwrapOrError(this->FileName, Obj->relas(&Sec)))
+ printRelocation(Obj, SecNdx, SymTab, R, ++RelNdx);
break;
case ELF::SHT_RELR:
case ELF::SHT_ANDROID_RELR:
if (opts::RawRelr)
- for (const auto &R : unwrapOrError(this->FileName, Obj->relrs(&Sec)))
+ for (const Elf_Relr &R :
+ unwrapOrError(this->FileName, Obj->relrs(&Sec)))
OS << to_string(format_hex_no_prefix(R, ELFT::Is64Bits ? 16 : 8))
<< "\n";
else
- for (const auto &R : RelrRelas)
- printRelocation(Obj, SecNdx, SymTab, R, ++RelNdx, false);
+ for (const Elf_Rel &R : RelrRels)
+ printRelocation(Obj, SecNdx, SymTab, R, ++RelNdx);
break;
case ELF::SHT_ANDROID_REL:
+ for (const Elf_Rela &R : AndroidRelas)
+ printRelocation(Obj, SecNdx, SymTab, (const Elf_Rel &)R, ++RelNdx);
+ break;
case ELF::SHT_ANDROID_RELA:
- for (const auto &R : AndroidRelas)
- printRelocation(Obj, SecNdx, SymTab, R, ++RelNdx,
- Sec.sh_type == ELF::SHT_ANDROID_RELA);
+ for (const Elf_Rela &R : AndroidRelas)
+ printRelocation(Obj, SecNdx, SymTab, R, ++RelNdx);
break;
}
}
std::string Name;
};
-template <class ELFT>
+template <class ELFT, class RelTy>
RelSymbol<ELFT> getSymbolForReloc(const ELFFile<ELFT> *Obj, StringRef FileName,
const ELFDumper<ELFT> *Dumper,
- const typename ELFT::Rela &Reloc) {
+ const RelTy &Reloc) {
uint32_t SymIndex = Reloc.getSymbol(Obj->isMips64EL());
auto WarnAndReturn = [&](const typename ELFT::Sym *Sym,
const Twine &Reason) -> RelSymbol<ELFT> {
} // namespace
template <class ELFT>
-void GNUStyle<ELFT>::printDynamicRelocation(const ELFO *Obj, Elf_Rela R,
- bool IsRela) {
+template <class RelTy>
+void GNUStyle<ELFT>::printDynamicRelocation(const ELFO *Obj, const RelTy &R) {
RelSymbol<ELFT> S = getSymbolForReloc(Obj, this->FileName, this->dumper(), R);
- printRelocation(Obj, S.Sym, S.Name, R, IsRela);
+ printRelocation(Obj, S.Sym, S.Name, R);
}
template <class ELFT>
<< " contains " << DynRelaRegion.Size << " bytes:\n";
printRelocHeader(ELF::SHT_RELA);
for (const Elf_Rela &Rela : this->dumper()->dyn_relas())
- printDynamicRelocation(Obj, Rela, true);
+ printDynamicRelocation(Obj, Rela);
}
if (DynRelRegion.Size > 0) {
OS << "\n'REL' relocation section at offset "
1)
<< " contains " << DynRelRegion.Size << " bytes:\n";
printRelocHeader(ELF::SHT_REL);
- for (const Elf_Rel &Rel : this->dumper()->dyn_rels()) {
- Elf_Rela Rela;
- Rela.r_offset = Rel.r_offset;
- Rela.r_info = Rel.r_info;
- Rela.r_addend = 0;
- printDynamicRelocation(Obj, Rela, false);
- }
+ for (const Elf_Rel &Rel : this->dumper()->dyn_rels())
+ printDynamicRelocation(Obj, Rel);
}
if (DynRelrRegion.Size > 0) {
OS << "\n'RELR' relocation section at offset "
<< " contains " << DynRelrRegion.Size << " bytes:\n";
printRelocHeader(ELF::SHT_REL);
Elf_Relr_Range Relrs = this->dumper()->dyn_relrs();
- std::vector<Elf_Rela> RelrRelas =
+ std::vector<Elf_Rel> RelrRels =
unwrapOrError(this->FileName, Obj->decode_relrs(Relrs));
- for (const Elf_Rela &Rela : RelrRelas) {
- printDynamicRelocation(Obj, Rela, false);
- }
+ for (const Elf_Rel &R : RelrRels)
+ printDynamicRelocation(Obj, R);
}
if (DynPLTRelRegion.Size) {
OS << "\n'PLT' relocation section at offset "
if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) {
printRelocHeader(ELF::SHT_RELA);
for (const Elf_Rela &Rela : DynPLTRelRegion.getAsArrayRef<Elf_Rela>())
- printDynamicRelocation(Obj, Rela, true);
+ printDynamicRelocation(Obj, Rela);
} else {
printRelocHeader(ELF::SHT_REL);
- for (const Elf_Rel &Rel : DynPLTRelRegion.getAsArrayRef<Elf_Rel>()) {
- Elf_Rela Rela;
- Rela.r_offset = Rel.r_offset;
- Rela.r_info = Rel.r_info;
- Rela.r_addend = 0;
- printDynamicRelocation(Obj, Rela, false);
- }
+ for (const Elf_Rel &Rel : DynPLTRelRegion.getAsArrayRef<Elf_Rel>())
+ printDynamicRelocation(Obj, Rel);
}
}
}
switch (Sec->sh_type) {
case ELF::SHT_REL:
- for (const Elf_Rel &R : unwrapOrError(this->FileName, Obj->rels(Sec))) {
- Elf_Rela Rela;
- Rela.r_offset = R.r_offset;
- Rela.r_info = R.r_info;
- Rela.r_addend = 0;
- printRelocation(Obj, SecNdx, Rela, ++RelNdx, SymTab);
- }
+ for (const Elf_Rel &R : unwrapOrError(this->FileName, Obj->rels(Sec)))
+ printRelocation(Obj, SecNdx, R, ++RelNdx, SymTab);
break;
case ELF::SHT_RELA:
for (const Elf_Rela &R : unwrapOrError(this->FileName, Obj->relas(Sec)))
for (const Elf_Relr &R : Relrs)
W.startLine() << W.hex(R) << "\n";
} else {
- std::vector<Elf_Rela> RelrRelas =
+ std::vector<Elf_Rel> RelrRels =
unwrapOrError(this->FileName, Obj->decode_relrs(Relrs));
- for (const Elf_Rela &R : RelrRelas)
+ for (const Elf_Rel &R : RelrRels)
printRelocation(Obj, SecNdx, R, ++RelNdx, SymTab);
}
break;
}
template <class ELFT>
+template <class RelTy>
void LLVMStyle<ELFT>::printRelocation(const ELFO *Obj, unsigned SecIndex,
- Elf_Rela Rel, unsigned RelIndex,
+ const RelTy &Rel, unsigned RelIndex,
const Elf_Shdr *SymTab) {
Expected<std::pair<const typename ELFT::Sym *, std::string>> Target =
this->dumper()->getRelocationTarget(SymTab, Rel);
SmallString<32> RelocName;
Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
+ uintX_t Addend = getAddend<ELFT>(Rel).getValueOr(0);
if (opts::ExpandRelocs) {
DictScope Group(W, "Relocation");
W.printHex("Offset", Rel.r_offset);
W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
W.printNumber("Symbol", !TargetName.empty() ? TargetName : "-",
Rel.getSymbol(Obj->isMips64EL()));
- W.printHex("Addend", Rel.r_addend);
+ W.printHex("Addend", Addend);
} else {
raw_ostream &OS = W.startLine();
OS << W.hex(Rel.r_offset) << " " << RelocName << " "
- << (!TargetName.empty() ? TargetName : "-") << " " << W.hex(Rel.r_addend)
+ << (!TargetName.empty() ? TargetName : "-") << " " << W.hex(Addend)
<< "\n";
}
}
printDynamicRelocation(Obj, Rela);
}
if (DynRelRegion.Size > 0) {
- for (const Elf_Rel &Rel : this->dumper()->dyn_rels()) {
- Elf_Rela Rela;
- Rela.r_offset = Rel.r_offset;
- Rela.r_info = Rel.r_info;
- Rela.r_addend = 0;
- printDynamicRelocation(Obj, Rela);
- }
+ for (const Elf_Rel &Rel : this->dumper()->dyn_rels())
+ printDynamicRelocation(Obj, Rel);
}
if (DynRelrRegion.Size > 0) {
Elf_Relr_Range Relrs = this->dumper()->dyn_relrs();
- std::vector<Elf_Rela> RelrRelas =
+ std::vector<Elf_Rel> RelrRels =
unwrapOrError(this->FileName, Obj->decode_relrs(Relrs));
- for (const Elf_Rela &Rela : RelrRelas)
- printDynamicRelocation(Obj, Rela);
+ for (const Elf_Rel &R : RelrRels)
+ printDynamicRelocation(Obj, R);
}
if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela))
for (const Elf_Rela &Rela : DynPLTRelRegion.getAsArrayRef<Elf_Rela>())
printDynamicRelocation(Obj, Rela);
else
- for (const Elf_Rel &Rel : DynPLTRelRegion.getAsArrayRef<Elf_Rel>()) {
- Elf_Rela Rela;
- Rela.r_offset = Rel.r_offset;
- Rela.r_info = Rel.r_info;
- Rela.r_addend = 0;
- printDynamicRelocation(Obj, Rela);
- }
+ for (const Elf_Rel &Rel : DynPLTRelRegion.getAsArrayRef<Elf_Rel>())
+ printDynamicRelocation(Obj, Rel);
+
W.unindent();
W.startLine() << "}\n";
}
template <class ELFT>
-void LLVMStyle<ELFT>::printDynamicRelocation(const ELFO *Obj, Elf_Rela Rel) {
+ template <class RelTy>
+void LLVMStyle<ELFT>::printDynamicRelocation(const ELFO *Obj, const RelTy& Rel) {
SmallString<32> RelocName;
Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
std::string SymbolName =
getSymbolForReloc(Obj, this->FileName, this->dumper(), Rel).Name;
+ uintX_t Addend = getAddend<ELFT>(Rel).getValueOr(0);
if (opts::ExpandRelocs) {
DictScope Group(W, "Relocation");
W.printHex("Offset", Rel.r_offset);
W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
W.printString("Symbol", !SymbolName.empty() ? SymbolName : "-");
- W.printHex("Addend", Rel.r_addend);
+ W.printHex("Addend", Addend);
} else {
raw_ostream &OS = W.startLine();
OS << W.hex(Rel.r_offset) << " " << RelocName << " "
- << (!SymbolName.empty() ? SymbolName : "-") << " " << W.hex(Rel.r_addend)
+ << (!SymbolName.empty() ? SymbolName : "-") << " " << W.hex(Addend)
<< "\n";
}
}