diff --git a/llvm/include/llvm/Target/TargetLoweringObjectFile.h b/llvm/include/llvm/Target/TargetLoweringObjectFile.h --- a/llvm/include/llvm/Target/TargetLoweringObjectFile.h +++ b/llvm/include/llvm/Target/TargetLoweringObjectFile.h @@ -15,6 +15,7 @@ #define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H #include "llvm/MC/MCObjectFileInfo.h" +#include "llvm/MC/MCRegister.h" #include namespace llvm { @@ -219,6 +220,14 @@ return SupportDebugThreadLocalLocation; } + /// Returns the register used as static base in RWPI variants. + virtual const MCRegister getStaticBase() const { return MCRegister::NoRegister; } + + /// Get the target specific RWPI relocation. + virtual const MCExpr *getIndirectSymViaRWPI(const MCSymbol *Sym) const { + return nullptr; + } + /// Get the target specific PC relative GOT entry relocation virtual const MCExpr *getIndirectSymViaGOTPCRel(const GlobalValue *GV, const MCSymbol *Sym, diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -262,14 +262,14 @@ if (Global) { const MCSymbol *Sym = Asm->getSymbol(Global); + unsigned PointerSize = Asm->getDataLayout().getPointerSize(); + assert((PointerSize == 4 || PointerSize == 8) && + "Add support for other sizes if necessary"); if (Global->isThreadLocal()) { if (Asm->TM.useEmulatedTLS()) { // TODO: add debug info for emulated thread local mode. } else { // FIXME: Make this work with -gsplit-dwarf. - unsigned PointerSize = Asm->getDataLayout().getPointerSize(); - assert((PointerSize == 4 || PointerSize == 8) && - "Add support for other sizes if necessary"); // Based on GCC's support for TLS: if (!DD->useSplitDwarf()) { // 1) Start with a constNu of the appropriate pointer size @@ -292,6 +292,24 @@ DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address : dwarf::DW_OP_form_tls_address); } + } else if (Asm->TM.getRelocationModel() == Reloc::RWPI || + Asm->TM.getRelocationModel() == Reloc::ROPI_RWPI) { + // Constant + addUInt(*Loc, dwarf::DW_FORM_data1, + PointerSize == 4 ? dwarf::DW_OP_const4u + : dwarf::DW_OP_const8u); + // Relocation offset + addExpr(*Loc, PointerSize == 4 ? dwarf::DW_FORM_data4 + : dwarf::DW_FORM_data8, + Asm->getObjFileLowering().getIndirectSymViaRWPI(Sym)); + // Base register + Register BaseReg = Asm->getObjFileLowering().getStaticBase(); + BaseReg = Asm->TM.getMCRegisterInfo()->getDwarfRegNum(BaseReg, false); + addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + BaseReg); + // Offset from base register + addSInt(*Loc, dwarf::DW_FORM_sdata, 0); + // Operation + addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); } else { DD->addArangeLabel(SymbolCU(this, Sym)); addOpAddress(*Loc, Sym); diff --git a/llvm/lib/Target/ARM/ARMTargetObjectFile.h b/llvm/lib/Target/ARM/ARMTargetObjectFile.h --- a/llvm/lib/Target/ARM/ARMTargetObjectFile.h +++ b/llvm/lib/Target/ARM/ARMTargetObjectFile.h @@ -11,6 +11,7 @@ #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCRegister.h" namespace llvm { @@ -23,6 +24,10 @@ void Initialize(MCContext &Ctx, const TargetMachine &TM) override; + const MCRegister getStaticBase() const override; + + const MCExpr *getIndirectSymViaRWPI(const MCSymbol *Sym) const override; + const MCExpr *getTTypeGlobalReference(const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, diff --git a/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp b/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp --- a/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp +++ b/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp @@ -54,6 +54,16 @@ } } +const MCRegister ARMElfTargetObjectFile::getStaticBase() const { + return ARM::R9; +} + +const MCExpr *ARMElfTargetObjectFile:: +getIndirectSymViaRWPI(const MCSymbol *Sym) const { + return MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_ARM_SBREL, + getContext()); +} + const MCExpr *ARMElfTargetObjectFile::getTTypeGlobalReference( const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, MachineModuleInfo *MMI, MCStreamer &Streamer) const { diff --git a/llvm/test/DebugInfo/ARM/rwpi.ll b/llvm/test/DebugInfo/ARM/rwpi.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/ARM/rwpi.ll @@ -0,0 +1,34 @@ +; RUN: llc -mtriple armv7-linux -relocation-model=rwpi -o - %s | FileCheck %s +; RUN: llc -mtriple armv7-linux -relocation-model=ropi-rwpi -o - %s | FileCheck %s + +@global = global i32 5, align 4, !dbg !0 + +; 8 bytes of data +; CHECK: .byte 8 @ DW_AT_location +; DW_OP_const4u +; CHECK-NEXT: .byte 12 +; relocation offset +; CHECK-NEXT: .long global(sbrel) +; DW_OP_breg9 +; CHECK-NEXT: .byte 121 +; offset from breg9 +; CHECK-NEXT: .byte 0 +; DW_OP_plus +; CHECK-NEXT: .byte 34 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!6, !7, !8, !9, !10} +!llvm.ident = !{!11} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "global", scope: !2, file: !3, line: 1, type: !5, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 14.0.0 (https://github.com/llvm/llvm-project.git 9f5c70c7ad404f0cb52416a0574d9e48d520be5d)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "rwpi.c", directory: "/tmp") +!4 = !{!0} +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !{i32 7, !"Dwarf Version", i32 4} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i32 1, !"wchar_size", i32 4} +!9 = !{i32 1, !"min_enum_size", i32 4} +!10 = !{i32 7, !"frame-pointer", i32 2} +!11 = !{!"clang version 14.0.0 (https://github.com/llvm/llvm-project.git 9f5c70c7ad404f0cb52416a0574d9e48d520be5d)"}