Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BOLT] Support map other function entry address #101466

Merged
merged 1 commit into from
Aug 7, 2024

Conversation

linsinan1995
Copy link
Member

Allow BOLT to map the old address to a new binary address if the old address is the entry of the function.

@llvmbot
Copy link
Member

llvmbot commented Aug 1, 2024

@llvm/pr-subscribers-bolt

Author: sinan (linsinan1995)

Changes

Allow BOLT to map the old address to a new binary address if the old address is the entry of the function.


Full diff: https://github.com/llvm/llvm-project/pull/101466.diff

2 Files Affected:

  • (modified) bolt/lib/Rewrite/RewriteInstance.cpp (+8)
  • (added) bolt/test/X86/dynamic-relocs-on-entry.s (+25)
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 9077869fe4955..e2273472c15de 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -5509,6 +5509,14 @@ uint64_t RewriteInstance::getNewFunctionOrDataAddress(uint64_t OldAddress) {
   if (const BinaryFunction *BF =
           BC->getBinaryFunctionContainingAddress(OldAddress)) {
     if (BF->isEmitted()) {
+      // If OldAddress is the another entry point of
+      // the function, then BOLT could get the new address.
+      if (BF->isMultiEntry()) {
+        for (auto &BB : *BF)
+          if (BB.isEntryPoint() &&
+              (BF->getAddress() + BB.getOffset()) == OldAddress)
+            return BF->getOutputAddress() + BB.getOffset();
+      }
       BC->errs() << "BOLT-ERROR: unable to get new address corresponding to "
                     "input address 0x"
                  << Twine::utohexstr(OldAddress) << " in function " << *BF
diff --git a/bolt/test/X86/dynamic-relocs-on-entry.s b/bolt/test/X86/dynamic-relocs-on-entry.s
new file mode 100644
index 0000000000000..7f47955440dd4
--- /dev/null
+++ b/bolt/test/X86/dynamic-relocs-on-entry.s
@@ -0,0 +1,25 @@
+// This test examines whether BOLT can correctly update when
+// dynamic relocation points to other entry points of the
+// function.
+
+# RUN: %clang %cflags -fPIC -pie %s -o %t.exe -nostdlib -Wl,-q
+# RUN: llvm-bolt %t.exe -o %t.bolt | FileCheck %s
+
+    .text
+    .type   chain, @function
+chain:
+    movq    $1, %rax
+Lable:
+    ret
+    .size   chain, .-chain
+    .type   _start, @function
+    .global _start
+_start:
+    jmpq    *.Lfoo(%rip)
+    ret
+    .size   _start, .-_start
+  .data
+.Lfoo:
+  .quad Lable
+
+# CHECK-NOT: BOLT-ERROR

@linsinan1995
Copy link
Member Author

take the assembly code attached in the test as an example

    .text
    .type   chain, @function
chain:
    movq    $1, %rax
Lable:
    ret
    .size   chain, .-chain
    .type   _start, @function
    .global _start
_start:
    jmpq    *.Lfoo(%rip)
    ret
    .size   _start, .-_start
  .data
.Lfoo:
  .quad Lable

(1) if -no-pie, there is not a dynamic relocation for Label, then everything is fine.

gcc test.s -nostdlib -nodefaultlibs -Wl,-q
llvm-bolt a.out -o a.opt

(2) if it is pie, then an error occurs

gcc test.s -nostdlib -nodefaultlibs -Wl,-q -fPIC -fPIE -pie
llvm-bolt a.out -o a.opt

BOLT-ERROR: unable to get new address corresponding to input address 0x1007 in function chain/1(*2). Consider adding this function to --skip-funcs=...

This change can make the case (2) work

bolt/test/X86/dynamic-relocs-on-entry.s Outdated Show resolved Hide resolved
bolt/test/X86/dynamic-relocs-on-entry.s Outdated Show resolved Hide resolved
@linsinan1995 linsinan1995 force-pushed the support-relocs-on-entries branch from 162bdd9 to 02d2df5 Compare August 2, 2024 12:33
Copy link
Member

@yota9 yota9 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM thanks!
JFYI next time you can use objdump with -R in order to skip extra file creation for readelf+objdump. It's a minor thing so I don't really mind anyway.

@linsinan1995 linsinan1995 force-pushed the support-relocs-on-entries branch from 02d2df5 to 595eaa1 Compare August 2, 2024 12:58
@ayermolo
Copy link
Contributor

ayermolo commented Aug 2, 2024

Looks like an X86 test is failing.

Allow BOLT to map old address to new binary address if the old
address is the other entry of the function.
## Check if the new address in `chain` is correctly updated by BOLT
# CHECK: Relocation section '.rela.dyn' at offset 0x{{.*}} contains 1 entry:
# CHECK: {{.*}} R_X86_64_RELATIVE [[ADDR:.+]]
# CHECK: [[#ADDR]]: c3 retq
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you need either remove # here or (probably even better) make var setting above like [[#%x,ADDR:]]

@linsinan1995 linsinan1995 force-pushed the support-relocs-on-entries branch from 595eaa1 to b049efe Compare August 2, 2024 15:49
Copy link
Member

@yota9 yota9 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test passed, thanks

@linsinan1995
Copy link
Member Author

Thanks for reviewing && suggestions @ayermolo @yota9

I will merge the code by Wednesday if there are no new comments.

@yota9
Copy link
Member

yota9 commented Aug 5, 2024

Also could you please push this one and #69136 to 19.x branch? Thanks!

@linsinan1995 linsinan1995 merged commit 734c048 into llvm:main Aug 7, 2024
6 checks passed
@linsinan1995
Copy link
Member Author

/cherry-pick 734c048

@linsinan1995 linsinan1995 added this to the LLVM 19.X Release milestone Aug 7, 2024
llvmbot pushed a commit to llvmbot/llvm-project that referenced this pull request Aug 7, 2024
Allow BOLT to map the old address to a new binary address if the old
address is the entry of the function.

(cherry picked from commit 734c048)
@llvmbot
Copy link
Member

llvmbot commented Aug 7, 2024

/pull-request #102282

banach-space pushed a commit to banach-space/llvm-project that referenced this pull request Aug 7, 2024
Allow BOLT to map the old address to a new binary address if the old
address is the entry of the function.
TIFitis pushed a commit that referenced this pull request Aug 8, 2024
Allow BOLT to map the old address to a new binary address if the old
address is the entry of the function.
tru pushed a commit to llvmbot/llvm-project that referenced this pull request Aug 10, 2024
Allow BOLT to map the old address to a new binary address if the old
address is the entry of the function.

(cherry picked from commit 734c048)
kstoimenov pushed a commit to kstoimenov/llvm-project that referenced this pull request Aug 15, 2024
Allow BOLT to map the old address to a new binary address if the old
address is the entry of the function.
peterwaller-arm added a commit to peterwaller-arm/llvm-project that referenced this pull request Nov 26, 2024
Add logic to map addresses referring to non-entry basic blocks.

PR llvm#101466 extended this function to enable it to map addresses for
the entry points of multi-entry functions, but this still left
references to individual basic blocks unmappable.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Development

Successfully merging this pull request may close these issues.

4 participants