forked from OSchip/llvm-project
[AArch64] - Return address signing dwarf support
- Reapply r343089 with a fix for DebugInfo/Sparc/gnu-window-save.ll llvm-svn: 343112
This commit is contained in:
parent
a30b48d020
commit
03ad8812f5
|
@ -18,7 +18,8 @@
|
||||||
defined HANDLE_DW_VIRTUALITY || defined HANDLE_DW_DEFAULTED || \
|
defined HANDLE_DW_VIRTUALITY || defined HANDLE_DW_DEFAULTED || \
|
||||||
defined HANDLE_DW_CC || defined HANDLE_DW_LNS || defined HANDLE_DW_LNE || \
|
defined HANDLE_DW_CC || defined HANDLE_DW_LNS || defined HANDLE_DW_LNE || \
|
||||||
defined HANDLE_DW_LNCT || defined HANDLE_DW_MACRO || \
|
defined HANDLE_DW_LNCT || defined HANDLE_DW_MACRO || \
|
||||||
defined HANDLE_DW_RLE || defined HANDLE_DW_CFA || \
|
defined HANDLE_DW_RLE || \
|
||||||
|
(defined HANDLE_DW_CFA && defined HANDLE_DW_CFA_PRED) || \
|
||||||
defined HANDLE_DW_APPLE_PROPERTY || defined HANDLE_DW_UT || \
|
defined HANDLE_DW_APPLE_PROPERTY || defined HANDLE_DW_UT || \
|
||||||
defined HANDLE_DWARF_SECTION || defined HANDLE_DW_IDX || \
|
defined HANDLE_DWARF_SECTION || defined HANDLE_DW_IDX || \
|
||||||
defined HANDLE_DW_END)
|
defined HANDLE_DW_END)
|
||||||
|
@ -85,6 +86,10 @@
|
||||||
#define HANDLE_DW_CFA(ID, NAME)
|
#define HANDLE_DW_CFA(ID, NAME)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef HANDLE_DW_CFA_PRED
|
||||||
|
#define HANDLE_DW_CFA_PRED(ID, NAME, PRED)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef HANDLE_DW_APPLE_PROPERTY
|
#ifndef HANDLE_DW_APPLE_PROPERTY
|
||||||
#define HANDLE_DW_APPLE_PROPERTY(ID, NAME)
|
#define HANDLE_DW_APPLE_PROPERTY(ID, NAME)
|
||||||
#endif
|
#endif
|
||||||
|
@ -831,9 +836,10 @@ HANDLE_DW_CFA(0x14, val_offset)
|
||||||
HANDLE_DW_CFA(0x15, val_offset_sf)
|
HANDLE_DW_CFA(0x15, val_offset_sf)
|
||||||
HANDLE_DW_CFA(0x16, val_expression)
|
HANDLE_DW_CFA(0x16, val_expression)
|
||||||
// Vendor extensions:
|
// Vendor extensions:
|
||||||
HANDLE_DW_CFA(0x1d, MIPS_advance_loc8)
|
HANDLE_DW_CFA_PRED(0x1d, MIPS_advance_loc8, SELECT_MIPS64)
|
||||||
HANDLE_DW_CFA(0x2d, GNU_window_save)
|
HANDLE_DW_CFA_PRED(0x2d, GNU_window_save, SELECT_SPARC)
|
||||||
HANDLE_DW_CFA(0x2e, GNU_args_size)
|
HANDLE_DW_CFA_PRED(0x2d, AARCH64_negate_ra_state, SELECT_AARCH64)
|
||||||
|
HANDLE_DW_CFA_PRED(0x2e, GNU_args_size, SELECT_X86)
|
||||||
|
|
||||||
// Apple Objective-C Property Attributes.
|
// Apple Objective-C Property Attributes.
|
||||||
// Keep this list in sync with clang's DeclSpec.h ObjCPropertyAttributeKind!
|
// Keep this list in sync with clang's DeclSpec.h ObjCPropertyAttributeKind!
|
||||||
|
@ -915,6 +921,7 @@ HANDLE_DW_IDX(0x05, type_hash)
|
||||||
#undef HANDLE_DW_MACRO
|
#undef HANDLE_DW_MACRO
|
||||||
#undef HANDLE_DW_RLE
|
#undef HANDLE_DW_RLE
|
||||||
#undef HANDLE_DW_CFA
|
#undef HANDLE_DW_CFA
|
||||||
|
#undef HANDLE_DW_CFA_PRED
|
||||||
#undef HANDLE_DW_APPLE_PROPERTY
|
#undef HANDLE_DW_APPLE_PROPERTY
|
||||||
#undef HANDLE_DW_UT
|
#undef HANDLE_DW_UT
|
||||||
#undef HANDLE_DWARF_SECTION
|
#undef HANDLE_DWARF_SECTION
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Support/Format.h"
|
#include "llvm/Support/Format.h"
|
||||||
#include "llvm/Support/FormatVariadicDetails.h"
|
#include "llvm/Support/FormatVariadicDetails.h"
|
||||||
|
#include "llvm/ADT/Triple.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class StringRef;
|
class StringRef;
|
||||||
|
@ -272,6 +273,7 @@ enum RangeListEntries {
|
||||||
/// Call frame instruction encodings.
|
/// Call frame instruction encodings.
|
||||||
enum CallFrameInfo {
|
enum CallFrameInfo {
|
||||||
#define HANDLE_DW_CFA(ID, NAME) DW_CFA_##NAME = ID,
|
#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"
|
#include "llvm/BinaryFormat/Dwarf.def"
|
||||||
DW_CFA_extended = 0x00,
|
DW_CFA_extended = 0x00,
|
||||||
|
|
||||||
|
@ -430,7 +432,7 @@ StringRef LNStandardString(unsigned Standard);
|
||||||
StringRef LNExtendedString(unsigned Encoding);
|
StringRef LNExtendedString(unsigned Encoding);
|
||||||
StringRef MacinfoString(unsigned Encoding);
|
StringRef MacinfoString(unsigned Encoding);
|
||||||
StringRef RangeListEncodingString(unsigned Encoding);
|
StringRef RangeListEncodingString(unsigned Encoding);
|
||||||
StringRef CallFrameString(unsigned Encoding);
|
StringRef CallFrameString(unsigned Encoding, Triple::ArchType Arch);
|
||||||
StringRef ApplePropertyString(unsigned);
|
StringRef ApplePropertyString(unsigned);
|
||||||
StringRef UnitTypeString(unsigned);
|
StringRef UnitTypeString(unsigned);
|
||||||
StringRef AtomTypeString(unsigned Atom);
|
StringRef AtomTypeString(unsigned Atom);
|
||||||
|
|
|
@ -90,6 +90,7 @@ class DWARFContext : public DIContext {
|
||||||
bool CheckedForDWP = false;
|
bool CheckedForDWP = false;
|
||||||
std::string DWPName;
|
std::string DWPName;
|
||||||
|
|
||||||
|
Triple::ArchType Arch;
|
||||||
std::unique_ptr<MCRegisterInfo> RegInfo;
|
std::unique_ptr<MCRegisterInfo> RegInfo;
|
||||||
|
|
||||||
/// Read compile units from the debug_info section (if necessary)
|
/// Read compile units from the debug_info section (if necessary)
|
||||||
|
@ -341,7 +342,7 @@ public:
|
||||||
/// Loads register info for the architecture of the provided object file.
|
/// Loads register info for the architecture of the provided object file.
|
||||||
/// Improves readability of dumped DWARF expressions. Requires the caller to
|
/// Improves readability of dumped DWARF expressions. Requires the caller to
|
||||||
/// have initialized the relevant target descriptions.
|
/// have initialized the relevant target descriptions.
|
||||||
Error loadRegisterInfo(const object::ObjectFile &Obj);
|
Error loadArchitectureInfo(const object::ObjectFile &Obj);
|
||||||
|
|
||||||
/// Get address size from CUs.
|
/// Get address size from CUs.
|
||||||
/// TODO: refactor compile_units() to make this const.
|
/// TODO: refactor compile_units() to make this const.
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/ADT/iterator.h"
|
#include "llvm/ADT/iterator.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
|
#include "llvm/ADT/Triple.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
|
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
|
||||||
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
||||||
#include "llvm/Support/Error.h"
|
#include "llvm/Support/Error.h"
|
||||||
|
@ -59,9 +60,11 @@ public:
|
||||||
unsigned size() const { return (unsigned)Instructions.size(); }
|
unsigned size() const { return (unsigned)Instructions.size(); }
|
||||||
bool empty() const { return Instructions.empty(); }
|
bool empty() const { return Instructions.empty(); }
|
||||||
|
|
||||||
CFIProgram(uint64_t CodeAlignmentFactor, int64_t DataAlignmentFactor)
|
CFIProgram(uint64_t CodeAlignmentFactor, int64_t DataAlignmentFactor,
|
||||||
|
Triple::ArchType Arch)
|
||||||
: CodeAlignmentFactor(CodeAlignmentFactor),
|
: CodeAlignmentFactor(CodeAlignmentFactor),
|
||||||
DataAlignmentFactor(DataAlignmentFactor) {}
|
DataAlignmentFactor(DataAlignmentFactor),
|
||||||
|
Arch(Arch) {}
|
||||||
|
|
||||||
/// Parse and store a sequence of CFI instructions from Data,
|
/// Parse and store a sequence of CFI instructions from Data,
|
||||||
/// starting at *Offset and ending at EndOffset. *Offset is updated
|
/// starting at *Offset and ending at EndOffset. *Offset is updated
|
||||||
|
@ -76,6 +79,7 @@ private:
|
||||||
std::vector<Instruction> Instructions;
|
std::vector<Instruction> Instructions;
|
||||||
const uint64_t CodeAlignmentFactor;
|
const uint64_t CodeAlignmentFactor;
|
||||||
const int64_t DataAlignmentFactor;
|
const int64_t DataAlignmentFactor;
|
||||||
|
Triple::ArchType Arch;
|
||||||
|
|
||||||
/// Convenience method to add a new instruction with the given opcode.
|
/// Convenience method to add a new instruction with the given opcode.
|
||||||
void addInstruction(uint8_t Opcode) {
|
void addInstruction(uint8_t Opcode) {
|
||||||
|
@ -130,8 +134,9 @@ public:
|
||||||
enum FrameKind { FK_CIE, FK_FDE };
|
enum FrameKind { FK_CIE, FK_FDE };
|
||||||
|
|
||||||
FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length, uint64_t CodeAlign,
|
FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length, uint64_t CodeAlign,
|
||||||
int64_t DataAlign)
|
int64_t DataAlign, Triple::ArchType Arch)
|
||||||
: Kind(K), Offset(Offset), Length(Length), CFIs(CodeAlign, DataAlign) {}
|
: Kind(K), Offset(Offset), Length(Length),
|
||||||
|
CFIs(CodeAlign, DataAlign, Arch) {}
|
||||||
|
|
||||||
virtual ~FrameEntry() {}
|
virtual ~FrameEntry() {}
|
||||||
|
|
||||||
|
@ -168,9 +173,9 @@ public:
|
||||||
int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister,
|
int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister,
|
||||||
SmallString<8> AugmentationData, uint32_t FDEPointerEncoding,
|
SmallString<8> AugmentationData, uint32_t FDEPointerEncoding,
|
||||||
uint32_t LSDAPointerEncoding, Optional<uint64_t> Personality,
|
uint32_t LSDAPointerEncoding, Optional<uint64_t> Personality,
|
||||||
Optional<uint32_t> PersonalityEnc)
|
Optional<uint32_t> PersonalityEnc, Triple::ArchType Arch)
|
||||||
: FrameEntry(FK_CIE, Offset, Length, CodeAlignmentFactor,
|
: FrameEntry(FK_CIE, Offset, Length, CodeAlignmentFactor,
|
||||||
DataAlignmentFactor),
|
DataAlignmentFactor, Arch),
|
||||||
Version(Version), Augmentation(std::move(Augmentation)),
|
Version(Version), Augmentation(std::move(Augmentation)),
|
||||||
AddressSize(AddressSize), SegmentDescriptorSize(SegmentDescriptorSize),
|
AddressSize(AddressSize), SegmentDescriptorSize(SegmentDescriptorSize),
|
||||||
CodeAlignmentFactor(CodeAlignmentFactor),
|
CodeAlignmentFactor(CodeAlignmentFactor),
|
||||||
|
@ -224,10 +229,11 @@ public:
|
||||||
// is obtained lazily once it's actually required.
|
// is obtained lazily once it's actually required.
|
||||||
FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset,
|
FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset,
|
||||||
uint64_t InitialLocation, uint64_t AddressRange, CIE *Cie,
|
uint64_t InitialLocation, uint64_t AddressRange, CIE *Cie,
|
||||||
Optional<uint64_t> LSDAAddress)
|
Optional<uint64_t> LSDAAddress, Triple::ArchType Arch)
|
||||||
: FrameEntry(FK_FDE, Offset, Length,
|
: FrameEntry(FK_FDE, Offset, Length,
|
||||||
Cie ? Cie->getCodeAlignmentFactor() : 0,
|
Cie ? Cie->getCodeAlignmentFactor() : 0,
|
||||||
Cie ? Cie->getDataAlignmentFactor() : 0),
|
Cie ? Cie->getDataAlignmentFactor() : 0,
|
||||||
|
Arch),
|
||||||
LinkedCIEOffset(LinkedCIEOffset), InitialLocation(InitialLocation),
|
LinkedCIEOffset(LinkedCIEOffset), InitialLocation(InitialLocation),
|
||||||
AddressRange(AddressRange), LinkedCIE(Cie), LSDAAddress(LSDAAddress) {}
|
AddressRange(AddressRange), LinkedCIE(Cie), LSDAAddress(LSDAAddress) {}
|
||||||
|
|
||||||
|
@ -256,6 +262,7 @@ private:
|
||||||
|
|
||||||
/// A parsed .debug_frame or .eh_frame section
|
/// A parsed .debug_frame or .eh_frame section
|
||||||
class DWARFDebugFrame {
|
class DWARFDebugFrame {
|
||||||
|
const Triple::ArchType Arch;
|
||||||
// True if this is parsing an eh_frame section.
|
// True if this is parsing an eh_frame section.
|
||||||
const bool IsEH;
|
const bool IsEH;
|
||||||
// Not zero for sane pointer values coming out of eh_frame
|
// Not zero for sane pointer values coming out of eh_frame
|
||||||
|
@ -272,7 +279,8 @@ public:
|
||||||
// it is a .debug_frame section. EHFrameAddress should be different
|
// it is a .debug_frame section. EHFrameAddress should be different
|
||||||
// than zero for correct parsing of .eh_frame addresses when they
|
// than zero for correct parsing of .eh_frame addresses when they
|
||||||
// use a PC-relative encoding.
|
// use a PC-relative encoding.
|
||||||
DWARFDebugFrame(bool IsEH = false, uint64_t EHFrameAddress = 0);
|
DWARFDebugFrame(Triple::ArchType Arch,
|
||||||
|
bool IsEH = false, uint64_t EHFrameAddress = 0);
|
||||||
~DWARFDebugFrame();
|
~DWARFDebugFrame();
|
||||||
|
|
||||||
/// Dump the section data into the given stream.
|
/// Dump the section data into the given stream.
|
||||||
|
|
|
@ -430,6 +430,7 @@ public:
|
||||||
OpUndefined,
|
OpUndefined,
|
||||||
OpRegister,
|
OpRegister,
|
||||||
OpWindowSave,
|
OpWindowSave,
|
||||||
|
OpNegateRAState,
|
||||||
OpGnuArgsSize
|
OpGnuArgsSize
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -509,6 +510,11 @@ public:
|
||||||
return MCCFIInstruction(OpWindowSave, L, 0, 0, "");
|
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
|
/// .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
|
/// was at the beginning of the function, after all initial instructions added
|
||||||
/// by .cfi_startproc were executed.
|
/// by .cfi_startproc were executed.
|
||||||
|
|
|
@ -891,6 +891,7 @@ public:
|
||||||
virtual void EmitCFIUndefined(int64_t Register);
|
virtual void EmitCFIUndefined(int64_t Register);
|
||||||
virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
|
virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
|
||||||
virtual void EmitCFIWindowSave();
|
virtual void EmitCFIWindowSave();
|
||||||
|
virtual void EmitCFINegateRAState();
|
||||||
|
|
||||||
virtual void EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc = SMLoc());
|
virtual void EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc = SMLoc());
|
||||||
virtual void EmitWinCFIEndProc(SMLoc Loc = SMLoc());
|
virtual void EmitWinCFIEndProc(SMLoc Loc = SMLoc());
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include "llvm/BinaryFormat/Dwarf.h"
|
#include "llvm/BinaryFormat/Dwarf.h"
|
||||||
#include "llvm/ADT/StringSwitch.h"
|
#include "llvm/ADT/StringSwitch.h"
|
||||||
|
#include "llvm/ADT/Triple.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
@ -455,14 +456,31 @@ StringRef llvm::dwarf::RangeListEncodingString(unsigned Encoding) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef llvm::dwarf::CallFrameString(unsigned Encoding) {
|
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_SPARC (Arch == llvm::Triple::sparc || 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"
|
||||||
|
|
||||||
switch (Encoding) {
|
switch (Encoding) {
|
||||||
default:
|
default:
|
||||||
return StringRef();
|
return StringRef();
|
||||||
|
#define HANDLE_DW_CFA_PRED(ID, NAME, PRED)
|
||||||
#define HANDLE_DW_CFA(ID, NAME) \
|
#define HANDLE_DW_CFA(ID, NAME) \
|
||||||
case DW_CFA_##NAME: \
|
case DW_CFA_##NAME: \
|
||||||
return "DW_CFA_" #NAME;
|
return "DW_CFA_" #NAME;
|
||||||
#include "llvm/BinaryFormat/Dwarf.def"
|
#include "llvm/BinaryFormat/Dwarf.def"
|
||||||
|
|
||||||
|
#undef SELECT_X86
|
||||||
|
#undef SELECT_SPARC
|
||||||
|
#undef SELECT_MIPS64
|
||||||
|
#undef SELECT_AARCH64
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -212,6 +212,9 @@ void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
|
||||||
case MCCFIInstruction::OpWindowSave:
|
case MCCFIInstruction::OpWindowSave:
|
||||||
OutStreamer->EmitCFIWindowSave();
|
OutStreamer->EmitCFIWindowSave();
|
||||||
break;
|
break;
|
||||||
|
case MCCFIInstruction::OpNegateRAState:
|
||||||
|
OutStreamer->EmitCFINegateRAState();
|
||||||
|
break;
|
||||||
case MCCFIInstruction::OpSameValue:
|
case MCCFIInstruction::OpSameValue:
|
||||||
OutStreamer->EmitCFISameValue(Inst.getRegister());
|
OutStreamer->EmitCFISameValue(Inst.getRegister());
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -207,6 +207,7 @@ void CFIInstrInserter::calculateOutgoingCFAInfo(MBBCFAInfo &MBBInfo) {
|
||||||
case MCCFIInstruction::OpUndefined:
|
case MCCFIInstruction::OpUndefined:
|
||||||
case MCCFIInstruction::OpRegister:
|
case MCCFIInstruction::OpRegister:
|
||||||
case MCCFIInstruction::OpWindowSave:
|
case MCCFIInstruction::OpWindowSave:
|
||||||
|
case MCCFIInstruction::OpNegateRAState:
|
||||||
case MCCFIInstruction::OpGnuArgsSize:
|
case MCCFIInstruction::OpGnuArgsSize:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -220,6 +220,7 @@ static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
|
||||||
.Case("undefined", MIToken::kw_cfi_undefined)
|
.Case("undefined", MIToken::kw_cfi_undefined)
|
||||||
.Case("register", MIToken::kw_cfi_register)
|
.Case("register", MIToken::kw_cfi_register)
|
||||||
.Case("window_save", MIToken::kw_cfi_window_save)
|
.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("blockaddress", MIToken::kw_blockaddress)
|
||||||
.Case("intrinsic", MIToken::kw_intrinsic)
|
.Case("intrinsic", MIToken::kw_intrinsic)
|
||||||
.Case("target-index", MIToken::kw_target_index)
|
.Case("target-index", MIToken::kw_target_index)
|
||||||
|
|
|
@ -89,6 +89,7 @@ struct MIToken {
|
||||||
kw_cfi_restore_state,
|
kw_cfi_restore_state,
|
||||||
kw_cfi_undefined,
|
kw_cfi_undefined,
|
||||||
kw_cfi_window_save,
|
kw_cfi_window_save,
|
||||||
|
kw_cfi_aarch64_negate_ra_sign_state,
|
||||||
kw_blockaddress,
|
kw_blockaddress,
|
||||||
kw_intrinsic,
|
kw_intrinsic,
|
||||||
kw_target_index,
|
kw_target_index,
|
||||||
|
|
|
@ -1816,6 +1816,9 @@ bool MIParser::parseCFIOperand(MachineOperand &Dest) {
|
||||||
case MIToken::kw_cfi_window_save:
|
case MIToken::kw_cfi_window_save:
|
||||||
CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr));
|
CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr));
|
||||||
break;
|
break;
|
||||||
|
case MIToken::kw_cfi_aarch64_negate_ra_sign_state:
|
||||||
|
CFIIndex = MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
|
||||||
|
break;
|
||||||
case MIToken::kw_cfi_escape: {
|
case MIToken::kw_cfi_escape: {
|
||||||
std::string Values;
|
std::string Values;
|
||||||
if (parseCFIEscapeValues(Values))
|
if (parseCFIEscapeValues(Values))
|
||||||
|
@ -2108,6 +2111,7 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest,
|
||||||
case MIToken::kw_cfi_restore_state:
|
case MIToken::kw_cfi_restore_state:
|
||||||
case MIToken::kw_cfi_undefined:
|
case MIToken::kw_cfi_undefined:
|
||||||
case MIToken::kw_cfi_window_save:
|
case MIToken::kw_cfi_window_save:
|
||||||
|
case MIToken::kw_cfi_aarch64_negate_ra_sign_state:
|
||||||
return parseCFIOperand(Dest);
|
return parseCFIOperand(Dest);
|
||||||
case MIToken::kw_blockaddress:
|
case MIToken::kw_blockaddress:
|
||||||
return parseBlockAddressOperand(Dest);
|
return parseBlockAddressOperand(Dest);
|
||||||
|
|
|
@ -696,6 +696,11 @@ static void printCFI(raw_ostream &OS, const MCCFIInstruction &CFI,
|
||||||
if (MCSymbol *Label = CFI.getLabel())
|
if (MCSymbol *Label = CFI.getLabel())
|
||||||
MachineOperand::printSymbol(OS, *Label);
|
MachineOperand::printSymbol(OS, *Label);
|
||||||
break;
|
break;
|
||||||
|
case MCCFIInstruction::OpNegateRAState:
|
||||||
|
OS << "negate_ra_sign_state ";
|
||||||
|
if (MCSymbol *Label = CFI.getLabel())
|
||||||
|
MachineOperand::printSymbol(OS, *Label);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// TODO: Print the other CFI Operations.
|
// TODO: Print the other CFI Operations.
|
||||||
OS << "<unserializable cfi directive>";
|
OS << "<unserializable cfi directive>";
|
||||||
|
|
|
@ -724,7 +724,7 @@ const DWARFDebugFrame *DWARFContext::getDebugFrame() {
|
||||||
// http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
|
// http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
|
||||||
DWARFDataExtractor debugFrameData(DObj->getDebugFrameSection(),
|
DWARFDataExtractor debugFrameData(DObj->getDebugFrameSection(),
|
||||||
isLittleEndian(), DObj->getAddressSize());
|
isLittleEndian(), DObj->getAddressSize());
|
||||||
DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
|
DebugFrame.reset(new DWARFDebugFrame(Arch, false /* IsEH */));
|
||||||
DebugFrame->parse(debugFrameData);
|
DebugFrame->parse(debugFrameData);
|
||||||
return DebugFrame.get();
|
return DebugFrame.get();
|
||||||
}
|
}
|
||||||
|
@ -735,7 +735,7 @@ const DWARFDebugFrame *DWARFContext::getEHFrame() {
|
||||||
|
|
||||||
DWARFDataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
|
DWARFDataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
|
||||||
DObj->getAddressSize());
|
DObj->getAddressSize());
|
||||||
DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
|
DebugFrame.reset(new DWARFDebugFrame(Arch, true /* IsEH */));
|
||||||
DebugFrame->parse(debugFrameData);
|
DebugFrame->parse(debugFrameData);
|
||||||
return DebugFrame.get();
|
return DebugFrame.get();
|
||||||
}
|
}
|
||||||
|
@ -1581,9 +1581,11 @@ DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
|
||||||
return llvm::make_unique<DWARFContext>(std::move(DObj), "");
|
return llvm::make_unique<DWARFContext>(std::move(DObj), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) {
|
Error DWARFContext::loadArchitectureInfo(const object::ObjectFile &Obj) {
|
||||||
// Detect the architecture from the object file. We usually don't need OS
|
// Detect the architecture from the object file. We usually don't need OS
|
||||||
// info to lookup a target and create register info.
|
// info to lookup a target and create register info.
|
||||||
|
Arch = Triple::ArchType(Obj.getArch());
|
||||||
|
|
||||||
Triple TT;
|
Triple TT;
|
||||||
TT.setArch(Triple::ArchType(Obj.getArch()));
|
TT.setArch(Triple::ArchType(Obj.getArch()));
|
||||||
TT.setVendor(Triple::UnknownVendor);
|
TT.setVendor(Triple::UnknownVendor);
|
||||||
|
|
|
@ -225,7 +225,7 @@ void CFIProgram::printOperand(raw_ostream &OS, const MCRegisterInfo *MRI,
|
||||||
switch (Type) {
|
switch (Type) {
|
||||||
case OT_Unset: {
|
case OT_Unset: {
|
||||||
OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to";
|
OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to";
|
||||||
auto OpcodeName = CallFrameString(Opcode);
|
auto OpcodeName = CallFrameString(Opcode, Arch);
|
||||||
if (!OpcodeName.empty())
|
if (!OpcodeName.empty())
|
||||||
OS << " " << OpcodeName;
|
OS << " " << OpcodeName;
|
||||||
else
|
else
|
||||||
|
@ -279,7 +279,7 @@ void CFIProgram::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
|
||||||
if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)
|
if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)
|
||||||
Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;
|
Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;
|
||||||
OS.indent(2 * IndentLevel);
|
OS.indent(2 * IndentLevel);
|
||||||
OS << CallFrameString(Opcode) << ":";
|
OS << CallFrameString(Opcode, Arch) << ":";
|
||||||
for (unsigned i = 0; i < Instr.Ops.size(); ++i)
|
for (unsigned i = 0; i < Instr.Ops.size(); ++i)
|
||||||
printOperand(OS, MRI, IsEH, Instr, i, Instr.Ops[i]);
|
printOperand(OS, MRI, IsEH, Instr, i, Instr.Ops[i]);
|
||||||
OS << '\n';
|
OS << '\n';
|
||||||
|
@ -325,8 +325,9 @@ void FDE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
DWARFDebugFrame::DWARFDebugFrame(bool IsEH, uint64_t EHFrameAddress)
|
DWARFDebugFrame::DWARFDebugFrame(Triple::ArchType Arch,
|
||||||
: IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
|
bool IsEH, uint64_t EHFrameAddress)
|
||||||
|
: Arch(Arch), IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
|
||||||
|
|
||||||
DWARFDebugFrame::~DWARFDebugFrame() = default;
|
DWARFDebugFrame::~DWARFDebugFrame() = default;
|
||||||
|
|
||||||
|
@ -460,7 +461,7 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
|
||||||
StartOffset, Length, Version, AugmentationString, AddressSize,
|
StartOffset, Length, Version, AugmentationString, AddressSize,
|
||||||
SegmentDescriptorSize, CodeAlignmentFactor, DataAlignmentFactor,
|
SegmentDescriptorSize, CodeAlignmentFactor, DataAlignmentFactor,
|
||||||
ReturnAddressRegister, AugmentationData, FDEPointerEncoding,
|
ReturnAddressRegister, AugmentationData, FDEPointerEncoding,
|
||||||
LSDAPointerEncoding, Personality, PersonalityEncoding);
|
LSDAPointerEncoding, Personality, PersonalityEncoding, Arch);
|
||||||
CIEs[StartOffset] = Cie.get();
|
CIEs[StartOffset] = Cie.get();
|
||||||
Entries.emplace_back(std::move(Cie));
|
Entries.emplace_back(std::move(Cie));
|
||||||
} else {
|
} else {
|
||||||
|
@ -512,7 +513,7 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
|
||||||
|
|
||||||
Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
|
Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
|
||||||
InitialLocation, AddressRange,
|
InitialLocation, AddressRange,
|
||||||
Cie, LSDAAddress));
|
Cie, LSDAAddress, Arch));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Error E =
|
if (Error E =
|
||||||
|
|
|
@ -285,6 +285,7 @@ public:
|
||||||
void EmitCFIUndefined(int64_t Register) override;
|
void EmitCFIUndefined(int64_t Register) override;
|
||||||
void EmitCFIRegister(int64_t Register1, int64_t Register2) override;
|
void EmitCFIRegister(int64_t Register1, int64_t Register2) override;
|
||||||
void EmitCFIWindowSave() override;
|
void EmitCFIWindowSave() override;
|
||||||
|
void EmitCFINegateRAState() override;
|
||||||
void EmitCFIReturnColumn(int64_t Register) override;
|
void EmitCFIReturnColumn(int64_t Register) override;
|
||||||
|
|
||||||
void EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) override;
|
void EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) override;
|
||||||
|
@ -1564,6 +1565,12 @@ void MCAsmStreamer::EmitCFIWindowSave() {
|
||||||
EmitEOL();
|
EmitEOL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MCAsmStreamer::EmitCFINegateRAState() {
|
||||||
|
MCStreamer::EmitCFINegateRAState();
|
||||||
|
OS << "\t.cfi_negate_ra_state";
|
||||||
|
EmitEOL();
|
||||||
|
}
|
||||||
|
|
||||||
void MCAsmStreamer::EmitCFIReturnColumn(int64_t Register) {
|
void MCAsmStreamer::EmitCFIReturnColumn(int64_t Register) {
|
||||||
MCStreamer::EmitCFIReturnColumn(Register);
|
MCStreamer::EmitCFIReturnColumn(Register);
|
||||||
OS << "\t.cfi_return_column " << Register;
|
OS << "\t.cfi_return_column " << Register;
|
||||||
|
|
|
@ -1332,6 +1332,10 @@ void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) {
|
||||||
Streamer.EmitIntValue(dwarf::DW_CFA_GNU_window_save, 1);
|
Streamer.EmitIntValue(dwarf::DW_CFA_GNU_window_save, 1);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case MCCFIInstruction::OpNegateRAState:
|
||||||
|
Streamer.EmitIntValue(dwarf::DW_CFA_AARCH64_negate_ra_state, 1);
|
||||||
|
return;
|
||||||
|
|
||||||
case MCCFIInstruction::OpUndefined: {
|
case MCCFIInstruction::OpUndefined: {
|
||||||
unsigned Reg = Instr.getRegister();
|
unsigned Reg = Instr.getRegister();
|
||||||
Streamer.EmitIntValue(dwarf::DW_CFA_undefined, 1);
|
Streamer.EmitIntValue(dwarf::DW_CFA_undefined, 1);
|
||||||
|
|
|
@ -565,6 +565,15 @@ void MCStreamer::EmitCFIWindowSave() {
|
||||||
CurFrame->Instructions.push_back(Instruction);
|
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) {
|
void MCStreamer::EmitCFIReturnColumn(int64_t Register) {
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
if (!CurFrame)
|
if (!CurFrame)
|
||||||
|
|
|
@ -622,6 +622,12 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
|
||||||
if (ShouldSignReturnAddress(MF)) {
|
if (ShouldSignReturnAddress(MF)) {
|
||||||
BuildMI(MBB, MBBI, DL, TII->get(AArch64::PACIASP))
|
BuildMI(MBB, MBBI, DL, TII->get(AArch64::PACIASP))
|
||||||
.setMIFlag(MachineInstr::FrameSetup);
|
.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
|
// All calls are tail calls in GHC calling conv, and functions have no
|
||||||
|
|
|
@ -175,6 +175,7 @@ private:
|
||||||
|
|
||||||
bool parseDirectiveReq(StringRef Name, SMLoc L);
|
bool parseDirectiveReq(StringRef Name, SMLoc L);
|
||||||
bool parseDirectiveUnreq(SMLoc L);
|
bool parseDirectiveUnreq(SMLoc L);
|
||||||
|
bool parseDirectiveCFINegateRAState();
|
||||||
|
|
||||||
bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
|
bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
|
||||||
SmallVectorImpl<SMLoc> &Loc);
|
SmallVectorImpl<SMLoc> &Loc);
|
||||||
|
@ -4925,6 +4926,8 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
|
||||||
parseDirectiveUnreq(Loc);
|
parseDirectiveUnreq(Loc);
|
||||||
else if (IDVal == ".inst")
|
else if (IDVal == ".inst")
|
||||||
parseDirectiveInst(Loc);
|
parseDirectiveInst(Loc);
|
||||||
|
else if (IDVal == ".cfi_negate_ra_state")
|
||||||
|
parseDirectiveCFINegateRAState();
|
||||||
else if (IsMachO) {
|
else if (IsMachO) {
|
||||||
if (IDVal == MCLOHDirectiveName())
|
if (IDVal == MCLOHDirectiveName())
|
||||||
parseDirectiveLOH(IDVal, Loc);
|
parseDirectiveLOH(IDVal, Loc);
|
||||||
|
@ -5298,6 +5301,13 @@ bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
|
||||||
|
if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
|
||||||
|
return true;
|
||||||
|
getStreamer().EmitCFINegateRAState();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
AArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
|
AArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
|
||||||
AArch64MCExpr::VariantKind &ELFRefKind,
|
AArch64MCExpr::VariantKind &ELFRefKind,
|
||||||
|
|
|
@ -24,17 +24,17 @@ define i32 @leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf" {
|
||||||
; CHECK-LABEL: @leaf_sign_all
|
; CHECK-LABEL: @leaf_sign_all
|
||||||
; CHECK: paciasp
|
; CHECK: paciasp
|
||||||
; CHECK: autiasp
|
; CHECK: autiasp
|
||||||
; CHECK-NEXT: ret
|
; CHECK: ret
|
||||||
define i32 @leaf_sign_all(i32 %x) "sign-return-address"="all" {
|
define i32 @leaf_sign_all(i32 %x) "sign-return-address"="all" {
|
||||||
ret i32 %x
|
ret i32 %x
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK: @leaf_clobbers_lr
|
; CHECK: @leaf_clobbers_lr
|
||||||
; CHECK: paciasp
|
; CHECK: paciasp
|
||||||
; CHECK-NEXT: str x30, [sp, #-16]!
|
; CHECK: str x30, [sp, #-16]!
|
||||||
; CHECK: ldr x30, [sp], #16
|
; CHECK: ldr x30, [sp], #16
|
||||||
; CHECK-NEXT: autiasp
|
; CHECK-NEXT: autiasp
|
||||||
; CHECK-NEXT: ret
|
; CHECK: ret
|
||||||
define i64 @leaf_clobbers_lr(i64 %x) "sign-return-address"="non-leaf" {
|
define i64 @leaf_clobbers_lr(i64 %x) "sign-return-address"="non-leaf" {
|
||||||
call void asm sideeffect "mov x30, $0", "r,~{lr}"(i64 %x) #1
|
call void asm sideeffect "mov x30, $0", "r,~{lr}"(i64 %x) #1
|
||||||
ret i64 %x
|
ret i64 %x
|
||||||
|
@ -45,7 +45,7 @@ declare i32 @foo(i32)
|
||||||
; CHECK: @non_leaf_sign_all
|
; CHECK: @non_leaf_sign_all
|
||||||
; CHECK: paciasp
|
; CHECK: paciasp
|
||||||
; CHECK: autiasp
|
; CHECK: autiasp
|
||||||
; CHECK-NEXT: ret
|
; CHECK: ret
|
||||||
define i32 @non_leaf_sign_all(i32 %x) "sign-return-address"="all" {
|
define i32 @non_leaf_sign_all(i32 %x) "sign-return-address"="all" {
|
||||||
%call = call i32 @foo(i32 %x)
|
%call = call i32 @foo(i32 %x)
|
||||||
ret i32 %call
|
ret i32 %call
|
||||||
|
@ -53,10 +53,10 @@ define i32 @non_leaf_sign_all(i32 %x) "sign-return-address"="all" {
|
||||||
|
|
||||||
; CHECK: @non_leaf_sign_non_leaf
|
; CHECK: @non_leaf_sign_non_leaf
|
||||||
; CHECK: paciasp
|
; CHECK: paciasp
|
||||||
; CHECK-NEXT: str x30, [sp, #-16]!
|
; CHECK: str x30, [sp, #-16]!
|
||||||
; CHECK: ldr x30, [sp], #16
|
; CHECK: ldr x30, [sp], #16
|
||||||
; CHECK-NEXT: autiasp
|
; CHECK: autiasp
|
||||||
; CHECK-NEXT: ret
|
; CHECK: ret
|
||||||
define i32 @non_leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf" {
|
define i32 @non_leaf_sign_non_leaf(i32 %x) "sign-return-address"="non-leaf" {
|
||||||
%call = call i32 @foo(i32 %x)
|
%call = call i32 @foo(i32 %x)
|
||||||
ret i32 %call
|
ret i32 %call
|
||||||
|
@ -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-LABEL: @leaf_sign_all_v83
|
||||||
; CHECK: paciasp
|
; CHECK: paciasp
|
||||||
; CHECK-NOT: ret
|
; CHECK-NOT: ret
|
||||||
; CHECK-NEXT: retaa
|
; CHECK: retaa
|
||||||
; CHECK-NOT: ret
|
; CHECK-NOT: ret
|
||||||
define i32 @leaf_sign_all_v83(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" {
|
define i32 @leaf_sign_all_v83(i32 %x) "sign-return-address"="all" "target-features"="+v8.3a" {
|
||||||
ret i32 %x
|
ret i32 %x
|
||||||
|
@ -75,10 +75,10 @@ declare fastcc i64 @bar(i64)
|
||||||
|
|
||||||
; CHECK-LABEL: @spill_lr_and_tail_call
|
; CHECK-LABEL: @spill_lr_and_tail_call
|
||||||
; CHECK: paciasp
|
; CHECK: paciasp
|
||||||
; CHECK-NEXT: str x30, [sp, #-16]!
|
; CHECK: str x30, [sp, #-16]!
|
||||||
; CHECK: ldr x30, [sp], #16
|
; CHECK: ldr x30, [sp], #16
|
||||||
; CHECK-NEXT: autiasp
|
; CHECK: autiasp
|
||||||
; CHECK-NEXT: b bar
|
; CHECK: b bar
|
||||||
define fastcc void @spill_lr_and_tail_call(i64 %x) "sign-return-address"="all" {
|
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
|
call void asm sideeffect "mov x30, $0", "r,~{lr}"(i64 %x) #1
|
||||||
tail call fastcc i64 @bar(i64 %x)
|
tail call fastcc i64 @bar(i64 %x)
|
||||||
|
|
|
@ -45,4 +45,6 @@ body: |
|
||||||
; CHECK: CFI_INSTRUCTION escape 0x61, 0x62, 0x63
|
; CHECK: CFI_INSTRUCTION escape 0x61, 0x62, 0x63
|
||||||
CFI_INSTRUCTION window_save
|
CFI_INSTRUCTION window_save
|
||||||
; CHECK: CFI_INSTRUCTION window_save
|
; CHECK: CFI_INSTRUCTION window_save
|
||||||
|
CFI_INSTRUCTION negate_ra_sign_state
|
||||||
|
; CHECK: CFI_INSTRUCTION negate_ra_sign_state
|
||||||
RET_ReallyLR
|
RET_ReallyLR
|
||||||
|
|
|
@ -393,7 +393,7 @@ bool collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
|
||||||
|
|
||||||
static bool dumpObjectFile(ObjectFile &Obj, DWARFContext &DICtx, Twine Filename,
|
static bool dumpObjectFile(ObjectFile &Obj, DWARFContext &DICtx, Twine Filename,
|
||||||
raw_ostream &OS) {
|
raw_ostream &OS) {
|
||||||
logAllUnhandledErrors(DICtx.loadRegisterInfo(Obj), errs(),
|
logAllUnhandledErrors(DICtx.loadArchitectureInfo(Obj), errs(),
|
||||||
Filename.str() + ": ");
|
Filename.str() + ": ");
|
||||||
// The UUID dump already contains all the same information.
|
// The UUID dump already contains all the same information.
|
||||||
if (!(DumpType & DIDT_UUID) || DumpType == DIDT_All)
|
if (!(DumpType & DIDT_UUID) || DumpType == DIDT_All)
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "llvm/BinaryFormat/Dwarf.h"
|
#include "llvm/BinaryFormat/Dwarf.h"
|
||||||
#include "llvm/Object/ELF.h"
|
#include "llvm/Object/ELF.h"
|
||||||
#include "llvm/Object/ELFTypes.h"
|
#include "llvm/Object/ELFTypes.h"
|
||||||
|
#include "llvm/Object/ELFObjectFile.h"
|
||||||
#include "llvm/Support/Casting.h"
|
#include "llvm/Support/Casting.h"
|
||||||
#include "llvm/Support/ScopedPrinter.h"
|
#include "llvm/Support/ScopedPrinter.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
|
@ -31,15 +32,15 @@ namespace DwarfCFIEH {
|
||||||
template <typename ELFT>
|
template <typename ELFT>
|
||||||
class PrinterContext {
|
class PrinterContext {
|
||||||
ScopedPrinter &W;
|
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 printEHFrameHdr(uint64_t Offset, uint64_t Address, uint64_t Size) const;
|
||||||
|
|
||||||
void printEHFrame(const typename ELFT::Shdr *EHFrameShdr) const;
|
void printEHFrame(const typename ELFT::Shdr *EHFrameShdr) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PrinterContext(ScopedPrinter &W, const object::ELFFile<ELFT> *Obj)
|
PrinterContext(ScopedPrinter &W, const object::ELFObjectFile<ELFT> *ObjF)
|
||||||
: W(W), Obj(Obj) {}
|
: W(W), ObjF(ObjF) {}
|
||||||
|
|
||||||
void printUnwindInformation() const;
|
void printUnwindInformation() const;
|
||||||
};
|
};
|
||||||
|
@ -59,6 +60,7 @@ static const typename ELFO::Elf_Shdr *findSectionByAddress(const ELFO *Obj,
|
||||||
|
|
||||||
template <typename ELFT>
|
template <typename ELFT>
|
||||||
void PrinterContext<ELFT>::printUnwindInformation() const {
|
void PrinterContext<ELFT>::printUnwindInformation() const {
|
||||||
|
const object::ELFFile<ELFT> *Obj = ObjF->getELFFile();
|
||||||
const typename ELFT::Phdr *EHFramePhdr = nullptr;
|
const typename ELFT::Phdr *EHFramePhdr = nullptr;
|
||||||
|
|
||||||
auto PHs = Obj->program_headers();
|
auto PHs = Obj->program_headers();
|
||||||
|
@ -101,6 +103,7 @@ void PrinterContext<ELFT>::printEHFrameHdr(uint64_t EHFrameHdrOffset,
|
||||||
W.startLine() << format("Offset: 0x%" PRIx64 "\n", EHFrameHdrOffset);
|
W.startLine() << format("Offset: 0x%" PRIx64 "\n", EHFrameHdrOffset);
|
||||||
W.startLine() << format("Size: 0x%" PRIx64 "\n", EHFrameHdrSize);
|
W.startLine() << format("Size: 0x%" PRIx64 "\n", EHFrameHdrSize);
|
||||||
|
|
||||||
|
const object::ELFFile<ELFT> *Obj = ObjF->getELFFile();
|
||||||
const auto *EHFrameHdrShdr = findSectionByAddress(Obj, EHFrameHdrAddress);
|
const auto *EHFrameHdrShdr = findSectionByAddress(Obj, EHFrameHdrAddress);
|
||||||
if (EHFrameHdrShdr) {
|
if (EHFrameHdrShdr) {
|
||||||
auto SectionName = Obj->getSectionName(EHFrameHdrShdr);
|
auto SectionName = Obj->getSectionName(EHFrameHdrShdr);
|
||||||
|
@ -173,6 +176,7 @@ void PrinterContext<ELFT>::printEHFrame(
|
||||||
ShOffset, Address);
|
ShOffset, Address);
|
||||||
W.indent();
|
W.indent();
|
||||||
|
|
||||||
|
const object::ELFFile<ELFT> *Obj = ObjF->getELFFile();
|
||||||
auto Result = Obj->getSectionContents(EHFrameShdr);
|
auto Result = Obj->getSectionContents(EHFrameShdr);
|
||||||
if (Error E = Result.takeError())
|
if (Error E = Result.takeError())
|
||||||
reportError(toString(std::move(E)));
|
reportError(toString(std::move(E)));
|
||||||
|
@ -183,7 +187,8 @@ void PrinterContext<ELFT>::printEHFrame(
|
||||||
Contents.size()),
|
Contents.size()),
|
||||||
ELFT::TargetEndianness == support::endianness::little,
|
ELFT::TargetEndianness == support::endianness::little,
|
||||||
ELFT::Is64Bits ? 8 : 4);
|
ELFT::Is64Bits ? 8 : 4);
|
||||||
DWARFDebugFrame EHFrame(/*IsEH=*/true, /*EHFrameAddress=*/Address);
|
DWARFDebugFrame EHFrame(Triple::ArchType(ObjF->getArch()), /*IsEH=*/true,
|
||||||
|
/*EHFrameAddress=*/Address);
|
||||||
EHFrame.parse(DE);
|
EHFrame.parse(DE);
|
||||||
|
|
||||||
for (const auto &Entry : EHFrame) {
|
for (const auto &Entry : EHFrame) {
|
||||||
|
|
|
@ -139,7 +139,7 @@ struct DynRegionInfo {
|
||||||
template<typename ELFT>
|
template<typename ELFT>
|
||||||
class ELFDumper : public ObjDumper {
|
class ELFDumper : public ObjDumper {
|
||||||
public:
|
public:
|
||||||
ELFDumper(const ELFFile<ELFT> *Obj, ScopedPrinter &Writer);
|
ELFDumper(const object::ELFObjectFile<ELFT> *ObjF, ScopedPrinter &Writer);
|
||||||
|
|
||||||
void printFileHeaders() override;
|
void printFileHeaders() override;
|
||||||
void printSections() override;
|
void printSections() override;
|
||||||
|
@ -181,6 +181,7 @@ private:
|
||||||
TYPEDEF_ELF_TYPES(ELFT)
|
TYPEDEF_ELF_TYPES(ELFT)
|
||||||
|
|
||||||
DynRegionInfo checkDRI(DynRegionInfo DRI) {
|
DynRegionInfo checkDRI(DynRegionInfo DRI) {
|
||||||
|
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
|
||||||
if (DRI.Addr < Obj->base() ||
|
if (DRI.Addr < Obj->base() ||
|
||||||
(const uint8_t *)DRI.Addr + DRI.Size > Obj->base() + Obj->getBufSize())
|
(const uint8_t *)DRI.Addr + DRI.Size > Obj->base() + Obj->getBufSize())
|
||||||
error(llvm::object::object_error::parse_failed);
|
error(llvm::object::object_error::parse_failed);
|
||||||
|
@ -188,11 +189,11 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
DynRegionInfo createDRIFrom(const Elf_Phdr *P, uintX_t EntSize) {
|
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) {
|
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);
|
void parseDynamicTable(ArrayRef<const Elf_Phdr *> LoadSegments);
|
||||||
|
@ -206,7 +207,7 @@ private:
|
||||||
void LoadVersionNeeds(const Elf_Shdr *ec) const;
|
void LoadVersionNeeds(const Elf_Shdr *ec) const;
|
||||||
void LoadVersionDefs(const Elf_Shdr *sec) const;
|
void LoadVersionDefs(const Elf_Shdr *sec) const;
|
||||||
|
|
||||||
const ELFO *Obj;
|
const object::ELFObjectFile<ELFT> *ObjF;
|
||||||
DynRegionInfo DynRelRegion;
|
DynRegionInfo DynRelRegion;
|
||||||
DynRegionInfo DynRelaRegion;
|
DynRegionInfo DynRelaRegion;
|
||||||
DynRegionInfo DynRelrRegion;
|
DynRegionInfo DynRelrRegion;
|
||||||
|
@ -289,6 +290,7 @@ void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic) const {
|
||||||
StringRef StrTable, SymtabName;
|
StringRef StrTable, SymtabName;
|
||||||
size_t Entries = 0;
|
size_t Entries = 0;
|
||||||
Elf_Sym_Range Syms(nullptr, nullptr);
|
Elf_Sym_Range Syms(nullptr, nullptr);
|
||||||
|
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
|
||||||
if (IsDynamic) {
|
if (IsDynamic) {
|
||||||
StrTable = DynamicStringTable;
|
StrTable = DynamicStringTable;
|
||||||
Syms = dynamic_symbols();
|
Syms = dynamic_symbols();
|
||||||
|
@ -451,7 +453,7 @@ private:
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
static std::error_code createELFDumper(const ELFFile<ELFT> *Obj,
|
static std::error_code createELFDumper(const ELFObjectFile<ELFT> *Obj,
|
||||||
ScopedPrinter &Writer,
|
ScopedPrinter &Writer,
|
||||||
std::unique_ptr<ObjDumper> &Result) {
|
std::unique_ptr<ObjDumper> &Result) {
|
||||||
Result.reset(new ELFDumper<ELFT>(Obj, Writer));
|
Result.reset(new ELFDumper<ELFT>(Obj, Writer));
|
||||||
|
@ -463,19 +465,19 @@ std::error_code createELFDumper(const object::ObjectFile *Obj,
|
||||||
std::unique_ptr<ObjDumper> &Result) {
|
std::unique_ptr<ObjDumper> &Result) {
|
||||||
// Little-endian 32-bit
|
// Little-endian 32-bit
|
||||||
if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
|
if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
|
||||||
return createELFDumper(ELFObj->getELFFile(), Writer, Result);
|
return createELFDumper(ELFObj, Writer, Result);
|
||||||
|
|
||||||
// Big-endian 32-bit
|
// Big-endian 32-bit
|
||||||
if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
|
if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
|
||||||
return createELFDumper(ELFObj->getELFFile(), Writer, Result);
|
return createELFDumper(ELFObj, Writer, Result);
|
||||||
|
|
||||||
// Little-endian 64-bit
|
// Little-endian 64-bit
|
||||||
if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
|
if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
|
||||||
return createELFDumper(ELFObj->getELFFile(), Writer, Result);
|
return createELFDumper(ELFObj, Writer, Result);
|
||||||
|
|
||||||
// Big-endian 64-bit
|
// Big-endian 64-bit
|
||||||
if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
|
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;
|
return readobj_error::unsupported_obj_file_format;
|
||||||
}
|
}
|
||||||
|
@ -488,7 +490,7 @@ template <class ELFT>
|
||||||
void ELFDumper<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const {
|
void ELFDumper<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const {
|
||||||
unsigned vn_size = sec->sh_size; // Size of section in bytes
|
unsigned vn_size = sec->sh_size; // Size of section in bytes
|
||||||
unsigned vn_count = sec->sh_info; // Number of Verneed entries
|
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;
|
const char *sec_end = sec_start + vn_size;
|
||||||
// The first Verneed entry is at the start of the section.
|
// The first Verneed entry is at the start of the section.
|
||||||
const char *p = sec_start;
|
const char *p = sec_start;
|
||||||
|
@ -522,7 +524,7 @@ template <class ELFT>
|
||||||
void ELFDumper<ELFT>::LoadVersionDefs(const Elf_Shdr *sec) const {
|
void ELFDumper<ELFT>::LoadVersionDefs(const Elf_Shdr *sec) const {
|
||||||
unsigned vd_size = sec->sh_size; // Size of section in bytes
|
unsigned vd_size = sec->sh_size; // Size of section in bytes
|
||||||
unsigned vd_count = sec->sh_info; // Number of Verdef entries
|
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;
|
const char *sec_end = sec_start + vd_size;
|
||||||
// The first Verdef entry is at the start of the section.
|
// The first Verdef entry is at the start of the section.
|
||||||
const char *p = sec_start;
|
const char *p = sec_start;
|
||||||
|
@ -700,13 +702,13 @@ static void printVersionDependencySection(ELFDumper<ELFT> *Dumper,
|
||||||
|
|
||||||
template <typename ELFT> void ELFDumper<ELFT>::printVersionInfo() {
|
template <typename ELFT> void ELFDumper<ELFT>::printVersionInfo() {
|
||||||
// Dump version symbol section.
|
// 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.
|
// 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.
|
// 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>
|
template <typename ELFT>
|
||||||
|
@ -727,7 +729,7 @@ StringRef ELFDumper<ELFT>::getSymbolVersion(StringRef StrTab,
|
||||||
|
|
||||||
// Get the corresponding version index entry
|
// Get the corresponding version index entry
|
||||||
const Elf_Versym *vs = unwrapOrError(
|
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;
|
size_t version_index = vs->vs_index & ELF::VERSYM_VERSION;
|
||||||
|
|
||||||
// Special markers for unversioned symbols.
|
// Special markers for unversioned symbols.
|
||||||
|
@ -760,6 +762,7 @@ StringRef ELFDumper<ELFT>::getSymbolVersion(StringRef StrTab,
|
||||||
|
|
||||||
template <typename ELFT>
|
template <typename ELFT>
|
||||||
StringRef ELFDumper<ELFT>::getStaticSymbolName(uint32_t Index) const {
|
StringRef ELFDumper<ELFT>::getStaticSymbolName(uint32_t Index) const {
|
||||||
|
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
|
||||||
StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*DotSymtabSec));
|
StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*DotSymtabSec));
|
||||||
Elf_Sym_Range Syms = unwrapOrError(Obj->symbols(DotSymtabSec));
|
Elf_Sym_Range Syms = unwrapOrError(Obj->symbols(DotSymtabSec));
|
||||||
if (Index >= Syms.size())
|
if (Index >= Syms.size())
|
||||||
|
@ -807,6 +810,7 @@ void ELFDumper<ELFT>::getSectionNameIndex(const Elf_Sym *Symbol,
|
||||||
if (SectionIndex == SHN_XINDEX)
|
if (SectionIndex == SHN_XINDEX)
|
||||||
SectionIndex = unwrapOrError(object::getExtendedSymbolTableIndex<ELFT>(
|
SectionIndex = unwrapOrError(object::getExtendedSymbolTableIndex<ELFT>(
|
||||||
Symbol, FirstSym, ShndxTable));
|
Symbol, FirstSym, ShndxTable));
|
||||||
|
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
|
||||||
const typename ELFT::Shdr *Sec =
|
const typename ELFT::Shdr *Sec =
|
||||||
unwrapOrError(Obj->getSection(SectionIndex));
|
unwrapOrError(Obj->getSection(SectionIndex));
|
||||||
SectionName = unwrapOrError(Obj->getSectionName(Sec));
|
SectionName = unwrapOrError(Obj->getSectionName(Sec));
|
||||||
|
@ -1375,9 +1379,11 @@ static const char *getElfMipsOptionsOdkType(unsigned Odk) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ELFT>
|
template <typename ELFT>
|
||||||
ELFDumper<ELFT>::ELFDumper(const ELFFile<ELFT> *Obj, ScopedPrinter &Writer)
|
ELFDumper<ELFT>::ELFDumper(const object::ELFObjectFile<ELFT> *ObjF,
|
||||||
: ObjDumper(Writer), Obj(Obj) {
|
ScopedPrinter &Writer)
|
||||||
|
: ObjDumper(Writer), ObjF(ObjF) {
|
||||||
SmallVector<const Elf_Phdr *, 4> LoadSegments;
|
SmallVector<const Elf_Phdr *, 4> LoadSegments;
|
||||||
|
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
|
||||||
for (const Elf_Phdr &Phdr : unwrapOrError(Obj->program_headers())) {
|
for (const Elf_Phdr &Phdr : unwrapOrError(Obj->program_headers())) {
|
||||||
if (Phdr.p_type == ELF::PT_DYNAMIC) {
|
if (Phdr.p_type == ELF::PT_DYNAMIC) {
|
||||||
DynamicTable = createDRIFrom(&Phdr, sizeof(Elf_Dyn));
|
DynamicTable = createDRIFrom(&Phdr, sizeof(Elf_Dyn));
|
||||||
|
@ -1458,7 +1464,7 @@ void ELFDumper<ELFT>::parseDynamicTable(
|
||||||
uint64_t Delta = VAddr - Phdr.p_vaddr;
|
uint64_t Delta = VAddr - Phdr.p_vaddr;
|
||||||
if (Delta >= Phdr.p_filesz)
|
if (Delta >= Phdr.p_filesz)
|
||||||
report_fatal_error("Virtual address is not in any segment");
|
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;
|
uint64_t SONameOffset = 0;
|
||||||
|
@ -1557,51 +1563,51 @@ typename ELFDumper<ELFT>::Elf_Relr_Range ELFDumper<ELFT>::dyn_relrs() const {
|
||||||
|
|
||||||
template<class ELFT>
|
template<class ELFT>
|
||||||
void ELFDumper<ELFT>::printFileHeaders() {
|
void ELFDumper<ELFT>::printFileHeaders() {
|
||||||
ELFDumperStyle->printFileHeaders(Obj);
|
ELFDumperStyle->printFileHeaders(ObjF->getELFFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class ELFT>
|
template<class ELFT>
|
||||||
void ELFDumper<ELFT>::printSections() {
|
void ELFDumper<ELFT>::printSections() {
|
||||||
ELFDumperStyle->printSections(Obj);
|
ELFDumperStyle->printSections(ObjF->getELFFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class ELFT>
|
template<class ELFT>
|
||||||
void ELFDumper<ELFT>::printRelocations() {
|
void ELFDumper<ELFT>::printRelocations() {
|
||||||
ELFDumperStyle->printRelocations(Obj);
|
ELFDumperStyle->printRelocations(ObjF->getELFFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void ELFDumper<ELFT>::printProgramHeaders() {
|
template <class ELFT> void ELFDumper<ELFT>::printProgramHeaders() {
|
||||||
ELFDumperStyle->printProgramHeaders(Obj);
|
ELFDumperStyle->printProgramHeaders(ObjF->getELFFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocations() {
|
template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocations() {
|
||||||
ELFDumperStyle->printDynamicRelocations(Obj);
|
ELFDumperStyle->printDynamicRelocations(ObjF->getELFFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class ELFT>
|
template<class ELFT>
|
||||||
void ELFDumper<ELFT>::printSymbols() {
|
void ELFDumper<ELFT>::printSymbols() {
|
||||||
ELFDumperStyle->printSymbols(Obj);
|
ELFDumperStyle->printSymbols(ObjF->getELFFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class ELFT>
|
template<class ELFT>
|
||||||
void ELFDumper<ELFT>::printDynamicSymbols() {
|
void ELFDumper<ELFT>::printDynamicSymbols() {
|
||||||
ELFDumperStyle->printDynamicSymbols(Obj);
|
ELFDumperStyle->printDynamicSymbols(ObjF->getELFFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void ELFDumper<ELFT>::printHashHistogram() {
|
template <class ELFT> void ELFDumper<ELFT>::printHashHistogram() {
|
||||||
ELFDumperStyle->printHashHistogram(Obj);
|
ELFDumperStyle->printHashHistogram(ObjF->getELFFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void ELFDumper<ELFT>::printCGProfile() {
|
template <class ELFT> void ELFDumper<ELFT>::printCGProfile() {
|
||||||
ELFDumperStyle->printCGProfile(Obj);
|
ELFDumperStyle->printCGProfile(ObjF->getELFFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void ELFDumper<ELFT>::printNotes() {
|
template <class ELFT> void ELFDumper<ELFT>::printNotes() {
|
||||||
ELFDumperStyle->printNotes(Obj);
|
ELFDumperStyle->printNotes(ObjF->getELFFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void ELFDumper<ELFT>::printELFLinkerOptions() {
|
template <class ELFT> void ELFDumper<ELFT>::printELFLinkerOptions() {
|
||||||
ELFDumperStyle->printELFLinkerOptions(Obj);
|
ELFDumperStyle->printELFLinkerOptions(ObjF->getELFFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *getTypeString(unsigned Arch, uint64_t Type) {
|
static const char *getTypeString(unsigned Arch, uint64_t Type) {
|
||||||
|
@ -1842,9 +1848,9 @@ void ELFDumper<ELFT>::printValue(uint64_t Type, uint64_t Value) {
|
||||||
|
|
||||||
template<class ELFT>
|
template<class ELFT>
|
||||||
void ELFDumper<ELFT>::printUnwindInfo() {
|
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) {
|
if (Machine == EM_386 || Machine == EM_X86_64) {
|
||||||
DwarfCFIEH::PrinterContext<ELFT> Ctx(W, Obj);
|
DwarfCFIEH::PrinterContext<ELFT> Ctx(W, ObjF);
|
||||||
return Ctx.printUnwindInformation();
|
return Ctx.printUnwindInformation();
|
||||||
}
|
}
|
||||||
W.startLine() << "UnwindInfo not implemented.\n";
|
W.startLine() << "UnwindInfo not implemented.\n";
|
||||||
|
@ -1853,6 +1859,7 @@ void ELFDumper<ELFT>::printUnwindInfo() {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <> void ELFDumper<ELF32LE>::printUnwindInfo() {
|
template <> void ELFDumper<ELF32LE>::printUnwindInfo() {
|
||||||
|
const ELFFile<ELF32LE> *Obj = ObjF->getELFFile();
|
||||||
const unsigned Machine = Obj->getHeader()->e_machine;
|
const unsigned Machine = Obj->getHeader()->e_machine;
|
||||||
if (Machine == EM_ARM) {
|
if (Machine == EM_ARM) {
|
||||||
ARM::EHABI::PrinterContext<ELF32LE> Ctx(W, Obj, DotSymtabSec);
|
ARM::EHABI::PrinterContext<ELF32LE> Ctx(W, Obj, DotSymtabSec);
|
||||||
|
@ -1895,7 +1902,7 @@ void ELFDumper<ELFT>::printDynamicTable() {
|
||||||
uintX_t Tag = Entry.getTag();
|
uintX_t Tag = Entry.getTag();
|
||||||
++I;
|
++I;
|
||||||
W.startLine() << " " << format_hex(Tag, Is64 ? 18 : 10, opts::Output != opts::GNU) << " "
|
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());
|
printValue(Tag, Entry.getVal());
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
}
|
}
|
||||||
|
@ -1962,6 +1969,7 @@ void ELFDumper<ELFT>::printAttributes() {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <> void ELFDumper<ELF32LE>::printAttributes() {
|
template <> void ELFDumper<ELF32LE>::printAttributes() {
|
||||||
|
const ELFFile<ELF32LE> *Obj = ObjF->getELFFile();
|
||||||
if (Obj->getHeader()->e_machine != EM_ARM) {
|
if (Obj->getHeader()->e_machine != EM_ARM) {
|
||||||
W.startLine() << "Attributes not implemented.\n";
|
W.startLine() << "Attributes not implemented.\n";
|
||||||
return;
|
return;
|
||||||
|
@ -2247,6 +2255,7 @@ MipsGOTParser<ELFT>::getPltSym(const Entry *E) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void ELFDumper<ELFT>::printMipsPLTGOT() {
|
template <class ELFT> void ELFDumper<ELFT>::printMipsPLTGOT() {
|
||||||
|
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
|
||||||
if (Obj->getHeader()->e_machine != EM_MIPS)
|
if (Obj->getHeader()->e_machine != EM_MIPS)
|
||||||
reportError("MIPS PLT GOT is available for MIPS targets only");
|
reportError("MIPS PLT GOT is available for MIPS targets only");
|
||||||
|
|
||||||
|
@ -2331,6 +2340,7 @@ static int getMipsRegisterSize(uint8_t Flag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void ELFDumper<ELFT>::printMipsABIFlags() {
|
template <class ELFT> void ELFDumper<ELFT>::printMipsABIFlags() {
|
||||||
|
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
|
||||||
const Elf_Shdr *Shdr = findSectionByName(*Obj, ".MIPS.abiflags");
|
const Elf_Shdr *Shdr = findSectionByName(*Obj, ".MIPS.abiflags");
|
||||||
if (!Shdr) {
|
if (!Shdr) {
|
||||||
W.startLine() << "There is no .MIPS.abiflags section in the file.\n";
|
W.startLine() << "There is no .MIPS.abiflags section in the file.\n";
|
||||||
|
@ -2376,6 +2386,7 @@ static void printMipsReginfoData(ScopedPrinter &W,
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() {
|
template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() {
|
||||||
|
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
|
||||||
const Elf_Shdr *Shdr = findSectionByName(*Obj, ".reginfo");
|
const Elf_Shdr *Shdr = findSectionByName(*Obj, ".reginfo");
|
||||||
if (!Shdr) {
|
if (!Shdr) {
|
||||||
W.startLine() << "There is no .reginfo section in the file.\n";
|
W.startLine() << "There is no .reginfo section in the file.\n";
|
||||||
|
@ -2393,6 +2404,7 @@ template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void ELFDumper<ELFT>::printMipsOptions() {
|
template <class ELFT> void ELFDumper<ELFT>::printMipsOptions() {
|
||||||
|
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
|
||||||
const Elf_Shdr *Shdr = findSectionByName(*Obj, ".MIPS.options");
|
const Elf_Shdr *Shdr = findSectionByName(*Obj, ".MIPS.options");
|
||||||
if (!Shdr) {
|
if (!Shdr) {
|
||||||
W.startLine() << "There is no .MIPS.options section in the file.\n";
|
W.startLine() << "There is no .MIPS.options section in the file.\n";
|
||||||
|
@ -2422,6 +2434,7 @@ template <class ELFT> void ELFDumper<ELFT>::printMipsOptions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void ELFDumper<ELFT>::printStackMap() const {
|
template <class ELFT> void ELFDumper<ELFT>::printStackMap() const {
|
||||||
|
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
|
||||||
const Elf_Shdr *StackMapSection = nullptr;
|
const Elf_Shdr *StackMapSection = nullptr;
|
||||||
for (const auto &Sec : unwrapOrError(Obj->sections())) {
|
for (const auto &Sec : unwrapOrError(Obj->sections())) {
|
||||||
StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
|
StringRef Name = unwrapOrError(Obj->getSectionName(&Sec));
|
||||||
|
@ -2442,11 +2455,11 @@ template <class ELFT> void ELFDumper<ELFT>::printStackMap() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void ELFDumper<ELFT>::printGroupSections() {
|
template <class ELFT> void ELFDumper<ELFT>::printGroupSections() {
|
||||||
ELFDumperStyle->printGroupSections(Obj);
|
ELFDumperStyle->printGroupSections(ObjF->getELFFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> void ELFDumper<ELFT>::printAddrsig() {
|
template <class ELFT> void ELFDumper<ELFT>::printAddrsig() {
|
||||||
ELFDumperStyle->printAddrsig(Obj);
|
ELFDumperStyle->printAddrsig(ObjF->getELFFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void printFields(formatted_raw_ostream &OS, StringRef Str1,
|
static inline void printFields(formatted_raw_ostream &OS, StringRef Str1,
|
||||||
|
|
Loading…
Reference in New Issue