New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[llvm-objcopy] Add --skip-symbol and --skip-symbols options #80873
Conversation
@llvm/pr-subscribers-llvm-binary-utilities Author: Ilia Kuklin (kuilpd) ChangesAdd an option to ignore (exclude) symbols when executing other options that can change the symbol's name, binding or visibility, similar to an existing option --keep-symbol that keeps a symbol from being removed by other options. Full diff: https://github.com/llvm/llvm-project/pull/80873.diff 5 Files Affected:
diff --git a/llvm/include/llvm/ObjCopy/ELF/ELFConfig.h b/llvm/include/llvm/ObjCopy/ELF/ELFConfig.h
index d77cb69b159db..52874ea55414d 100644
--- a/llvm/include/llvm/ObjCopy/ELF/ELFConfig.h
+++ b/llvm/include/llvm/ObjCopy/ELF/ELFConfig.h
@@ -9,6 +9,7 @@
#ifndef LLVM_OBJCOPY_ELF_ELFCONFIG_H
#define LLVM_OBJCOPY_ELF_ELFCONFIG_H
+#include "llvm/ObjCopy/CommonConfig.h"
#include "llvm/Object/ELFTypes.h"
namespace llvm {
@@ -18,6 +19,8 @@ namespace objcopy {
struct ELFConfig {
uint8_t NewSymbolVisibility = (uint8_t)ELF::STV_DEFAULT;
+ NameMatcher SymbolsToIgnore;
+
// 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
diff --git a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
index b6d77d17bae36..f8c0413684f22 100644
--- a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
+++ b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
@@ -290,6 +290,8 @@ static Error updateAndRemoveSymbols(const CommonConfig &Config,
return Error::success();
Obj.SymbolTable->updateSymbols([&](Symbol &Sym) {
+ if (ELFConfig.SymbolsToIgnore.matches(Sym.Name))
+ return;
// Common and undefined symbols don't make sense as local symbols, and can
// even cause crashes if we localize those, so skip them.
if (!Sym.isCommon() && Sym.getShndx() != SHN_UNDEF &&
diff --git a/llvm/test/tools/llvm-objcopy/ELF/ignore-symbols.test b/llvm/test/tools/llvm-objcopy/ELF/ignore-symbols.test
new file mode 100644
index 0000000000000..13a15b46038ee
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/ELF/ignore-symbols.test
@@ -0,0 +1,41 @@
+
+# RUN: yaml2obj %s -o %t.o
+# RUN: echo 'foo[2-3]' > %t.ignore.regex
+
+# RUN: cp %t.o %t1.o
+# RUN: llvm-objcopy %t1.o --localize-hidden --ignore-symbols=%t.ignore.regex --regex
+# RUN: llvm-readelf -s %t1.o | FileCheck %s --check-prefix=SYMS
+# SYMS-DAG: LOCAL HIDDEN 1 foo1
+# SYMS-DAG: GLOBAL HIDDEN 1 foo2
+# SYMS-DAG: GLOBAL HIDDEN 1 foo3
+
+# RUN: cp %t.o %t1.o
+# RUN: llvm-objcopy %t1.o --localize-hidden --ignore-symbol=foo3
+# RUN: llvm-readelf -s %t1.o | FileCheck %s --check-prefix=SYM
+# SYM-DAG: LOCAL HIDDEN 1 foo1
+# SYM-DAG: LOCAL HIDDEN 1 foo2
+# SYM-DAG: GLOBAL HIDDEN 1 foo3
+
+!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:
+ - Name: foo1
+ Section: .text
+ Binding: STB_GLOBAL
+ Other: [ STV_HIDDEN ]
+ - Name: foo2
+ Section: .text
+ Binding: STB_GLOBAL
+ Other: [ STV_HIDDEN ]
+ - Name: foo3
+ Section: .text
+ Binding: STB_GLOBAL
+ Other: [ STV_HIDDEN ]
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index f15307181fad6..0238839b3221d 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -955,6 +955,15 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
addSymbolsFromFile(Config.SymbolsToKeep, DC.Alloc, Arg->getValue(),
SymbolMatchStyle, ErrorCallback))
return std::move(E);
+ for (auto *Arg : InputArgs.filtered(OBJCOPY_ignore_symbol))
+ if (Error E = ELFConfig.SymbolsToIgnore.addMatcher(NameOrPattern::create(
+ Arg->getValue(), SymbolMatchStyle, ErrorCallback)))
+ return std::move(E);
+ for (auto *Arg : InputArgs.filtered(OBJCOPY_ignore_symbols))
+ if (Error E = addSymbolsFromFile(ELFConfig.SymbolsToIgnore, DC.Alloc,
+ Arg->getValue(), SymbolMatchStyle,
+ ErrorCallback))
+ return std::move(E);
for (auto *Arg : InputArgs.filtered(OBJCOPY_add_symbol)) {
Expected<NewSymbolInfo> SymInfo = parseNewSymbolInfo(Arg->getValue());
if (!SymInfo)
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOpts.td b/llvm/tools/llvm-objcopy/ObjcopyOpts.td
index ead8cd28d3877..8f6dd912a4fd5 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOpts.td
+++ b/llvm/tools/llvm-objcopy/ObjcopyOpts.td
@@ -196,6 +196,20 @@ defm keep_symbols
"be repeated to read symbols from many files">,
MetaVarName<"filename">;
+defm ignore_symbol : Eq<"ignore-symbol", "Do not change parameters of symbol <symbol> "
+ "when executing other options that can change the symbol's "
+ "name, binding or visibility">,
+ MetaVarName<"symbol">;
+
+defm ignore_symbols
+ : Eq<"ignore-symbols",
+ "Reads a list of symbols from <filename> and runs as if "
+ "--ignore-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">,
+ MetaVarName<"filename">;
+
defm dump_section
: Eq<"dump-section",
"Dump contents of section named <section> into file <file>">,
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think many of the same comments I made in #80872 apply equally well to this PR, so I'm not going to list them all out here too. Please address them in this PR, and then I'll come back and review again
This needs motivation. I think Binutils maintainers will likely have a strong opinion about the name if they add a similar option. I suspect that |
ee12133
to
c94c1f6
Compare
Before reviewing this further, I'd like the motivation explained as per this comment. |
This option is needed mostly to support cases where there is a need to change parameters of a vast number of symbols with exception of a few specific symbols. Writing a negative pattern is much simpler than many positive patterns that avoid a certain case. Plus, since there is an option --keep-symbol that does exactly this but for removing symbols, there should also be one that keeps symbols' parameters from being changed. |
Thanks. This doesn't seem unreasonable to me. However, a) I don't like the name (people may think that @MaskRay, any comments on the motivation? |
I made a request to create an account on sourceware.org last Monday, but still haven't gotten any reply. |
So far got a reply suggesting to rename it to "--skip-symbols". Seems fair to me. |
Thanks, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implementation basically looks good. You need to update the PR title and description for the new option names, since that is used in the final commit message.
As --skip-symbol is something you might expect to work for other formats (it might be implemented later), it should be added to the list of options that generate an error when a non-ELF format is detected in the (I think) config manager code.
You also should have a test case that tests multiple --skip-symbol options specified at the same time. Finally, I think there's value to test --skip-symbol + --set-symbol-visibility explicitly, to demonstrate their order.
62a4b6f
to
ac06362
Compare
https://sourceware.org/bugzilla/show_bug.cgi?id=31000#c3 Nick has a comment whether we really need a filename variant option, since we can just use |
I added it to make it consistent with other options, pretty much all of them have a separate option to read symbols from a file. If someone wants, they can certainly use response files, but I don't know if it warrants the removal of these file reading options. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://sourceware.org/bugzilla/show_bug.cgi?id=31000#c3 Nick has a comment whether we really need a filename variant option, since we can just use
@xxx
This thread refers to the --set-symbol-visibility
option, not the --skip-symbols
option in this ticket. Here, I think --skip-symbols
makes sense, since it's not something you need any further flexibility with.
ac06362
to
f997fd9
Compare
@@ -464,6 +464,19 @@ them. | |||
Read a list of symbols from <filename> and change their visibility to the | |||
specified value. Visibility values: default, internal, hidden, protected. | |||
|
|||
.. option:: --skip-symbol <symbol> | |||
|
|||
Do not change the parameters of symbol ``<symbol>`` when executing other |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this mention that this does not prevent removing symbols?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it needs to: it explicitly states the things that it impacts (name/binding/visibility). It's probably harmless to add it though.
The latest updated looks good |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the pre-merge checks, your test is failing.
@@ -464,6 +464,19 @@ them. | |||
Read a list of symbols from <filename> and change their visibility to the | |||
specified value. Visibility values: default, internal, hidden, protected. | |||
|
|||
.. option:: --skip-symbol <symbol> | |||
|
|||
Do not change the parameters of symbol ``<symbol>`` when executing other |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it needs to: it explicitly states the things that it impacts (name/binding/visibility). It's probably harmless to add it though.
# RS-SYM-DAG: foo5 | ||
|
||
## Check --skip-symbols functionality when changing symbol names. | ||
# RUN: echo -e "foo1 bar1\nfoo2 bar2" > %t.renames.list |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs moving earlier (it might be why the test is failing...).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs moving earlier (it might be why the test is failing...).
You're right, the test didn't fail on my machine because the file still remained from previous runs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks. The buildkite failures appear to be unrelated, so feel free to merge.
Add --skip-symbol and --skip-symbols options that allow to skip symbols when executing other options that can change the symbol's name, binding or visibility, similar to an existing option --keep-symbol that keeps a symbol from being removed by other options.
Add --skip-symbol and --skip-symbols options that allow to skip symbols when executing other options that can change the symbol's name, binding or visibility, similar to an existing option --keep-symbol that keeps a symbol from being removed by other options.