Page 1 of 1
LD Relaxing too hard
Posted: Sat Jun 19, 2010 9:48 pm
by thepowersgang
When I ported my OS to 64-bit I came across several strange bugs in my code, most of which I have fixed. However, there seems to be an odd one in the way GNU LD is linking.
From my linker map:
Code: Select all
.rodata.str1.1
0xffffffff80130d1a 0x138 arch/x86_64/mm_virt.o.x86_64
0x13f (size before relaxing)
.rodata.str1.1
0x0000000000000000 0x5 arch/x86_64/mm_phys.o.x86_64
.rodata.str1.1
0xffffffff80130e52 0x7 arch/x86_64/vm8086.o.x86_64
.rodata.str1.1 section from mm_virt.o (last two lines)
Code: Select all
0120 004d4d5f 4e65774b 53746163 6b3a2046 .MM_NewKStack: F
0130 6f756e64 206f6e65 20617420 257000 ound one at %p.
.rodata.str1.1 section from vm8086.o
LD applies some sort of space optimization on the mm_virt.o rodata and changes the final size down. However, this causes the last 7 bytes of one of the strings to be replaced with the first 7 from vm80806.o
This causes the string printed in mm_virt to come out as "MM_NewKStack: Found oneVM8086"
Has anyone encountered a similar behavior and knows how to fix it? or even why it is happening?
<edit>I'm using GNU LD 2.20.1 (Ubuntu 10.04 native build)</edit>
Re: LD Relaxing too hard
Posted: Sun Jun 20, 2010 2:39 am
by Combuster
There is a null terminator there, are you writing fixed sizes or...?
Re: LD Relaxing too hard
Posted: Sun Jun 20, 2010 3:10 am
by thepowersgang
The problem is not with my string code, it's with the way LD is handling the .rodata sections in these files. It's assuming the last seven bytes of the mm_virt.o.x86_64 one are unused, so it allows vm8086.o.x86_64 to be written there.
Re: LD Relaxing too hard
Posted: Sun Jun 20, 2010 3:38 am
by gerryg400
Seems like a bug in LD. Try moving rodata into .text and see what happens.
Re: LD Relaxing too hard
Posted: Sun Jun 20, 2010 3:51 am
by thepowersgang
moving .rodata to .text yields no change, as I would have expected.
I was assuming a LD bug, but I also try not to blame the toolchain unless it deserves it, because in most cases it's my own dumb fault. What I find annoying is that this is the latest version of binutils, so there's no version to upgrade to.
Re: LD Relaxing too hard
Posted: Sun Jun 20, 2010 4:23 am
by Combuster
Ok, now with less sleepy thoughts:
1: Why are you using Ubuntu's host toolchain?
2: My 64-bit toolchain does not put strings in ".rodata.???", but in regular ".rodata", what is causing this change?
3. Why are you using a toolchain with a version number that yields a ton of links to the "unstable branch" with known issues?
4. Have you tried turning off the -relax switch that's on by default (--no-relax) or is your binutils braindead enough not to have it?
(side note, on gentoo, all 8 versions/revisions of binutils past 2.18 are masked as not being of production quality, that imo says enough)
Re: LD Relaxing too hard
Posted: Sun Jun 20, 2010 5:34 am
by cyr1x
Combuster wrote:
2: My 64-bit toolchain does not put strings in ".rodata.???", but in regular ".rodata", what is causing this change?
This is when you are using wide characters:
* UTF-8 rodata.str1.1
* UTF-16 rodata.str2.2
* UTF-32 rodata.str4.4
Re: LD Relaxing too hard
Posted: Sun Jun 20, 2010 5:41 am
by gerryg400
2: My 64-bit toolchain does not put strings in ".rodata.???", but in regular ".rodata", what is causing this change?
My cross-compiled tool-chain puts strings in .rodata.str1.1 and .rodata.str1.8 too. My understanding is if the string including null is 32 bytes or longer it goes into .rodata.str1.8. These string are 8byte aligned.
Re: LD Relaxing too hard
Posted: Sun Jun 20, 2010 8:08 am
by thepowersgang
Ok, I'm using the default toolchain because I was a little too lazy to create a cross-compiler when the default one seemed to be working just fine.
It appears that (at least in this version) the --no-relax argument does not exist
I'll try compiling a new toolchain with 2.18 and see what happens, but I do wonder why Ubuntu are using an "unstable" edition of binutils
Re: LD Relaxing too hard
Posted: Sun Jun 20, 2010 8:34 am
by Combuster
Slightly OT:
cyr1x wrote:Combuster wrote:
2: My 64-bit toolchain does not put strings in ".rodata.???", but in regular ".rodata", what is causing this change?
This is when you are using wide characters:
My cross-compiled tool-chain puts strings in .rodata.str1.1 and .rodata.str1.8 too. My understanding is if the string including null is 32 bytes or longer it goes into .rodata.str1.8. These string are 8byte aligned.
Since neither answers the question: it turns out that GCC (at least version 4.3.4) only creates such sections when
optimisations are enabled.
Re: LD Relaxing too hard
Posted: Sun Jun 20, 2010 8:51 am
by Solar
thepowersgang wrote:I'll try compiling a new toolchain with 2.18 and see what happens, but I do wonder why Ubuntu are using an "unstable" edition of binutils
Distribution maintainers take the latest version that fixes the bugs their users have been nagging about, while at the same time floating their boat. If that version later appears to be incompatibly broken, they're more or less stuck with it until the next major release comes out. (Not saying that this happened to the Ubuntu people, but I've been close enough to distro maintainers to have heard the cries of anguish.) They also tend to take patches from development branches, or backward compatibility patches from the last time they screwed up, and what you end up with is a toolchain that's good for your distro but as unreproducable for others as it gets. Which is why the upstream maintainers usually turn down any bug reports for distro-specific versions and insist on you trying the vanilla sources first.
One more reason to go for a cross-compiler - you know exactly what's in there, and who to blame if it screws up.
Re: LD Relaxing too hard
Posted: Mon Jun 21, 2010 9:01 am
by thepowersgang
Alright, after compiling versions 2.18, 2.19.1 and 2.20.1 with all exhibiting the same bug (when targeting x86_64-none-elf) it seems that it is either a very strange edge case bug, or an obscure misconfiguration on my part.
Does anyone have an idea as to why it would be doing this?
Re: LD Relaxing too hard
Posted: Mon Jun 21, 2010 9:40 am
by Combuster
Could you, for reference, post a tarball with the minimal set of sources and shell script/makefile that generates the (wrong) output?
Re: LD Relaxing too hard
Posted: Thu Jun 24, 2010 4:24 am
by thepowersgang
I'll try to make a proper test case on the weekend, but for now there's my git repo at
http://git.ucc.asn.au/?p=acess2.git or the git snapshot at
http://www.mutabah.net/Downloads/Acess2 ... git.tar.gz
A quick attempt to create a test case failed, so I think there may be an error in my flags somewhere.