Skip to content

[BOLT] Add --custom-allocation-vma flag #136385

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

Merged
merged 3 commits into from
Apr 19, 2025

Conversation

rafaelauler
Copy link
Contributor

Add an advanced-user flag so we are able to rewrite binaries when we fail
to identify a suitable location to put new code. User then can supply a custom
location via --custom-allocation-vma. This happens more obviously if the binary
has segments mapped to very high addresses.

@llvmbot
Copy link
Member

llvmbot commented Apr 18, 2025

@llvm/pr-subscribers-bolt

Author: Rafael Auler (rafaelauler)

Changes

Add an advanced-user flag so we are able to rewrite binaries when we fail
to identify a suitable location to put new code. User then can supply a custom
location via --custom-allocation-vma. This happens more obviously if the binary
has segments mapped to very high addresses.


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

2 Files Affected:

  • (modified) bolt/lib/Rewrite/RewriteInstance.cpp (+26)
  • (added) bolt/test/X86/high-segments.s (+46)
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 37dcfa868c211..518c8150d6728 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -237,6 +237,13 @@ UseGnuStack("use-gnu-stack",
   cl::ZeroOrMore,
   cl::cat(BoltCategory));
 
+static cl::opt<uint64_t>
+CustomAllocationVMA("custom-allocation-vma",
+           cl::desc("use a custom address at which new code will be put, "
+                    "bypassing BOLT's logic to detect where to put code"),
+  cl::ZeroOrMore,
+  cl::cat(BoltCategory));
+
 static cl::opt<bool>
 SequentialDisassembly("sequential-disassembly",
   cl::desc("performs disassembly sequentially"),
@@ -592,6 +599,25 @@ Error RewriteInstance::discoverStorage() {
 
   FirstNonAllocatableOffset = NextAvailableOffset;
 
+  if (opts::CustomAllocationVMA) {
+    // If user specified a custom address where we should start writing new
+    // data, honor that.
+    NextAvailableAddress = opts::CustomAllocationVMA;
+    // Sanity check the user-supplied address and emit warnings if something
+    // seems off.
+    for (const ELF64LE::Phdr &Phdr : PHs) {
+      switch (Phdr.p_type) {
+        case ELF::PT_LOAD:
+          if (NextAvailableAddress >= Phdr.p_vaddr &&
+              NextAvailableAddress < Phdr.p_vaddr + Phdr.p_memsz) {
+            BC->errs() << "BOLT-WARNING: user-supplied allocation vma 0x"
+                       << Twine::utohexstr(NextAvailableAddress)
+                       << " conflicts with ELF segment at 0x"
+                       << Twine::utohexstr(Phdr.p_vaddr) << "\n";
+          }
+      }
+    }
+  }
   NextAvailableAddress = alignTo(NextAvailableAddress, BC->PageAlign);
   NextAvailableOffset = alignTo(NextAvailableOffset, BC->PageAlign);
 
diff --git a/bolt/test/X86/high-segments.s b/bolt/test/X86/high-segments.s
new file mode 100644
index 0000000000000..dfddf18004c2a
--- /dev/null
+++ b/bolt/test/X86/high-segments.s
@@ -0,0 +1,46 @@
+// Check that we are able to rewrite binaries when we fail to identify a
+// suitable location to put new code and user supplies a custom one via
+// --custom-allocation-vma. This happens more obviously if the binary has
+// segments mapped to very high addresses.
+
+// In this example, my.reserved.section is mapped to a segment to be loaded
+// at address 0x10000000000, while regular text should be at 0x200000. We
+// pick a vma in the middle at 0x700000 to carve space for BOLT to put data,
+// since BOLT's usual route of allocating after the last segment will put
+// code far away and that will blow up relocations from main.
+
+// RUN: split-file %s %t
+// RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %t/main.s -o %t.o
+// RUN: %clang %cflags -no-pie %t.o -o %t.exe -Wl,-T %t/main.ls
+// RUN: llvm-bolt %t.exe -o %t.bolt --custom-allocation-vma=0x700000
+
+//--- main.s
+  .type            reserved_space,@object
+  .section        .my.reserved.section,"awx",@nobits
+  .globl           reserved_space
+  .p2align         4, 0x0
+reserved_space:
+  .zero  0x80000000
+  .size   reserved_space, 0x80000000
+
+	.text
+  .globl main
+  .globl _start
+  .type main, %function
+_start:
+main:
+	.cfi_startproc
+  nop
+  nop
+  nop
+  retq
+	.cfi_endproc
+.size main, .-main
+
+//--- main.ls
+SECTIONS
+{
+    .my.reserved.section 1<<40 : {
+      *(.my.reserved.section);
+    }
+} INSERT BEFORE .comment;

Copy link

github-actions bot commented Apr 18, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@aaupov aaupov left a comment

Choose a reason for hiding this comment

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

LGTM, but please fix formatting before landing

@rafaelauler rafaelauler force-pushed the users/rafaelauler/bolt-add-vma-flag branch from ea291ae to 3c806af Compare April 19, 2025 00:50
@@ -237,6 +237,12 @@ UseGnuStack("use-gnu-stack",
cl::ZeroOrMore,
cl::cat(BoltCategory));

static cl::opt<uint64_t> CustomAllocationVMA(
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you want this flag to be at the top level or hidden?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, it's a good idea to put it hidden. Let me do that.

@rafaelauler rafaelauler merged commit 3bcb724 into main Apr 19, 2025
10 checks passed
@rafaelauler rafaelauler deleted the users/rafaelauler/bolt-add-vma-flag branch April 19, 2025 04:02
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
Add an advanced-user flag so we are able to rewrite binaries when we fail
to identify a suitable location to put new code. User then can supply a
custom location via --custom-allocation-vma. This happens more obviously if the
binary has segments mapped to very high addresses.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
Add an advanced-user flag so we are able to rewrite binaries when we fail
to identify a suitable location to put new code. User then can supply a
custom location via --custom-allocation-vma. This happens more obviously if the
binary has segments mapped to very high addresses.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
Add an advanced-user flag so we are able to rewrite binaries when we fail
to identify a suitable location to put new code. User then can supply a
custom location via --custom-allocation-vma. This happens more obviously if the
binary has segments mapped to very high addresses.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants