@@ -411,10 +411,16 @@ Error MachOLinkGraphBuilder::graphifyRegularSymbols() {
411
411
<< " as it has a custom parser.\n " ;
412
412
});
413
413
continue ;
414
+ } else if ((NSec.Flags & MachO::SECTION_TYPE) ==
415
+ MachO::S_CSTRING_LITERALS) {
416
+ if (auto Err = graphifyCStringSection (
417
+ NSec, std::move (SecIndexToSymbols[SecIndex])))
418
+ return Err;
419
+ continue ;
414
420
} else
415
421
LLVM_DEBUG ({
416
- dbgs () << " Processing section " << NSec. GraphSection -> getName ()
417
- << " ...\n " ;
422
+ dbgs () << " Graphifying regular section "
423
+ << NSec. GraphSection -> getName () << " ...\n " ;
418
424
});
419
425
420
426
bool SectionIsNoDeadStrip = NSec.Flags & MachO::S_ATTR_NO_DEAD_STRIP;
@@ -525,34 +531,14 @@ Error MachOLinkGraphBuilder::graphifyRegularSymbols() {
525
531
bool SymLive =
526
532
(NSym.Desc & MachO::N_NO_DEAD_STRIP) || SectionIsNoDeadStrip;
527
533
528
- LLVM_DEBUG ({
529
- dbgs () << " " << formatv (" {0:x16}" , NSym.Value ) << " -- "
530
- << formatv (" {0:x16}" , SymEnd) << " : " ;
531
- if (!NSym.Name )
532
- dbgs () << " <anonymous symbol>" ;
533
- else
534
- dbgs () << NSym.Name ;
535
- if (SymLive)
536
- dbgs () << " [no-dead-strip]" ;
537
- if (LastCanonicalAddr == NSym.Value )
538
- dbgs () << " [non-canonical]" ;
539
- dbgs () << " \n " ;
540
- });
534
+ auto &Sym = createStandardGraphSymbol (NSym, B, SymEnd - NSym.Value ,
535
+ SectionIsText, SymLive,
536
+ LastCanonicalAddr != NSym.Value );
541
537
542
- auto &Sym =
543
- NSym.Name
544
- ? G->addDefinedSymbol (B, NSym.Value - BlockStart, *NSym.Name ,
545
- SymEnd - NSym.Value , NSym.L , NSym.S ,
546
- SectionIsText, SymLive)
547
- : G->addAnonymousSymbol (B, NSym.Value - BlockStart,
548
- SymEnd - NSym.Value , SectionIsText,
549
- SymLive);
550
- NSym.GraphSymbol = &Sym;
551
538
if (LastCanonicalAddr != Sym.getAddress ()) {
552
539
if (LastCanonicalAddr)
553
540
SymEnd = *LastCanonicalAddr;
554
541
LastCanonicalAddr = Sym.getAddress ();
555
- setCanonicalSymbol (Sym);
556
542
}
557
543
}
558
544
}
@@ -561,6 +547,41 @@ Error MachOLinkGraphBuilder::graphifyRegularSymbols() {
561
547
return Error::success ();
562
548
}
563
549
550
+ Symbol &MachOLinkGraphBuilder::createStandardGraphSymbol (NormalizedSymbol &NSym,
551
+ Block &B, size_t Size,
552
+ bool IsText,
553
+ bool IsNoDeadStrip,
554
+ bool IsCanonical) {
555
+
556
+ LLVM_DEBUG ({
557
+ dbgs () << " " << formatv (" {0:x16}" , NSym.Value ) << " -- "
558
+ << formatv (" {0:x16}" , NSym.Value + Size) << " : " ;
559
+ if (!NSym.Name )
560
+ dbgs () << " <anonymous symbol>" ;
561
+ else
562
+ dbgs () << NSym.Name ;
563
+ if (IsText)
564
+ dbgs () << " [text]" ;
565
+ if (IsNoDeadStrip)
566
+ dbgs () << " [no-dead-strip]" ;
567
+ if (!IsCanonical)
568
+ dbgs () << " [non-canonical]" ;
569
+ dbgs () << " \n " ;
570
+ });
571
+
572
+ auto &Sym = NSym.Name ? G->addDefinedSymbol (B, NSym.Value - B.getAddress (),
573
+ *NSym.Name , Size, NSym.L , NSym.S ,
574
+ IsText, IsNoDeadStrip)
575
+ : G->addAnonymousSymbol (B, NSym.Value - B.getAddress (),
576
+ Size, IsText, IsNoDeadStrip);
577
+ NSym.GraphSymbol = &Sym;
578
+
579
+ if (IsCanonical)
580
+ setCanonicalSymbol (Sym);
581
+
582
+ return Sym;
583
+ }
584
+
564
585
Error MachOLinkGraphBuilder::graphifySectionsWithCustomParsers () {
565
586
// Graphify special sections.
566
587
for (auto &KV : IndexToSection) {
@@ -581,5 +602,95 @@ Error MachOLinkGraphBuilder::graphifySectionsWithCustomParsers() {
581
602
return Error::success ();
582
603
}
583
604
605
+ Error MachOLinkGraphBuilder::graphifyCStringSection (
606
+ NormalizedSection &NSec, std::vector<NormalizedSymbol *> NSyms) {
607
+
608
+ assert (NSec.GraphSection && " C string literal section missing graph section" );
609
+ assert (NSec.Data && " C string literal section has no data" );
610
+
611
+ LLVM_DEBUG ({
612
+ dbgs () << " Graphifying C-string literal section "
613
+ << NSec.GraphSection ->getName () << " \n " ;
614
+ });
615
+
616
+ if (NSec.Data [NSec.Size - 1 ] != ' \0 ' )
617
+ return make_error<JITLinkError>(" C string literal section " +
618
+ NSec.GraphSection ->getName () +
619
+ " does not end with null terminator" );
620
+
621
+ // / Sort into reverse order to use as a stack.
622
+ llvm::sort (NSyms,
623
+ [](const NormalizedSymbol *LHS, const NormalizedSymbol *RHS) {
624
+ if (LHS->Value != RHS->Value )
625
+ return LHS->Value > RHS->Value ;
626
+ if (LHS->L != RHS->L )
627
+ return LHS->L > RHS->L ;
628
+ if (LHS->S != RHS->S )
629
+ return LHS->S > RHS->S ;
630
+ if (RHS->Name ) {
631
+ if (!LHS->Name )
632
+ return true ;
633
+ return *LHS->Name > *RHS->Name ;
634
+ }
635
+ return false ;
636
+ });
637
+
638
+ bool SectionIsNoDeadStrip = NSec.Flags & MachO::S_ATTR_NO_DEAD_STRIP;
639
+ bool SectionIsText = NSec.Flags & MachO::S_ATTR_PURE_INSTRUCTIONS;
640
+ JITTargetAddress BlockStart = 0 ;
641
+
642
+ // Scan section for null characters.
643
+ for (size_t I = 0 ; I != NSec.Size ; ++I)
644
+ if (NSec.Data [I] == ' \0 ' ) {
645
+ JITTargetAddress BlockEnd = I + 1 ;
646
+ size_t BlockSize = BlockEnd - BlockStart;
647
+ // Create a block for this null terminated string.
648
+ auto &B = G->createContentBlock (*NSec.GraphSection ,
649
+ {NSec.Data + BlockStart, BlockSize},
650
+ NSec.Address + BlockStart, 1 , 0 );
651
+
652
+ LLVM_DEBUG ({
653
+ dbgs () << " Created block " << formatv (" {0:x}" , B.getAddress ())
654
+ << " -- " << formatv (" {0:x}" , B.getAddress () + B.getSize ())
655
+ << " for \" " << StringRef (B.getContent ().data ()) << " \"\n " ;
656
+ });
657
+
658
+ // Process any symbols that point into this block.
659
+ JITTargetAddress LastCanonicalAddr = BlockEnd;
660
+ Symbol *BlockStartSymbol = nullptr ;
661
+ while (!NSyms.empty () &&
662
+ NSyms.back ()->Value < (B.getAddress () + BlockSize)) {
663
+ auto &NSym = *NSyms.back ();
664
+ size_t SymSize = (B.getAddress () + BlockSize) - NSyms.back ()->Value ;
665
+ bool SymLive =
666
+ (NSym.Desc & MachO::N_NO_DEAD_STRIP) || SectionIsNoDeadStrip;
667
+
668
+ auto &S =
669
+ createStandardGraphSymbol (NSym, B, SymSize, SectionIsText, SymLive,
670
+ NSym.Value != LastCanonicalAddr);
671
+
672
+ if (S.getAddress () == B.getAddress () && !BlockStartSymbol)
673
+ BlockStartSymbol = &S;
674
+
675
+ NSyms.pop_back ();
676
+ }
677
+
678
+ if (!BlockStartSymbol) {
679
+ auto &S = G->addAnonymousSymbol (B, 0 , BlockSize, false , false );
680
+ setCanonicalSymbol (S);
681
+ LLVM_DEBUG ({
682
+ dbgs () << " Adding anonymous symbol for "
683
+ << formatv (" {0:x16} -- {1:x16}" , S.getAddress (),
684
+ S.getAddress () + BlockSize)
685
+ << " \n " ;
686
+ });
687
+ }
688
+
689
+ BlockStart += BlockSize;
690
+ }
691
+
692
+ return Error::success ();
693
+ }
694
+
584
695
} // end namespace jitlink
585
696
} // end namespace llvm
0 commit comments