@@ -609,6 +609,113 @@ static void addSymbol(Object &Obj, const NewSymbolInfo &SymInfo,
609
609
Sec ? (uint16_t )SYMBOL_SIMPLE_INDEX : (uint16_t )SHN_ABS, 0 );
610
610
}
611
611
612
+ namespace {
613
+ struct RemoveNoteDetail {
614
+ struct DeletedRange {
615
+ uint64_t OldFrom;
616
+ uint64_t OldTo;
617
+ };
618
+
619
+ template <class ELFT >
620
+ static std::vector<DeletedRange>
621
+ findNotesToRemove (ArrayRef<uint8_t > Data, size_t Align,
622
+ ArrayRef<RemoveNoteInfo> NotesToRemove);
623
+ static std::vector<uint8_t > updateData (ArrayRef<uint8_t > OldData,
624
+ ArrayRef<DeletedRange> ToRemove);
625
+ };
626
+ } // namespace
627
+
628
+ template <class ELFT >
629
+ std::vector<RemoveNoteDetail::DeletedRange>
630
+ RemoveNoteDetail::findNotesToRemove (ArrayRef<uint8_t > Data, size_t Align,
631
+ ArrayRef<RemoveNoteInfo> NotesToRemove) {
632
+ using Elf_Nhdr = typename ELFT::Nhdr;
633
+ using Elf_Note = typename ELFT::Note;
634
+ std::vector<DeletedRange> ToRemove;
635
+ uint64_t CurPos = 0 ;
636
+ while (CurPos + sizeof (Elf_Nhdr) <= Data.size ()) {
637
+ auto Nhdr = reinterpret_cast <const Elf_Nhdr *>(Data.data () + CurPos);
638
+ size_t FullSize = Nhdr->getSize (Align);
639
+ if (CurPos + FullSize > Data.size ())
640
+ break ;
641
+ Elf_Note Note (*Nhdr);
642
+ bool ShouldRemove =
643
+ llvm::any_of (NotesToRemove, [&Note](const RemoveNoteInfo &NoteInfo) {
644
+ return NoteInfo.TypeId == Note.getType () &&
645
+ (NoteInfo.Name .empty () || NoteInfo.Name == Note.getName ());
646
+ });
647
+ if (ShouldRemove)
648
+ ToRemove.push_back ({CurPos, CurPos + FullSize});
649
+ CurPos += FullSize;
650
+ }
651
+ return ToRemove;
652
+ }
653
+
654
+ std::vector<uint8_t >
655
+ RemoveNoteDetail::updateData (ArrayRef<uint8_t > OldData,
656
+ ArrayRef<DeletedRange> ToRemove) {
657
+ std::vector<uint8_t > NewData;
658
+ NewData.reserve (OldData.size ());
659
+ uint64_t CurPos = 0 ;
660
+ for (const DeletedRange &RemRange : ToRemove) {
661
+ if (CurPos < RemRange.OldFrom ) {
662
+ auto Slice = OldData.slice (CurPos, RemRange.OldFrom - CurPos);
663
+ NewData.insert (NewData.end (), Slice.begin (), Slice.end ());
664
+ }
665
+ CurPos = RemRange.OldTo ;
666
+ }
667
+ if (CurPos < OldData.size ()) {
668
+ auto Slice = OldData.slice (CurPos);
669
+ NewData.insert (NewData.end (), Slice.begin (), Slice.end ());
670
+ }
671
+ return NewData;
672
+ }
673
+
674
+ static Error removeNotes (Object &Obj, endianness Endianness,
675
+ ArrayRef<RemoveNoteInfo> NotesToRemove,
676
+ function_ref<Error(Error)> ErrorCallback) {
677
+ // TODO: Support note segments.
678
+ if (ErrorCallback) {
679
+ for (Segment &Seg : Obj.segments ()) {
680
+ if (Seg.Type == PT_NOTE) {
681
+ if (Error E = ErrorCallback (createStringError (
682
+ errc::not_supported, " note segments are not supported" )))
683
+ return E;
684
+ break ;
685
+ }
686
+ }
687
+ }
688
+ for (auto &Sec : Obj.sections ()) {
689
+ if (Sec.Type != SHT_NOTE || !Sec.hasContents ())
690
+ continue ;
691
+ // TODO: Support note sections in segments.
692
+ if (Sec.ParentSegment ) {
693
+ if (ErrorCallback)
694
+ if (Error E = ErrorCallback (createStringError (
695
+ errc::not_supported,
696
+ " cannot remove note(s) from " + Sec.Name +
697
+ " : sections in segments are not supported" )))
698
+ return E;
699
+ continue ;
700
+ }
701
+ ArrayRef<uint8_t > OldData = Sec.getContents ();
702
+ size_t Align = std::max<size_t >(4 , Sec.Align );
703
+ // Note: notes for both 32-bit and 64-bit ELF files use 4-byte words in the
704
+ // header, so the parsers are the same.
705
+ auto ToRemove = (Endianness == endianness::little)
706
+ ? RemoveNoteDetail::findNotesToRemove<ELF64LE>(
707
+ OldData, Align, NotesToRemove)
708
+ : RemoveNoteDetail::findNotesToRemove<ELF64BE>(
709
+ OldData, Align, NotesToRemove);
710
+ if (!ToRemove.empty ()) {
711
+ if (Error E = Obj.updateSectionData (
712
+ Sec, RemoveNoteDetail::updateData (OldData, ToRemove)))
713
+ return E;
714
+ }
715
+ }
716
+ return Error::success ();
717
+ }
718
+
612
719
static Error
613
720
handleUserSection (const NewSectionInfo &NewSection,
614
721
function_ref<Error(StringRef, ArrayRef<uint8_t >)> F) {
@@ -799,6 +906,12 @@ static Error handleArgs(const CommonConfig &Config, const ELFConfig &ELFConfig,
799
906
? endianness::little
800
907
: endianness::big;
801
908
909
+ if (!ELFConfig.NotesToRemove .empty ()) {
910
+ if (Error Err =
911
+ removeNotes (Obj, E, ELFConfig.NotesToRemove , Config.ErrorCallback ))
912
+ return Err;
913
+ }
914
+
802
915
for (const NewSectionInfo &AddedSection : Config.AddSection ) {
803
916
auto AddSection = [&](StringRef Name, ArrayRef<uint8_t > Data) -> Error {
804
917
OwnedDataSection &NewSection =
0 commit comments