Issue Details (XML | Word | Printable)

Key: PCC-362
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Anders Magnusson
Reporter: Iain Hibbert
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
pcc

weak references not working right

Created: 25/Jun/11 03:11 PM   Updated: 07/May/14 06:36 PM
Component/s: i386 target
Affects Version/s: None
Fix Version/s: None

Environment: NetBSD/i386


 Description  « Hide
Weak references, via the __weakref__ attribute do not work correctly,
the example code

#include <stdio.h>

void my_foo(void) __attribute__((__weakref__("foo")));

int
main(int ac, char *av[])
{
    printf("my_foo %p\n", my_foo);

    if (my_foo != NULL)
        my_foo();

    return 0;
}

shows the problem, when compiled with pcc results in undefined references to "foo"
what should happen I think, is that the assembler output references "my_foo" and a

   .weakref my_foo,foo

line is emitted, this allows the linker to decide if foo can be resolved, or if it should
supply a nil value..

 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
Anders Magnusson added a comment - 25/Jun/11 04:12 PM
weakref is not supported except for recent binutils. I have some support for it in pcc, but it should probably be checked in configure whether it exist or not.

Anders Magnusson added a comment - 01/May/14 05:53 PM
i386 target now has weakref attribute.

Iain Hibbert added a comment - 05/May/14 09:10 PM
Hi, there is a further wrinkle wrt this weakref. A variable declared with weakref should not have local storage. The following, I think more complete, example demonstrates

static void foo0(void) __attribute__((__weakref__("FOO0")));
static void foo1(void) __attribute__((__weakref__("FOO1")));
static int bar0 __attribute__((__weakref__("BAR0")));
static int bar1 __attribute__((__weakref__("BAR1")));

int
main(int ac, char *av[])
{
    if (&foo0 == (void *)0L) // FOO0 is defined
        return 1;

    if (&foo1 != (void *)0L) // FOO1 is not defined
        return 1;

    if (&bar0 == (void *)0L) // BAR0 is defined
        return 1;

    if (&bar1 != (void *)0L) // BAR1 is not defined
        return 1;

    return 0; // Ok
}

void
FOO0(void)
{
}

int BAR0;

when compiled with "pcc test.c" fails with

/tmp/ctm.28756b: Assembler messages:
/tmp/ctm.28756b:59: Error: symbol `bar0' is already defined
/tmp/ctm.28756b:61: Error: symbol `bar1' is already defined
as terminated with status 1

this is because the compiler emitted storage commands for bar0 and bar1 even though they are not defined

        .local bar0
        .comm bar0,04,4
        .local bar1
        .comm bar1,04,4
        .comm BAR0,04,4

NB gcc and clang both require the "static" declarator for weak reference attributes

Anders Magnusson added a comment - 07/May/14 04:11 PM
Hm, strange, the gcc manual uses extern for its explanation of weakref :-)

          extern int x() __attribute__ ((weakref ("y")));
          /* is equivalent to... */
          extern int x() __attribute__ ((weak, weakref, alias ("y")));
          /* and to... */
          extern int x() __attribute__ ((weakref));
          extern int x() __attribute__ ((alias ("y")));

Anders Magnusson added a comment - 07/May/14 06:36 PM
Now it won't emit storage for weakref variables.