[PATCH] D64948: IR: Teach Constant::needsRelocation() that relative pointers don't need to be relocated.

Peter Collingbourne via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 18 13:46:50 PDT 2019


pcc created this revision.
pcc added reviewers: rnk, eugenis.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.

This causes sections with relative pointers to be marked as read only,
which means that they won't end up sharing pages with writable data.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D64948

Files:
  llvm/lib/IR/Constants.cpp
  llvm/test/CodeGen/X86/relptr-rodata.ll


Index: llvm/test/CodeGen/X86/relptr-rodata.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/X86/relptr-rodata.ll
@@ -0,0 +1,21 @@
+; RUN: llc -relocation-model=pic -data-sections -o - %s | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+ at hidden = external hidden global i8
+ at default = external global i8
+
+; CHECK: .section .rodata.rodata
+; CHECK: rodata:
+; CHECK: .long hidden-rodata
+ at rodata = hidden constant i32 trunc (i64 sub (i64 ptrtoint (i8* @hidden to i64), i64 ptrtoint (i32* @rodata to i64)) to i32)
+
+; CHECK: .section .data.rel.ro.relro1
+; CHECK: relro1:
+; CHECK: .long default-relro1
+ at relro1 = hidden constant i32 trunc (i64 sub (i64 ptrtoint (i8* @default to i64), i64 ptrtoint (i32* @relro1 to i64)) to i32)
+
+; CHECK: .section .data.rel.ro.relro2
+; CHECK: relro2:
+; CHECK: .long hidden-relro2
+ at relro2 = constant i32 trunc (i64 sub (i64 ptrtoint (i8* @hidden to i64), i64 ptrtoint (i32* @relro2 to i64)) to i32)
Index: llvm/lib/IR/Constants.cpp
===================================================================
--- llvm/lib/IR/Constants.cpp
+++ llvm/lib/IR/Constants.cpp
@@ -502,22 +502,34 @@
   if (const BlockAddress *BA = dyn_cast<BlockAddress>(this))
     return BA->getFunction()->needsRelocation();
 
-  // While raw uses of blockaddress need to be relocated, differences between
-  // two of them don't when they are for labels in the same function.  This is a
-  // common idiom when creating a table for the indirect goto extension, so we
-  // handle it efficiently here.
-  if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(this))
+  if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(this)) {
     if (CE->getOpcode() == Instruction::Sub) {
       ConstantExpr *LHS = dyn_cast<ConstantExpr>(CE->getOperand(0));
       ConstantExpr *RHS = dyn_cast<ConstantExpr>(CE->getOperand(1));
       if (LHS && RHS && LHS->getOpcode() == Instruction::PtrToInt &&
-          RHS->getOpcode() == Instruction::PtrToInt &&
-          isa<BlockAddress>(LHS->getOperand(0)) &&
-          isa<BlockAddress>(RHS->getOperand(0)) &&
-          cast<BlockAddress>(LHS->getOperand(0))->getFunction() ==
-              cast<BlockAddress>(RHS->getOperand(0))->getFunction())
-        return false;
+          RHS->getOpcode() == Instruction::PtrToInt) {
+        Constant *LHSOp0 = LHS->getOperand(0);
+        Constant *RHSOp0 = RHS->getOperand(0);
+
+        // While raw uses of blockaddress need to be relocated, differences
+        // between two of them don't when they are for labels in the same
+        // function.  This is a common idiom when creating a table for the
+        // indirect goto extension, so we handle it efficiently here.
+        if (isa<BlockAddress>(LHSOp0) && isa<BlockAddress>(LHSOp0) &&
+            cast<BlockAddress>(LHSOp0)->getFunction() ==
+                cast<BlockAddress>(RHSOp0)->getFunction())
+          return false;
+
+        // Relative pointers do not need to be dynamically relocated.
+        if (auto *LHSGV = dyn_cast<GlobalValue>(
+                LHSOp0->stripPointerCastsNoFollowAliases()))
+          if (auto *RHSGV = dyn_cast<GlobalValue>(
+                  RHSOp0->stripPointerCastsNoFollowAliases()))
+            if (LHSGV->isDSOLocal() && RHSGV->isDSOLocal())
+              return false;
+      }
     }
+  }
 
   bool Result = false;
   for (unsigned i = 0, e = getNumOperands(); i != e; ++i)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D64948.210661.patch
Type: text/x-patch
Size: 3452 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190718/d1139c9b/attachment.bin>


More information about the llvm-commits mailing list