[PATCH] D39392: Do not add weak undefined symbols to .dynsym unless -pic or -shared are given.

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 1 20:11:23 PST 2017


Rui Ueyama <ruiu at google.com> writes:

> On Fri, Dec 1, 2017 at 7:21 PM, Rafael Avila de Espindola <
> rafael.espindola at gmail.com> wrote:
>
>> Rui Ueyama <ruiu at google.com> writes:
>>
>> > I'm not sure if you understand the problem I'm trying to resolve.
>> >
>> > IIUC, what https://bugs.llvm.org/show_bug.cgi?id=34301#c5 claims as a
>> bug
>> > is not a bug.
>>
>> No, sorry. It is a bug.
>>
>> The user found a difference in behavior that broke a feature they
>> depended on. That worked on bfd and gold. They were kind enough to
>> report the issue and we fixed it. We should not break it.
>>
>> > Weak external symbols that were not compiled with -fPIC are fundamentally
>> > not representable when they are resolved to other DSOs.
>>
>> They were compiled with -fPIC. The comment says:
>>
>> clang -o dummy dummy.c -fPIC
>>
>
> Oh okay, if it doesn't work, it is a bug in my patch. I didn't intend to
> break that functionality. But once again please read my comment. I believe
> the direction of this patch is something that you can agree.

I think your patch is fundamentally incompatible with that feature.

First, lets clear a possible confusion. The assumption in a particular
.o of a symbol being local to the final program has nothing to do with
that program being position independent or not. By local I mean not in a
shared library, not STB_LOCAL.

If a .o file has

movl    $bar1, %eax

It assumes that bar will be local. It is a sad missing feature in clang
and gcc that the only way to get it to assume that declarations are not
local is to compile that TU with -fPIC.

Clang could have a -fno-assume-local-declarations so that

extern int bar1;
int* foo1(void) {
  return &bar1;
}
int bar2 = 42;
int* foo2(void) {
  return &bar2;
}


Compiles to

movq    bar1 at GOTPCREL(%rip), %rax
...
movl    $bar2, %eax

In fact, it could even accept an attribute so that some declarations
were assumed local and some were not.

Even without this feature a program doing something like the example in
the bug:

extern __attribute__((weak)) int print_status();
int foo() {
    return print_status();
}

only has to compile this TU with -fPIC. It can leave it out of every
other TU and the final binary can be linked without -pie or -shared.

And it will still be able to represent print_status being present or not
at runtime, since the one TU that matters used a got to access
print_status.

That is why a patch requiring the linker to be passed -pie or -shared
would be a regression.

Cheers,
Rafael


More information about the llvm-commits mailing list