-
Notifications
You must be signed in to change notification settings - Fork 17.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/link: shared libraries have DT_TEXTREL set #10914
Comments
I think we have to move .gopclntab section to a read/write segment.
reference to .text symbols might be ok because .text is shared, but
reference to .data symbols are definitely not.
Alternatively, we can make addresses in gopclntab relative to the
start of .gopclntab.
|
Ah but sorting out segments is the external linker's job, the segment stuff in the linker is afaict just noise in that case. We could change .gopclntab to not require relocs but the same affects the .rodata and .typelink sections and I think those are harder. It's easy to change the linker to make .gopclntab/.rodata/.typelink read-write, but that just makes the external linker lump everything into one RWE segment which isn't really what we want. |
I mean, we set .gopclntab/.rodata/.typelink as read/write sections
when generating go.o for shared library. Then they will be grouped
into a RW segment in the shared library, and absolute address
relocations will be fine.
Is there any assumptions by the runtime that those sections are
readonly?
|
No, that's what I tried, it doesn't seem to work, you get this:
which aiui is worse than tip. |
You need to put the sections into the object file in a different order and that's a different level of mess (or so it seems to me). |
that's interesting. I don't understand why the linker decides to add a RWE
segment rather than RE + RW segments.
What's the section table of the go.o that generates such weird shared
library?
|
I guess we need to align the sections we want to end up in different segments at least to a page? Paging @ianlancetaylor I guess. |
How did you manage to get a writable .rodata section? That does not look desirable. |
I would guess that you are using GNU ld rather than gold. GNU ld sorts sections by name using a default linker script. It will put the .rodata section and the .text section in the same segment. If .rodata is writable, that forces the segment to be writable. At that point there is no need to make a separate data segment, so you wind up with a single segment. This is obviously bad. Having a DT_TEXTREL tag is also bad. It means that the shared library text segments can not be shared--in other words, the shared libraries are not shared. |
so the solution is to reduce the number of sections exposed
to the linker to just .text, .data, .bss and .tbss?
|
I would say that the solution is to not have a writable .rodata section. That doesn't make a lot of sense. If the value needs to be writable only to support a relocation, put it in a .data.rel.ro section and pass -z relro to the linker. |
so does the magical name ".data.rel.ro" work for other sections?
the problem in this issue is .pclntab, .typelink and the like, which
contains absolute address relocations.
|
No, data.rel.ro is special (and so is .gnu.linkonce.d.rel.ro and .data.rel.ro.local). A section with that name, when linked with -z relro, will be placed at the start of the data segment in such a way that the dynamic linker can mark it as readonly after applying dynamic relocations (the dynamic linker is told what to make readonly via a PT_GNU_RELRO segment). Sections whose names are not recognized, like .pclntab, etc., will, if writable, be treated as ordinary writable sections and placed in the data segment. The problem leading to the single segment was due to a section with a special name (.rodata) having unexpected flags. |
Ian appears to have answered these questions already :-) http://www.airs.com/blog/archives/189 I think the linker could (all behind a Buildmode==BuildmodeShared check of course), scan for SRODATA objects that have relocations (len(s.R) > 0) and move them to a new SRELRODATA type, plus associated stuff to create the .data.rel.ro section (I guess it could even check the relocations and if they are all to local symbols, move them to a SRELRODATALOCAL type...). |
Well, I've learnt a bunch about the linker: https://go-review.googlesource.com/10300. Probably best to leave this for 1.6 though. |
CL https://golang.org/cl/10300 mentions this issue. |
…making a shared object Currently Go produces shared libraries that cannot be shared between processes because they have relocations against the text segment (not text section). This fixes this by moving some data from .rodata to .data.rel.ro and by marking some sections rw (so the program linker puts them into a different segment). I think this is all way too much for 1.5 but I wanted to hammer my way to something working. Will fix after 1.6. Fixes golang#10914 Change-Id: I7178daadc0ae87953d5a084aa3d580f4e3b46d47
CL https://golang.org/cl/14142 mentions this issue. |
…making a shared object Currently Go produces shared libraries that cannot be shared between processes because they have relocations against the text segment (not text section). This fixes this by moving some data to sections with magic names recognized by the static linker. Fixes golang#10914 Updates golang#9210 Change-Id: I7178daadc0ae87953d5a084aa3d580f4e3b46d47
…de=c-shared on arm All the code was there to do this, it just wasn't hooked up. Fixes golang#10914 Change-Id: Ide8f9bbe50fecb5d11cd579915ee98d4c7efe403
…making a shared object Currently Go produces shared libraries that cannot be shared between processes because they have relocations against the text segment (not text section). This fixes this by moving some data to sections with magic names recognized by the static linker. Fixes golang#10914 Updates golang#9210 Change-Id: I7178daadc0ae87953d5a084aa3d580f4e3b46d47
…de=c-shared on arm All the code was there to do this, it just wasn't hooked up. Fixes golang#10914 Change-Id: Ide8f9bbe50fecb5d11cd579915ee98d4c7efe403
…de=c-shared on arm All the code was there to do this, it just wasn't hooked up. Fixes #10914 Change-Id: Ide8f9bbe50fecb5d11cd579915ee98d4c7efe403 Reviewed-on: https://go-review.googlesource.com/14142 Reviewed-by: Ian Lance Taylor <iant@golang.org>
CL https://golang.org/cl/14306 mentions this issue. |
…making a shared object Currently Go produces shared libraries that cannot be shared between processes because they have relocations against the text segment (not text section). This fixes this by moving some data to sections with magic names recognized by the static linker. The change in genasmsym to add STYPELINK to the switch should fix things on darwin/arm64. Fixes #10914 Updates #9210 Change-Id: Iab4a6678dd04cec6114e683caac5cf31b1063309 Reviewed-on: https://go-review.googlesource.com/14306 Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
…making a shared object Currently Go produces shared libraries that cannot be shared between processes because they have relocations against the text segment (not text section). This fixes this by moving some data to sections with magic names recognized by the static linker. The change in genasmsym to add STYPELINK to the switch should fix things on darwin/arm64. Fixes golang#10914 Updates golang#9210 Change-Id: Iab4a6678dd04cec6114e683caac5cf31b1063309
…de=c-shared on arm All the code was there to do this, it just wasn't hooked up. Fixes golang#10914 Change-Id: Ide8f9bbe50fecb5d11cd579915ee98d4c7efe403
This produces a warning from lintian, debian's package checker.
There don't actually seem to be relocations to the .text, but rather (linking with -Wl,--warn-shared-textrel):
/usr/bin/ld: /home/mwhudson/tmp/hl/runtime/go.o: warning: relocation in readonly section `.gopclntab'.
/usr/bin/ld: warning: creating a DT_TEXTREL in a shared object.
The relocations are mostly R_X86_64_RELATIVE (presumably function pointers) but there are also some references to runtime.no_pointers_stackmap.
I don't know how serious this is. There seems to be some support in the linker for a separate 'segro' vs 'segtext' but it's disabled for external linking...
The text was updated successfully, but these errors were encountered: