@@ -783,11 +783,9 @@ Error LinuxKernelRewriter::rewriteORCTables() {
783
783
};
784
784
785
785
// Emit new ORC entries for the emitted function.
786
- auto emitORC = [&](const BinaryFunction &BF) -> Error {
787
- assert (!BF.isSplit () && " Split functions not supported by ORC writer yet." );
788
-
786
+ auto emitORC = [&](const FunctionFragment &FF) -> Error {
789
787
ORCState CurrentState = NullORC;
790
- for (BinaryBasicBlock *BB : BF. getLayout (). blocks () ) {
788
+ for (BinaryBasicBlock *BB : FF ) {
791
789
for (MCInst &Inst : *BB) {
792
790
ErrorOr<ORCState> ErrorOrState =
793
791
BC.MIB ->tryGetAnnotationAs <ORCState>(Inst, " ORC" );
@@ -808,7 +806,36 @@ Error LinuxKernelRewriter::rewriteORCTables() {
808
806
return Error::success ();
809
807
};
810
808
809
+ // Emit ORC entries for cold fragments. We assume that these fragments are
810
+ // emitted contiguously in memory using reserved space in the kernel. This
811
+ // assumption is validated in post-emit pass validateORCTables() where we
812
+ // check that ORC entries are sorted by their addresses.
813
+ auto emitColdORC = [&]() -> Error {
814
+ for (BinaryFunction &BF :
815
+ llvm::make_second_range (BC.getBinaryFunctions ())) {
816
+ if (!BC.shouldEmit (BF))
817
+ continue ;
818
+ for (FunctionFragment &FF : BF.getLayout ().getSplitFragments ())
819
+ if (Error E = emitORC (FF))
820
+ return E;
821
+ }
822
+
823
+ return Error::success ();
824
+ };
825
+
826
+ bool ShouldEmitCold = !BC.BOLTReserved .empty ();
811
827
for (ORCListEntry &Entry : ORCEntries) {
828
+ if (ShouldEmitCold && Entry.IP > BC.BOLTReserved .start ()) {
829
+ if (Error E = emitColdORC ())
830
+ return E;
831
+
832
+ // Emit terminator entry at the end of the reserved region.
833
+ if (Error E = emitORCEntry (BC.BOLTReserved .end (), NullORC))
834
+ return E;
835
+
836
+ ShouldEmitCold = false ;
837
+ }
838
+
812
839
// Emit original entries for functions that we haven't modified.
813
840
if (!Entry.BF || !BC.shouldEmit (*Entry.BF )) {
814
841
// Emit terminator only if it marks the start of a function.
@@ -822,7 +849,7 @@ Error LinuxKernelRewriter::rewriteORCTables() {
822
849
// Emit all ORC entries for a function referenced by an entry and skip over
823
850
// the rest of entries for this function by resetting its ORC attribute.
824
851
if (Entry.BF ->hasORC ()) {
825
- if (Error E = emitORC (* Entry.BF ))
852
+ if (Error E = emitORC (Entry.BF -> getLayout (). getMainFragment () ))
826
853
return E;
827
854
Entry.BF ->setHasORC (false );
828
855
}
@@ -831,10 +858,9 @@ Error LinuxKernelRewriter::rewriteORCTables() {
831
858
LLVM_DEBUG (dbgs () << " BOLT-DEBUG: emitted " << NumEmitted
832
859
<< " ORC entries\n " );
833
860
834
- // Replicate terminator entry at the end of sections to match the original
835
- // table sizes.
836
- const BinaryFunction &LastBF = BC.getBinaryFunctions ().rbegin ()->second ;
837
- const uint64_t LastIP = LastBF.getAddress () + LastBF.getMaxSize ();
861
+ // Populate ORC tables with a terminator entry with max address to match the
862
+ // original table sizes.
863
+ const uint64_t LastIP = std::numeric_limits<uint64_t >::max ();
838
864
while (UnwindWriter.bytesRemaining ()) {
839
865
if (Error E = emitORCEntry (LastIP, NullORC, nullptr , /* Force*/ true ))
840
866
return E;
0 commit comments