[llvm-dev] [LLD] Can't create dynamic relocation R_X86_64_64 against local symbol in readonly segment

3,848 views
Skip to first unread message

Martin Richtarsky via llvm-dev

unread,
Mar 23, 2017, 8:23:30 AM3/23/17
to llvm-dev
Hi,

the attached example works with bfd-ld and with gold, but not with lld:

$ cat rodatareloc.s
...
.align 16
leaq .JTab(%rip), %r10
jmp *(%r10, %rdx, 8)
...
.section .rodata
.JTab:
.quad .L00, .L01, .L02, .L03, .L04, .L05, .L06, .L07
.quad .L08, .L09, .L10, .L11, .L12, .L13, .L14, .L15, .L16

$ gcc -o rodatareloc.s.o -c rodatareloc.s
$ lld -o rodatareloc.so -shared rodatareloc.s.o

ld: error: rodatareloc.s.o:(.rodata+0x0): can't create dynamic relocation
R_X86_64_64 against local symbol in readonly segment defined in
rodatareloc.s.o


Changing the section from .rodata to .data fixes it, but I guess this
should be supported also for .rodata. Should I open a bug?

Best regards,
Martin
lld_rodata_dynamic_relro.tar.gz

Joerg Sonnenberger via llvm-dev

unread,
Mar 23, 2017, 10:14:52 AM3/23/17
to llvm...@lists.llvm.org
On Thu, Mar 23, 2017 at 01:23:24PM +0100, Martin Richtarsky via llvm-dev wrote:
> ld: error: rodatareloc.s.o:(.rodata+0x0): can't create dynamic relocation
> R_X86_64_64 against local symbol in readonly segment defined in
> rodatareloc.s.o
>
>
> Changing the section from .rodata to .data fixes it, but I guess this
> should be supported also for .rodata. Should I open a bug?

This is not a bug, lld is completely correct. You are explicitly asking
for a read-only section and the choosen relocation is position
dependent, so yes, it correctly bails out.

Joerg
_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

Rui Ueyama via llvm-dev

unread,
Mar 23, 2017, 11:15:31 AM3/23/17
to Joerg Sonnenberger, llvm-dev
Yes, this is correct and expected behavior. But why do you want to make it work?

Rafael Avila de Espindola via llvm-dev

unread,
Mar 23, 2017, 11:23:25 AM3/23/17
to Martin Richtarsky, llvm-dev

I think this is just a difference in defaults. If you pass "-z notext"
to lld it should work.

Cheers,
Rafael

Martin Richtarsky via llvm-dev

unread,
Mar 23, 2017, 11:47:19 AM3/23/17
to Rafael Avila de Espindola, llvm-dev
Rafael Avila de Espindola wrote:
>> $ gcc -o rodatareloc.s.o -c rodatareloc.s
>> $ lld -o rodatareloc.so -shared rodatareloc.s.o
>>
>> ld: error: rodatareloc.s.o:(.rodata+0x0): can't create dynamic
>> relocation
>> R_X86_64_64 against local symbol in readonly segment defined in
>> rodatareloc.s.o
>>
>>
>> Changing the section from .rodata to .data fixes it, but I guess this
>> should be supported also for .rodata. Should I open a bug?
>
> I think this is just a difference in defaults. If you pass "-z notext"
> to lld it should work.

Thanks, this helps! Any reason why the defaults are different to gold and
presumably bfd-ld?

I don't understand much of what is happening behind the scenes, but on
loading time, couldn't the rodata section just be mapped read-only, and
still the relocation be applied to the text section, pointing to wherever
rodata was mapped? No modification should be necessary to the rodata
section.

Thanks and Best regards,
Martin

Rui Ueyama via llvm-dev

unread,
Mar 23, 2017, 12:05:26 PM3/23/17
to Martin Richtarsky, llvm-dev
Your .rodata contains a vector of addresses, and we don't know the actual addresses until load-time, because your .so file can be loaded to anywhere in your address space. Thus, we cannot fix .rodata contents at link-time. So your .so needs load-time modifications to the .rodata section. (Does this answer your question?)

I think our default choice of forbidding relocations against read-only sections is reasonable, because most programs don't need text relocations, and if that happens, it is with a high probability a mistake instead of an intentional behavior.

Mark Kettenis via llvm-dev

unread,
Mar 23, 2017, 12:08:58 PM3/23/17
to s...@martinien.de, llvm...@lists.llvm.org
> Date: Thu, 23 Mar 2017 16:47:11 +0100
> From: Martin Richtarsky via llvm-dev <llvm...@lists.llvm.org>

>
> >> $ gcc -o rodatareloc.s.o -c rodatareloc.s
> >> $ lld -o rodatareloc.so -shared rodatareloc.s.o
> >>
> >> ld: error: rodatareloc.s.o:(.rodata+0x0): can't create dynamic
> >> relocation
> >> R_X86_64_64 against local symbol in readonly segment defined in
> >> rodatareloc.s.o
> >>
> >>
> >> Changing the section from .rodata to .data fixes it, but I guess this
> >> should be supported also for .rodata. Should I open a bug?
> >
> > I think this is just a difference in defaults. If you pass "-z notext"
> > to lld it should work.
>
> Thanks, this helps! Any reason why the defaults are different to gold and
> presumably bfd-ld?

Yes. Releocations in .rodata are undesirable. This way the
programming errors or compiler bugs that cause them get caught.

> I don't understand much of what is happening behind the scenes, but on
> loading time, couldn't the rodata section just be mapped read-only, and
> still the relocation be applied to the text section, pointing to wherever
> rodata was mapped? No modification should be necessary to the rodata
> section.

The dynamic linker can patch these up. But doing so kills the
"shared" aspect of the object as the pages in question will no longer
be shared between processes.

Sean Silva via llvm-dev

unread,
Mar 24, 2017, 5:31:18 PM3/24/17
to Rui Ueyama, llvm-dev


On Mar 23, 2017 10:05 AM, "Rui Ueyama via llvm-dev" <llvm...@lists.llvm.org> wrote:
Your .rodata contains a vector of addresses, and we don't know the actual addresses until load-time, because your .so file can be loaded to anywhere in your address space. Thus, we cannot fix .rodata contents at link-time. So your .so needs load-time modifications to the .rodata section. (Does this answer your question?)

I think our default choice of forbidding relocations against read-only sections is reasonable, because most programs don't need text relocations,

In this case it is rodata though which is a bit more reasonable. If this is really common then we can probably limit our stricter default only to executable sections.

and if that happens, it is with a high probability a mistake instead of an intentional behavior.

Our diagnostic should probably mention to use -z notext though in the case a user needs it. For example, a user might be grateful that we found their bug, but they want to file it in their tracker and get back to it later because their focus at the moment is just to try out LLD on their project (we want them to be able to do that without yak shaving).

It might also be good to distill this discussion into a doc page and have our diagnostic emit a note with a link to it, for users that are less familiar and would benefit from a longer explanation that is too long for a diagnostic. (The rust compiler does something like this for its diagnostics and I found it pretty neat)

-- Sean Silva
Reply all
Reply to author
Forward
0 new messages