1
0
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:
Jordan Rupprecht 2018-09-05 13:10:03 +00:00
parent 1aa290ab4d
commit 52282e180e
2 changed files with 110 additions and 14 deletions

View 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.

View File

@ -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);
}