forked from OSchip/llvm-project
[DebugInfo][ARM] Fix incorrect debug information for RWPI accessed globals
When compiling for the RWPI relocation model the debug information is wrong: * the debug location is described as { DW_OP_addr Var } instead of { DW_OP_constNu Var DW_OP_bregX 0 DW_OP_plus } * the relocation type is R_ARM_ABS32 instead of R_ARM_SBREL32 Differential Revision: https://reviews.llvm.org/D111404
This commit is contained in:
parent
b8ce97372d
commit
04dc68710a
|
@ -15,6 +15,7 @@
|
||||||
#define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
|
#define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
|
||||||
|
|
||||||
#include "llvm/MC/MCObjectFileInfo.h"
|
#include "llvm/MC/MCObjectFileInfo.h"
|
||||||
|
#include "llvm/MC/MCRegister.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
@ -219,6 +220,14 @@ public:
|
||||||
return SupportDebugThreadLocalLocation;
|
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
|
/// Get the target specific PC relative GOT entry relocation
|
||||||
virtual const MCExpr *getIndirectSymViaGOTPCRel(const GlobalValue *GV,
|
virtual const MCExpr *getIndirectSymViaGOTPCRel(const GlobalValue *GV,
|
||||||
const MCSymbol *Sym,
|
const MCSymbol *Sym,
|
||||||
|
|
|
@ -262,14 +262,14 @@ void DwarfCompileUnit::addLocationAttribute(
|
||||||
|
|
||||||
if (Global) {
|
if (Global) {
|
||||||
const MCSymbol *Sym = Asm->getSymbol(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 (Global->isThreadLocal()) {
|
||||||
if (Asm->TM.useEmulatedTLS()) {
|
if (Asm->TM.useEmulatedTLS()) {
|
||||||
// TODO: add debug info for emulated thread local mode.
|
// TODO: add debug info for emulated thread local mode.
|
||||||
} else {
|
} else {
|
||||||
// FIXME: Make this work with -gsplit-dwarf.
|
// 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:
|
// Based on GCC's support for TLS:
|
||||||
if (!DD->useSplitDwarf()) {
|
if (!DD->useSplitDwarf()) {
|
||||||
// 1) Start with a constNu of the appropriate pointer size
|
// 1) Start with a constNu of the appropriate pointer size
|
||||||
|
@ -292,6 +292,24 @@ void DwarfCompileUnit::addLocationAttribute(
|
||||||
DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address
|
DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address
|
||||||
: dwarf::DW_OP_form_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 {
|
} else {
|
||||||
DD->addArangeLabel(SymbolCU(this, Sym));
|
DD->addArangeLabel(SymbolCU(this, Sym));
|
||||||
addOpAddress(*Loc, Sym);
|
addOpAddress(*Loc, Sym);
|
||||||
|
|
|
@ -54,6 +54,16 @@ void ARMElfTargetObjectFile::Initialize(MCContext &Ctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 MCExpr *ARMElfTargetObjectFile::getTTypeGlobalReference(
|
||||||
const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM,
|
const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM,
|
||||||
MachineModuleInfo *MMI, MCStreamer &Streamer) const {
|
MachineModuleInfo *MMI, MCStreamer &Streamer) const {
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
|
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
|
||||||
#include "llvm/MC/MCExpr.h"
|
#include "llvm/MC/MCExpr.h"
|
||||||
|
#include "llvm/MC/MCRegister.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
|
@ -23,6 +24,10 @@ public:
|
||||||
|
|
||||||
void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
|
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,
|
const MCExpr *getTTypeGlobalReference(const GlobalValue *GV,
|
||||||
unsigned Encoding,
|
unsigned Encoding,
|
||||||
const TargetMachine &TM,
|
const TargetMachine &TM,
|
||||||
|
|
|
@ -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)"}
|
Loading…
Reference in New Issue