CommonConfig.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- CommonConfig.h -------------------------------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_OBJCOPY_COMMONCONFIG_H
  14. #define LLVM_OBJCOPY_COMMONCONFIG_H
  15. #include "llvm/ADT/ArrayRef.h"
  16. #include "llvm/ADT/CachedHashString.h"
  17. #include "llvm/ADT/DenseSet.h"
  18. #include "llvm/ADT/SmallVector.h"
  19. #include "llvm/ADT/StringMap.h"
  20. #include "llvm/ADT/StringRef.h"
  21. #include "llvm/Object/ELFTypes.h"
  22. #include "llvm/Support/GlobPattern.h"
  23. #include "llvm/Support/MemoryBuffer.h"
  24. #include "llvm/Support/Regex.h"
  25. // Necessary for llvm::DebugCompressionType::None
  26. #include "llvm/Target/TargetOptions.h"
  27. #include <optional>
  28. #include <vector>
  29. namespace llvm {
  30. namespace objcopy {
  31. enum class FileFormat {
  32. Unspecified,
  33. ELF,
  34. Binary,
  35. IHex,
  36. };
  37. // This type keeps track of the machine info for various architectures. This
  38. // lets us map architecture names to ELF types and the e_machine value of the
  39. // ELF file.
  40. struct MachineInfo {
  41. MachineInfo(uint16_t EM, uint8_t ABI, bool Is64, bool IsLittle)
  42. : EMachine(EM), OSABI(ABI), Is64Bit(Is64), IsLittleEndian(IsLittle) {}
  43. // Alternative constructor that defaults to NONE for OSABI.
  44. MachineInfo(uint16_t EM, bool Is64, bool IsLittle)
  45. : MachineInfo(EM, ELF::ELFOSABI_NONE, Is64, IsLittle) {}
  46. // Default constructor for unset fields.
  47. MachineInfo() : MachineInfo(0, 0, false, false) {}
  48. uint16_t EMachine;
  49. uint8_t OSABI;
  50. bool Is64Bit;
  51. bool IsLittleEndian;
  52. };
  53. // Flags set by --set-section-flags or --rename-section. Interpretation of these
  54. // is format-specific and not all flags are meaningful for all object file
  55. // formats. This is a bitmask; many section flags may be set.
  56. enum SectionFlag {
  57. SecNone = 0,
  58. SecAlloc = 1 << 0,
  59. SecLoad = 1 << 1,
  60. SecNoload = 1 << 2,
  61. SecReadonly = 1 << 3,
  62. SecDebug = 1 << 4,
  63. SecCode = 1 << 5,
  64. SecData = 1 << 6,
  65. SecRom = 1 << 7,
  66. SecMerge = 1 << 8,
  67. SecStrings = 1 << 9,
  68. SecContents = 1 << 10,
  69. SecShare = 1 << 11,
  70. SecExclude = 1 << 12,
  71. LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/SecExclude)
  72. };
  73. struct SectionRename {
  74. StringRef OriginalName;
  75. StringRef NewName;
  76. std::optional<SectionFlag> NewFlags;
  77. };
  78. struct SectionFlagsUpdate {
  79. StringRef Name;
  80. SectionFlag NewFlags;
  81. };
  82. enum class DiscardType {
  83. None, // Default
  84. All, // --discard-all (-x)
  85. Locals, // --discard-locals (-X)
  86. };
  87. enum class MatchStyle {
  88. Literal, // Default for symbols.
  89. Wildcard, // Default for sections, or enabled with --wildcard (-w).
  90. Regex, // Enabled with --regex.
  91. };
  92. class NameOrPattern {
  93. StringRef Name;
  94. // Regex is shared between multiple CommonConfig instances.
  95. std::shared_ptr<Regex> R;
  96. std::shared_ptr<GlobPattern> G;
  97. bool IsPositiveMatch = true;
  98. NameOrPattern(StringRef N) : Name(N) {}
  99. NameOrPattern(std::shared_ptr<Regex> R) : R(R) {}
  100. NameOrPattern(std::shared_ptr<GlobPattern> G, bool IsPositiveMatch)
  101. : G(G), IsPositiveMatch(IsPositiveMatch) {}
  102. public:
  103. // ErrorCallback is used to handle recoverable errors. An Error returned
  104. // by the callback aborts the parsing and is then returned by this function.
  105. static Expected<NameOrPattern>
  106. create(StringRef Pattern, MatchStyle MS,
  107. llvm::function_ref<Error(Error)> ErrorCallback);
  108. bool isPositiveMatch() const { return IsPositiveMatch; }
  109. std::optional<StringRef> getName() const {
  110. if (!R && !G)
  111. return Name;
  112. return std::nullopt;
  113. }
  114. bool operator==(StringRef S) const {
  115. return R ? R->match(S) : G ? G->match(S) : Name == S;
  116. }
  117. bool operator!=(StringRef S) const { return !operator==(S); }
  118. };
  119. // Matcher that checks symbol or section names against the command line flags
  120. // provided for that option.
  121. class NameMatcher {
  122. DenseSet<CachedHashStringRef> PosNames;
  123. std::vector<NameOrPattern> PosPatterns;
  124. std::vector<NameOrPattern> NegMatchers;
  125. public:
  126. Error addMatcher(Expected<NameOrPattern> Matcher) {
  127. if (!Matcher)
  128. return Matcher.takeError();
  129. if (Matcher->isPositiveMatch()) {
  130. if (std::optional<StringRef> MaybeName = Matcher->getName())
  131. PosNames.insert(CachedHashStringRef(*MaybeName));
  132. else
  133. PosPatterns.push_back(std::move(*Matcher));
  134. } else {
  135. NegMatchers.push_back(std::move(*Matcher));
  136. }
  137. return Error::success();
  138. }
  139. bool matches(StringRef S) const {
  140. return (PosNames.contains(CachedHashStringRef(S)) ||
  141. is_contained(PosPatterns, S)) &&
  142. !is_contained(NegMatchers, S);
  143. }
  144. bool empty() const {
  145. return PosNames.empty() && PosPatterns.empty() && NegMatchers.empty();
  146. }
  147. };
  148. enum class SymbolFlag {
  149. Global,
  150. Local,
  151. Weak,
  152. Default,
  153. Hidden,
  154. Protected,
  155. File,
  156. Section,
  157. Object,
  158. Function,
  159. IndirectFunction,
  160. Debug,
  161. Constructor,
  162. Warning,
  163. Indirect,
  164. Synthetic,
  165. UniqueObject,
  166. };
  167. // Symbol info specified by --add-symbol option. Symbol flags not supported
  168. // by a concrete format should be ignored.
  169. struct NewSymbolInfo {
  170. StringRef SymbolName;
  171. StringRef SectionName;
  172. uint64_t Value = 0;
  173. std::vector<SymbolFlag> Flags;
  174. std::vector<StringRef> BeforeSyms;
  175. };
  176. // Specify section name and section body for newly added or updated section.
  177. struct NewSectionInfo {
  178. NewSectionInfo() = default;
  179. NewSectionInfo(StringRef Name, std::unique_ptr<MemoryBuffer> &&Buffer)
  180. : SectionName(Name), SectionData(std::move(Buffer)) {}
  181. StringRef SectionName;
  182. std::shared_ptr<MemoryBuffer> SectionData;
  183. };
  184. // Configuration for copying/stripping a single file.
  185. struct CommonConfig {
  186. // Main input/output options
  187. StringRef InputFilename;
  188. FileFormat InputFormat = FileFormat::Unspecified;
  189. StringRef OutputFilename;
  190. FileFormat OutputFormat = FileFormat::Unspecified;
  191. // Only applicable when --output-format!=binary (e.g. elf64-x86-64).
  192. std::optional<MachineInfo> OutputArch;
  193. // Advanced options
  194. StringRef AddGnuDebugLink;
  195. // Cached gnu_debuglink's target CRC
  196. uint32_t GnuDebugLinkCRC32;
  197. std::optional<StringRef> ExtractPartition;
  198. StringRef SplitDWO;
  199. StringRef SymbolsPrefix;
  200. StringRef AllocSectionsPrefix;
  201. DiscardType DiscardMode = DiscardType::None;
  202. // Repeated options
  203. std::vector<NewSectionInfo> AddSection;
  204. std::vector<StringRef> DumpSection;
  205. std::vector<NewSectionInfo> UpdateSection;
  206. // Section matchers
  207. NameMatcher KeepSection;
  208. NameMatcher OnlySection;
  209. NameMatcher ToRemove;
  210. // Symbol matchers
  211. NameMatcher SymbolsToGlobalize;
  212. NameMatcher SymbolsToKeep;
  213. NameMatcher SymbolsToLocalize;
  214. NameMatcher SymbolsToRemove;
  215. NameMatcher UnneededSymbolsToRemove;
  216. NameMatcher SymbolsToWeaken;
  217. NameMatcher SymbolsToKeepGlobal;
  218. // Map options
  219. StringMap<SectionRename> SectionsToRename;
  220. StringMap<uint64_t> SetSectionAlignment;
  221. StringMap<SectionFlagsUpdate> SetSectionFlags;
  222. StringMap<uint64_t> SetSectionType;
  223. StringMap<StringRef> SymbolsToRename;
  224. // Symbol info specified by --add-symbol option.
  225. std::vector<NewSymbolInfo> SymbolsToAdd;
  226. // Boolean options
  227. bool DeterministicArchives = true;
  228. bool ExtractDWO = false;
  229. bool ExtractMainPartition = false;
  230. bool OnlyKeepDebug = false;
  231. bool PreserveDates = false;
  232. bool StripAll = false;
  233. bool StripAllGNU = false;
  234. bool StripDWO = false;
  235. bool StripDebug = false;
  236. bool StripNonAlloc = false;
  237. bool StripSections = false;
  238. bool StripUnneeded = false;
  239. bool Weaken = false;
  240. bool DecompressDebugSections = false;
  241. DebugCompressionType CompressionType = DebugCompressionType::None;
  242. };
  243. } // namespace objcopy
  244. } // namespace llvm
  245. #endif // LLVM_OBJCOPY_COMMONCONFIG_H
  246. #ifdef __GNUC__
  247. #pragma GCC diagnostic pop
  248. #endif