[llvm-dev] GNU objcopy compatibility for --globalize-symbol and --keep-global-symbol (-G)
Jordan Rupprecht via llvm-dev
llvm-dev at lists.llvm.org
Wed Aug 15 12:23:37 PDT 2018
In attempting to add support for -G/--keep-global-symbol, I played around
with GNU objcopy to see how it handles various situations, especially in
interacting with --globalize-symbol. I'd like to see if anyone has
objections to the behavior proposed in https://reviews.llvm.org/D50589.
Long, gory details below:
These two "global" flags are named similarly, but can have very different
effects:
* --globalize-symbol makes a symbol global.
+ According to man pages: "Give symbol symbolname global scoping so that
it is visible outside of the file in which it is defined."
* --keep-global-symbol will make all symbols local *except* for any symbols
specified via --keep-global-symbol.
+ According to man pages: "Keep only symbol symbolname global. Make all
other symbols local to the file, so that they are not visible externally."
(Note: "--keep-global-symbol LocalSymbol" does not promote it to being a
global symbol)
However, the actual thing GNU sources for objcopy.c does (simplified to
just relevant bits) is this:
for (auto sym : symbols) {
auto flags = sym->flags;
auto name = sym->name;
// If flag is global/weak, and --keep-global-symbol includes it,
// make it local
if ((flags & (GLOBAL | WEAK)) &&
(keep_globals.size() != 0 && !list_contains(keep_globals, name))) {
sym->flags &= ~(GLOBAL | WEAK);
sym->flags |= LOCAL;
}
// If flag is local and --globalize-symbol is set, make it global
// Note: checks flags, not sym->flags
if ((flags & LOCAL) && list_contains(globalize, name)) {
sym->flags &= ~LOCAL;
sym->flags |= GLOBAL;
}
}
This seems strange for a few reasons:
* Weak symbols are not globalized. The help for --globalize-symbol never
mention it doesn't handle weak symbols, so this seems like a bug in GNU
objcopy.
* If one were to do "--globalize-symbol SomeGlobal --keep-global-symbol
SomeOtherGlobal", you might expect that both SomeGlobal and SomeOtherGlobal
are global in the output file... but it isn't. (Admittedly, this is a weird
command line usage). Because --keep-global-symbol is set and doesn't
include SomeGlobal, SomeGlobal will be demoted to a local symbol. And
because the check to see if we should apply the --globalize-symbol flag
checks "flags" (the original flag set), and not "sym->flags", it decides
not to do anything, so SomeGlobal remains a local symbol.
The proposed behavior in https://reviews.llvm.org/D50589 is to break from
GNU here, so that --globalize-symbol will always make a symbol global,
including when it's a weak symbol, and including when it isn't included in
--keep-global-symbol.
(Actually, --globalize-symbol is already implemented and promotes weak
symbols to global, this message is more of a "hey, we're already different
from GNU, is that OK?" for that part)
Thanks -- Jordan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180815/8762e516/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4849 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180815/8762e516/attachment.bin>
More information about the llvm-dev
mailing list