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