aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools
diff options
context:
space:
mode:
authorIgor Kudrin <ikudrin@accesssoftek.com>2025-01-23 14:27:40 -0800
committerGitHub <noreply@github.com>2025-01-23 14:27:40 -0800
commit9324e6a7a5c5adc5b5c38c3e3cbecd7e1e98876a (patch)
treeaaad4d1c5e6f3a8fc7d6af98ad467e2cf92b61ab /llvm/tools
parentf5bd623d060051f6f6715c153aa60a577df6f540 (diff)
downloadllvm-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.cpp55
-rw-r--r--llvm/tools/llvm-objcopy/ObjcopyOpts.td4
-rw-r--r--llvm/tools/llvm-objcopy/llvm-objcopy.cpp2
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;