forked from OSchip/llvm-project
[mips] Fix TestDWARF32Version5Addr8AllForms test failure on MIPS hosts
The `DIEExpr` is used in debug information entries for either TLS variables or call sites. For now the last case is unsupported for targets with delay slots, for MIPS in particular. The `DIEExpr::EmitValue` method calls a virtual `EmitDebugThreadLocal` routine which, in case of MIPS, always emits either `.dtprelword` or `.dtpreldword` directives. That is okay for "main" code, but in unit tests `DIEExpr` instances can be created not for TLS variables only even on MIPS hosts. That is a reason of the `TestDWARF32Version5Addr8AllForms` failure because handling of the `R_MIPS_TLS_DTPREL` relocation writes incorrect value into dwarf structures. And anyway unconditional emitting of `.dtprelword` directives will be incorrect when/if debug information entries for call sites become supported on MIPS. The patch solves the problem by wrapping expression created in the `MipsTargetObjectFile::getDebugThreadLocalSymbol` method in to the `MipsMCExpr` expression with a new `MEK_DTPREL` tag. This tag is recognized in the `MipsAsmPrinter::EmitDebugThreadLocal` method and `.dtprelword` directives created in this case only. In other cases the expression saved as a regular data. Differential Revision: http://reviews.llvm.org/D54937 llvm-svn: 348194
This commit is contained in:
parent
a45a55fc67
commit
f76884b0d3
|
@ -613,6 +613,9 @@ getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
|
|||
case MipsMCExpr::MEK_Special:
|
||||
llvm_unreachable("Unhandled fixup kind!");
|
||||
break;
|
||||
case MipsMCExpr::MEK_DTPREL:
|
||||
llvm_unreachable("MEK_DTPREL is used for TLS DIEExpr only");
|
||||
break;
|
||||
case MipsMCExpr::MEK_CALL_HI16:
|
||||
FixupKind = Mips::fixup_Mips_CALL_HI16;
|
||||
break;
|
||||
|
|
|
@ -43,6 +43,9 @@ void MipsMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
|
|||
case MEK_Special:
|
||||
llvm_unreachable("MEK_None and MEK_Special are invalid");
|
||||
break;
|
||||
case MEK_DTPREL:
|
||||
llvm_unreachable("MEK_DTPREL is used for TLS DIEExpr only");
|
||||
break;
|
||||
case MEK_CALL_HI16:
|
||||
OS << "%call_hi";
|
||||
break;
|
||||
|
@ -157,6 +160,8 @@ MipsMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
|
|||
case MEK_None:
|
||||
case MEK_Special:
|
||||
llvm_unreachable("MEK_None and MEK_Special are invalid");
|
||||
case MEK_DTPREL:
|
||||
llvm_unreachable("MEK_DTPREL is used for TLS DIEExpr only");
|
||||
case MEK_DTPREL_HI:
|
||||
case MEK_DTPREL_LO:
|
||||
case MEK_GOT:
|
||||
|
@ -244,6 +249,9 @@ void MipsMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
|
|||
case MEK_Special:
|
||||
llvm_unreachable("MEK_None and MEK_Special are invalid");
|
||||
break;
|
||||
case MEK_DTPREL:
|
||||
llvm_unreachable("MEK_DTPREL is used for TLS DIEExpr only");
|
||||
break;
|
||||
case MEK_CALL_HI16:
|
||||
case MEK_CALL_LO16:
|
||||
case MEK_GOT:
|
||||
|
|
|
@ -22,6 +22,7 @@ public:
|
|||
MEK_None,
|
||||
MEK_CALL_HI16,
|
||||
MEK_CALL_LO16,
|
||||
MEK_DTPREL,
|
||||
MEK_DTPREL_HI,
|
||||
MEK_DTPREL_LO,
|
||||
MEK_GOT,
|
||||
|
|
|
@ -1205,16 +1205,22 @@ void MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
|
|||
// Emit .dtprelword or .dtpreldword directive
|
||||
// and value for debug thread local expression.
|
||||
void MipsAsmPrinter::EmitDebugValue(const MCExpr *Value, unsigned Size) const {
|
||||
switch (Size) {
|
||||
case 4:
|
||||
OutStreamer->EmitDTPRel32Value(Value);
|
||||
break;
|
||||
case 8:
|
||||
OutStreamer->EmitDTPRel64Value(Value);
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unexpected size of expression value.");
|
||||
if (auto *MipsExpr = dyn_cast<MipsMCExpr>(Value)) {
|
||||
if (MipsExpr && MipsExpr->getKind() == MipsMCExpr::MEK_DTPREL) {
|
||||
switch (Size) {
|
||||
case 4:
|
||||
OutStreamer->EmitDTPRel32Value(MipsExpr->getSubExpr());
|
||||
break;
|
||||
case 8:
|
||||
OutStreamer->EmitDTPRel64Value(MipsExpr->getSubExpr());
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unexpected size of expression value.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
AsmPrinter::EmitDebugValue(Value, Size);
|
||||
}
|
||||
|
||||
// Align all targets of indirect branches on bundle size. Used only if target
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "MipsTargetObjectFile.h"
|
||||
#include "MipsSubtarget.h"
|
||||
#include "MipsTargetMachine.h"
|
||||
#include "MCTargetDesc/MipsMCExpr.h"
|
||||
#include "llvm/BinaryFormat/ELF.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
|
@ -189,6 +190,7 @@ const MCExpr *
|
|||
MipsTargetObjectFile::getDebugThreadLocalSymbol(const MCSymbol *Sym) const {
|
||||
const MCExpr *Expr =
|
||||
MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
|
||||
return MCBinaryExpr::createAdd(
|
||||
Expr = MCBinaryExpr::createAdd(
|
||||
Expr, MCConstantExpr::create(0x8000, getContext()), getContext());
|
||||
return MipsMCExpr::create(MipsMCExpr::MEK_DTPREL, Expr, getContext());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue