mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
[llvm-strip] Support stripping multiple input files
Summary: Allow strip to be called on multiple input files, which is interpreted as stripping N files in place. Using multiple input files is incompatible with -o. To allow this, create a `DriverConfig` struct which just wraps a list of `CopyConfigs`. objcopy will only ever have a single `CopyConfig`, but strip will have N (where N >= 1) CopyConfigs. Reviewers: alexshap, jakehehrlich Reviewed By: alexshap, jakehehrlich Subscribers: MaskRay, jakehehrlich, llvm-commits Differential Revision: https://reviews.llvm.org/D51660 llvm-svn: 341464
This commit is contained in:
parent
1aa290ab4d
commit
52282e180e
75
test/tools/llvm-objcopy/strip-multiple-files.test
Normal file
75
test/tools/llvm-objcopy/strip-multiple-files.test
Normal file
@ -0,0 +1,75 @@
|
||||
# RUN: yaml2obj %s > %t.o
|
||||
|
||||
# Run llvm-strip normally. This will create a stripped object file for later
|
||||
# tests so we only have to run FileCheck on it once.
|
||||
# RUN: cp %t.o %t.1.o
|
||||
# RUN: llvm-strip --keep-symbol=foo %t.1.o -o %t.stripped.o
|
||||
# RUN: llvm-readobj -symbols %t.stripped.o | FileCheck %s
|
||||
|
||||
# llvm-strip on two files:
|
||||
# RUN: cp %t.o %t.1.o
|
||||
# RUN: cp %t.o %t.2.o
|
||||
# RUN: llvm-strip --keep-symbol=foo %t.1.o %t.2.o
|
||||
# RUN: cmp %t.1.o %t.stripped.o
|
||||
# RUN: cmp %t.2.o %t.stripped.o
|
||||
|
||||
# llvm-strip on three files:
|
||||
# RUN: cp %t.o %t.1.o
|
||||
# RUN: cp %t.o %t.2.o
|
||||
# RUN: cp %t.o %t.3.o
|
||||
# RUN: llvm-strip --keep-symbol=foo %t.1.o %t.2.o %t.3.o
|
||||
# RUN: cmp %t.1.o %t.stripped.o
|
||||
# RUN: cmp %t.2.o %t.stripped.o
|
||||
# RUN: cmp %t.3.o %t.stripped.o
|
||||
|
||||
# -o cannot be used with multiple input files
|
||||
# RUN: cp %t.o %t.1.o
|
||||
# RUN: cp %t.o %t.2.o
|
||||
# RUN: not llvm-strip --keep-symbol=foo -o %t.stripped.o %t.1.o %t.2.o 2>&1 \
|
||||
# RUN: | FileCheck %s --check-prefix=BAD-O-FLAG
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
Symbols:
|
||||
Local:
|
||||
- Name: foo
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
Value: 0x1234
|
||||
Size: 8
|
||||
- Name: bar
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
Value: 0x5678
|
||||
Size: 8
|
||||
|
||||
# CHECK: Symbols [
|
||||
# CHECK-NEXT: Symbol {
|
||||
# CHECK-NEXT: Name:
|
||||
# CHECK-NEXT: Value: 0x0
|
||||
# CHECK-NEXT: Size: 0
|
||||
# CHECK-NEXT: Binding: Local
|
||||
# CHECK-NEXT: Type: None
|
||||
# CHECK-NEXT: Other: 0
|
||||
# CHECK-NEXT: Section: Undefined
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Symbol {
|
||||
# CHECK-NEXT: Name: foo
|
||||
# CHECK-NEXT: Value: 0x1234
|
||||
# CHECK-NEXT: Size: 8
|
||||
# CHECK-NEXT: Binding: Local
|
||||
# CHECK-NEXT: Type: Function
|
||||
# CHECK-NEXT: Other: 0
|
||||
# CHECK-NEXT: Section: .text
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: ]
|
||||
|
||||
# BAD-O-FLAG: Multiple input files cannot be used in combination with -o.
|
@ -128,6 +128,7 @@ struct SectionRename {
|
||||
Optional<uint64_t> NewFlags;
|
||||
};
|
||||
|
||||
// Configuration for copying/stripping a single file.
|
||||
struct CopyConfig {
|
||||
// Main input/output options
|
||||
StringRef InputFilename;
|
||||
@ -177,6 +178,13 @@ struct CopyConfig {
|
||||
bool Weaken = false;
|
||||
};
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
using SectionPred = std::function<bool(const SectionBase &Sec)>;
|
||||
|
||||
enum SectionFlag {
|
||||
@ -818,7 +826,7 @@ static void addGlobalSymbolsFromFile(std::vector<std::string> &Symbols,
|
||||
// ParseObjcopyOptions returns the config and sets the input arguments. If a
|
||||
// help flag is set then ParseObjcopyOptions will print the help messege and
|
||||
// exit.
|
||||
static CopyConfig parseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
|
||||
static DriverConfig parseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
|
||||
ObjcopyOptTable T;
|
||||
unsigned MissingArgumentIndex, MissingArgumentCount;
|
||||
llvm::opt::InputArgList InputArgs =
|
||||
@ -918,13 +926,15 @@ static CopyConfig parseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
|
||||
|
||||
Config.PreserveDates = InputArgs.hasArg(OBJCOPY_preserve_dates);
|
||||
|
||||
return Config;
|
||||
DriverConfig DC;
|
||||
DC.CopyConfigs.push_back(std::move(Config));
|
||||
return DC;
|
||||
}
|
||||
|
||||
// ParseStripOptions returns the config and sets the input arguments. If a
|
||||
// help flag is set then ParseStripOptions will print the help messege and
|
||||
// exit.
|
||||
static CopyConfig parseStripOptions(ArrayRef<const char *> ArgsArr) {
|
||||
static DriverConfig parseStripOptions(ArrayRef<const char *> ArgsArr) {
|
||||
StripOptTable T;
|
||||
unsigned MissingArgumentIndex, MissingArgumentCount;
|
||||
llvm::opt::InputArgList InputArgs =
|
||||
@ -949,14 +959,10 @@ static CopyConfig parseStripOptions(ArrayRef<const char *> ArgsArr) {
|
||||
if (Positional.empty())
|
||||
error("No input file specified");
|
||||
|
||||
if (Positional.size() > 1)
|
||||
error("Support for multiple input files is not implemented yet");
|
||||
if (Positional.size() > 1 && InputArgs.hasArg(STRIP_output))
|
||||
error("Multiple input files cannot be used in combination with -o");
|
||||
|
||||
CopyConfig Config;
|
||||
Config.InputFilename = Positional[0];
|
||||
Config.OutputFilename =
|
||||
InputArgs.getLastArgValue(STRIP_output, Positional[0]);
|
||||
|
||||
Config.StripDebug = InputArgs.hasArg(STRIP_strip_debug);
|
||||
|
||||
Config.DiscardAll = InputArgs.hasArg(STRIP_discard_all);
|
||||
@ -974,16 +980,31 @@ static CopyConfig parseStripOptions(ArrayRef<const char *> ArgsArr) {
|
||||
|
||||
Config.PreserveDates = InputArgs.hasArg(STRIP_preserve_dates);
|
||||
|
||||
return Config;
|
||||
DriverConfig DC;
|
||||
if (Positional.size() == 1) {
|
||||
Config.InputFilename = Positional[0];
|
||||
Config.OutputFilename =
|
||||
InputArgs.getLastArgValue(STRIP_output, Positional[0]);
|
||||
DC.CopyConfigs.push_back(std::move(Config));
|
||||
} else {
|
||||
for (const char *Filename : Positional) {
|
||||
Config.InputFilename = Filename;
|
||||
Config.OutputFilename = Filename;
|
||||
DC.CopyConfigs.push_back(Config);
|
||||
}
|
||||
}
|
||||
|
||||
return DC;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
InitLLVM X(argc, argv);
|
||||
ToolName = argv[0];
|
||||
CopyConfig Config;
|
||||
DriverConfig DriverConfig;
|
||||
if (sys::path::stem(ToolName).endswith_lower("strip"))
|
||||
Config = parseStripOptions(makeArrayRef(argv + 1, argc));
|
||||
DriverConfig = parseStripOptions(makeArrayRef(argv + 1, argc));
|
||||
else
|
||||
Config = parseObjcopyOptions(makeArrayRef(argv + 1, argc));
|
||||
executeElfObjcopy(Config);
|
||||
DriverConfig = parseObjcopyOptions(makeArrayRef(argv + 1, argc));
|
||||
for (const CopyConfig &CopyConfig : DriverConfig.CopyConfigs)
|
||||
executeElfObjcopy(CopyConfig);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user