[llvm] [llvm-objcopy][ELF] Add an option to remove notes (PR #118739)

James Henderson via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 17 01:09:40 PST 2025


================
@@ -609,6 +609,97 @@ static void addSymbol(Object &Obj, const NewSymbolInfo &SymInfo,
       Sec ? (uint16_t)SYMBOL_SIMPLE_INDEX : (uint16_t)SHN_ABS, 0);
 }
 
+namespace {
+struct RemoveNoteDetail {
+  struct DeletedRange {
+    uint64_t OldFrom;
+    uint64_t OldTo;
+    uint64_t NewPos;
+  };
+
+  template <class ELFT>
+  static std::vector<DeletedRange>
+  findNotesToRemove(ArrayRef<uint8_t> Data, size_t Align,
+                    ArrayRef<RemoveNoteInfo> NotesToRemove);
+  static std::vector<uint8_t> updateData(ArrayRef<uint8_t> OldData,
+                                         ArrayRef<DeletedRange> ToRemove);
+};
+
+} // namespace
+
+template <class ELFT>
+std::vector<RemoveNoteDetail::DeletedRange>
+RemoveNoteDetail::findNotesToRemove(ArrayRef<uint8_t> Data, size_t Align,
+                                    ArrayRef<RemoveNoteInfo> NotesToRemove) {
+  LLVM_ELF_IMPORT_TYPES_ELFT(ELFT);
+  std::vector<DeletedRange> ToRemove;
+  uint64_t CurPos = 0;
+  uint64_t NewPos = 0;
+  while (CurPos + sizeof(Elf_Nhdr) <= Data.size()) {
+    auto Nhdr = reinterpret_cast<const Elf_Nhdr *>(Data.data() + CurPos);
+    size_t FullSize = Nhdr->getSize(Align);
+    if (CurPos + FullSize > Data.size())
+      break;
+    Elf_Note Note(*Nhdr);
+    bool ShouldRemove =
+        llvm::any_of(NotesToRemove, [&Note](const RemoveNoteInfo &NoteInfo) {
+          return NoteInfo.TypeId == Note.getType() &&
+                 (NoteInfo.Name.empty() || NoteInfo.Name == Note.getName());
+        });
+    if (ShouldRemove)
+      ToRemove.push_back({CurPos, CurPos + FullSize, NewPos});
+    else
+      NewPos += FullSize;
+    CurPos += FullSize;
+  }
+  return ToRemove;
+}
+
+std::vector<uint8_t>
+RemoveNoteDetail::updateData(ArrayRef<uint8_t> OldData,
+                             ArrayRef<DeletedRange> ToRemove) {
+  std::vector<uint8_t> NewData;
+  NewData.reserve(OldData.size());
+  uint64_t CurPos = 0;
+  for (auto &RemRange : ToRemove) {
+    if (CurPos < RemRange.OldFrom) {
+      auto Slice = OldData.slice(CurPos, RemRange.OldFrom - CurPos);
+      NewData.insert(NewData.end(), Slice.begin(), Slice.end());
+    }
+    assert(RemRange.NewPos == NewData.size());
+    CurPos = RemRange.OldTo;
+  }
+  if (CurPos < OldData.size()) {
+    auto Slice = OldData.slice(CurPos);
+    NewData.insert(NewData.end(), Slice.begin(), Slice.end());
+  }
+  return NewData;
+}
+
+static Error removeNote(Object &Obj, endianness Endianness,
+                        ArrayRef<RemoveNoteInfo> NotesToRemove) {
+  for (auto &Sec : Obj.sections()) {
+    // TODO: Support note sections in segments
+    if (Sec.Type != SHT_NOTE || Sec.ParentSegment || !Sec.hasContents())
+      continue;
----------------
jh7370 wrote:

Thanks for the update. I skimmed it and am wondering whether the callback should be part of the `Config` variable, to reduce the number of parameters being passed around. Also, in common with similar callbacks I've done elsewhere (looking at the debug line code in particular), perhaps the callback should take an `Error`, to allow for the richer information that that can contain to be passed back and checked. Will check the rest of the updates next week.

https://github.com/llvm/llvm-project/pull/118739


More information about the llvm-commits mailing list