@@ -237,6 +237,13 @@ UseGnuStack("use-gnu-stack",
237
237
cl::ZeroOrMore,
238
238
cl::cat(BoltCategory));
239
239
240
+ static cl::opt<uint64_t >
241
+ CustomAllocationVMA (" custom-allocation-vma" ,
242
+ cl::desc (" use a custom address at which new code will be put, "
243
+ " bypassing BOLT's logic to detect where to put code" ),
244
+ cl::ZeroOrMore,
245
+ cl::cat(BoltCategory));
246
+
240
247
static cl::opt<bool >
241
248
SequentialDisassembly (" sequential-disassembly" ,
242
249
cl::desc (" performs disassembly sequentially" ),
@@ -592,6 +599,25 @@ Error RewriteInstance::discoverStorage() {
592
599
593
600
FirstNonAllocatableOffset = NextAvailableOffset;
594
601
602
+ if (opts::CustomAllocationVMA) {
603
+ // If user specified a custom address where we should start writing new
604
+ // data, honor that.
605
+ NextAvailableAddress = opts::CustomAllocationVMA;
606
+ // Sanity check the user-supplied address and emit warnings if something
607
+ // seems off.
608
+ for (const ELF64LE::Phdr &Phdr : PHs) {
609
+ switch (Phdr.p_type ) {
610
+ case ELF::PT_LOAD:
611
+ if (NextAvailableAddress >= Phdr.p_vaddr &&
612
+ NextAvailableAddress < Phdr.p_vaddr + Phdr.p_memsz ) {
613
+ BC->errs () << " BOLT-WARNING: user-supplied allocation vma 0x"
614
+ << Twine::utohexstr (NextAvailableAddress)
615
+ << " conflicts with ELF segment at 0x"
616
+ << Twine::utohexstr (Phdr.p_vaddr ) << " \n " ;
617
+ }
618
+ }
619
+ }
620
+ }
595
621
NextAvailableAddress = alignTo (NextAvailableAddress, BC->PageAlign );
596
622
NextAvailableOffset = alignTo (NextAvailableOffset, BC->PageAlign );
597
623
0 commit comments