1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[llvm-objcopy] Implement -G/--keep-global-symbol(s).

Summary:
Port GNU Objcopy -G/--keep-global-symbol(s).

This is slightly different than the already-implemented --globalize-symbol, which marks a symbol as global when copying. When --keep-global-symbol (alias -G) is used, *only* those symbols marked will stay global, and all other globals are demoted to local. (Also note that it doesn't *promote* a symbol to global). Additionally, there is a pluralized version of the flag --keep-global-symbols, which effectively applies --keep-global-symbol for every non-comment in a file.

Reviewers: jakehehrlich, jhenderson, alexshap

Reviewed By: jhenderson

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D50589

llvm-svn: 340105
This commit is contained in:
Jordan Rupprecht 2018-08-17 22:34:48 +00:00
parent c29b0fbcdc
commit eb7a7f2cd2
4 changed files with 200 additions and 0 deletions

View File

@ -0,0 +1,51 @@
# RUN: yaml2obj %s > %t.o
# Tests --keep-global-symbol when used in combination with --globalize-symbol on
# a different symbol.
# RUN: llvm-objcopy \
# RUN: --globalize-symbol Local1 \
# RUN: --keep-global-symbol Local2 \
# RUN: --globalize-symbol Weak1 \
# RUN: --keep-global-symbol Weak2 \
# RUN: --globalize-symbol Global1 \
# RUN: --keep-global-symbol Global2 \
# RUN: %t.o %t.2.o
# RUN: llvm-readobj -elf-output-style=GNU -symbols %t.2.o | FileCheck %s
!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: Local1
Section: .text
- Name: Local2
Section: .text
Weak:
- Name: Weak1
Section: .text
- Name: Weak2
Section: .text
Global:
- Name: Global1
Section: .text
- Name: Global2
Section: .text
# CHECK: Symbol table '.symtab' contains 7 entries:
# CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name
# CHECK-NEXT: 0: {{.*}} LOCAL {{.*}}
# CHECK-NEXT: 1: {{.*}} LOCAL {{.*}} Local2
# CHECK-NEXT: 2: {{.*}} GLOBAL {{.*}} Local1
# CHECK-NEXT: 3: {{.*}} GLOBAL {{.*}} Global1
# CHECK-NEXT: 4: {{.*}} GLOBAL {{.*}} Global2
# CHECK-NEXT: 5: {{.*}} GLOBAL {{.*}} Weak1
# CHECK-NEXT: 6: {{.*}} WEAK {{.*}} Weak2

View File

@ -0,0 +1,95 @@
# RUN: yaml2obj %s > %t.o
# Tests that only global symbols (via -G/--keep-global-symbols) are kept via
# the several different variants of -G/--keep-global-symbol(s).
#
# Local1: Local because "-G Local1" doesn't make symbols global.
# Local2: Global because of "--globalize-symbol Local2".
# Weak1: Weak because "-G Weak1" doesn't make symbols global.
# Weak2: Global because of "--globalize-symbol Weak2".
# Weak3: Local because no -G flag covers it.
# Global1: Global because of "-G Global1".
# Global2: Global because of "--keep-global-symbol Global2".
# Global3: Global because of "--keep-global-symbols %t-globals1.txt".
# Global4: Global because of "--keep-global-symbols %t-globals2.txt".
# Global5: Local, it appears in %t-globals2.txt but only in comments and as
# part of another symbol
# Global6: Local, it appears in %t-globals2.txt but only part of another symbol
# "Global5 Global6": Global, because it appears in %t-globals2.txt, but we only
# trim leading and trailing whitespace. We don't just take the first chunk
# that looks like a symbol.
# RUN: echo Global2 > %t-globals1.txt
# RUN: echo " Global3 " > %t-globals2.txt
# RUN: echo "Global4 # Global5" >> %t-globals2.txt
# RUN: echo " Global5 Global6 " >> %t-globals2.txt
# RUN: echo "Unknown" >> %t-globals2.txt
# RUN: echo " " >> %t-globals2.txt
# RUN: echo "# File with no symbols" > %t-globals3.txt
# RUN: llvm-objcopy \
# RUN: -G Global1 \
# RUN: --keep-global-symbol Global2 \
# RUN: --keep-global-symbols %t-globals1.txt \
# RUN: --keep-global-symbols %t-globals2.txt \
# RUN: -G Local1 \
# RUN: --globalize-symbol Local2 \
# RUN: -G Weak1 \
# RUN: --globalize-symbol Weak2 \
# RUN: %t.o %t.2.o
# RUN: llvm-readobj -elf-output-style=GNU -symbols %t.2.o | FileCheck %s
!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: Local1
Section: .text
- Name: Local2
Section: .text
Weak:
- Name: Weak1
Section: .text
- Name: Weak2
Section: .text
- Name: Weak3
Section: .text
Global:
- Name: Global1
Section: .text
- Name: Global2
Section: .text
- Name: Global3
Section: .text
- Name: Global4
Section: .text
- Name: Global5
Section: .text
- Name: Global6
Section: .text
- Name: "Global5 Global6"
Section: .text
# CHECK: Symbol table '.symtab' contains 13 entries:
# CHECK-NEXT: Num: Value Size Type Bind Vis Ndx Name
# CHECK-NEXT: 0: {{.*}} LOCAL {{.*}}
# CHECK-NEXT: 1: {{.*}} LOCAL {{.*}} Local1
# CHECK-NEXT: 2: {{.*}} LOCAL {{.*}} Global5
# CHECK-NEXT: 3: {{.*}} LOCAL {{.*}} Global6
# CHECK-NEXT: 4: {{.*}} LOCAL {{.*}} Weak3
# CHECK-NEXT: 5: {{.*}} GLOBAL {{.*}} Local2
# CHECK-NEXT: 6: {{.*}} GLOBAL {{.*}} Global1
# CHECK-NEXT: 7: {{.*}} GLOBAL {{.*}} Global2
# CHECK-NEXT: 8: {{.*}} GLOBAL {{.*}} Global3
# CHECK-NEXT: 9: {{.*}} GLOBAL {{.*}} Global4
# CHECK-NEXT: 10: {{.*}} GLOBAL {{.*}} Global5 Global6
# CHECK-NEXT: 11: {{.*}} WEAK {{.*}} Weak1
# CHECK-NEXT: 12: {{.*}} GLOBAL {{.*}} Weak2

View File

@ -81,6 +81,24 @@ def L : JoinedOrSeparate<["-"], "L">,
defm globalize_symbol : Eq<"globalize-symbol">,
MetaVarName<"symbol">,
HelpText<"Mark <symbol> as global">;
defm keep_global_symbol
: Eq<"keep-global-symbol">,
MetaVarName<"symbol">,
HelpText<"Convert all symbols except <symbol> to local. May be repeated "
"to convert all except a set of symbols to local.">;
def G : JoinedOrSeparate<[ "-" ], "G">, Alias<keep_global_symbol>;
defm keep_global_symbols
: Eq<"keep-global-symbols">,
MetaVarName<"filename">,
HelpText<
"Reads a list of symbols from <filename> and runs as if "
"--keep-global-symbol=<symbol> is set for each one. <filename> "
"contains one symbol per line and may contain comments beginning "
"with '#'. Leading and trailing whitespace is stripped from each "
"line. May be repeated to read symbols from many files.">;
defm weaken_symbol : Eq<"weaken-symbol">,
MetaVarName<"symbol">,
HelpText<"Mark <symbol> as weak">;

View File

@ -154,6 +154,7 @@ struct CopyConfig {
std::vector<StringRef> SymbolsToRemove;
std::vector<StringRef> SymbolsToWeaken;
std::vector<StringRef> ToRemove;
std::vector<std::string> SymbolsToKeepGlobal;
// Map options
StringMap<SectionRename> SectionsToRename;
@ -428,6 +429,20 @@ static void handleArgs(const CopyConfig &Config, Object &Obj,
is_contained(Config.SymbolsToLocalize, Sym.Name)))
Sym.Binding = STB_LOCAL;
// Note: these two globalize flags have very similar names but different
// meanings:
//
// --globalize-symbol: promote a symbol to global
// --keep-global-symbol: all symbols except for these should be made local
//
// If --globalize-symbol is specified for a given symbol, it will be
// global in the output file even if it is not included via
// --keep-global-symbol. Because of that, make sure to check
// --globalize-symbol second.
if (!Config.SymbolsToKeepGlobal.empty() &&
!is_contained(Config.SymbolsToKeepGlobal, Sym.Name))
Sym.Binding = STB_LOCAL;
if (!Config.SymbolsToGlobalize.empty() &&
is_contained(Config.SymbolsToGlobalize, Sym.Name))
Sym.Binding = STB_GLOBAL;
@ -782,6 +797,23 @@ static void executeElfObjcopy(const CopyConfig &Config) {
}
}
static void addGlobalSymbolsFromFile(std::vector<std::string> &Symbols,
StringRef Filename) {
SmallVector<StringRef, 16> Lines;
auto BufOrErr = MemoryBuffer::getFile(Filename);
if (!BufOrErr)
reportError(Filename, BufOrErr.getError());
BufOrErr.get()->getBuffer().split(Lines, '\n');
for (StringRef Line : Lines) {
// Ignore everything after '#', trim whitespace, and only add the symbol if
// it's not empty.
auto TrimmedLine = Line.split('#').first.trim();
if (!TrimmedLine.empty())
Symbols.push_back(TrimmedLine.str());
}
}
// ParseObjcopyOptions returns the config and sets the input arguments. If a
// help flag is set then ParseObjcopyOptions will print the help messege and
// exit.
@ -870,6 +902,10 @@ static CopyConfig parseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
Config.KeepFileSymbols = InputArgs.hasArg(OBJCOPY_keep_file_symbols);
for (auto Arg : InputArgs.filtered(OBJCOPY_localize_symbol))
Config.SymbolsToLocalize.push_back(Arg->getValue());
for (auto Arg : InputArgs.filtered(OBJCOPY_keep_global_symbol))
Config.SymbolsToKeepGlobal.push_back(Arg->getValue());
for (auto Arg : InputArgs.filtered(OBJCOPY_keep_global_symbols))
addGlobalSymbolsFromFile(Config.SymbolsToKeepGlobal, Arg->getValue());
for (auto Arg : InputArgs.filtered(OBJCOPY_globalize_symbol))
Config.SymbolsToGlobalize.push_back(Arg->getValue());
for (auto Arg : InputArgs.filtered(OBJCOPY_weaken_symbol))