diff options
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; |