[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