[lld] r320817 - Handle a VersymIndex of 0 as an error.

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 4 11:56:23 PST 2018

On Fri, Dec 22, 2017 at 9:27 PM, Rafael Avila de Espindola
<rafael.espindola at gmail.com> wrote:
> Simon Atanasyan <simon at atanasyan.com> writes:
>> Hi Rafael,
>> Starting from this commit I get the following error in attempt to
>> build MIPS executable:
>> [[
>> error: corrupt input file: version definition index 0 for symbol
>> _gp_disp is out of bounds
>>>>> defined in ..../code-2017.10-mti/lib/gcc/mips-mti-linux-gnu/6.3.0/../../../../mips-mti-linux-gnu/lib/mipsel-r2-hard/lib/libgcc_s.so.1
>> ]]
>> The "_gp_disp" symbol defined in the "libgcc_s.so.1" as "SECTION
>> GLOBAL DEFAULT ABS". The "libgcc_s.so.1" is a part of CodeScape
>> toolchain and linked using GNU tools.
>> Do you think that libgcc_s.so.1 has broken version info or global
>> section symbol is a corner case and zero VersymIndex is a correct
>> value?
> I can't think of a useful meaning for that value. Are current bfd linkers
> still producing that value? If so, could you provide instructions on how
> to create a .so with that issue?
> What behavior is expected of users of that .so? Should they ignore the
> symbol?

Short description of the problem: _gp_disp symbol in a DSO generated
by the BFD linker gets zero version definition index. This symbol is
global while '0' means unversioned local symbol. This triggers an
assertion in the LLD code when it links this DSO with other code. As a
result LLD cannot link MIPS code.

The _gp_disp symbol is a special symbol resolved by a linker. It
represents offset between start of a function and GOT. Linker does not
need to write this symbol to an output file because _gp_disp is
useless there. But GNU linkers do that. So in the output file produced
by GNU linkers this symbol is defined as "SECTION GLOBAL DEFAULT ABS

I do not know is this behaviour specific to _gp_disp symbol only or
all section global absolute symbol get zero version definition index.

Matthew: What do you think - is it a bug in GNU tools?

Reproduction script:
$ cat gpdisp.s
  .global foo
  lui    $t0, %hi(_gp_disp)
  addi   $t0, $t0, %lo(_gp_disp)

$ cat gpdisp.ver
TTT_7.0.0 {

$ mips-mti-linux-gnu-as gpdisp.s -o gpdisp.o
$ mips-mti-linux-gnu-ld -shared gpdisp.o -o libgpdisp.so
--version-script gpdisp.ver

$ cat main.s
  .global __start
  lw     $t0, %got(foo)($gp)

$ mips-mti-linux-gnu-as main.s -o main.o
$ ld.lld main.o libgpdisp.so
ld.lld: error: corrupt input file: version definition index 0 for
symbol _gp_disp is out of bounds
>>> defined in libgpdisp.so

Simon Atanasyan

More information about the llvm-commits mailing list