summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC/MCObjectStreamer.cpp
diff options
context:
space:
mode:
authorAlex Bradbury <asb@lowrisc.org>2018-08-16 11:26:37 +0000
committerAlex Bradbury <asb@lowrisc.org>2018-08-16 11:26:37 +0000
commitfdc4647ca37c64ba60207b9ec3f412779aa894aa (patch)
tree0a41146e30e8900a2680b3d647eceeb3c6591676 /llvm/lib/MC/MCObjectStreamer.cpp
parent8f46505beb83c39c3fafca55d0d740dc2f58f90e (diff)
downloadbcm5719-llvm-fdc4647ca37c64ba60207b9ec3f412779aa894aa.tar.gz
bcm5719-llvm-fdc4647ca37c64ba60207b9ec3f412779aa894aa.zip
[RISCV][MC] Don't fold symbol differences if requiresDiffExpressionRelocations is true
When emitting the difference between two symbols, the standard behavior is that the difference will be resolved to an absolute value if both of the symbols are offsets from the same data fragment. This is undesirable on architectures such as RISC-V where relaxation in the linker may cause the computed difference to become invalid. This caused an issue when compiling to object code, where the size of a function in the debug information was already calculated even though it could change as a consequence of relaxation in the subsequent linking stage. This patch inhibits the resolution of symbol differences to absolute values where the target's AsmBackend has declared that it does not want these to be folded. Differential Revision: https://reviews.llvm.org/D45773 Patch by Edward Jones. llvm-svn: 339864
Diffstat (limited to 'llvm/lib/MC/MCObjectStreamer.cpp')
-rw-r--r--llvm/lib/MC/MCObjectStreamer.cpp11
1 files changed, 7 insertions, 4 deletions
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 4b6dad5ce8f..102aa4d4513 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -61,9 +61,12 @@ void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
// As a compile-time optimization, avoid allocating and evaluating an MCExpr
// tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment.
-static Optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,
- const MCSymbol *Lo) {
+static Optional<uint64_t>
+absoluteSymbolDiff(MCAssembler &Asm, const MCSymbol *Hi, const MCSymbol *Lo) {
assert(Hi && Lo);
+ if (Asm.getBackendPtr()->requiresDiffExpressionRelocations())
+ return None;
+
if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
Hi->isVariable() || Lo->isVariable())
return None;
@@ -74,7 +77,7 @@ static Optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,
void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
const MCSymbol *Lo,
unsigned Size) {
- if (Optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo)) {
+ if (Optional<uint64_t> Diff = absoluteSymbolDiff(getAssembler(), Hi, Lo)) {
EmitIntValue(*Diff, Size);
return;
}
@@ -83,7 +86,7 @@ void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
const MCSymbol *Lo) {
- if (Optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo)) {
+ if (Optional<uint64_t> Diff = absoluteSymbolDiff(getAssembler(), Hi, Lo)) {
EmitULEB128IntValue(*Diff);
return;
}
OpenPOWER on IntegriCloud