aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools
diff options
context:
space:
mode:
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;