@@ -237,6 +237,13 @@ UseGnuStack("use-gnu-stack",
237237 cl::ZeroOrMore,
238238 cl::cat(BoltCategory));
239239
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+
240247static cl::opt<bool >
241248SequentialDisassembly (" sequential-disassembly" ,
242249 cl::desc (" performs disassembly sequentially" ),
@@ -592,6 +599,25 @@ Error RewriteInstance::discoverStorage() {
592599
593600 FirstNonAllocatableOffset = NextAvailableOffset;
594601
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+ }
595621 NextAvailableAddress = alignTo (NextAvailableAddress, BC->PageAlign );
596622 NextAvailableOffset = alignTo (NextAvailableOffset, BC->PageAlign );
597623
0 commit comments