7 changes: 7 additions & 0 deletions llvm/lib/MC/MCAsmStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ class MCAsmStreamer final : public MCStreamer {
void EmitCFIUndefined(int64_t Register) override;
void EmitCFIRegister(int64_t Register1, int64_t Register2) override;
void EmitCFIWindowSave() override;
void EmitCFINegateRAState() override;
void EmitCFIReturnColumn(int64_t Register) override;

void EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) override;
Expand Down Expand Up @@ -1564,6 +1565,12 @@ void MCAsmStreamer::EmitCFIWindowSave() {
EmitEOL();
}

void MCAsmStreamer::EmitCFINegateRAState() {
MCStreamer::EmitCFINegateRAState();
OS << "\t.cfi_negate_ra_state";
EmitEOL();
}

void MCAsmStreamer::EmitCFIReturnColumn(int64_t Register) {
MCStreamer::EmitCFIReturnColumn(Register);
OS << "\t.cfi_return_column " << Register;
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/MC/MCDwarf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1332,6 +1332,10 @@ void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) {
Streamer.EmitIntValue(dwarf::DW_CFA_GNU_window_save, 1);
return;

case MCCFIInstruction::OpNegateRAState:
Streamer.EmitIntValue(dwarf::DW_CFA_AARCH64_negate_ra_state, 1);
return;

case MCCFIInstruction::OpUndefined: {
unsigned Reg = Instr.getRegister();
Streamer.EmitIntValue(dwarf::DW_CFA_undefined, 1);
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/MC/MCStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,15 @@ void MCStreamer::EmitCFIWindowSave() {
CurFrame->Instructions.push_back(Instruction);
}

void MCStreamer::EmitCFINegateRAState() {
MCSymbol *Label = EmitCFILabel();
MCCFIInstruction Instruction = MCCFIInstruction::createNegateRAState(Label);
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
return;
CurFrame->Instructions.push_back(Instruction);
}

void MCStreamer::EmitCFIReturnColumn(int64_t Register) {
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
if (!CurFrame)
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,12 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
if (ShouldSignReturnAddress(MF)) {
BuildMI(MBB, MBBI, DL, TII->get(AArch64::PACIASP))
.setMIFlag(MachineInstr::FrameSetup);

unsigned CFIIndex =
MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
.addCFIIndex(CFIIndex)
.setMIFlags(MachineInstr::FrameSetup);
}

// All calls are tail calls in GHC calling conv, and functions have no
Expand Down
10 changes: 10 additions & 0 deletions llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ class AArch64AsmParser : public MCTargetAsmParser {

bool parseDirectiveReq(StringRef Name, SMLoc L);
bool parseDirectiveUnreq(SMLoc L);
bool parseDirectiveCFINegateRAState();

bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
SmallVectorImpl<SMLoc> &Loc);
Expand Down Expand Up @@ -4925,6 +4926,8 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
parseDirectiveUnreq(Loc);
else if (IDVal == ".inst")
parseDirectiveInst(Loc);
else if (IDVal == ".cfi_negate_ra_state")
parseDirectiveCFINegateRAState();
else if (IsMachO) {
if (IDVal == MCLOHDirectiveName())
parseDirectiveLOH(IDVal, Loc);
Expand Down Expand Up @@ -5298,6 +5301,13 @@ bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
return false;
}

bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
return true;
getStreamer().EmitCFINegateRAState();
return false;
}

bool
AArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
AArch64MCExpr::VariantKind &ELFRefKind,
Expand Down
22 changes: 11 additions & 11 deletions llvm/test/CodeGen/AArch64/sign-return-address.ll
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ define i32 @leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf" {
; CHECK-LABEL: @leaf_sign_all
; CHECK: paciasp
; CHECK: autiasp
; CHECK-NEXT: ret
; CHECK: ret
define i32 @leaf_sign_all(i32 %x) "sign-return-address"="all" {
ret i32 %x
}

; CHECK: @leaf_clobbers_lr
; CHECK: paciasp
; CHECK-NEXT: str x30, [sp, #-16]!
; CHECK: str x30, [sp, #-16]!
; CHECK: ldr x30, [sp], #16
; CHECK-NEXT: autiasp
; CHECK-NEXT: ret
; CHECK: ret
define i64 @leaf_clobbers_lr(i64 %x) "sign-return-address"="non-leaf" {
call void asm sideeffect "mov x30, $0", "r,~{lr}"(i64 %x) #1
ret i64 %x
Expand All @@ -45,18 +45,18 @@ declare i32 @foo(i32)
; CHECK: @non_leaf_sign_all
; CHECK: paciasp
; CHECK: autiasp
; CHECK-NEXT: ret
; CHECK: ret
define i32 @non_leaf_sign_all(i32 %x) "sign-return-address"="all" {
%call = call i32 @foo(i32 %x)
ret i32 %call
}

; CHECK: @non_leaf_sign_non_leaf
; CHECK: paciasp
; CHECK-NEXT: str x30, [sp, #-16]!
; CHECK: str x30, [sp, #-16]!
; CHECK: ldr x30, [sp], #16
; CHECK-NEXT: autiasp
; CHECK-NEXT: ret
; CHECK: autiasp
; CHECK: ret
define i32 @non_leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf" {
%call = call i32 @foo(i32 %x)
ret i32 %call
Expand All @@ -65,7 +65,7 @@ define i32 @non_leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf" {
; CHECK-LABEL: @leaf_sign_all_v83
; CHECK: paciasp
; CHECK-NOT: ret
; CHECK-NEXT: retaa
; CHECK: retaa
; CHECK-NOT: ret
define i32 @leaf_sign_all_v83(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" {
ret i32 %x
Expand All @@ -75,10 +75,10 @@ declare fastcc i64 @bar(i64)

; CHECK-LABEL: @spill_lr_and_tail_call
; CHECK: paciasp
; CHECK-NEXT: str x30, [sp, #-16]!
; CHECK: str x30, [sp, #-16]!
; CHECK: ldr x30, [sp], #16
; CHECK-NEXT: autiasp
; CHECK-NEXT: b bar
; CHECK: autiasp
; CHECK: b bar
define fastcc void @spill_lr_and_tail_call(i64 %x) "sign-return-address"="all" {
call void asm sideeffect "mov x30, $0", "r,~{lr}"(i64 %x) #1
tail call fastcc i64 @bar(i64 %x)
Expand Down
2 changes: 2 additions & 0 deletions llvm/test/CodeGen/MIR/AArch64/cfi.mir
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,6 @@ body: |
; CHECK: CFI_INSTRUCTION escape 0x61, 0x62, 0x63
CFI_INSTRUCTION window_save
; CHECK: CFI_INSTRUCTION window_save
CFI_INSTRUCTION negate_ra_sign_state
; CHECK: CFI_INSTRUCTION negate_ra_sign_state
RET_ReallyLR
2 changes: 1 addition & 1 deletion llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ bool collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,

static bool dumpObjectFile(ObjectFile &Obj, DWARFContext &DICtx, Twine Filename,
raw_ostream &OS) {
logAllUnhandledErrors(DICtx.loadRegisterInfo(Obj), errs(),
logAllUnhandledErrors(DICtx.loadArchitectureInfo(Obj), errs(),
Filename.str() + ": ");
// The UUID dump already contains all the same information.
if (!(DumpType & DIDT_UUID) || DumpType == DIDT_All)
Expand Down
13 changes: 9 additions & 4 deletions llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Object/ELF.h"
#include "llvm/Object/ELFTypes.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/Debug.h"
Expand All @@ -31,15 +32,15 @@ namespace DwarfCFIEH {
template <typename ELFT>
class PrinterContext {
ScopedPrinter &W;
const object::ELFFile<ELFT> *Obj;
const object::ELFObjectFile<ELFT> *ObjF;

void printEHFrameHdr(uint64_t Offset, uint64_t Address, uint64_t Size) const;

void printEHFrame(const typename ELFT::Shdr *EHFrameShdr) const;

public:
PrinterContext(ScopedPrinter &W, const object::ELFFile<ELFT> *Obj)
: W(W), Obj(Obj) {}
PrinterContext(ScopedPrinter &W, const object::ELFObjectFile<ELFT> *ObjF)
: W(W), ObjF(ObjF) {}

void printUnwindInformation() const;
};
Expand All @@ -59,6 +60,7 @@ static const typename ELFO::Elf_Shdr *findSectionByAddress(const ELFO *Obj,

template <typename ELFT>
void PrinterContext<ELFT>::printUnwindInformation() const {
const object::ELFFile<ELFT> *Obj = ObjF->getELFFile();
const typename ELFT::Phdr *EHFramePhdr = nullptr;

auto PHs = Obj->program_headers();
Expand Down Expand Up @@ -101,6 +103,7 @@ void PrinterContext<ELFT>::printEHFrameHdr(uint64_t EHFrameHdrOffset,
W.startLine() << format("Offset: 0x%" PRIx64 "\n", EHFrameHdrOffset);
W.startLine() << format("Size: 0x%" PRIx64 "\n", EHFrameHdrSize);

const object::ELFFile<ELFT> *Obj = ObjF->getELFFile();
const auto *EHFrameHdrShdr = findSectionByAddress(Obj, EHFrameHdrAddress);
if (EHFrameHdrShdr) {
auto SectionName = Obj->getSectionName(EHFrameHdrShdr);
Expand Down Expand Up @@ -173,6 +176,7 @@ void PrinterContext<ELFT>::printEHFrame(
ShOffset, Address);
W.indent();

const object::ELFFile<ELFT> *Obj = ObjF->getELFFile();
auto Result = Obj->getSectionContents(EHFrameShdr);
if (Error E = Result.takeError())
reportError(toString(std::move(E)));
Expand All @@ -183,7 +187,8 @@ void PrinterContext<ELFT>::printEHFrame(
Contents.size()),
ELFT::TargetEndianness == support::endianness::little,
ELFT::Is64Bits ? 8 : 4);
DWARFDebugFrame EHFrame(/*IsEH=*/true, /*EHFrameAddress=*/Address);
DWARFDebugFrame EHFrame(Triple::ArchType(ObjF->getArch()), /*IsEH=*/true,
/*EHFrameAddress=*/Address);
EHFrame.parse(DE);

for (const auto &Entry : EHFrame) {
Expand Down
81 changes: 47 additions & 34 deletions llvm/tools/llvm-readobj/ELFDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ struct DynRegionInfo {
template<typename ELFT>
class ELFDumper : public ObjDumper {
public:
ELFDumper(const ELFFile<ELFT> *Obj, ScopedPrinter &Writer);
ELFDumper(const object::ELFObjectFile<ELFT> *ObjF, ScopedPrinter &Writer);

void printFileHeaders() override;
void printSections() override;
Expand Down Expand Up @@ -181,18 +181,19 @@ class ELFDumper : public ObjDumper {
TYPEDEF_ELF_TYPES(ELFT)

DynRegionInfo checkDRI(DynRegionInfo DRI) {
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
if (DRI.Addr < Obj->base() ||
(const uint8_t *)DRI.Addr + DRI.Size > Obj->base() + Obj->getBufSize())
error(llvm::object::object_error::parse_failed);
return DRI;
}

DynRegionInfo createDRIFrom(const Elf_Phdr *P, uintX_t EntSize) {
return checkDRI({Obj->base() + P->p_offset, P->p_filesz, EntSize});
return checkDRI({ObjF->getELFFile()->base() + P->p_offset, P->p_filesz, EntSize});
}

DynRegionInfo createDRIFrom(const Elf_Shdr *S) {
return checkDRI({Obj->base() + S->sh_offset, S->sh_size, S->sh_entsize});
return checkDRI({ObjF->getELFFile()->base() + S->sh_offset, S->sh_size, S->sh_entsize});
}

void parseDynamicTable(ArrayRef<const Elf_Phdr *> LoadSegments);
Expand All @@ -206,7 +207,7 @@ class ELFDumper : public ObjDumper {
void LoadVersionNeeds(const Elf_Shdr *ec) const;
void LoadVersionDefs(const Elf_Shdr *sec) const;

const ELFO *Obj;
const object::ELFObjectFile<ELFT> *ObjF;
DynRegionInfo DynRelRegion;
DynRegionInfo DynRelaRegion;
DynRegionInfo DynRelrRegion;
Expand Down Expand Up @@ -289,6 +290,7 @@ void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic) const {
StringRef StrTable, SymtabName;
size_t Entries = 0;
Elf_Sym_Range Syms(nullptr, nullptr);
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
if (IsDynamic) {
StrTable = DynamicStringTable;
Syms = dynamic_symbols();
Expand Down Expand Up @@ -451,7 +453,7 @@ template <typename ELFT> class LLVMStyle : public DumpStyle<ELFT> {
namespace llvm {

template <class ELFT>
static std::error_code createELFDumper(const ELFFile<ELFT> *Obj,
static std::error_code createELFDumper(const ELFObjectFile<ELFT> *Obj,
ScopedPrinter &Writer,
std::unique_ptr<ObjDumper> &Result) {
Result.reset(new ELFDumper<ELFT>(Obj, Writer));
Expand All @@ -463,19 +465,19 @@ std::error_code createELFDumper(const object::ObjectFile *Obj,
std::unique_ptr<ObjDumper> &Result) {
// Little-endian 32-bit
if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
return createELFDumper(ELFObj->getELFFile(), Writer, Result);
return createELFDumper(ELFObj, Writer, Result);

// Big-endian 32-bit
if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
return createELFDumper(ELFObj->getELFFile(), Writer, Result);
return createELFDumper(ELFObj, Writer, Result);

// Little-endian 64-bit
if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
return createELFDumper(ELFObj->getELFFile(), Writer, Result);
return createELFDumper(ELFObj, Writer, Result);

// Big-endian 64-bit
if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
return createELFDumper(ELFObj->getELFFile(), Writer, Result);
return createELFDumper(ELFObj, Writer, Result);

return readobj_error::unsupported_obj_file_format;
}
Expand All @@ -488,7 +490,7 @@ template <class ELFT>
void ELFDumper<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const {
unsigned vn_size = sec->sh_size; // Size of section in bytes
unsigned vn_count = sec->sh_info; // Number of Verneed entries
const char *sec_start = (const char *)Obj->base() + sec->sh_offset;
const char *sec_start = (const char *)ObjF->getELFFile()->base() + sec->sh_offset;
const char *sec_end = sec_start + vn_size;
// The first Verneed entry is at the start of the section.
const char *p = sec_start;
Expand Down Expand Up @@ -522,7 +524,7 @@ template <class ELFT>
void ELFDumper<ELFT>::LoadVersionDefs(const Elf_Shdr *sec) const {
unsigned vd_size = sec->sh_size; // Size of section in bytes
unsigned vd_count = sec->sh_info; // Number of Verdef entries
const char *sec_start = (const char *)Obj->base() + sec->sh_offset;
const char *sec_start = (const char *)ObjF->getELFFile()->base() + sec->sh_offset;
const char *sec_end = sec_start + vd_size;
// The first Verdef entry is at the start of the section.
const char *p = sec_start;
Expand Down Expand Up @@ -700,13 +702,13 @@ static void printVersionDependencySection(ELFDumper<ELFT> *Dumper,

template <typename ELFT> void ELFDumper<ELFT>::printVersionInfo() {
// Dump version symbol section.
printVersionSymbolSection(this, Obj, dot_gnu_version_sec, W);
printVersionSymbolSection(this, ObjF->getELFFile(), dot_gnu_version_sec, W);

// Dump version definition section.
printVersionDefinitionSection(this, Obj, dot_gnu_version_d_sec, W);
printVersionDefinitionSection(this, ObjF->getELFFile(), dot_gnu_version_d_sec, W);

// Dump version dependency section.
printVersionDependencySection(this, Obj, dot_gnu_version_r_sec, W);
printVersionDependencySection(this, ObjF->getELFFile(), dot_gnu_version_r_sec, W);
}

template <typename ELFT>
Expand All @@ -727,7 +729,7 @@ StringRef ELFDumper<ELFT>::getSymbolVersion(StringRef StrTab,

// Get the corresponding version index entry
const Elf_Versym *vs = unwrapOrError(
Obj->template getEntry<Elf_Versym>(dot_gnu_version_sec, entry_index));
ObjF->getELFFile()->template getEntry<Elf_Versym>(dot_gnu_version_sec, entry_index));
size_t version_index = vs->vs_index & ELF::VERSYM_VERSION;

// Special markers for unversioned symbols.
Expand Down Expand Up @@ -760,6 +762,7 @@ StringRef ELFDumper<ELFT>::getSymbolVersion(StringRef StrTab,

template <typename ELFT>
StringRef ELFDumper<ELFT>::getStaticSymbolName(uint32_t Index) const {
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*DotSymtabSec));
Elf_Sym_Range Syms = unwrapOrError(Obj->symbols(DotSymtabSec));
if (Index >= Syms.size())
Expand Down Expand Up @@ -807,6 +810,7 @@ void ELFDumper<ELFT>::getSectionNameIndex(const Elf_Sym *Symbol,
if (SectionIndex == SHN_XINDEX)
SectionIndex = unwrapOrError(object::getExtendedSymbolTableIndex<ELFT>(
Symbol, FirstSym, ShndxTable));
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
const typename ELFT::Shdr *Sec =
unwrapOrError(Obj->getSection(SectionIndex));
SectionName = unwrapOrError(Obj->getSectionName(Sec));
Expand Down Expand Up @@ -1375,9 +1379,11 @@ static const char *getElfMipsOptionsOdkType(unsigned Odk) {
}

template <typename ELFT>
ELFDumper<ELFT>::ELFDumper(const ELFFile<ELFT> *Obj, ScopedPrinter &Writer)
: ObjDumper(Writer), Obj(Obj) {
ELFDumper<ELFT>::ELFDumper(const object::ELFObjectFile<ELFT> *ObjF,
ScopedPrinter &Writer)
: ObjDumper(Writer), ObjF(ObjF) {
SmallVector<const Elf_Phdr *, 4> LoadSegments;
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
for (const Elf_Phdr &Phdr : unwrapOrError(Obj->program_headers())) {
if (Phdr.p_type == ELF::PT_DYNAMIC) {
DynamicTable = createDRIFrom(&Phdr, sizeof(Elf_Dyn));
Expand Down Expand Up @@ -1458,7 +1464,7 @@ void ELFDumper<ELFT>::parseDynamicTable(
uint64_t Delta = VAddr - Phdr.p_vaddr;
if (Delta >= Phdr.p_filesz)
report_fatal_error("Virtual address is not in any segment");
return Obj->base() + Phdr.p_offset + Delta;
return ObjF->getELFFile()->base() + Phdr.p_offset + Delta;
};

uint64_t SONameOffset = 0;
Expand Down Expand Up @@ -1557,51 +1563,51 @@ typename ELFDumper<ELFT>::Elf_Relr_Range ELFDumper<ELFT>::dyn_relrs() const {

template<class ELFT>
void ELFDumper<ELFT>::printFileHeaders() {
ELFDumperStyle->printFileHeaders(Obj);
ELFDumperStyle->printFileHeaders(ObjF->getELFFile());
}

template<class ELFT>
void ELFDumper<ELFT>::printSections() {
ELFDumperStyle->printSections(Obj);
ELFDumperStyle->printSections(ObjF->getELFFile());
}

template<class ELFT>
void ELFDumper<ELFT>::printRelocations() {
ELFDumperStyle->printRelocations(Obj);
ELFDumperStyle->printRelocations(ObjF->getELFFile());
}

template <class ELFT> void ELFDumper<ELFT>::printProgramHeaders() {
ELFDumperStyle->printProgramHeaders(Obj);
ELFDumperStyle->printProgramHeaders(ObjF->getELFFile());
}

template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocations() {
ELFDumperStyle->printDynamicRelocations(Obj);
ELFDumperStyle->printDynamicRelocations(ObjF->getELFFile());
}

template<class ELFT>
void ELFDumper<ELFT>::printSymbols() {
ELFDumperStyle->printSymbols(Obj);
ELFDumperStyle->printSymbols(ObjF->getELFFile());
}

template<class ELFT>
void ELFDumper<ELFT>::printDynamicSymbols() {
ELFDumperStyle->printDynamicSymbols(Obj);
ELFDumperStyle->printDynamicSymbols(ObjF->getELFFile());
}

template <class ELFT> void ELFDumper<ELFT>::printHashHistogram() {
ELFDumperStyle->printHashHistogram(Obj);
ELFDumperStyle->printHashHistogram(ObjF->getELFFile());
}

template <class ELFT> void ELFDumper<ELFT>::printCGProfile() {
ELFDumperStyle->printCGProfile(Obj);
ELFDumperStyle->printCGProfile(ObjF->getELFFile());
}

template <class ELFT> void ELFDumper<ELFT>::printNotes() {
ELFDumperStyle->printNotes(Obj);
ELFDumperStyle->printNotes(ObjF->getELFFile());
}

template <class ELFT> void ELFDumper<ELFT>::printELFLinkerOptions() {
ELFDumperStyle->printELFLinkerOptions(Obj);
ELFDumperStyle->printELFLinkerOptions(ObjF->getELFFile());
}

static const char *getTypeString(unsigned Arch, uint64_t Type) {
Expand Down Expand Up @@ -1842,9 +1848,9 @@ void ELFDumper<ELFT>::printValue(uint64_t Type, uint64_t Value) {

template<class ELFT>
void ELFDumper<ELFT>::printUnwindInfo() {
const unsigned Machine = Obj->getHeader()->e_machine;
const unsigned Machine = ObjF->getELFFile()->getHeader()->e_machine;
if (Machine == EM_386 || Machine == EM_X86_64) {
DwarfCFIEH::PrinterContext<ELFT> Ctx(W, Obj);
DwarfCFIEH::PrinterContext<ELFT> Ctx(W, ObjF);
return Ctx.printUnwindInformation();
}
W.startLine() << "UnwindInfo not implemented.\n";
Expand All @@ -1853,6 +1859,7 @@ void ELFDumper<ELFT>::printUnwindInfo() {
namespace {

template <> void ELFDumper<ELF32LE>::printUnwindInfo() {
const ELFFile<ELF32LE> *Obj = ObjF->getELFFile();
const unsigned Machine = Obj->getHeader()->e_machine;
if (Machine == EM_ARM) {
ARM::EHABI::PrinterContext<ELF32LE> Ctx(W, Obj, DotSymtabSec);
Expand Down Expand Up @@ -1895,7 +1902,7 @@ void ELFDumper<ELFT>::printDynamicTable() {
uintX_t Tag = Entry.getTag();
++I;
W.startLine() << " " << format_hex(Tag, Is64 ? 18 : 10, opts::Output != opts::GNU) << " "
<< format("%-21s", getTypeString(Obj->getHeader()->e_machine, Tag));
<< format("%-21s", getTypeString(ObjF->getELFFile()->getHeader()->e_machine, Tag));
printValue(Tag, Entry.getVal());
OS << "\n";
}
Expand Down Expand Up @@ -1962,6 +1969,7 @@ void ELFDumper<ELFT>::printAttributes() {
namespace {

template <> void ELFDumper<ELF32LE>::printAttributes() {
const ELFFile<ELF32LE> *Obj = ObjF->getELFFile();
if (Obj->getHeader()->e_machine != EM_ARM) {
W.startLine() << "Attributes not implemented.\n";
return;
Expand Down Expand Up @@ -2247,6 +2255,7 @@ MipsGOTParser<ELFT>::getPltSym(const Entry *E) const {
}

template <class ELFT> void ELFDumper<ELFT>::printMipsPLTGOT() {
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
if (Obj->getHeader()->e_machine != EM_MIPS)
reportError("MIPS PLT GOT is available for MIPS targets only");

Expand Down Expand Up @@ -2331,6 +2340,7 @@ static int getMipsRegisterSize(uint8_t Flag) {
}

template <class ELFT> void ELFDumper<ELFT>::printMipsABIFlags() {
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
const Elf_Shdr *Shdr = findSectionByName(*Obj, ".MIPS.abiflags");
if (!Shdr) {
W.startLine() << "There is no .MIPS.abiflags section in the file.\n";
Expand Down Expand Up @@ -2376,6 +2386,7 @@ static void printMipsReginfoData(ScopedPrinter &W,
}

template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() {
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
const Elf_Shdr *Shdr = findSectionByName(*Obj, ".reginfo");
if (!Shdr) {
W.startLine() << "There is no .reginfo section in the file.\n";
Expand All @@ -2393,6 +2404,7 @@ template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() {
}

template <class ELFT> void ELFDumper<ELFT>::printMipsOptions() {
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
const Elf_Shdr *Shdr = findSectionByName(*Obj, ".MIPS.options");
if (!Shdr) {
W.startLine() << "There is no .MIPS.options section in the file.\n";
Expand Down Expand Up @@ -2422,6 +2434,7 @@ template <class ELFT> void ELFDumper<ELFT>::printMipsOptions() {
}

template <class ELFT> void ELFDumper<ELFT>::printStackMap() const {
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
const Elf_Shdr *StackMapSection = nullptr;
for (const auto &Sec : unwrapOrError(Obj->sections())) {
StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
Expand All @@ -2442,11 +2455,11 @@ template <class ELFT> void ELFDumper<ELFT>::printStackMap() const {
}

template <class ELFT> void ELFDumper<ELFT>::printGroupSections() {
ELFDumperStyle->printGroupSections(Obj);
ELFDumperStyle->printGroupSections(ObjF->getELFFile());
}

template <class ELFT> void ELFDumper<ELFT>::printAddrsig() {
ELFDumperStyle->printAddrsig(Obj);
ELFDumperStyle->printAddrsig(ObjF->getELFFile());
}

static inline void printFields(formatted_raw_ostream &OS, StringRef Str1,
Expand Down