bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/21375] New: MIPS: Non-zero run-time value produced for PIC refer


From: address@hidden
Subject: [Bug ld/21375] New: MIPS: Non-zero run-time value produced for PIC references to undefined hidden or internal weak symbols
Date: Tue, 11 Apr 2017 18:04:20 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=21375

            Bug ID: 21375
           Summary: MIPS: Non-zero run-time value produced for PIC
                    references to undefined hidden or internal weak
                    symbols
           Product: binutils
           Version: 2.29 (HEAD)
            Status: NEW
          Severity: normal
          Priority: P2
         Component: ld
          Assignee: address@hidden
          Reporter: address@hidden
  Target Milestone: ---
            Target: mips*-*-linux-gnu

Created attachment 9986
  --> https://sourceware.org/bugzilla/attachment.cgi?id=9986&action=edit
WIP bug fix

This has been discovered in the course of PR ld/21334 investigation.

We have an issue in the MIPS backend, with handling undefined hidden
and internal weak symbols.  References to such symbols are supposed to
resolve to 0 according to the ELF gABI[1]:

"Unresolved weak symbols have a zero value."

and the 64-bit MIPS psABI[2]:

"If a symbol with one of these [hidden or internal] attributes has no
definition within the executable/DSO being linked, then it must be
resolved to allocated space if common, resolved to zero if weak, or an
error reported otherwise."

however if a GOT relocation is used, then a local GOT entry is created
and used to satisfy the reference.  Such an entry is then (in DSO and
PIE binaries) subject to the usual load-time relocation, which means a
non-zero value will be returned if the base address is non-zero.  This
will defeat the usual run-time sequence like:

void a (void) __attribute__ ((visibility ("hidden"), weak));

void
x (void)
{
  if (a)
    a ();
}

This can be reproduced with this simple code:

$ cat libtest.c
extern int a __attribute__ ((visibility ("hidden"), weak));

int *
x (void)
{
  return &a;
}
$ cat test.c
#include <stdio.h>

int *x (void);

int
main (void)
{
  printf ("a: %p\n", x ());

  return 0;
}
$ gcc -shared -fPIC -o libtest.so libtest.c
$ gcc -o test test.c -Wl,-rpath,$(pwd) libtest.so
$ ./test
a: 0x77184000
$ 

What instead we should do I believe is create an *external* GOT entry
for the weak undefined symbol entered in the dynamic symbol table as
hidden or internal external absolute and having the value of 0.  Having
a hidden or internal dynamic symbol is as from 22 June 2000 contrary to
the ELF gABI [3]:

"A hidden symbol contained in a relocatable object must be either
removed or converted to STB_LOCAL binding by the link-editor when the
relocatable object is included in an executable file or shared object."

"An internal symbol contained in a relocatable object must be either
removed or converted to STB_LOCAL binding by the link-editor when the
relocatable object is included in an executable file or shared object."

however so is having a non-zero undefined weak symbol.  Furthermore the
gABI's requirement was introduced after the MIPS psABI first defined
hidden and internal symbol export classes, and with the psABI's
definition of DT_MIPS_HIDDEN_GOTIDX [4]:

"This member contains the index in the GOT of the first entry for a
hidden symbol.  It is mandatory if there are hidden symbol entries."

indicating support for hidden symbols in the dynamic symbol table,
clearly without consideration what the implications for the MIPS psABI
of the gABI's requirement might be.

As from glibc commit b6084a958f20 ("Treat STV_HIDDEN and STV_INTERNAL
symbols as STB_LOCAL") the GNU dynamic loader handles hidden and internal
dynamic symbols correctly and I think producing a non-compliant binary
file that produces a result that is generally expected is more reasonable
than producing one that is neither compliant nor works as expected.

With this approach there is still an issue with the GNU dynamic loader
that does not tell regular and absolute symbols apart and relocates the
latter as if they were regular.  This actually causes the linker solution
outlined here to make no change at all in run-time behaviour, but this is
not a regression and is clearly a bug in the dynamic loader which can be
addressed in a simple manner.  A separate bug report will be filed to
handle that problem and referred here.

References:

[1] "System V Application Binary Interface - DRAFT - 19 October 2010",
    The SCO Group, Section "Symbol Table",
    <http://www.sco.com/developers/gabi/2012-12-31/ch4.symtab.html>

[2] "64-bit ELF Object File Specification, Draft Version 2.5", MIPS
    Technologies / Silicon Graphics Computer Systems, Order Number
    007-4658-001, Section 2.5 "Symbol Table", p. 22,
   
<http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf>

[3] "System V Application Binary Interface - DRAFT - 22 June 2000",
    The Santa Cruz Operation, Inc., Section "Symbol Table",
    <http://www.sco.com/developers/gabi/2000-07-17/ch4.symtab.html>

[4] same as [2], Section 3.3.1 "Dynamic Section", pp. 83, 84

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]