This caused the DebugInfo/Sparc/gnu-window-save.ll test to fail.
> Functions that have signed return addresses need additional dwarf support:
> - After signing the LR, and before authenticating it, the LR register is in a
> state the is unusable by a debugger or unwinder
> - To account for this a new directive, .cfi_negate_ra_state, is added
> - This directive says the signed state of the LR register has now changed,
> i.e. unsigned -> signed or signed -> unsigned
> - This directive has the same CFA code as the SPARC directive GNU_window_save
> (0x2d), adding a macro to account for multiply defined codes
> - This patch matches the gcc implementation of this support:
> https://patchwork.ozlabs.org/patch/800271/
>
> Differential Revision: https://reviews.llvm.org/D50136
llvm-svn: 343103
defined HANDLE_DW_VIRTUALITY || defined HANDLE_DW_DEFAULTED || \
defined HANDLE_DW_CC || defined HANDLE_DW_LNS || defined HANDLE_DW_LNE || \
defined HANDLE_DW_LNCT || defined HANDLE_DW_MACRO || \
- defined HANDLE_DW_RLE || \
- (defined HANDLE_DW_CFA && defined HANDLE_DW_CFA_PRED) || \
+ defined HANDLE_DW_RLE || defined HANDLE_DW_CFA || \
defined HANDLE_DW_APPLE_PROPERTY || defined HANDLE_DW_UT || \
defined HANDLE_DWARF_SECTION || defined HANDLE_DW_IDX || \
defined HANDLE_DW_END)
#define HANDLE_DW_CFA(ID, NAME)
#endif
-#ifndef HANDLE_DW_CFA_PRED
-#define HANDLE_DW_CFA_PRED(ID, NAME, PRED)
-#endif
-
#ifndef HANDLE_DW_APPLE_PROPERTY
#define HANDLE_DW_APPLE_PROPERTY(ID, NAME)
#endif
HANDLE_DW_CFA(0x15, val_offset_sf)
HANDLE_DW_CFA(0x16, val_expression)
// Vendor extensions:
-HANDLE_DW_CFA_PRED(0x1d, MIPS_advance_loc8, SELECT_MIPS64)
-HANDLE_DW_CFA_PRED(0x2d, GNU_window_save, SELECT_SPARC64)
-HANDLE_DW_CFA_PRED(0x2d, AARCH64_negate_ra_state, SELECT_AARCH64)
-HANDLE_DW_CFA_PRED(0x2e, GNU_args_size, SELECT_X86)
+HANDLE_DW_CFA(0x1d, MIPS_advance_loc8)
+HANDLE_DW_CFA(0x2d, GNU_window_save)
+HANDLE_DW_CFA(0x2e, GNU_args_size)
// Apple Objective-C Property Attributes.
// Keep this list in sync with clang's DeclSpec.h ObjCPropertyAttributeKind!
#undef HANDLE_DW_MACRO
#undef HANDLE_DW_RLE
#undef HANDLE_DW_CFA
-#undef HANDLE_DW_CFA_PRED
#undef HANDLE_DW_APPLE_PROPERTY
#undef HANDLE_DW_UT
#undef HANDLE_DWARF_SECTION
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadicDetails.h"
-#include "llvm/ADT/Triple.h"
namespace llvm {
class StringRef;
/// Call frame instruction encodings.
enum CallFrameInfo {
#define HANDLE_DW_CFA(ID, NAME) DW_CFA_##NAME = ID,
-#define HANDLE_DW_CFA_PRED(ID, NAME, ARCH) DW_CFA_##NAME = ID,
#include "llvm/BinaryFormat/Dwarf.def"
DW_CFA_extended = 0x00,
StringRef LNExtendedString(unsigned Encoding);
StringRef MacinfoString(unsigned Encoding);
StringRef RangeListEncodingString(unsigned Encoding);
-StringRef CallFrameString(unsigned Encoding, Triple::ArchType Arch);
+StringRef CallFrameString(unsigned Encoding);
StringRef ApplePropertyString(unsigned);
StringRef UnitTypeString(unsigned);
StringRef AtomTypeString(unsigned Atom);
bool CheckedForDWP = false;
std::string DWPName;
- Triple::ArchType Arch;
std::unique_ptr<MCRegisterInfo> RegInfo;
/// Read compile units from the debug_info section (if necessary)
/// Loads register info for the architecture of the provided object file.
/// Improves readability of dumped DWARF expressions. Requires the caller to
/// have initialized the relevant target descriptions.
- Error loadArchitectureInfo(const object::ObjectFile &Obj);
+ Error loadRegisterInfo(const object::ObjectFile &Obj);
/// Get address size from CUs.
/// TODO: refactor compile_units() to make this const.
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
#include "llvm/Support/Error.h"
unsigned size() const { return (unsigned)Instructions.size(); }
bool empty() const { return Instructions.empty(); }
- CFIProgram(uint64_t CodeAlignmentFactor, int64_t DataAlignmentFactor,
- Triple::ArchType Arch)
+ CFIProgram(uint64_t CodeAlignmentFactor, int64_t DataAlignmentFactor)
: CodeAlignmentFactor(CodeAlignmentFactor),
- DataAlignmentFactor(DataAlignmentFactor),
- Arch(Arch) {}
+ DataAlignmentFactor(DataAlignmentFactor) {}
/// Parse and store a sequence of CFI instructions from Data,
/// starting at *Offset and ending at EndOffset. *Offset is updated
std::vector<Instruction> Instructions;
const uint64_t CodeAlignmentFactor;
const int64_t DataAlignmentFactor;
- Triple::ArchType Arch;
/// Convenience method to add a new instruction with the given opcode.
void addInstruction(uint8_t Opcode) {
enum FrameKind { FK_CIE, FK_FDE };
FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length, uint64_t CodeAlign,
- int64_t DataAlign, Triple::ArchType Arch)
- : Kind(K), Offset(Offset), Length(Length),
- CFIs(CodeAlign, DataAlign, Arch) {}
+ int64_t DataAlign)
+ : Kind(K), Offset(Offset), Length(Length), CFIs(CodeAlign, DataAlign) {}
virtual ~FrameEntry() {}
int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister,
SmallString<8> AugmentationData, uint32_t FDEPointerEncoding,
uint32_t LSDAPointerEncoding, Optional<uint64_t> Personality,
- Optional<uint32_t> PersonalityEnc, Triple::ArchType Arch)
+ Optional<uint32_t> PersonalityEnc)
: FrameEntry(FK_CIE, Offset, Length, CodeAlignmentFactor,
- DataAlignmentFactor, Arch),
+ DataAlignmentFactor),
Version(Version), Augmentation(std::move(Augmentation)),
AddressSize(AddressSize), SegmentDescriptorSize(SegmentDescriptorSize),
CodeAlignmentFactor(CodeAlignmentFactor),
// is obtained lazily once it's actually required.
FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset,
uint64_t InitialLocation, uint64_t AddressRange, CIE *Cie,
- Optional<uint64_t> LSDAAddress, Triple::ArchType Arch)
+ Optional<uint64_t> LSDAAddress)
: FrameEntry(FK_FDE, Offset, Length,
Cie ? Cie->getCodeAlignmentFactor() : 0,
- Cie ? Cie->getDataAlignmentFactor() : 0,
- Arch),
+ Cie ? Cie->getDataAlignmentFactor() : 0),
LinkedCIEOffset(LinkedCIEOffset), InitialLocation(InitialLocation),
AddressRange(AddressRange), LinkedCIE(Cie), LSDAAddress(LSDAAddress) {}
/// A parsed .debug_frame or .eh_frame section
class DWARFDebugFrame {
- const Triple::ArchType Arch;
// True if this is parsing an eh_frame section.
const bool IsEH;
// Not zero for sane pointer values coming out of eh_frame
// it is a .debug_frame section. EHFrameAddress should be different
// than zero for correct parsing of .eh_frame addresses when they
// use a PC-relative encoding.
- DWARFDebugFrame(Triple::ArchType Arch,
- bool IsEH = false, uint64_t EHFrameAddress = 0);
+ DWARFDebugFrame(bool IsEH = false, uint64_t EHFrameAddress = 0);
~DWARFDebugFrame();
/// Dump the section data into the given stream.
OpUndefined,
OpRegister,
OpWindowSave,
- OpNegateRAState,
OpGnuArgsSize
};
return MCCFIInstruction(OpWindowSave, L, 0, 0, "");
}
- /// .cfi_negate_ra_state AArch64 negate RA state.
- static MCCFIInstruction createNegateRAState(MCSymbol *L) {
- return MCCFIInstruction(OpNegateRAState, L, 0, 0, "");
- }
-
/// .cfi_restore says that the rule for Register is now the same as it
/// was at the beginning of the function, after all initial instructions added
/// by .cfi_startproc were executed.
virtual void EmitCFIUndefined(int64_t Register);
virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
virtual void EmitCFIWindowSave();
- virtual void EmitCFINegateRAState();
virtual void EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc = SMLoc());
virtual void EmitWinCFIEndProc(SMLoc Loc = SMLoc());
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
}
}
-StringRef llvm::dwarf::CallFrameString(unsigned Encoding,
- Triple::ArchType Arch) {
-#define SELECT_AARCH64 (Arch == llvm::Triple::aarch64_be || Arch == llvm::Triple::aarch64)
-#define SELECT_MIPS64 Arch == llvm::Triple::mips64
-#define SELECT_SPARC64 Arch == llvm::Triple::sparcv9
-#define SELECT_X86 (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64)
-#define HANDLE_DW_CFA(ID, NAME)
-#define HANDLE_DW_CFA_PRED(ID, NAME, PRED) \
- if (ID == Encoding && PRED) \
- return "DW_CFA_" #NAME;
-#include "llvm/BinaryFormat/Dwarf.def"
-
+StringRef llvm::dwarf::CallFrameString(unsigned Encoding) {
switch (Encoding) {
default:
return StringRef();
-#define HANDLE_DW_CFA_PRED(ID, NAME, PRED)
#define HANDLE_DW_CFA(ID, NAME) \
case DW_CFA_##NAME: \
return "DW_CFA_" #NAME;
#include "llvm/BinaryFormat/Dwarf.def"
-
-#undef SELECT_X86
-#undef SELECT_SPARC64
-#undef SELECT_MIPS64
-#undef SELECT_AARCH64
}
}
case MCCFIInstruction::OpWindowSave:
OutStreamer->EmitCFIWindowSave();
break;
- case MCCFIInstruction::OpNegateRAState:
- OutStreamer->EmitCFINegateRAState();
- break;
case MCCFIInstruction::OpSameValue:
OutStreamer->EmitCFISameValue(Inst.getRegister());
break;
case MCCFIInstruction::OpUndefined:
case MCCFIInstruction::OpRegister:
case MCCFIInstruction::OpWindowSave:
- case MCCFIInstruction::OpNegateRAState:
case MCCFIInstruction::OpGnuArgsSize:
break;
}
.Case("undefined", MIToken::kw_cfi_undefined)
.Case("register", MIToken::kw_cfi_register)
.Case("window_save", MIToken::kw_cfi_window_save)
- .Case("negate_ra_sign_state", MIToken::kw_cfi_aarch64_negate_ra_sign_state)
.Case("blockaddress", MIToken::kw_blockaddress)
.Case("intrinsic", MIToken::kw_intrinsic)
.Case("target-index", MIToken::kw_target_index)
kw_cfi_restore_state,
kw_cfi_undefined,
kw_cfi_window_save,
- kw_cfi_aarch64_negate_ra_sign_state,
kw_blockaddress,
kw_intrinsic,
kw_target_index,
case MIToken::kw_cfi_window_save:
CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr));
break;
- case MIToken::kw_cfi_aarch64_negate_ra_sign_state:
- CFIIndex = MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
- break;
case MIToken::kw_cfi_escape: {
std::string Values;
if (parseCFIEscapeValues(Values))
case MIToken::kw_cfi_restore_state:
case MIToken::kw_cfi_undefined:
case MIToken::kw_cfi_window_save:
- case MIToken::kw_cfi_aarch64_negate_ra_sign_state:
return parseCFIOperand(Dest);
case MIToken::kw_blockaddress:
return parseBlockAddressOperand(Dest);
if (MCSymbol *Label = CFI.getLabel())
MachineOperand::printSymbol(OS, *Label);
break;
- case MCCFIInstruction::OpNegateRAState:
- OS << "negate_ra_sign_state ";
- if (MCSymbol *Label = CFI.getLabel())
- MachineOperand::printSymbol(OS, *Label);
- break;
default:
// TODO: Print the other CFI Operations.
OS << "<unserializable cfi directive>";
// http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
DWARFDataExtractor debugFrameData(DObj->getDebugFrameSection(),
isLittleEndian(), DObj->getAddressSize());
- DebugFrame.reset(new DWARFDebugFrame(Arch, false /* IsEH */));
+ DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
DebugFrame->parse(debugFrameData);
return DebugFrame.get();
}
DWARFDataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
DObj->getAddressSize());
- DebugFrame.reset(new DWARFDebugFrame(Arch, true /* IsEH */));
+ DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
DebugFrame->parse(debugFrameData);
return DebugFrame.get();
}
return llvm::make_unique<DWARFContext>(std::move(DObj), "");
}
-Error DWARFContext::loadArchitectureInfo(const object::ObjectFile &Obj) {
+Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) {
// Detect the architecture from the object file. We usually don't need OS
// info to lookup a target and create register info.
- Arch = Triple::ArchType(Obj.getArch());
-
Triple TT;
TT.setArch(Triple::ArchType(Obj.getArch()));
TT.setVendor(Triple::UnknownVendor);
switch (Type) {
case OT_Unset: {
OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to";
- auto OpcodeName = CallFrameString(Opcode, Arch);
+ auto OpcodeName = CallFrameString(Opcode);
if (!OpcodeName.empty())
OS << " " << OpcodeName;
else
if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)
Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;
OS.indent(2 * IndentLevel);
- OS << CallFrameString(Opcode, Arch) << ":";
+ OS << CallFrameString(Opcode) << ":";
for (unsigned i = 0; i < Instr.Ops.size(); ++i)
printOperand(OS, MRI, IsEH, Instr, i, Instr.Ops[i]);
OS << '\n';
OS << "\n";
}
-DWARFDebugFrame::DWARFDebugFrame(Triple::ArchType Arch,
- bool IsEH, uint64_t EHFrameAddress)
- : Arch(Arch), IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
+DWARFDebugFrame::DWARFDebugFrame(bool IsEH, uint64_t EHFrameAddress)
+ : IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
DWARFDebugFrame::~DWARFDebugFrame() = default;
StartOffset, Length, Version, AugmentationString, AddressSize,
SegmentDescriptorSize, CodeAlignmentFactor, DataAlignmentFactor,
ReturnAddressRegister, AugmentationData, FDEPointerEncoding,
- LSDAPointerEncoding, Personality, PersonalityEncoding, Arch);
+ LSDAPointerEncoding, Personality, PersonalityEncoding);
CIEs[StartOffset] = Cie.get();
Entries.emplace_back(std::move(Cie));
} else {
Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
InitialLocation, AddressRange,
- Cie, LSDAAddress, Arch));
+ Cie, LSDAAddress));
}
if (Error E =
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;
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;
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);
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)
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
bool parseDirectiveReq(StringRef Name, SMLoc L);
bool parseDirectiveUnreq(SMLoc L);
- bool parseDirectiveCFINegateRAState();
bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
SmallVectorImpl<SMLoc> &Loc);
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);
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,
; CHECK-LABEL: @leaf_sign_all
; CHECK: paciasp
; CHECK: autiasp
-; CHECK: ret
+; CHECK-NEXT: ret
define i32 @leaf_sign_all(i32 %x) "sign-return-address"="all" {
ret i32 %x
}
; CHECK: @leaf_clobbers_lr
; CHECK: paciasp
-; CHECK: str x30, [sp, #-16]!
+; CHECK-NEXT: str x30, [sp, #-16]!
; CHECK: ldr x30, [sp], #16
; CHECK-NEXT: autiasp
-; CHECK: ret
+; CHECK-NEXT: 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
; CHECK: @non_leaf_sign_all
; CHECK: paciasp
; CHECK: autiasp
-; CHECK: ret
+; CHECK-NEXT: 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: str x30, [sp, #-16]!
+; CHECK-NEXT: str x30, [sp, #-16]!
; CHECK: ldr x30, [sp], #16
-; CHECK: autiasp
-; CHECK: ret
+; CHECK-NEXT: autiasp
+; CHECK-NEXT: ret
define i32 @non_leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf" {
%call = call i32 @foo(i32 %x)
ret i32 %call
; CHECK-LABEL: @leaf_sign_all_v83
; CHECK: paciasp
; CHECK-NOT: ret
-; CHECK: retaa
+; CHECK-NEXT: retaa
; CHECK-NOT: ret
define i32 @leaf_sign_all_v83(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" {
ret i32 %x
; CHECK-LABEL: @spill_lr_and_tail_call
; CHECK: paciasp
-; CHECK: str x30, [sp, #-16]!
+; CHECK-NEXT: str x30, [sp, #-16]!
; CHECK: ldr x30, [sp], #16
-; CHECK: autiasp
-; CHECK: b bar
+; CHECK-NEXT: autiasp
+; CHECK-NEXT: 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)
; 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
static bool dumpObjectFile(ObjectFile &Obj, DWARFContext &DICtx, Twine Filename,
raw_ostream &OS) {
- logAllUnhandledErrors(DICtx.loadArchitectureInfo(Obj), errs(),
+ logAllUnhandledErrors(DICtx.loadRegisterInfo(Obj), errs(),
Filename.str() + ": ");
// The UUID dump already contains all the same information.
if (!(DumpType & DIDT_UUID) || DumpType == DIDT_All)
#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"
template <typename ELFT>
class PrinterContext {
ScopedPrinter &W;
- const object::ELFObjectFile<ELFT> *ObjF;
+ const object::ELFFile<ELFT> *Obj;
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::ELFObjectFile<ELFT> *ObjF)
- : W(W), ObjF(ObjF) {}
+ PrinterContext(ScopedPrinter &W, const object::ELFFile<ELFT> *Obj)
+ : W(W), Obj(Obj) {}
void printUnwindInformation() const;
};
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();
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);
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)));
Contents.size()),
ELFT::TargetEndianness == support::endianness::little,
ELFT::Is64Bits ? 8 : 4);
- DWARFDebugFrame EHFrame(Triple::ArchType(ObjF->getArch()), /*IsEH=*/true,
- /*EHFrameAddress=*/Address);
+ DWARFDebugFrame EHFrame(/*IsEH=*/true, /*EHFrameAddress=*/Address);
EHFrame.parse(DE);
for (const auto &Entry : EHFrame) {
template<typename ELFT>
class ELFDumper : public ObjDumper {
public:
- ELFDumper(const object::ELFObjectFile<ELFT> *ObjF, ScopedPrinter &Writer);
+ ELFDumper(const ELFFile<ELFT> *Obj, ScopedPrinter &Writer);
void printFileHeaders() override;
void printSections() override;
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);
}
DynRegionInfo createDRIFrom(const Elf_Phdr *P, uintX_t EntSize) {
- return checkDRI({ObjF->getELFFile()->base() + P->p_offset, P->p_filesz, EntSize});
+ return checkDRI({Obj->base() + P->p_offset, P->p_filesz, EntSize});
}
DynRegionInfo createDRIFrom(const Elf_Shdr *S) {
- return checkDRI({ObjF->getELFFile()->base() + S->sh_offset, S->sh_size, S->sh_entsize});
+ return checkDRI({Obj->base() + S->sh_offset, S->sh_size, S->sh_entsize});
}
void parseDynamicTable(ArrayRef<const Elf_Phdr *> LoadSegments);
void LoadVersionNeeds(const Elf_Shdr *ec) const;
void LoadVersionDefs(const Elf_Shdr *sec) const;
- const object::ELFObjectFile<ELFT> *ObjF;
+ const ELFO *Obj;
DynRegionInfo DynRelRegion;
DynRegionInfo DynRelaRegion;
DynRegionInfo DynRelrRegion;
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();
namespace llvm {
template <class ELFT>
-static std::error_code createELFDumper(const ELFObjectFile<ELFT> *Obj,
+static std::error_code createELFDumper(const ELFFile<ELFT> *Obj,
ScopedPrinter &Writer,
std::unique_ptr<ObjDumper> &Result) {
Result.reset(new ELFDumper<ELFT>(Obj, Writer));
std::unique_ptr<ObjDumper> &Result) {
// Little-endian 32-bit
if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
- return createELFDumper(ELFObj, Writer, Result);
+ return createELFDumper(ELFObj->getELFFile(), Writer, Result);
// Big-endian 32-bit
if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
- return createELFDumper(ELFObj, Writer, Result);
+ return createELFDumper(ELFObj->getELFFile(), Writer, Result);
// Little-endian 64-bit
if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
- return createELFDumper(ELFObj, Writer, Result);
+ return createELFDumper(ELFObj->getELFFile(), Writer, Result);
// Big-endian 64-bit
if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
- return createELFDumper(ELFObj, Writer, Result);
+ return createELFDumper(ELFObj->getELFFile(), Writer, Result);
return readobj_error::unsupported_obj_file_format;
}
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 *)ObjF->getELFFile()->base() + sec->sh_offset;
+ const char *sec_start = (const char *)Obj->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;
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 *)ObjF->getELFFile()->base() + sec->sh_offset;
+ const char *sec_start = (const char *)Obj->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;
template <typename ELFT> void ELFDumper<ELFT>::printVersionInfo() {
// Dump version symbol section.
- printVersionSymbolSection(this, ObjF->getELFFile(), dot_gnu_version_sec, W);
+ printVersionSymbolSection(this, Obj, dot_gnu_version_sec, W);
// Dump version definition section.
- printVersionDefinitionSection(this, ObjF->getELFFile(), dot_gnu_version_d_sec, W);
+ printVersionDefinitionSection(this, Obj, dot_gnu_version_d_sec, W);
// Dump version dependency section.
- printVersionDependencySection(this, ObjF->getELFFile(), dot_gnu_version_r_sec, W);
+ printVersionDependencySection(this, Obj, dot_gnu_version_r_sec, W);
}
template <typename ELFT>
// Get the corresponding version index entry
const Elf_Versym *vs = unwrapOrError(
- ObjF->getELFFile()->template getEntry<Elf_Versym>(dot_gnu_version_sec, entry_index));
+ Obj->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.
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())
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));
}
template <typename ELFT>
-ELFDumper<ELFT>::ELFDumper(const object::ELFObjectFile<ELFT> *ObjF,
- ScopedPrinter &Writer)
- : ObjDumper(Writer), ObjF(ObjF) {
+ELFDumper<ELFT>::ELFDumper(const ELFFile<ELFT> *Obj, ScopedPrinter &Writer)
+ : ObjDumper(Writer), Obj(Obj) {
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));
uint64_t Delta = VAddr - Phdr.p_vaddr;
if (Delta >= Phdr.p_filesz)
report_fatal_error("Virtual address is not in any segment");
- return ObjF->getELFFile()->base() + Phdr.p_offset + Delta;
+ return Obj->base() + Phdr.p_offset + Delta;
};
uint64_t SONameOffset = 0;
template<class ELFT>
void ELFDumper<ELFT>::printFileHeaders() {
- ELFDumperStyle->printFileHeaders(ObjF->getELFFile());
+ ELFDumperStyle->printFileHeaders(Obj);
}
template<class ELFT>
void ELFDumper<ELFT>::printSections() {
- ELFDumperStyle->printSections(ObjF->getELFFile());
+ ELFDumperStyle->printSections(Obj);
}
template<class ELFT>
void ELFDumper<ELFT>::printRelocations() {
- ELFDumperStyle->printRelocations(ObjF->getELFFile());
+ ELFDumperStyle->printRelocations(Obj);
}
template <class ELFT> void ELFDumper<ELFT>::printProgramHeaders() {
- ELFDumperStyle->printProgramHeaders(ObjF->getELFFile());
+ ELFDumperStyle->printProgramHeaders(Obj);
}
template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocations() {
- ELFDumperStyle->printDynamicRelocations(ObjF->getELFFile());
+ ELFDumperStyle->printDynamicRelocations(Obj);
}
template<class ELFT>
void ELFDumper<ELFT>::printSymbols() {
- ELFDumperStyle->printSymbols(ObjF->getELFFile());
+ ELFDumperStyle->printSymbols(Obj);
}
template<class ELFT>
void ELFDumper<ELFT>::printDynamicSymbols() {
- ELFDumperStyle->printDynamicSymbols(ObjF->getELFFile());
+ ELFDumperStyle->printDynamicSymbols(Obj);
}
template <class ELFT> void ELFDumper<ELFT>::printHashHistogram() {
- ELFDumperStyle->printHashHistogram(ObjF->getELFFile());
+ ELFDumperStyle->printHashHistogram(Obj);
}
template <class ELFT> void ELFDumper<ELFT>::printCGProfile() {
- ELFDumperStyle->printCGProfile(ObjF->getELFFile());
+ ELFDumperStyle->printCGProfile(Obj);
}
template <class ELFT> void ELFDumper<ELFT>::printNotes() {
- ELFDumperStyle->printNotes(ObjF->getELFFile());
+ ELFDumperStyle->printNotes(Obj);
}
template <class ELFT> void ELFDumper<ELFT>::printELFLinkerOptions() {
- ELFDumperStyle->printELFLinkerOptions(ObjF->getELFFile());
+ ELFDumperStyle->printELFLinkerOptions(Obj);
}
static const char *getTypeString(unsigned Arch, uint64_t Type) {
template<class ELFT>
void ELFDumper<ELFT>::printUnwindInfo() {
- const unsigned Machine = ObjF->getELFFile()->getHeader()->e_machine;
+ const unsigned Machine = Obj->getHeader()->e_machine;
if (Machine == EM_386 || Machine == EM_X86_64) {
- DwarfCFIEH::PrinterContext<ELFT> Ctx(W, ObjF);
+ DwarfCFIEH::PrinterContext<ELFT> Ctx(W, Obj);
return Ctx.printUnwindInformation();
}
W.startLine() << "UnwindInfo not implemented.\n";
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);
uintX_t Tag = Entry.getTag();
++I;
W.startLine() << " " << format_hex(Tag, Is64 ? 18 : 10, opts::Output != opts::GNU) << " "
- << format("%-21s", getTypeString(ObjF->getELFFile()->getHeader()->e_machine, Tag));
+ << format("%-21s", getTypeString(Obj->getHeader()->e_machine, Tag));
printValue(Tag, Entry.getVal());
OS << "\n";
}
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;
}
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");
}
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";
}
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";
}
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";
}
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));
}
template <class ELFT> void ELFDumper<ELFT>::printGroupSections() {
- ELFDumperStyle->printGroupSections(ObjF->getELFFile());
+ ELFDumperStyle->printGroupSections(Obj);
}
template <class ELFT> void ELFDumper<ELFT>::printAddrsig() {
- ELFDumperStyle->printAddrsig(ObjF->getELFFile());
+ ELFDumperStyle->printAddrsig(Obj);
}
static inline void printFields(formatted_raw_ostream &OS, StringRef Str1,