Fix up MCFixup::getAccessVariant to handle unary expressions.
authorKaelyn Takata <rikka@google.com>
Mon, 14 Apr 2014 16:50:22 +0000 (16:50 +0000)
committerKaelyn Takata <rikka@google.com>
Mon, 14 Apr 2014 16:50:22 +0000 (16:50 +0000)
This allows correct relocations to be generated for a symbolic
address that is being adjusted by a negative constant. Since r204294,
such expressions have triggered undefined behavior when LLVM was built
without assertions.

Credit goes to Rafael for this patch; I'm submitting it on his behalf
as he is on vacation this week.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206192 91177308-0d34-0410-b5e6-96231b3b80d8

lib/MC/MCFixup.cpp
test/MC/ELF/relocation.s

index 8f15db571f3a4208ce13d9d0f3c86e07990d35ef..dab4197b1a41a54e895d4a64aa1833dfe46df243 100644 (file)
@@ -12,7 +12,12 @@ using namespace llvm;
 
 static MCSymbolRefExpr::VariantKind getAccessVariant(const MCExpr *Expr) {
   switch (Expr->getKind()) {
-  case MCExpr::Unary:
+  case MCExpr::Unary: {
+    const MCUnaryExpr *UE = cast<MCUnaryExpr>(Expr);
+    assert(getAccessVariant(UE->getSubExpr()) == MCSymbolRefExpr::VK_None);
+    return MCSymbolRefExpr::VK_None;
+  }
+
   case MCExpr::Target:
     llvm_unreachable("unsupported");
 
index d2ee6afda36c38e51c19478ddd85920e7c10c5d9..7755f06f3f4819d52ae42ca990ab475d1265dee2 100644 (file)
@@ -28,6 +28,8 @@ bar:
        zed = foo +2
        call zed@PLT
 
+        leaq    -1+foo(%rip), %r11
+
 // CHECK:        Section {
 // CHECK:          Name: .rela.text
 // CHECK:          Relocations [
@@ -53,6 +55,7 @@ bar:
 // CHECK-NEXT:       0x8D R_X86_64_PC16 foo 0x8D
 // CHECK-NEXT:       0x8F R_X86_64_PC8 foo 0x8F
 // CHECK-NEXT:       0x91 R_X86_64_PLT32 foo 0xFFFFFFFFFFFFFFFE
+// CHECK-NEXT:       0x98 R_X86_64_PC32 foo 0xFFFFFFFFFFFFFFFB
 // CHECK-NEXT:     ]
 // CHECK-NEXT:   }