[PATCH] BFD: Prevent writing the MIPS _gp_disp symbol into symbol tables

Simon Atanasyan simon@atanasyan.com
Wed Feb 7 12:35:00 GMT 2018

Hi Maciej,

On Tue, Feb 6, 2018 at 11:32 PM, Maciej W. Rozycki <macro@mips.com> wrote:
>> The _gp_disp is a magic symbol, always implicitly defined by the linker.
>> It does not make a sense to write it into symbol tables for output files.
>> Moreover, now if the linker gets a version script, the _gp_disp symbol
>> gets zero version definition index. This symbol is global while the zero
>> index means unversioned local symbol. That confuses some tools like for
>> example the LLD linker when they get such files as inputs.
>  Hmm, LLD being confused may well be a bug in that program.
>  The thing is we have been doing this since forever and there were no
> issues so far, so obviously anything you observe must be a corner case.
> E.g. I've had a quick look at a shared library I built back in 2001 and it
> does have `_gp_disp' in its dynamic symbol table, as an absolute symbol
> set to the canonical gp value.  And it is no different with binaries built
> nowadays.  So before we move forward, can you please post an actual test
> case which reproduces the problem?

Here is a reproduction script for the problem:

$ cat test.s
  .global foo
  lui    $t0, %hi(_gp_disp)
  addi   $t0, $t0, %lo(_gp_disp)

$ cat test.ver
LLD_1.0.0 { global: foo; };

$ mips-mti-linux-gnu-as test.s -o test.o
$ mips-mti-linux-gnu-ld -shared test.o -o libtest.so --version-script test.ver
$ mips-mti-linux-gnu-readelf -sV libtest.so

Symbol table '.dynsym' contains 11 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000370     0 SECTION LOCAL  DEFAULT    9
     2: 00010380     0 NOTYPE  GLOBAL DEFAULT   10 _fdata
     3: 00018370     0 SECTION GLOBAL DEFAULT  ABS _gp_disp

Version symbols section '.gnu.version' contains 11 entries:
 Addr: 0000000000000318  Offset: 0x000318  Link: 5 (.dynsym)
  000:   0 (*local*)       0 (*local*)       1 (*global*)      0 (*local*)

Please note that the .gnu.version's entry related to the _gp_disp
symbol contains zero. Zero means "The symbol is local, not available
outside the object", while _gp_disp has GLOBAL binding. LLD does not
like that difference.

Probably the better solution would be to fix _gp_disp entry in the
.gnu.version and write 1 there. From the other side, I thought that
removing the _gp_disp from symbols table was not too bad idea because
this symbol is useless in a linked file.

I can implement both fixes or one of them.

>  Also this is your first submission to binutils and it is substantial
> enough for you to have a copyright assignment or a similar arrangement in
> place with FSF before it can be accepted for inclusion.  Do you have one
> already?  Please let me know if you need further guidance with that and I
> will help you.

No, I do not have a copyright assignment, so please guide me on this way.

Thanks in advance.

Simon Atanasyan

More information about the Binutils mailing list