CopyConfig.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. //===- CopyConfig.h -------------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef LLVM_TOOLS_LLVM_OBJCOPY_COPY_CONFIG_H
  9. #define LLVM_TOOLS_LLVM_OBJCOPY_COPY_CONFIG_H
  10. #include "ELF/ELFConfig.h"
  11. #include "llvm/ADT/ArrayRef.h"
  12. #include "llvm/ADT/BitmaskEnum.h"
  13. #include "llvm/ADT/DenseSet.h"
  14. #include "llvm/ADT/Optional.h"
  15. #include "llvm/ADT/SmallVector.h"
  16. #include "llvm/ADT/StringMap.h"
  17. #include "llvm/ADT/StringRef.h"
  18. #include "llvm/Object/ELFTypes.h"
  19. #include "llvm/Support/Allocator.h"
  20. #include "llvm/Support/Error.h"
  21. #include "llvm/Support/GlobPattern.h"
  22. #include "llvm/Support/Regex.h"
  23. // Necessary for llvm::DebugCompressionType::None
  24. #include "llvm/Target/TargetOptions.h"
  25. #include <vector>
  26. namespace llvm {
  27. namespace objcopy {
  28. enum class FileFormat {
  29. Unspecified,
  30. ELF,
  31. Binary,
  32. IHex,
  33. };
  34. // This type keeps track of the machine info for various architectures. This
  35. // lets us map architecture names to ELF types and the e_machine value of the
  36. // ELF file.
  37. struct MachineInfo {
  38. MachineInfo(uint16_t EM, uint8_t ABI, bool Is64, bool IsLittle)
  39. : EMachine(EM), OSABI(ABI), Is64Bit(Is64), IsLittleEndian(IsLittle) {}
  40. // Alternative constructor that defaults to NONE for OSABI.
  41. MachineInfo(uint16_t EM, bool Is64, bool IsLittle)
  42. : MachineInfo(EM, ELF::ELFOSABI_NONE, Is64, IsLittle) {}
  43. // Default constructor for unset fields.
  44. MachineInfo() : MachineInfo(0, 0, false, false) {}
  45. uint16_t EMachine;
  46. uint8_t OSABI;
  47. bool Is64Bit;
  48. bool IsLittleEndian;
  49. };
  50. // Flags set by --set-section-flags or --rename-section. Interpretation of these
  51. // is format-specific and not all flags are meaningful for all object file
  52. // formats. This is a bitmask; many section flags may be set.
  53. enum SectionFlag {
  54. SecNone = 0,
  55. SecAlloc = 1 << 0,
  56. SecLoad = 1 << 1,
  57. SecNoload = 1 << 2,
  58. SecReadonly = 1 << 3,
  59. SecDebug = 1 << 4,
  60. SecCode = 1 << 5,
  61. SecData = 1 << 6,
  62. SecRom = 1 << 7,
  63. SecMerge = 1 << 8,
  64. SecStrings = 1 << 9,
  65. SecContents = 1 << 10,
  66. SecShare = 1 << 11,
  67. SecExclude = 1 << 12,
  68. LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/SecExclude)
  69. };
  70. struct SectionRename {
  71. StringRef OriginalName;
  72. StringRef NewName;
  73. Optional<SectionFlag> NewFlags;
  74. };
  75. struct SectionFlagsUpdate {
  76. StringRef Name;
  77. SectionFlag NewFlags;
  78. };
  79. enum class DiscardType {
  80. None, // Default
  81. All, // --discard-all (-x)
  82. Locals, // --discard-locals (-X)
  83. };
  84. enum class MatchStyle {
  85. Literal, // Default for symbols.
  86. Wildcard, // Default for sections, or enabled with --wildcard (-w).
  87. Regex, // Enabled with --regex.
  88. };
  89. class NameOrPattern {
  90. StringRef Name;
  91. // Regex is shared between multiple CopyConfig instances.
  92. std::shared_ptr<Regex> R;
  93. std::shared_ptr<GlobPattern> G;
  94. bool IsPositiveMatch = true;
  95. NameOrPattern(StringRef N) : Name(N) {}
  96. NameOrPattern(std::shared_ptr<Regex> R) : R(R) {}
  97. NameOrPattern(std::shared_ptr<GlobPattern> G, bool IsPositiveMatch)
  98. : G(G), IsPositiveMatch(IsPositiveMatch) {}
  99. public:
  100. // ErrorCallback is used to handle recoverable errors. An Error returned
  101. // by the callback aborts the parsing and is then returned by this function.
  102. static Expected<NameOrPattern>
  103. create(StringRef Pattern, MatchStyle MS,
  104. llvm::function_ref<Error(Error)> ErrorCallback);
  105. bool isPositiveMatch() const { return IsPositiveMatch; }
  106. bool operator==(StringRef S) const {
  107. return R ? R->match(S) : G ? G->match(S) : Name == S;
  108. }
  109. bool operator!=(StringRef S) const { return !operator==(S); }
  110. };
  111. // Matcher that checks symbol or section names against the command line flags
  112. // provided for that option.
  113. class NameMatcher {
  114. std::vector<NameOrPattern> PosMatchers;
  115. std::vector<NameOrPattern> NegMatchers;
  116. public:
  117. Error addMatcher(Expected<NameOrPattern> Matcher) {
  118. if (!Matcher)
  119. return Matcher.takeError();
  120. if (Matcher->isPositiveMatch())
  121. PosMatchers.push_back(std::move(*Matcher));
  122. else
  123. NegMatchers.push_back(std::move(*Matcher));
  124. return Error::success();
  125. }
  126. bool matches(StringRef S) const {
  127. return is_contained(PosMatchers, S) && !is_contained(NegMatchers, S);
  128. }
  129. bool empty() const { return PosMatchers.empty() && NegMatchers.empty(); }
  130. };
  131. // Configuration for copying/stripping a single file.
  132. struct CopyConfig {
  133. // Format-specific options to be initialized lazily when needed.
  134. Optional<elf::ELFCopyConfig> ELF;
  135. // Main input/output options
  136. StringRef InputFilename;
  137. FileFormat InputFormat = FileFormat::Unspecified;
  138. StringRef OutputFilename;
  139. FileFormat OutputFormat = FileFormat::Unspecified;
  140. // Only applicable when --output-format!=binary (e.g. elf64-x86-64).
  141. Optional<MachineInfo> OutputArch;
  142. // Advanced options
  143. StringRef AddGnuDebugLink;
  144. // Cached gnu_debuglink's target CRC
  145. uint32_t GnuDebugLinkCRC32;
  146. StringRef BuildIdLinkDir;
  147. Optional<StringRef> BuildIdLinkInput;
  148. Optional<StringRef> BuildIdLinkOutput;
  149. Optional<StringRef> ExtractPartition;
  150. StringRef SplitDWO;
  151. StringRef SymbolsPrefix;
  152. StringRef AllocSectionsPrefix;
  153. DiscardType DiscardMode = DiscardType::None;
  154. Optional<StringRef> NewSymbolVisibility;
  155. // Repeated options
  156. std::vector<StringRef> AddSection;
  157. std::vector<StringRef> DumpSection;
  158. std::vector<StringRef> SymbolsToAdd;
  159. std::vector<StringRef> RPathToAdd;
  160. std::vector<StringRef> RPathToPrepend;
  161. DenseMap<StringRef, StringRef> RPathsToUpdate;
  162. DenseMap<StringRef, StringRef> InstallNamesToUpdate;
  163. DenseSet<StringRef> RPathsToRemove;
  164. // install-name-tool's id option
  165. Optional<StringRef> SharedLibId;
  166. // Section matchers
  167. NameMatcher KeepSection;
  168. NameMatcher OnlySection;
  169. NameMatcher ToRemove;
  170. // Symbol matchers
  171. NameMatcher SymbolsToGlobalize;
  172. NameMatcher SymbolsToKeep;
  173. NameMatcher SymbolsToLocalize;
  174. NameMatcher SymbolsToRemove;
  175. NameMatcher UnneededSymbolsToRemove;
  176. NameMatcher SymbolsToWeaken;
  177. NameMatcher SymbolsToKeepGlobal;
  178. // Map options
  179. StringMap<SectionRename> SectionsToRename;
  180. StringMap<uint64_t> SetSectionAlignment;
  181. StringMap<SectionFlagsUpdate> SetSectionFlags;
  182. StringMap<StringRef> SymbolsToRename;
  183. // ELF entry point address expression. The input parameter is an entry point
  184. // address in the input ELF file. The entry address in the output file is
  185. // calculated with EntryExpr(input_address), when either --set-start or
  186. // --change-start is used.
  187. std::function<uint64_t(uint64_t)> EntryExpr;
  188. // Boolean options
  189. bool AllowBrokenLinks = false;
  190. bool DeterministicArchives = true;
  191. bool ExtractDWO = false;
  192. bool ExtractMainPartition = false;
  193. bool KeepFileSymbols = false;
  194. bool LocalizeHidden = false;
  195. bool OnlyKeepDebug = false;
  196. bool PreserveDates = false;
  197. bool StripAll = false;
  198. bool StripAllGNU = false;
  199. bool StripDWO = false;
  200. bool StripDebug = false;
  201. bool StripNonAlloc = false;
  202. bool StripSections = false;
  203. bool StripSwiftSymbols = false;
  204. bool StripUnneeded = false;
  205. bool Weaken = false;
  206. bool DecompressDebugSections = false;
  207. // install-name-tool's --delete_all_rpaths
  208. bool RemoveAllRpaths = false;
  209. DebugCompressionType CompressionType = DebugCompressionType::None;
  210. // parseELFConfig performs ELF-specific command-line parsing. Fills `ELF` on
  211. // success or returns an Error otherwise.
  212. Error parseELFConfig() {
  213. if (!ELF) {
  214. Expected<elf::ELFCopyConfig> ELFConfig = elf::parseConfig(*this);
  215. if (!ELFConfig)
  216. return ELFConfig.takeError();
  217. ELF = *ELFConfig;
  218. }
  219. return Error::success();
  220. }
  221. };
  222. // Configuration for the overall invocation of this tool. When invoked as
  223. // objcopy, will always contain exactly one CopyConfig. When invoked as strip,
  224. // will contain one or more CopyConfigs.
  225. struct DriverConfig {
  226. SmallVector<CopyConfig, 1> CopyConfigs;
  227. BumpPtrAllocator Alloc;
  228. };
  229. // ParseObjcopyOptions returns the config and sets the input arguments. If a
  230. // help flag is set then ParseObjcopyOptions will print the help messege and
  231. // exit. ErrorCallback is used to handle recoverable errors. An Error returned
  232. // by the callback aborts the parsing and is then returned by this function.
  233. Expected<DriverConfig>
  234. parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
  235. llvm::function_ref<Error(Error)> ErrorCallback);
  236. // ParseInstallNameToolOptions returns the config and sets the input arguments.
  237. // If a help flag is set then ParseInstallNameToolOptions will print the help
  238. // messege and exit.
  239. Expected<DriverConfig>
  240. parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr);
  241. // ParseBitcodeStripOptions returns the config and sets the input arguments.
  242. // If a help flag is set then ParseBitcodeStripOptions will print the help
  243. // messege and exit.
  244. Expected<DriverConfig> parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr);
  245. // ParseStripOptions returns the config and sets the input arguments. If a
  246. // help flag is set then ParseStripOptions will print the help messege and
  247. // exit. ErrorCallback is used to handle recoverable errors. An Error returned
  248. // by the callback aborts the parsing and is then returned by this function.
  249. Expected<DriverConfig>
  250. parseStripOptions(ArrayRef<const char *> ArgsArr,
  251. llvm::function_ref<Error(Error)> ErrorCallback);
  252. } // namespace objcopy
  253. } // namespace llvm
  254. #endif