diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:51:42 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:51:42 +0000 |
commit | 1d5ae1026e831016fc29fd927877c86af904481f (patch) | |
tree | 2cdfd12620fcfa5d9e4a0389f85368e8e36f63f9 /tools/llvm-objcopy/CopyConfig.h | |
parent | e6d1592492a3a379186bfb02bd0f4eda0669c0d5 (diff) |
Notes
Diffstat (limited to 'tools/llvm-objcopy/CopyConfig.h')
-rw-r--r-- | tools/llvm-objcopy/CopyConfig.h | 110 |
1 files changed, 84 insertions, 26 deletions
diff --git a/tools/llvm-objcopy/CopyConfig.h b/tools/llvm-objcopy/CopyConfig.h index aff3631a487c..55a55d3a2bc2 100644 --- a/tools/llvm-objcopy/CopyConfig.h +++ b/tools/llvm-objcopy/CopyConfig.h @@ -9,6 +9,7 @@ #ifndef LLVM_TOOLS_LLVM_OBJCOPY_COPY_CONFIG_H #define LLVM_TOOLS_LLVM_OBJCOPY_COPY_CONFIG_H +#include "ELF/ELFConfig.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitmaskEnum.h" #include "llvm/ADT/Optional.h" @@ -18,6 +19,7 @@ #include "llvm/Object/ELFTypes.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Error.h" +#include "llvm/Support/GlobPattern.h" #include "llvm/Support/Regex.h" // Necessary for llvm::DebugCompressionType::None #include "llvm/Target/TargetOptions.h" @@ -87,36 +89,71 @@ enum class DiscardType { Locals, // --discard-locals (-X) }; -class NameOrRegex { +enum class MatchStyle { + Literal, // Default for symbols. + Wildcard, // Default for sections, or enabled with --wildcard (-w). + Regex, // Enabled with --regex. +}; + +class NameOrPattern { StringRef Name; // Regex is shared between multiple CopyConfig instances. std::shared_ptr<Regex> R; + std::shared_ptr<GlobPattern> G; + bool IsPositiveMatch = true; + + NameOrPattern(StringRef N) : Name(N) {} + NameOrPattern(std::shared_ptr<Regex> R) : R(R) {} + NameOrPattern(std::shared_ptr<GlobPattern> G, bool IsPositiveMatch) + : G(G), IsPositiveMatch(IsPositiveMatch) {} public: - NameOrRegex(StringRef Pattern, bool IsRegex); - bool operator==(StringRef S) const { return R ? R->match(S) : Name == S; } + // ErrorCallback is used to handle recoverable errors. An Error returned + // by the callback aborts the parsing and is then returned by this function. + static Expected<NameOrPattern> + create(StringRef Pattern, MatchStyle MS, + llvm::function_ref<Error(Error)> ErrorCallback); + + bool isPositiveMatch() const { return IsPositiveMatch; } + bool operator==(StringRef S) const { + return R ? R->match(S) : G ? G->match(S) : Name == S; + } bool operator!=(StringRef S) const { return !operator==(S); } }; -struct NewSymbolInfo { - StringRef SymbolName; - StringRef SectionName; - uint64_t Value = 0; - uint8_t Type = ELF::STT_NOTYPE; - uint8_t Bind = ELF::STB_GLOBAL; - uint8_t Visibility = ELF::STV_DEFAULT; +// Matcher that checks symbol or section names against the command line flags +// provided for that option. +class NameMatcher { + std::vector<NameOrPattern> PosMatchers; + std::vector<NameOrPattern> NegMatchers; + +public: + Error addMatcher(Expected<NameOrPattern> Matcher) { + if (!Matcher) + return Matcher.takeError(); + if (Matcher->isPositiveMatch()) + PosMatchers.push_back(std::move(*Matcher)); + else + NegMatchers.push_back(std::move(*Matcher)); + return Error::success(); + } + bool matches(StringRef S) const { + return is_contained(PosMatchers, S) && !is_contained(NegMatchers, S); + } + bool empty() const { return PosMatchers.empty() && NegMatchers.empty(); } }; // Configuration for copying/stripping a single file. struct CopyConfig { + // Format-specific options to be initialized lazily when needed. + Optional<elf::ELFCopyConfig> ELF; + // Main input/output options StringRef InputFilename; FileFormat InputFormat; StringRef OutputFilename; FileFormat OutputFormat; - // Only applicable for --input-format=binary - MachineInfo BinaryArch; // Only applicable when --output-format!=binary (e.g. elf64-x86-64). Optional<MachineInfo> OutputArch; @@ -132,24 +169,30 @@ struct CopyConfig { StringRef SymbolsPrefix; StringRef AllocSectionsPrefix; DiscardType DiscardMode = DiscardType::None; + Optional<StringRef> NewSymbolVisibility; // Repeated options std::vector<StringRef> AddSection; std::vector<StringRef> DumpSection; - std::vector<NewSymbolInfo> SymbolsToAdd; - std::vector<NameOrRegex> KeepSection; - std::vector<NameOrRegex> OnlySection; - std::vector<NameOrRegex> SymbolsToGlobalize; - std::vector<NameOrRegex> SymbolsToKeep; - std::vector<NameOrRegex> SymbolsToLocalize; - std::vector<NameOrRegex> SymbolsToRemove; - std::vector<NameOrRegex> UnneededSymbolsToRemove; - std::vector<NameOrRegex> SymbolsToWeaken; - std::vector<NameOrRegex> ToRemove; - std::vector<NameOrRegex> SymbolsToKeepGlobal; + std::vector<StringRef> SymbolsToAdd; + + // Section matchers + NameMatcher KeepSection; + NameMatcher OnlySection; + NameMatcher ToRemove; + + // Symbol matchers + NameMatcher SymbolsToGlobalize; + NameMatcher SymbolsToKeep; + NameMatcher SymbolsToLocalize; + NameMatcher SymbolsToRemove; + NameMatcher UnneededSymbolsToRemove; + NameMatcher SymbolsToWeaken; + NameMatcher SymbolsToKeepGlobal; // Map options StringMap<SectionRename> SectionsToRename; + StringMap<uint64_t> SetSectionAlignment; StringMap<SectionFlagsUpdate> SetSectionFlags; StringMap<StringRef> SymbolsToRename; @@ -178,6 +221,18 @@ struct CopyConfig { bool Weaken = false; bool DecompressDebugSections = false; DebugCompressionType CompressionType = DebugCompressionType::None; + + // parseELFConfig performs ELF-specific command-line parsing. Fills `ELF` on + // success or returns an Error otherwise. + Error parseELFConfig() { + if (!ELF) { + Expected<elf::ELFCopyConfig> ELFConfig = elf::parseConfig(*this); + if (!ELFConfig) + return ELFConfig.takeError(); + ELF = *ELFConfig; + } + return Error::success(); + } }; // Configuration for the overall invocation of this tool. When invoked as @@ -190,8 +245,11 @@ struct DriverConfig { // ParseObjcopyOptions returns the config and sets the input arguments. If a // help flag is set then ParseObjcopyOptions will print the help messege and -// exit. -Expected<DriverConfig> parseObjcopyOptions(ArrayRef<const char *> ArgsArr); +// exit. ErrorCallback is used to handle recoverable errors. An Error returned +// by the callback aborts the parsing and is then returned by this function. +Expected<DriverConfig> +parseObjcopyOptions(ArrayRef<const char *> ArgsArr, + llvm::function_ref<Error(Error)> ErrorCallback); // ParseStripOptions returns the config and sets the input arguments. If a // help flag is set then ParseStripOptions will print the help messege and @@ -199,7 +257,7 @@ Expected<DriverConfig> parseObjcopyOptions(ArrayRef<const char *> ArgsArr); // by the callback aborts the parsing and is then returned by this function. Expected<DriverConfig> parseStripOptions(ArrayRef<const char *> ArgsArr, - std::function<Error(Error)> ErrorCallback); + llvm::function_ref<Error(Error)> ErrorCallback); } // namespace objcopy } // namespace llvm |