1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00
llvm-mirror/tools/llvm-objcopy/CopyConfig.h
Fangrui Song 3296757d5e [llvm-objcopy] Delete --build-id-link-{dir,input,output}
The few options are niche. They solved a problem which was traditionally solved
with more shell commands (`llvm-readelf -n` fetches the Build ID. Then
`ln` is used to hard link the file to a directory derived from the Build ID.)

Due to limitation, they are no longer used by Fuchsia and they don't appear to
be used elsewhere (checked with Google Search and Debian Code Search). So delete
them without a transition period.

Announcement: https://lists.llvm.org/pipermail/llvm-dev/2021-February/148446.html

Differential Revision: https://reviews.llvm.org/D96310
2021-02-15 11:17:32 -08:00

287 lines
9.2 KiB
C++

//===- CopyConfig.h -------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#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/DenseSet.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#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"
#include <vector>
namespace llvm {
namespace objcopy {
enum class FileFormat {
Unspecified,
ELF,
Binary,
IHex,
};
// This type keeps track of the machine info for various architectures. This
// lets us map architecture names to ELF types and the e_machine value of the
// ELF file.
struct MachineInfo {
MachineInfo(uint16_t EM, uint8_t ABI, bool Is64, bool IsLittle)
: EMachine(EM), OSABI(ABI), Is64Bit(Is64), IsLittleEndian(IsLittle) {}
// Alternative constructor that defaults to NONE for OSABI.
MachineInfo(uint16_t EM, bool Is64, bool IsLittle)
: MachineInfo(EM, ELF::ELFOSABI_NONE, Is64, IsLittle) {}
// Default constructor for unset fields.
MachineInfo() : MachineInfo(0, 0, false, false) {}
uint16_t EMachine;
uint8_t OSABI;
bool Is64Bit;
bool IsLittleEndian;
};
// Flags set by --set-section-flags or --rename-section. Interpretation of these
// is format-specific and not all flags are meaningful for all object file
// formats. This is a bitmask; many section flags may be set.
enum SectionFlag {
SecNone = 0,
SecAlloc = 1 << 0,
SecLoad = 1 << 1,
SecNoload = 1 << 2,
SecReadonly = 1 << 3,
SecDebug = 1 << 4,
SecCode = 1 << 5,
SecData = 1 << 6,
SecRom = 1 << 7,
SecMerge = 1 << 8,
SecStrings = 1 << 9,
SecContents = 1 << 10,
SecShare = 1 << 11,
SecExclude = 1 << 12,
LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/SecExclude)
};
struct SectionRename {
StringRef OriginalName;
StringRef NewName;
Optional<SectionFlag> NewFlags;
};
struct SectionFlagsUpdate {
StringRef Name;
SectionFlag NewFlags;
};
enum class DiscardType {
None, // Default
All, // --discard-all (-x)
Locals, // --discard-locals (-X)
};
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:
// 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); }
};
// 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 = FileFormat::Unspecified;
StringRef OutputFilename;
FileFormat OutputFormat = FileFormat::Unspecified;
// Only applicable when --output-format!=binary (e.g. elf64-x86-64).
Optional<MachineInfo> OutputArch;
// Advanced options
StringRef AddGnuDebugLink;
// Cached gnu_debuglink's target CRC
uint32_t GnuDebugLinkCRC32;
Optional<StringRef> ExtractPartition;
StringRef SplitDWO;
StringRef SymbolsPrefix;
StringRef AllocSectionsPrefix;
DiscardType DiscardMode = DiscardType::None;
Optional<StringRef> NewSymbolVisibility;
// Repeated options
std::vector<StringRef> AddSection;
std::vector<StringRef> DumpSection;
std::vector<StringRef> SymbolsToAdd;
std::vector<StringRef> RPathToAdd;
std::vector<StringRef> RPathToPrepend;
DenseMap<StringRef, StringRef> RPathsToUpdate;
DenseMap<StringRef, StringRef> InstallNamesToUpdate;
DenseSet<StringRef> RPathsToRemove;
// install-name-tool's id option
Optional<StringRef> SharedLibId;
// 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;
// ELF entry point address expression. The input parameter is an entry point
// address in the input ELF file. The entry address in the output file is
// calculated with EntryExpr(input_address), when either --set-start or
// --change-start is used.
std::function<uint64_t(uint64_t)> EntryExpr;
// Boolean options
bool AllowBrokenLinks = false;
bool DeterministicArchives = true;
bool ExtractDWO = false;
bool ExtractMainPartition = false;
bool KeepFileSymbols = false;
bool LocalizeHidden = false;
bool OnlyKeepDebug = false;
bool PreserveDates = false;
bool StripAll = false;
bool StripAllGNU = false;
bool StripDWO = false;
bool StripDebug = false;
bool StripNonAlloc = false;
bool StripSections = false;
bool StripSwiftSymbols = false;
bool StripUnneeded = false;
bool Weaken = false;
bool DecompressDebugSections = false;
// install-name-tool's --delete_all_rpaths
bool RemoveAllRpaths = 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
// objcopy, will always contain exactly one CopyConfig. When invoked as strip,
// will contain one or more CopyConfigs.
struct DriverConfig {
SmallVector<CopyConfig, 1> CopyConfigs;
BumpPtrAllocator Alloc;
};
// ParseObjcopyOptions returns the config and sets the input arguments. If a
// help flag is set then ParseObjcopyOptions will print the help messege and
// 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);
// ParseInstallNameToolOptions returns the config and sets the input arguments.
// If a help flag is set then ParseInstallNameToolOptions will print the help
// messege and exit.
Expected<DriverConfig>
parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr);
// ParseBitcodeStripOptions returns the config and sets the input arguments.
// If a help flag is set then ParseBitcodeStripOptions will print the help
// messege and exit.
Expected<DriverConfig> parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr);
// ParseStripOptions returns the config and sets the input arguments. If a
// help flag is set then ParseStripOptions will print the help messege and
// 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>
parseStripOptions(ArrayRef<const char *> ArgsArr,
llvm::function_ref<Error(Error)> ErrorCallback);
} // namespace objcopy
} // namespace llvm
#endif