-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[llvm-objcopy] Add --set-symbol-visibility and --set-symbols-visibility options #80872
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
Changes from 26 commits
af5f188
cc05728
97b1e2d
d3104d1
524b13f
9ec88f2
450e1f6
20a8c43
f6b659b
c6faec2
105e335
cf0c1e5
88c3cf2
78cd496
4ab67a1
17f6c40
0b28280
62a8bac
4f7a5cd
ed84dfd
2d14e71
7cd45b4
98e127f
287cf46
fe8a2d0
d25332c
72022ae
ca26144
26da9e3
5df01eb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -298,6 +298,10 @@ static Error updateAndRemoveSymbols(const CommonConfig &Config, | |
Config.SymbolsToLocalize.matches(Sym.Name))) | ||
Sym.Binding = STB_LOCAL; | ||
|
||
for (auto &[Matcher, VisibilityType] : ELFConfig.SymbolsToSetVisibility) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change VisibilityType to Visibility like elsewhere? |
||
if (Matcher.matches(Sym.Name) && Sym.getShndx() != SHN_UNDEF) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is there a special case for undefined symbol? A protected/hidden undefined should be allowed. The following code generates a hidden undefined symbol.
The option should have the ability to change their visibility. |
||
Sym.Visibility = VisibilityType; | ||
|
||
// Note: these two globalize flags have very similar names but different | ||
// meanings: | ||
// | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,311 @@ | ||
# RUN: yaml2obj --docnum=1 %s -o %t.o | ||
# RUN: echo '.*' > %t.symbols.regex | ||
|
||
## Check that the visibility of all symbols is properly set to DEFAULT. | ||
# RUN: llvm-objcopy %t.o %t0.o --set-symbols-visibility=%t.symbols.regex=default --regex | ||
# RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=DEF | ||
|
||
# DEF-DAG: DEFAULT 1 default_local | ||
# DEF-DAG: DEFAULT 1 internal_local | ||
# DEF-DAG: DEFAULT 1 hidden_local | ||
# DEF-DAG: DEFAULT 1 protected_local | ||
# DEF-DAG: DEFAULT 1 default_global | ||
# DEF-DAG: DEFAULT 1 default_weak | ||
# DEF-DAG: DEFAULT 1 internal_global | ||
# DEF-DAG: DEFAULT 1 internal_weak | ||
# DEF-DAG: DEFAULT 1 hidden_global | ||
# DEF-DAG: DEFAULT 1 hidden_weak | ||
# DEF-DAG: DEFAULT 1 protected_global | ||
# DEF-DAG: DEFAULT 1 protected_weak | ||
|
||
## Check that the visibility of all symbols is properly set to HIDDEN. | ||
# RUN: llvm-objcopy %t.o %t1.o --set-symbols-visibility=%t.symbols.regex=hidden --regex | ||
# RUN: llvm-readelf -s %t1.o | FileCheck %s --check-prefix=HID | ||
|
||
# HID-DAG: HIDDEN 1 default_local | ||
# HID-DAG: HIDDEN 1 internal_local | ||
# HID-DAG: HIDDEN 1 hidden_local | ||
# HID-DAG: HIDDEN 1 protected_local | ||
# HID-DAG: HIDDEN 1 default_global | ||
# HID-DAG: HIDDEN 1 default_weak | ||
# HID-DAG: HIDDEN 1 internal_global | ||
# HID-DAG: HIDDEN 1 internal_weak | ||
# HID-DAG: HIDDEN 1 hidden_global | ||
# HID-DAG: HIDDEN 1 hidden_weak | ||
# HID-DAG: HIDDEN 1 protected_global | ||
# HID-DAG: HIDDEN 1 protected_weak | ||
|
||
## Check that the visibility of all symbols is properly set to PROTECTED. | ||
# RUN: llvm-objcopy %t.o %t2.o --set-symbols-visibility=%t.symbols.regex=protected --regex | ||
# RUN: llvm-readelf -s %t2.o | FileCheck %s --check-prefix=PRO | ||
|
||
# PRO-DAG: PROTECTED 1 default_local | ||
# PRO-DAG: PROTECTED 1 internal_local | ||
# PRO-DAG: PROTECTED 1 hidden_local | ||
# PRO-DAG: PROTECTED 1 protected_local | ||
# PRO-DAG: PROTECTED 1 default_global | ||
# PRO-DAG: PROTECTED 1 default_weak | ||
# PRO-DAG: PROTECTED 1 internal_global | ||
# PRO-DAG: PROTECTED 1 internal_weak | ||
# PRO-DAG: PROTECTED 1 hidden_global | ||
# PRO-DAG: PROTECTED 1 hidden_weak | ||
# PRO-DAG: PROTECTED 1 protected_global | ||
# PRO-DAG: PROTECTED 1 protected_weak | ||
|
||
## Check that the visibility of all symbols is properly set to INTERNAL. | ||
# RUN: llvm-objcopy %t.o %t3.o --set-symbols-visibility=%t.symbols.regex=internal --regex | ||
# RUN: llvm-readelf -s %t3.o | FileCheck %s --check-prefix=INT | ||
|
||
# INT-DAG: INTERNAL 1 default_local | ||
# INT-DAG: INTERNAL 1 internal_local | ||
# INT-DAG: INTERNAL 1 hidden_local | ||
# INT-DAG: INTERNAL 1 protected_local | ||
# INT-DAG: INTERNAL 1 default_global | ||
# INT-DAG: INTERNAL 1 default_weak | ||
# INT-DAG: INTERNAL 1 internal_global | ||
# INT-DAG: INTERNAL 1 internal_weak | ||
# INT-DAG: INTERNAL 1 hidden_global | ||
# INT-DAG: INTERNAL 1 hidden_weak | ||
# INT-DAG: INTERNAL 1 protected_global | ||
# INT-DAG: INTERNAL 1 protected_weak | ||
|
||
## Check that setting the visibility of certain symbols that were read from | ||
## a file does not affect other symbols. | ||
# RUN: echo -e "default_local\ninternal_local" > %t.symbol.list | ||
# RUN: llvm-objcopy %t.o %t4.o --set-symbols-visibility=%t.symbol.list=hidden | ||
# RUN: llvm-readelf -s %t4.o | FileCheck %s --check-prefix=FILE | ||
|
||
# FILE-DAG: HIDDEN 1 default_local | ||
# FILE-DAG: HIDDEN 1 internal_local | ||
## Unaffected symbols: | ||
# FILE-DAG: HIDDEN 1 hidden_local | ||
# FILE-DAG: PROTECTED 1 protected_local | ||
# FILE-DAG: DEFAULT 1 default_global | ||
# FILE-DAG: DEFAULT 1 default_weak | ||
# FILE-DAG: INTERNAL 1 internal_global | ||
# FILE-DAG: INTERNAL 1 internal_weak | ||
# FILE-DAG: HIDDEN 1 hidden_global | ||
# FILE-DAG: HIDDEN 1 hidden_weak | ||
# FILE-DAG: PROTECTED 1 protected_global | ||
# FILE-DAG: PROTECTED 1 protected_weak | ||
|
||
## Check that the visibility of a single symbol is set correctly, | ||
## and that no other symbols are affected. | ||
# RUN: llvm-objcopy %t.o %t5.o --set-symbol-visibility=default_local=hidden \ | ||
# RUN: --set-symbol-visibility=internal_local=protected \ | ||
# RUN: --set-symbol-visibility=hidden_local=internal \ | ||
# RUN: --set-symbol-visibility=protected_local=default | ||
# RUN: llvm-readelf -s %t5.o | FileCheck %s --check-prefix=SINGLE | ||
|
||
# SINGLE-DAG: HIDDEN 1 default_local | ||
# SINGLE-DAG: PROTECTED 1 internal_local | ||
# SINGLE-DAG: INTERNAL 1 hidden_local | ||
# SINGLE-DAG: DEFAULT 1 protected_local | ||
## Unaffected symbols: | ||
# SINGLE-DAG: DEFAULT 1 default_global | ||
# SINGLE-DAG: DEFAULT 1 default_weak | ||
# SINGLE-DAG: INTERNAL 1 internal_global | ||
# SINGLE-DAG: INTERNAL 1 internal_weak | ||
# SINGLE-DAG: HIDDEN 1 hidden_global | ||
# SINGLE-DAG: HIDDEN 1 hidden_weak | ||
# SINGLE-DAG: PROTECTED 1 protected_global | ||
# SINGLE-DAG: PROTECTED 1 protected_weak | ||
|
||
## Check that the visibility of symbols specified by a regex are set correctly, | ||
## and that no other symbols are affected. | ||
# RUN: llvm-objcopy %t.o %t6.o --set-symbol-visibility='.*'_local=hidden --regex | ||
# RUN: llvm-readelf -s %t6.o | FileCheck %s --check-prefix=REGEX | ||
|
||
# REGEX-DAG: HIDDEN 1 default_local | ||
# REGEX-DAG: HIDDEN 1 internal_local | ||
# REGEX-DAG: HIDDEN 1 hidden_local | ||
# REGEX-DAG: HIDDEN 1 protected_local | ||
## Unaffected symbols: | ||
# REGEX-DAG: DEFAULT 1 default_global | ||
# REGEX-DAG: DEFAULT 1 default_weak | ||
# REGEX-DAG: INTERNAL 1 internal_global | ||
# REGEX-DAG: INTERNAL 1 internal_weak | ||
# REGEX-DAG: HIDDEN 1 hidden_global | ||
# REGEX-DAG: HIDDEN 1 hidden_weak | ||
# REGEX-DAG: PROTECTED 1 protected_global | ||
# REGEX-DAG: PROTECTED 1 protected_weak | ||
|
||
## Check that the visibility of symbols specified by a wildcard are set correctly, | ||
## and that no other symbols are affected. | ||
# RUN: llvm-objcopy %t.o %t7.o --set-symbol-visibility='*_local'=hidden --wildcard | ||
# RUN: llvm-readelf -s %t7.o | FileCheck %s --check-prefix=WILDCARD | ||
|
||
# WILDCARD-DAG: HIDDEN 1 default_local | ||
# WILDCARD-DAG: HIDDEN 1 internal_local | ||
# WILDCARD-DAG: HIDDEN 1 hidden_local | ||
# WILDCARD-DAG: HIDDEN 1 protected_local | ||
## Unaffected symbols: | ||
# WILDCARD-DAG: DEFAULT 1 default_global | ||
# WILDCARD-DAG: DEFAULT 1 default_weak | ||
# WILDCARD-DAG: INTERNAL 1 internal_global | ||
# WILDCARD-DAG: INTERNAL 1 internal_weak | ||
# WILDCARD-DAG: HIDDEN 1 hidden_global | ||
# WILDCARD-DAG: HIDDEN 1 hidden_weak | ||
# WILDCARD-DAG: PROTECTED 1 protected_global | ||
# WILDCARD-DAG: PROTECTED 1 protected_weak | ||
|
||
## Check that the latest option that matches the same symbols as any of the previous | ||
## options overwrites the visibility of these symbols. | ||
# RUN: echo -e '*_weak\n*_local' > %t.symbols.pattern | ||
# RUN: llvm-objcopy %t.o %t8.o --set-symbol-visibility='default_*'=hidden \ | ||
# RUN: --set-symbol-visibility='internal_*'=hidden \ | ||
# RUN: --set-symbols-visibility=%t.symbols.pattern=protected \ | ||
# RUN: --wildcard | ||
# RUN: llvm-readelf -s %t8.o | FileCheck %s --check-prefix=REWRITE | ||
|
||
# REWRITE-DAG: PROTECTED 1 default_local | ||
# REWRITE-DAG: HIDDEN 1 default_global | ||
# REWRITE-DAG: PROTECTED 1 default_weak | ||
# REWRITE-DAG: PROTECTED 1 internal_local | ||
# REWRITE-DAG: HIDDEN 1 internal_global | ||
# REWRITE-DAG: PROTECTED 1 internal_weak | ||
# REWRITE-DAG: PROTECTED 1 hidden_local | ||
# REWRITE-DAG: PROTECTED 1 hidden_weak | ||
# REWRITE-DAG: PROTECTED 1 protected_local | ||
# REWRITE-DAG: PROTECTED 1 protected_weak | ||
## Unaffected symbols: | ||
# REWRITE-DAG: HIDDEN 1 hidden_global | ||
# REWRITE-DAG: PROTECTED 1 protected_global | ||
|
||
## Check that a symbol name with a special charater is treated as a plain name | ||
## when pattern matching options are not enabled. | ||
# RUN: yaml2obj --docnum=2 %s -o %t9.o | ||
# RUN: llvm-objcopy %t9.o --set-symbol-visibility='f*o'=hidden | ||
# RUN: llvm-readelf -s %t9.o | FileCheck %s --check-prefix=SPECIAL | ||
|
||
# SPECIAL-DAG: HIDDEN 1 f*o | ||
## Unaffected symbol: | ||
# SPECIAL-DAG: DEFAULT 1 foo | ||
|
||
# RUN: yaml2obj --docnum=3 %s -o %t10.o | ||
|
||
## Check that symbols with SHN_UNDEF index are ignored when setting visibility. | ||
# RUN: llvm-objcopy %t10.o --set-symbol-visibility=foo=hidden | ||
# RUN: llvm-readelf -s %t10.o | FileCheck %s --check-prefix=UNDEF | ||
# UNDEF: DEFAULT UND foo | ||
|
||
## Check that passing an invalid visibility type generates an error message. | ||
# RUN: echo 'foo' > %t.symbols | ||
# RUN: not llvm-objcopy %t10.o --set-symbols-visibility=%t.symbols=invalid-type 2>&1 | \ | ||
# RUN: FileCheck %s --check-prefix=TYPE | ||
# RUN: not llvm-objcopy %t10.o --set-symbol-visibility=foo=invalid-type 2>&1 | \ | ||
# RUN: FileCheck %s --check-prefix=TYPE | ||
# TYPE: error: 'invalid-type' is not a valid symbol visibility | ||
|
||
## Check that omitting the '=' character generates an error. | ||
# RUN: not llvm-objcopy %t10.o --set-symbols-visibility=%t.symbols,hidden 2>&1 | \ | ||
# RUN: FileCheck %s --check-prefix=FORMAT -DOPTION=--set-symbols-visibility | ||
# RUN: not llvm-objcopy %t10.o --set-symbol-visibility=foo default 2>&1 | \ | ||
# RUN: FileCheck %s --check-prefix=FORMAT -DOPTION=--set-symbol-visibility | ||
# FORMAT: error: bad format for [[OPTION]] | ||
|
||
## Check that using an invalid symbol pattern generates an error. | ||
# RUN: echo '*.' > %t.symbols.regex | ||
# RUN: not llvm-objcopy %t10.o --set-symbols-visibility=%t.symbols.regex=hidden --regex 2>&1 | \ | ||
# RUN: FileCheck %s --check-prefix=SYMBOL | ||
# RUN: not llvm-objcopy %t10.o --set-symbol-visibility='*.'=default --regex 2>&1 | \ | ||
# RUN: FileCheck %s --check-prefix=SYMBOL | ||
# SYMBOL: error: cannot compile regular expression '*.': repetition-operator operand invalid | ||
|
||
## Check passing an invalid filename generates an error. | ||
# RUN: not llvm-objcopy %t10.o --set-symbols-visibility=no_file=hidden 2>&1 | \ | ||
# RUN: FileCheck %s --check-prefix=NO_FILE -DMSG=%errc_ENOENT | ||
# NO_FILE: error: 'no_file': [[MSG]] | ||
|
||
--- | ||
!ELF | ||
FileHeader: | ||
Class: ELFCLASS64 | ||
Data: ELFDATA2LSB | ||
Type: ET_REL | ||
Machine: EM_X86_64 | ||
Sections: | ||
- Name: .text | ||
Type: SHT_PROGBITS | ||
Symbols: | ||
- Name: default_local | ||
Section: .text | ||
Binding: STB_LOCAL | ||
- Name: protected_local | ||
Section: .text | ||
Binding: STB_LOCAL | ||
Other: [ STV_PROTECTED ] | ||
- Name: internal_local | ||
Section: .text | ||
Binding: STB_LOCAL | ||
Other: [ STV_INTERNAL ] | ||
- Name: hidden_local | ||
Section: .text | ||
Binding: STB_LOCAL | ||
Other: [ STV_HIDDEN ] | ||
- Name: default_weak | ||
Section: .text | ||
Binding: STB_WEAK | ||
- Name: internal_weak | ||
Section: .text | ||
Binding: STB_WEAK | ||
Other: [ STV_INTERNAL ] | ||
- Name: hidden_weak | ||
Section: .text | ||
Binding: STB_WEAK | ||
Other: [ STV_HIDDEN ] | ||
- Name: protected_weak | ||
Section: .text | ||
Binding: STB_WEAK | ||
Other: [ STV_PROTECTED ] | ||
- Name: default_global | ||
Section: .text | ||
Binding: STB_GLOBAL | ||
- Name: internal_global | ||
Section: .text | ||
Binding: STB_GLOBAL | ||
Other: [ STV_INTERNAL ] | ||
- Name: hidden_global | ||
Section: .text | ||
Binding: STB_GLOBAL | ||
Other: [ STV_HIDDEN ] | ||
- Name: protected_global | ||
Section: .text | ||
Binding: STB_GLOBAL | ||
Other: [ STV_PROTECTED ] | ||
- Name: ignored_name | ||
Section: .text | ||
Binding: STB_GLOBAL | ||
Other: [ STV_INTERNAL ] | ||
... | ||
|
||
--- | ||
!ELF | ||
FileHeader: | ||
Class: ELFCLASS64 | ||
Data: ELFDATA2LSB | ||
Type: ET_REL | ||
Machine: EM_X86_64 | ||
Sections: | ||
- Name: .text | ||
Type: SHT_PROGBITS | ||
Symbols: | ||
- Name: f*o | ||
Section: .text | ||
Binding: STB_LOCAL | ||
- Name: foo | ||
Section: .text | ||
Binding: STB_LOCAL | ||
... | ||
|
||
--- | ||
!ELF | ||
FileHeader: | ||
Class: ELFCLASS64 | ||
Data: ELFDATA2LSB | ||
Type: ET_REL | ||
Machine: EM_X86_64 | ||
Symbols: | ||
- Name: foo | ||
Binding: STB_LOCAL | ||
... |
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.
Imperative sentence like other 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.
I replied in another comment:
Uh oh!
There was an error while loading. Please reload this page.
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.
Yes, there are ~8 options that are inconsistent with others. Actually there is a larger problem that many help messages are slightly wrong, not synced with the clearer semantics by @jh7370 in https://reviews.llvm.org/D63820
I am working on a patch to fix these help messages.
For the new options, definitely use imperative sentences as llvm/docs/CommandGuide/llvm-objcopy.rst uses.
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.
#82830