1343171Sdim//===- CopyConfig.h -------------------------------------------------------===// 2343171Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6343171Sdim// 7343171Sdim//===----------------------------------------------------------------------===// 8343171Sdim 9343171Sdim#ifndef LLVM_TOOLS_LLVM_OBJCOPY_COPY_CONFIG_H 10343171Sdim#define LLVM_TOOLS_LLVM_OBJCOPY_COPY_CONFIG_H 11343171Sdim 12360784Sdim#include "ELF/ELFConfig.h" 13343171Sdim#include "llvm/ADT/ArrayRef.h" 14353358Sdim#include "llvm/ADT/BitmaskEnum.h" 15343171Sdim#include "llvm/ADT/Optional.h" 16343171Sdim#include "llvm/ADT/SmallVector.h" 17343171Sdim#include "llvm/ADT/StringMap.h" 18343171Sdim#include "llvm/ADT/StringRef.h" 19353358Sdim#include "llvm/Object/ELFTypes.h" 20353358Sdim#include "llvm/Support/Allocator.h" 21353358Sdim#include "llvm/Support/Error.h" 22360784Sdim#include "llvm/Support/GlobPattern.h" 23353358Sdim#include "llvm/Support/Regex.h" 24343171Sdim// Necessary for llvm::DebugCompressionType::None 25343171Sdim#include "llvm/Target/TargetOptions.h" 26343171Sdim#include <vector> 27343171Sdim 28343171Sdimnamespace llvm { 29343171Sdimnamespace objcopy { 30343171Sdim 31353358Sdimenum class FileFormat { 32353358Sdim Unspecified, 33353358Sdim ELF, 34353358Sdim Binary, 35353358Sdim IHex, 36353358Sdim}; 37353358Sdim 38343171Sdim// This type keeps track of the machine info for various architectures. This 39343171Sdim// lets us map architecture names to ELF types and the e_machine value of the 40343171Sdim// ELF file. 41343171Sdimstruct MachineInfo { 42353358Sdim MachineInfo(uint16_t EM, uint8_t ABI, bool Is64, bool IsLittle) 43353358Sdim : EMachine(EM), OSABI(ABI), Is64Bit(Is64), IsLittleEndian(IsLittle) {} 44353358Sdim // Alternative constructor that defaults to NONE for OSABI. 45353358Sdim MachineInfo(uint16_t EM, bool Is64, bool IsLittle) 46353358Sdim : MachineInfo(EM, ELF::ELFOSABI_NONE, Is64, IsLittle) {} 47353358Sdim // Default constructor for unset fields. 48353358Sdim MachineInfo() : MachineInfo(0, 0, false, false) {} 49343171Sdim uint16_t EMachine; 50353358Sdim uint8_t OSABI; 51343171Sdim bool Is64Bit; 52343171Sdim bool IsLittleEndian; 53343171Sdim}; 54343171Sdim 55353358Sdim// Flags set by --set-section-flags or --rename-section. Interpretation of these 56353358Sdim// is format-specific and not all flags are meaningful for all object file 57353358Sdim// formats. This is a bitmask; many section flags may be set. 58353358Sdimenum SectionFlag { 59353358Sdim SecNone = 0, 60353358Sdim SecAlloc = 1 << 0, 61353358Sdim SecLoad = 1 << 1, 62353358Sdim SecNoload = 1 << 2, 63353358Sdim SecReadonly = 1 << 3, 64353358Sdim SecDebug = 1 << 4, 65353358Sdim SecCode = 1 << 5, 66353358Sdim SecData = 1 << 6, 67353358Sdim SecRom = 1 << 7, 68353358Sdim SecMerge = 1 << 8, 69353358Sdim SecStrings = 1 << 9, 70353358Sdim SecContents = 1 << 10, 71353358Sdim SecShare = 1 << 11, 72353358Sdim LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ SecShare) 73353358Sdim}; 74353358Sdim 75343171Sdimstruct SectionRename { 76343171Sdim StringRef OriginalName; 77343171Sdim StringRef NewName; 78353358Sdim Optional<SectionFlag> NewFlags; 79343171Sdim}; 80343171Sdim 81353358Sdimstruct SectionFlagsUpdate { 82353358Sdim StringRef Name; 83353358Sdim SectionFlag NewFlags; 84353358Sdim}; 85353358Sdim 86353358Sdimenum class DiscardType { 87353358Sdim None, // Default 88353358Sdim All, // --discard-all (-x) 89353358Sdim Locals, // --discard-locals (-X) 90353358Sdim}; 91353358Sdim 92360784Sdimenum class MatchStyle { 93360784Sdim Literal, // Default for symbols. 94360784Sdim Wildcard, // Default for sections, or enabled with --wildcard (-w). 95360784Sdim Regex, // Enabled with --regex. 96360784Sdim}; 97360784Sdim 98360784Sdimclass NameOrPattern { 99353358Sdim StringRef Name; 100353358Sdim // Regex is shared between multiple CopyConfig instances. 101353358Sdim std::shared_ptr<Regex> R; 102360784Sdim std::shared_ptr<GlobPattern> G; 103360784Sdim bool IsPositiveMatch = true; 104353358Sdim 105360784Sdim NameOrPattern(StringRef N) : Name(N) {} 106360784Sdim NameOrPattern(std::shared_ptr<Regex> R) : R(R) {} 107360784Sdim NameOrPattern(std::shared_ptr<GlobPattern> G, bool IsPositiveMatch) 108360784Sdim : G(G), IsPositiveMatch(IsPositiveMatch) {} 109360784Sdim 110353358Sdimpublic: 111360784Sdim // ErrorCallback is used to handle recoverable errors. An Error returned 112360784Sdim // by the callback aborts the parsing and is then returned by this function. 113360784Sdim static Expected<NameOrPattern> 114360784Sdim create(StringRef Pattern, MatchStyle MS, 115360784Sdim llvm::function_ref<Error(Error)> ErrorCallback); 116360784Sdim 117360784Sdim bool isPositiveMatch() const { return IsPositiveMatch; } 118360784Sdim bool operator==(StringRef S) const { 119360784Sdim return R ? R->match(S) : G ? G->match(S) : Name == S; 120360784Sdim } 121353358Sdim bool operator!=(StringRef S) const { return !operator==(S); } 122353358Sdim}; 123353358Sdim 124360784Sdim// Matcher that checks symbol or section names against the command line flags 125360784Sdim// provided for that option. 126360784Sdimclass NameMatcher { 127360784Sdim std::vector<NameOrPattern> PosMatchers; 128360784Sdim std::vector<NameOrPattern> NegMatchers; 129360784Sdim 130360784Sdimpublic: 131360784Sdim Error addMatcher(Expected<NameOrPattern> Matcher) { 132360784Sdim if (!Matcher) 133360784Sdim return Matcher.takeError(); 134360784Sdim if (Matcher->isPositiveMatch()) 135360784Sdim PosMatchers.push_back(std::move(*Matcher)); 136360784Sdim else 137360784Sdim NegMatchers.push_back(std::move(*Matcher)); 138360784Sdim return Error::success(); 139360784Sdim } 140360784Sdim bool matches(StringRef S) const { 141360784Sdim return is_contained(PosMatchers, S) && !is_contained(NegMatchers, S); 142360784Sdim } 143360784Sdim bool empty() const { return PosMatchers.empty() && NegMatchers.empty(); } 144353358Sdim}; 145353358Sdim 146343171Sdim// Configuration for copying/stripping a single file. 147343171Sdimstruct CopyConfig { 148360784Sdim // Format-specific options to be initialized lazily when needed. 149360784Sdim Optional<elf::ELFCopyConfig> ELF; 150360784Sdim 151343171Sdim // Main input/output options 152343171Sdim StringRef InputFilename; 153360784Sdim FileFormat InputFormat = FileFormat::Unspecified; 154343171Sdim StringRef OutputFilename; 155360784Sdim FileFormat OutputFormat = FileFormat::Unspecified; 156343171Sdim 157343171Sdim // Only applicable when --output-format!=binary (e.g. elf64-x86-64). 158343171Sdim Optional<MachineInfo> OutputArch; 159343171Sdim 160343171Sdim // Advanced options 161343171Sdim StringRef AddGnuDebugLink; 162353358Sdim // Cached gnu_debuglink's target CRC 163353358Sdim uint32_t GnuDebugLinkCRC32; 164343171Sdim StringRef BuildIdLinkDir; 165343171Sdim Optional<StringRef> BuildIdLinkInput; 166343171Sdim Optional<StringRef> BuildIdLinkOutput; 167353358Sdim Optional<StringRef> ExtractPartition; 168343171Sdim StringRef SplitDWO; 169343171Sdim StringRef SymbolsPrefix; 170353358Sdim StringRef AllocSectionsPrefix; 171353358Sdim DiscardType DiscardMode = DiscardType::None; 172360784Sdim Optional<StringRef> NewSymbolVisibility; 173343171Sdim 174343171Sdim // Repeated options 175343171Sdim std::vector<StringRef> AddSection; 176343171Sdim std::vector<StringRef> DumpSection; 177360784Sdim std::vector<StringRef> SymbolsToAdd; 178360784Sdim std::vector<StringRef> RPathToAdd; 179343171Sdim 180360784Sdim // Section matchers 181360784Sdim NameMatcher KeepSection; 182360784Sdim NameMatcher OnlySection; 183360784Sdim NameMatcher ToRemove; 184360784Sdim 185360784Sdim // Symbol matchers 186360784Sdim NameMatcher SymbolsToGlobalize; 187360784Sdim NameMatcher SymbolsToKeep; 188360784Sdim NameMatcher SymbolsToLocalize; 189360784Sdim NameMatcher SymbolsToRemove; 190360784Sdim NameMatcher UnneededSymbolsToRemove; 191360784Sdim NameMatcher SymbolsToWeaken; 192360784Sdim NameMatcher SymbolsToKeepGlobal; 193360784Sdim 194343171Sdim // Map options 195343171Sdim StringMap<SectionRename> SectionsToRename; 196360784Sdim StringMap<uint64_t> SetSectionAlignment; 197353358Sdim StringMap<SectionFlagsUpdate> SetSectionFlags; 198343171Sdim StringMap<StringRef> SymbolsToRename; 199343171Sdim 200353358Sdim // ELF entry point address expression. The input parameter is an entry point 201353358Sdim // address in the input ELF file. The entry address in the output file is 202353358Sdim // calculated with EntryExpr(input_address), when either --set-start or 203353358Sdim // --change-start is used. 204353358Sdim std::function<uint64_t(uint64_t)> EntryExpr; 205353358Sdim 206343171Sdim // Boolean options 207353358Sdim bool AllowBrokenLinks = false; 208343171Sdim bool DeterministicArchives = true; 209343171Sdim bool ExtractDWO = false; 210353358Sdim bool ExtractMainPartition = false; 211343171Sdim bool KeepFileSymbols = false; 212343171Sdim bool LocalizeHidden = false; 213343171Sdim bool OnlyKeepDebug = false; 214343171Sdim bool PreserveDates = false; 215343171Sdim bool StripAll = false; 216343171Sdim bool StripAllGNU = false; 217343171Sdim bool StripDWO = false; 218343171Sdim bool StripDebug = false; 219343171Sdim bool StripNonAlloc = false; 220343171Sdim bool StripSections = false; 221343171Sdim bool StripUnneeded = false; 222343171Sdim bool Weaken = false; 223343171Sdim bool DecompressDebugSections = false; 224343171Sdim DebugCompressionType CompressionType = DebugCompressionType::None; 225360784Sdim 226360784Sdim // parseELFConfig performs ELF-specific command-line parsing. Fills `ELF` on 227360784Sdim // success or returns an Error otherwise. 228360784Sdim Error parseELFConfig() { 229360784Sdim if (!ELF) { 230360784Sdim Expected<elf::ELFCopyConfig> ELFConfig = elf::parseConfig(*this); 231360784Sdim if (!ELFConfig) 232360784Sdim return ELFConfig.takeError(); 233360784Sdim ELF = *ELFConfig; 234360784Sdim } 235360784Sdim return Error::success(); 236360784Sdim } 237343171Sdim}; 238343171Sdim 239343171Sdim// Configuration for the overall invocation of this tool. When invoked as 240343171Sdim// objcopy, will always contain exactly one CopyConfig. When invoked as strip, 241343171Sdim// will contain one or more CopyConfigs. 242343171Sdimstruct DriverConfig { 243343171Sdim SmallVector<CopyConfig, 1> CopyConfigs; 244353358Sdim BumpPtrAllocator Alloc; 245343171Sdim}; 246343171Sdim 247343171Sdim// ParseObjcopyOptions returns the config and sets the input arguments. If a 248343171Sdim// help flag is set then ParseObjcopyOptions will print the help messege and 249360784Sdim// exit. ErrorCallback is used to handle recoverable errors. An Error returned 250360784Sdim// by the callback aborts the parsing and is then returned by this function. 251360784SdimExpected<DriverConfig> 252360784SdimparseObjcopyOptions(ArrayRef<const char *> ArgsArr, 253360784Sdim llvm::function_ref<Error(Error)> ErrorCallback); 254343171Sdim 255360784Sdim// ParseInstallNameToolOptions returns the config and sets the input arguments. 256360784Sdim// If a help flag is set then ParseInstallNameToolOptions will print the help 257360784Sdim// messege and exit. 258360784SdimExpected<DriverConfig> 259360784SdimparseInstallNameToolOptions(ArrayRef<const char *> ArgsArr); 260360784Sdim 261343171Sdim// ParseStripOptions returns the config and sets the input arguments. If a 262343171Sdim// help flag is set then ParseStripOptions will print the help messege and 263353358Sdim// exit. ErrorCallback is used to handle recoverable errors. An Error returned 264353358Sdim// by the callback aborts the parsing and is then returned by this function. 265353358SdimExpected<DriverConfig> 266353358SdimparseStripOptions(ArrayRef<const char *> ArgsArr, 267360784Sdim llvm::function_ref<Error(Error)> ErrorCallback); 268343171Sdim} // namespace objcopy 269343171Sdim} // namespace llvm 270343171Sdim 271343171Sdim#endif 272