Index: lib/MC/MCExpr.cpp =================================================================== --- lib/MC/MCExpr.cpp +++ lib/MC/MCExpr.cpp @@ -709,10 +709,12 @@ !ABE->getRHS()->evaluateAsRelocatableImpl(RHSValue, Asm, Layout, Fixup, Addrs, InSet)) return false; + bool LHSAbs = LHSValue.isAbsolute(); + bool RHSAbs = RHSValue.isAbsolute(); // We only support a few operations on non-constant expressions, handle // those first. - if (!LHSValue.isAbsolute() || !RHSValue.isAbsolute()) { + if (!LHSAbs && !RHSAbs) { switch (ABE->getOpcode()) { default: return false; @@ -766,6 +768,21 @@ case MCBinaryExpr::Xor: Result = LHS ^ RHS; break; } + // One side evaluates as absolute, adjust the relocatable addend + if (LHSAbs ^ RHSAbs) { + MCValue &RelValue = LHSAbs ? RHSValue : LHSValue; + switch (ABE->getOpcode()) { + default: + return false; + case MCBinaryExpr::Sub: + case MCBinaryExpr::Add: + break; + } + Res = MCValue::get(RelValue.getSymA(), RelValue.getSymB(), + Result, RelValue.getRefKind()); + return true; + } + Res = MCValue::get(Result); return true; } Index: test/MC/ARM/dot-symbol-relocation.s =================================================================== --- test/MC/ARM/dot-symbol-relocation.s +++ test/MC/ARM/dot-symbol-relocation.s @@ -0,0 +1,16 @@ +# RUN: llvm-mc -filetype=obj -triple=arm -o - %s | \ +# RUN: llvm-objdump -triple=arm -r -s - | FileCheck %s + +# CHECK: 00000004 R_ARM_ABS32 .text +# CHECK: 00000008 R_ARM_ABS32 .text +# CHECK: 0000000c R_ARM_ABS32 .text +# CHECK: 00000010 R_ARM_ABS32 .text +# CHECK: 00000014 R_ARM_ABS32 .text +# CHECK: 42000000 46000000 c6ffffff 4e000000 +# CHECK: 52000000 1c010000 +.word 0x42 +.word 0x42 - . +.word . - 0x42 +.word 0x42 + . +.word . + 0x42 +.word 0x42 + 0x42 + . + 0x42 + 0x42 \ No newline at end of file