@@ -237,6 +237,12 @@ UseGnuStack("use-gnu-stack",
237237 cl::ZeroOrMore,
238238 cl::cat(BoltCategory));
239239
240+ static cl::opt<uint64_t > CustomAllocationVMA (
241+ " 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, cl::cat(BoltCategory));
245+
240246static cl::opt<bool >
241247SequentialDisassembly (" sequential-disassembly" ,
242248 cl::desc (" performs disassembly sequentially" ),
@@ -592,6 +598,25 @@ Error RewriteInstance::discoverStorage() {
592598
593599 FirstNonAllocatableOffset = NextAvailableOffset;
594600
601+ if (opts::CustomAllocationVMA) {
602+ // If user specified a custom address where we should start writing new
603+ // data, honor that.
604+ NextAvailableAddress = opts::CustomAllocationVMA;
605+ // Sanity check the user-supplied address and emit warnings if something
606+ // seems off.
607+ for (const ELF64LE::Phdr &Phdr : PHs) {
608+ switch (Phdr.p_type ) {
609+ case ELF::PT_LOAD:
610+ if (NextAvailableAddress >= Phdr.p_vaddr &&
611+ NextAvailableAddress < Phdr.p_vaddr + Phdr.p_memsz ) {
612+ BC->errs () << " BOLT-WARNING: user-supplied allocation vma 0x"
613+ << Twine::utohexstr (NextAvailableAddress)
614+ << " conflicts with ELF segment at 0x"
615+ << Twine::utohexstr (Phdr.p_vaddr ) << " \n " ;
616+ }
617+ }
618+ }
619+ }
595620 NextAvailableAddress = alignTo (NextAvailableAddress, BC->PageAlign );
596621 NextAvailableOffset = alignTo (NextAvailableOffset, BC->PageAlign );
597622
0 commit comments