@@ -3856,136 +3856,138 @@ std::vector<BinarySection *> RewriteInstance::getCodeSections() {
38563856}
38573857
38583858void RewriteInstance::mapCodeSections (BOLTLinker::SectionMapper MapSection) {
3859- if (BC->HasRelocations ) {
3860- // Map sections for functions with pre-assigned addresses.
3861- for (BinaryFunction *InjectedFunction : BC->getInjectedBinaryFunctions ()) {
3862- const uint64_t OutputAddress = InjectedFunction->getOutputAddress ();
3863- if (!OutputAddress)
3864- continue ;
3865-
3866- ErrorOr<BinarySection &> FunctionSection =
3867- InjectedFunction->getCodeSection ();
3868- assert (FunctionSection && " function should have section" );
3869- FunctionSection->setOutputAddress (OutputAddress);
3870- MapSection (*FunctionSection, OutputAddress);
3871- InjectedFunction->setImageAddress (FunctionSection->getAllocAddress ());
3872- InjectedFunction->setImageSize (FunctionSection->getOutputSize ());
3873- }
3874-
3875- // Populate the list of sections to be allocated.
3876- std::vector<BinarySection *> CodeSections = getCodeSections ();
3859+ if (!BC->HasRelocations ) {
3860+ mapCodeSectionsInPlace (MapSection);
3861+ return ;
3862+ }
38773863
3878- // Remove sections that were pre-allocated (patch sections).
3879- llvm::erase_if (CodeSections, [](BinarySection *Section) {
3880- return Section->getOutputAddress ();
3881- });
3882- LLVM_DEBUG (dbgs () << " Code sections in the order of output:\n " ;
3883- for (const BinarySection *Section : CodeSections)
3884- dbgs () << Section->getName () << ' \n ' ;
3885- );
3864+ // Map sections for functions with pre-assigned addresses.
3865+ for (BinaryFunction *InjectedFunction : BC->getInjectedBinaryFunctions ()) {
3866+ const uint64_t OutputAddress = InjectedFunction->getOutputAddress ();
3867+ if (!OutputAddress)
3868+ continue ;
38863869
3887- uint64_t PaddingSize = 0 ; // size of padding required at the end
3870+ ErrorOr<BinarySection &> FunctionSection =
3871+ InjectedFunction->getCodeSection ();
3872+ assert (FunctionSection && " function should have section" );
3873+ FunctionSection->setOutputAddress (OutputAddress);
3874+ MapSection (*FunctionSection, OutputAddress);
3875+ InjectedFunction->setImageAddress (FunctionSection->getAllocAddress ());
3876+ InjectedFunction->setImageSize (FunctionSection->getOutputSize ());
3877+ }
38883878
3889- // Allocate sections starting at a given Address.
3890- auto allocateAt = [&](uint64_t Address) {
3891- const char *LastNonColdSectionName = BC->HasWarmSection
3892- ? BC->getWarmCodeSectionName ()
3893- : BC->getMainCodeSectionName ();
3894- for (BinarySection *Section : CodeSections) {
3895- Address = alignTo (Address, Section->getAlignment ());
3896- Section->setOutputAddress (Address);
3897- Address += Section->getOutputSize ();
3898-
3899- // Hugify: Additional huge page from right side due to
3900- // weird ASLR mapping addresses (4KB aligned)
3901- if (opts::Hugify && !BC->HasFixedLoadAddress &&
3902- Section->getName () == LastNonColdSectionName)
3903- Address = alignTo (Address, Section->getAlignment ());
3904- }
3879+ // Populate the list of sections to be allocated.
3880+ std::vector<BinarySection *> CodeSections = getCodeSections ();
39053881
3906- // Make sure we allocate enough space for huge pages.
3907- ErrorOr<BinarySection &> TextSection =
3908- BC->getUniqueSectionByName (LastNonColdSectionName);
3909- if (opts::HotText && TextSection && TextSection->hasValidSectionID ()) {
3910- uint64_t HotTextEnd =
3911- TextSection->getOutputAddress () + TextSection->getOutputSize ();
3912- HotTextEnd = alignTo (HotTextEnd, BC->PageAlign );
3913- if (HotTextEnd > Address) {
3914- PaddingSize = HotTextEnd - Address;
3915- Address = HotTextEnd;
3916- }
3917- }
3918- return Address;
3919- };
3882+ // Remove sections that were pre-allocated (patch sections).
3883+ llvm::erase_if (CodeSections, [](BinarySection *Section) {
3884+ return Section->getOutputAddress ();
3885+ });
3886+ LLVM_DEBUG (dbgs () << " Code sections in the order of output:\n " ;
3887+ for (const BinarySection *Section : CodeSections) dbgs ()
3888+ << Section->getName () << ' \n ' ;);
39203889
3921- // Try to allocate sections before the \p Address and return an address for
3922- // the allocation of the first section, or 0 if [0, Address) range is not
3923- // big enough to fit all sections.
3924- auto allocateBefore = [&](uint64_t Address) -> uint64_t {
3925- for (BinarySection *Section : llvm::reverse (CodeSections)) {
3926- if (Section->getOutputSize () > Address)
3927- return 0 ;
3928- Address -= Section->getOutputSize ();
3929- Address = alignDown (Address, Section->getAlignment ());
3930- Section->setOutputAddress (Address);
3931- }
3932- return Address;
3933- };
3890+ uint64_t PaddingSize = 0 ; // size of padding required at the end
39343891
3935- // Check if we can fit code in the original .text
3936- bool AllocationDone = false ;
3937- if (opts::UseOldText) {
3938- uint64_t StartAddress;
3939- uint64_t EndAddress;
3940- if (opts::HotFunctionsAtEnd) {
3941- EndAddress = BC->OldTextSectionAddress + BC->OldTextSectionSize ;
3942- StartAddress = allocateBefore (EndAddress);
3943- } else {
3944- StartAddress = BC->OldTextSectionAddress ;
3945- EndAddress = allocateAt (BC->OldTextSectionAddress );
3946- }
3892+ // Allocate sections starting at a given Address.
3893+ auto allocateAt = [&](uint64_t Address) {
3894+ const char *LastNonColdSectionName = BC->HasWarmSection
3895+ ? BC->getWarmCodeSectionName ()
3896+ : BC->getMainCodeSectionName ();
3897+ for (BinarySection *Section : CodeSections) {
3898+ Address = alignTo (Address, Section->getAlignment ());
3899+ Section->setOutputAddress (Address);
3900+ Address += Section->getOutputSize ();
3901+
3902+ // Hugify: Additional huge page from right side due to
3903+ // weird ASLR mapping addresses (4KB aligned)
3904+ if (opts::Hugify && !BC->HasFixedLoadAddress &&
3905+ Section->getName () == LastNonColdSectionName)
3906+ Address = alignTo (Address, Section->getAlignment ());
3907+ }
39473908
3948- const uint64_t CodeSize = EndAddress - StartAddress;
3949- if (CodeSize <= BC->OldTextSectionSize ) {
3950- BC->outs () << " BOLT-INFO: using original .text for new code with 0x"
3951- << Twine::utohexstr (opts::AlignText) << " alignment" ;
3952- if (StartAddress != BC->OldTextSectionAddress )
3953- BC->outs () << " at 0x" << Twine::utohexstr (StartAddress);
3954- BC->outs () << ' \n ' ;
3955- AllocationDone = true ;
3956- } else {
3957- BC->errs ()
3958- << " BOLT-WARNING: original .text too small to fit the new code"
3959- << " using 0x" << Twine::utohexstr (opts::AlignText)
3960- << " alignment. " << CodeSize << " bytes needed, have "
3961- << BC->OldTextSectionSize << " bytes available.\n " ;
3962- opts::UseOldText = false ;
3909+ // Make sure we allocate enough space for huge pages.
3910+ ErrorOr<BinarySection &> TextSection =
3911+ BC->getUniqueSectionByName (LastNonColdSectionName);
3912+ if (opts::HotText && TextSection && TextSection->hasValidSectionID ()) {
3913+ uint64_t HotTextEnd =
3914+ TextSection->getOutputAddress () + TextSection->getOutputSize ();
3915+ HotTextEnd = alignTo (HotTextEnd, BC->PageAlign );
3916+ if (HotTextEnd > Address) {
3917+ PaddingSize = HotTextEnd - Address;
3918+ Address = HotTextEnd;
39633919 }
39643920 }
3921+ return Address;
3922+ };
39653923
3966- if (!AllocationDone)
3967- NextAvailableAddress = allocateAt (NextAvailableAddress);
3924+ // Try to allocate sections before the \p Address and return an address for
3925+ // the allocation of the first section, or 0 if [0, Address) range is not
3926+ // big enough to fit all sections.
3927+ auto allocateBefore = [&](uint64_t Address) -> uint64_t {
3928+ for (BinarySection *Section : llvm::reverse (CodeSections)) {
3929+ if (Section->getOutputSize () > Address)
3930+ return 0 ;
3931+ Address -= Section->getOutputSize ();
3932+ Address = alignDown (Address, Section->getAlignment ());
3933+ Section->setOutputAddress (Address);
3934+ }
3935+ return Address;
3936+ };
39683937
3969- // Do the mapping for ORC layer based on the allocation.
3970- for (BinarySection *Section : CodeSections) {
3971- LLVM_DEBUG (
3972- dbgs () << " BOLT: mapping " << Section->getName () << " at 0x"
3973- << Twine::utohexstr (Section->getAllocAddress ()) << " to 0x"
3974- << Twine::utohexstr (Section->getOutputAddress ()) << ' \n ' );
3975- MapSection (*Section, Section->getOutputAddress ());
3976- Section->setOutputFileOffset (
3977- getFileOffsetForAddress (Section->getOutputAddress ()));
3938+ // Check if we can fit code in the original .text
3939+ bool AllocationDone = false ;
3940+ if (opts::UseOldText) {
3941+ uint64_t StartAddress;
3942+ uint64_t EndAddress;
3943+ if (opts::HotFunctionsAtEnd) {
3944+ EndAddress = BC->OldTextSectionAddress + BC->OldTextSectionSize ;
3945+ StartAddress = allocateBefore (EndAddress);
3946+ } else {
3947+ StartAddress = BC->OldTextSectionAddress ;
3948+ EndAddress = allocateAt (BC->OldTextSectionAddress );
3949+ }
3950+
3951+ const uint64_t CodeSize = EndAddress - StartAddress;
3952+ if (CodeSize <= BC->OldTextSectionSize ) {
3953+ BC->outs () << " BOLT-INFO: using original .text for new code with 0x"
3954+ << Twine::utohexstr (opts::AlignText) << " alignment" ;
3955+ if (StartAddress != BC->OldTextSectionAddress )
3956+ BC->outs () << " at 0x" << Twine::utohexstr (StartAddress);
3957+ BC->outs () << ' \n ' ;
3958+ AllocationDone = true ;
3959+ } else {
3960+ BC->errs () << " BOLT-WARNING: original .text too small to fit the new code"
3961+ << " using 0x" << Twine::utohexstr (opts::AlignText)
3962+ << " alignment. " << CodeSize << " bytes needed, have "
3963+ << BC->OldTextSectionSize << " bytes available.\n " ;
3964+ opts::UseOldText = false ;
39783965 }
3966+ }
39793967
3980- // Check if we need to insert a padding section for hot text.
3981- if (PaddingSize && !opts::UseOldText)
3982- BC->outs () << " BOLT-INFO: padding code to 0x"
3983- << Twine::utohexstr (NextAvailableAddress)
3984- << " to accommodate hot text\n " ;
3968+ if (!AllocationDone)
3969+ NextAvailableAddress = allocateAt (NextAvailableAddress);
39853970
3986- return ;
3971+ // Do the mapping for ORC layer based on the allocation.
3972+ for (BinarySection *Section : CodeSections) {
3973+ LLVM_DEBUG (dbgs () << " BOLT: mapping " << Section->getName () << " at 0x"
3974+ << Twine::utohexstr (Section->getAllocAddress ())
3975+ << " to 0x"
3976+ << Twine::utohexstr (Section->getOutputAddress ()) << ' \n ' );
3977+ MapSection (*Section, Section->getOutputAddress ());
3978+ Section->setOutputFileOffset (
3979+ getFileOffsetForAddress (Section->getOutputAddress ()));
39873980 }
39883981
3982+ // Check if we need to insert a padding section for hot text.
3983+ if (PaddingSize && !opts::UseOldText)
3984+ BC->outs () << " BOLT-INFO: padding code to 0x"
3985+ << Twine::utohexstr (NextAvailableAddress)
3986+ << " to accommodate hot text\n " ;
3987+ }
3988+
3989+ void RewriteInstance::mapCodeSectionsInPlace (
3990+ BOLTLinker::SectionMapper MapSection) {
39893991 // Processing in non-relocation mode.
39903992 uint64_t NewTextSectionStartAddress = NextAvailableAddress;
39913993
0 commit comments