diff options
author | Igor Kudrin <ikudrin@accesssoftek.com> | 2025-01-23 14:27:40 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-23 14:27:40 -0800 |
commit | 9324e6a7a5c5adc5b5c38c3e3cbecd7e1e98876a (patch) | |
tree | aaad4d1c5e6f3a8fc7d6af98ad467e2cf92b61ab /llvm/tools | |
parent | f5bd623d060051f6f6715c153aa60a577df6f540 (diff) | |
download | llvm-9324e6a7a5c5adc5b5c38c3e3cbecd7e1e98876a.zip llvm-9324e6a7a5c5adc5b5c38c3e3cbecd7e1e98876a.tar.gz llvm-9324e6a7a5c5adc5b5c38c3e3cbecd7e1e98876a.tar.bz2 |
[llvm-objcopy][ELF] Add an option to remove notes (#118739)
This adds an option `--remove-note=[name/]type` to selectively delete
notes in ELF files, where `type` is the numeric value of the note type
and `name` is the name of the originator. The name can be omitted, in
which case all notes of the specified type will be removed. For now,
only `SHT_NOTE` sections that are not associated with segments are
handled. The implementation can be extended later as needed.
RFC: https://discourse.llvm.org/t/rfc-llvm-objcopy-feature-for-editing-notes/83491
Diffstat (limited to 'llvm/tools')
-rw-r--r-- | llvm/tools/llvm-objcopy/ObjcopyOptions.cpp | 55 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/ObjcopyOpts.td | 4 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/llvm-objcopy.cpp | 2 |
3 files changed, 61 insertions, 0 deletions
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp index 0925fc5..0d20959 100644 --- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp +++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp @@ -538,6 +538,38 @@ static Expected<NewSymbolInfo> parseNewSymbolInfo(StringRef FlagValue) { return SI; } +static Expected<RemoveNoteInfo> parseRemoveNoteInfo(StringRef FlagValue) { + // Parse value given with --remove-note option. The format is: + // + // [name/]type_id + // + // where: + // <name> - optional note name. If not given, all notes with the specified + // <type_id> are removed. + // <type_id> - note type value, can be decimal or hexadecimal number prefixed + // with 0x. + RemoveNoteInfo NI; + StringRef TypeIdStr; + if (auto Idx = FlagValue.find('/'); Idx != StringRef::npos) { + if (Idx == 0) + return createStringError( + errc::invalid_argument, + "bad format for --remove-note, note name is empty"); + NI.Name = FlagValue.slice(0, Idx); + TypeIdStr = FlagValue.substr(Idx + 1); + } else { + TypeIdStr = FlagValue; + } + if (TypeIdStr.empty()) + return createStringError(errc::invalid_argument, + "bad format for --remove-note, missing type_id"); + if (TypeIdStr.getAsInteger(0, NI.TypeId)) + return createStringError(errc::invalid_argument, + "bad note type_id for --remove-note: '%s'", + TypeIdStr.str().c_str()); + return NI; +} + // Parse input option \p ArgValue and load section data. This function // extracts section name and name of the file keeping section data from // ArgValue, loads data from the file, and stores section name and data @@ -1221,6 +1253,29 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> ArgsArr, }; } + for (auto *Arg : InputArgs.filtered(OBJCOPY_remove_note)) { + Expected<RemoveNoteInfo> NoteInfo = parseRemoveNoteInfo(Arg->getValue()); + if (!NoteInfo) + return NoteInfo.takeError(); + + ELFConfig.NotesToRemove.push_back(*NoteInfo); + } + + if (!ELFConfig.NotesToRemove.empty()) { + if (!Config.ToRemove.empty()) + return createStringError( + errc::invalid_argument, + "cannot specify both --remove-note and --remove-section"); + if (!Config.AddSection.empty()) + return createStringError( + errc::invalid_argument, + "cannot specify both --remove-note and --add-section"); + if (!Config.UpdateSection.empty()) + return createStringError( + errc::invalid_argument, + "cannot specify both --remove-note and --update-section"); + } + if (Config.DecompressDebugSections && Config.CompressionType != DebugCompressionType::None) { return createStringError( diff --git a/llvm/tools/llvm-objcopy/ObjcopyOpts.td b/llvm/tools/llvm-objcopy/ObjcopyOpts.td index 434b5ff..fbc6a59 100644 --- a/llvm/tools/llvm-objcopy/ObjcopyOpts.td +++ b/llvm/tools/llvm-objcopy/ObjcopyOpts.td @@ -297,3 +297,7 @@ defm pad_to "of zero or the value specified by the --gap-fill option. " "This option is only supported for ELF input and binary output">, MetaVarName<"address">; + +defm remove_note + : Eq<"remove-note", "Remove note(s) with <type_id> and optional <name>">, + MetaVarName<"[name/]type_id">; diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp index ad3e604..7e708e3 100644 --- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -248,6 +248,8 @@ int llvm_objcopy_main(int argc, char **argv, const llvm::ToolContext &) { return 1; } for (ConfigManager &ConfigMgr : DriverConfig->CopyConfigs) { + assert(!ConfigMgr.Common.ErrorCallback); + ConfigMgr.Common.ErrorCallback = reportWarning; if (Error E = executeObjcopy(ConfigMgr)) { logAllUnhandledErrors(std::move(E), WithColor::error(errs(), ToolName)); return 1; |