[PATCH] D63564: Add undefined symbols from linker script to output file

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 19 21:31:18 PDT 2019


MaskRay added a comment.

If I read correctly, the Linux kernel use case boils down to:

`ld.bfd -r a.o -u test -o b.o` adds an undefined symbol `test` to `b.o` but ld.lld doesn't.

The problem can be observed with the following commands (the default linker script of ld.bfd
defines some other symbols but they are irrelevant to your issue):

  % ld.bfd a.o -u test -o a && nm a   # or a.lds a.o
  ld.bfd: warning: cannot find entry symbol _start; defaulting to 0000000000400078
  0000000000601000 A __bss_start
  0000000000601000 A _edata
  0000000000601000 A _end
  0000000000601000 n _GLOBAL_OFFSET_TABLE_
                   U _start
                   U test
  % ld.lld a.o -u test -o a && nm a   # or a.lds a.o
  ld.lld: warning: cannot find entry symbol _start; defaulting to 0x201000

The documentation of ld.bfd says:

  '-u SYMBOL'
  '--undefined=SYMBOL'
       Force SYMBOL to be entered in the output file as an undefined
       symbol.  Doing this may, for example, trigger linking of additional
       modules from standard libraries.  '-u' may be repeated with
       different option arguments to enter additional undefined symbols.
       This option is equivalent to the 'EXTERN' linker script command.
  
  'EXTERN(SYMBOL SYMBOL ...)'
       Force SYMBOL to be entered in the output file as an undefined
       symbol.  Doing this may, for example, trigger linking of additional
       modules from standard libraries.  You may list several SYMBOLs for
       each 'EXTERN', and you may use 'EXTERN' multiple times.  This
       command has the same effect as the '-u' command-line option.

It and the behavior I observed from ld.bfd do appear to suggest -u and EXTERN() should be handled the same way. However, this patch adds an undefined symbol for `EXTERN` but does not do the same for `-u`.
I think if we want to fix the issue, we should make the two consistent.

Another thing is that:

`ld.bfd -shared a.o -u test -o a.so` adds test to .symtab but not .dynsym .
However, with a similar change to Driver.cpp `Config->Undefined`, `test` will be added to both .symtab and .dynsym . The symbol is .dynsym is definitely not desired (it can cause "undefined references" in a subsequent executable linking). I need to think more how this issue should be tacked.

Meanwhile, can you check, in the Linux kernel, if the `-u test` can be moved from the `-r` link to a subsequent link? The combined `-r -u` looks a bit unusual and I am not sure if that is desired.
(I am happy with current lld semantics of -u thought it is different from ld.bfd.
Given that we now have --undefined-glob, changing the semantics of -u will make it inconsistent with --undefined-glob)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63564/new/

https://reviews.llvm.org/D63564





More information about the llvm-commits mailing list