<div dir="ltr">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 <a href="https://reviews.llvm.org/D50589" target="_blank" class="cremed">https://reviews.llvm.org/D50589</a>. Long, gory details below:<div><br></div><div>These two "global" flags are named similarly, but can have very different effects:</div><div>* --globalize-symbol makes a symbol global.</div><div> +  According to man pages: "Give symbol symbolname global scoping so that it is visible outside of the file in which it is defined."</div><div><div>* --keep-global-symbol will make all symbols local *except* for any symbols specified via --keep-global-symbol.</div><div> + According to man pages: "Keep only symbol symbolname global.  Make all other symbols local to the file, so that they are not visible externally."</div><div><br></div><div>(Note: "--keep-global-symbol LocalSymbol" does not promote it to being a global symbol)</div><div><br></div><div>However, the actual thing GNU sources for objcopy.c does (simplified to just relevant bits) is this:</div><div><br></div><div><div><font face="monospace, monospace">  for (auto sym : symbols) {</font></div><div><font face="monospace, monospace">    auto flags = sym->flags;</font></div><div><font face="monospace, monospace">    auto name = sym->name;</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    // If flag is global/weak, and --keep-global-symbol includes it,</font></div><div><font face="monospace, monospace">    // make it local</font></div><div><font face="monospace, monospace">    if ((flags & (GLOBAL | WEAK)) &&</font></div><div><font face="monospace, monospace">        (keep_globals.size() != 0 && !list_contains(keep_globals, name))) {</font></div><div><font face="monospace, monospace">      sym->flags &= ~(GLOBAL | WEAK);</font></div><div><font face="monospace, monospace">      sym->flags |= LOCAL;</font></div><div><font face="monospace, monospace">    }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    // If flag is local and --globalize-symbol is set, make it global</font></div><div><font face="monospace, monospace">    // Note: checks flags, not sym->flags</font></div><div><font face="monospace, monospace">    if ((flags & LOCAL) && list_contains(globalize, name)) {</font></div><div><font face="monospace, monospace">      sym->flags &= ~LOCAL;</font></div><div><font face="monospace, monospace">      sym->flags |= GLOBAL;</font></div><div><font face="monospace, monospace">    }</font></div><div><font face="monospace, monospace">  }</font></div></div><div><font face="monospace, monospace"><br></font></div><div>This seems strange for a few reasons:</div><div><br></div><div>* 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.</div><div><br></div><div>* 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.</div><div><br></div><div>The proposed behavior in <a href="https://reviews.llvm.org/D50589" target="_blank" class="cremed">https://reviews.llvm.org/D50589</a> 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.</div><div><br></div><div>(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)</div><div><br></div></div><div>Thanks -- Jordan</div></div>