summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Atanasyan <simon@atanasyan.com>2018-12-03 21:54:43 +0000
committerSimon Atanasyan <simon@atanasyan.com>2018-12-03 21:54:43 +0000
commitf76884b0d3b96a151d1c631685f9770d45630173 (patch)
tree249e806d4c0bf78150cf452968e8832b05c6e86a
parenta45a55fc6735fd7f44fec46c49717e8a687738c9 (diff)
downloadbcm5719-llvm-f76884b0d3b96a151d1c631685f9770d45630173.tar.gz
bcm5719-llvm-f76884b0d3b96a151d1c631685f9770d45630173.zip
[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
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp3
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp8
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h1
-rw-r--r--llvm/lib/Target/Mips/MipsAsmPrinter.cpp24
-rw-r--r--llvm/lib/Target/Mips/MipsTargetObjectFile.cpp4
5 files changed, 30 insertions, 10 deletions
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index 8e880b635c1..f43a4d980f9 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -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;
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp
index 0bddba78145..99857e083c6 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.cpp
@@ -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:
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h
index 495d525ccff..bf3274ab5d1 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h
@@ -22,6 +22,7 @@ public:
MEK_None,
MEK_CALL_HI16,
MEK_CALL_LO16,
+ MEK_DTPREL,
MEK_DTPREL_HI,
MEK_DTPREL_LO,
MEK_GOT,
diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
index 75d01a05b91..362431fd42a 100644
--- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -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
diff --git a/llvm/lib/Target/Mips/MipsTargetObjectFile.cpp b/llvm/lib/Target/Mips/MipsTargetObjectFile.cpp
index f767c832198..f53ee0631b5 100644
--- a/llvm/lib/Target/Mips/MipsTargetObjectFile.cpp
+++ b/llvm/lib/Target/Mips/MipsTargetObjectFile.cpp
@@ -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());
}
OpenPOWER on IntegriCloud