Page 1 of 1
Strange code generation by x86_64-pc-linux-gnu-gcc
Posted: Tue Apr 25, 2006 10:45 pm
by hendric
Hi all,I'm now busy implementing early_kprintf aimed to print strings into screen.For test I write a simple function as follow:
Code: Select all
int early_kprintf(char* fmt,char* fmt2,...)
{
???return 0;
}
After compiling by x86_64-pc-linux-gnu-gcc(with version 3.4.0), I tried to link all .o files.But "relocationg truncated to fit: .text 0x6fe+.text" error again happened.I ran objdump to dump the very .o file,I found it strange:
Code: Select all
00000000000006b0 <early_kprintf>:
6b0:???55 ???push %rbp
6b1:???48 89 e5 ???mov %rsp,%rbp
6b4:???48 81 ec d0 00 00 00 ???sub $0xd0,%rsp
6bb:???48 89 bd 48 ff ff ff ???mov %rdi,0xffffffffffffff48(%rbp)
6c2:???48 89 95 60 ff ff ff ???mov %rdx,0xffffffffffffff60(%rbp)
6c9:???48 89 8d 68 ff ff ff ???mov %rcx,0xffffffffffffff68(%rbp)
6d0:???4c 89 85 70 ff ff ff ???mov %r8,0xffffffffffffff70(%rbp)
6d7:???4c 89 8d 78 ff ff ff ???mov %r9,0xffffffffffffff78(%rbp)
6de:???0f b6 c0 ???movzbl %al,%eax
6e1:???48 89 85 38 ff ff ff ???mov %rax,0xffffffffffffff38(%rbp)
6e8:???48 8b 95 38 ff ff ff ???mov 0xffffffffffffff38(%rbp),%rdx
6ef:???48 8d 04 95 00 00 00 ???lea 0x0(,%rdx,4),%rax
6f6:???00
6f7:???48 c7 85 38 ff ff ff ???movq $0x0,0xffffffffffffff38(%rbp)
6fe:???00 00 00 00
702:???48 29 85 38 ff ff ff ???sub %rax,0xffffffffffffff38(%rbp)
709:???48 8d 45 ff ???lea 0xffffffffffffffff(%rbp),%rax
70d:???48 8b 95 38 ff ff ff ???mov 0xffffffffffffff38(%rbp),%rdx
714:???ff e2 ???jmpq *%edx
716:???0f 29 78 f1 ???movaps %xmm7,0xfffffffffffffff1(%rax)
71a:???0f 29 70 e1 ???movaps %xmm6,0xffffffffffffffe1(%rax)
71e:???0f 29 68 d1 ???movaps %xmm5,0xffffffffffffffd1(%rax)
722:???0f 29 60 c1 ???movaps %xmm4,0xffffffffffffffc1(%rax)
726:???0f 29 58 b1 ???movaps %xmm3,0xffffffffffffffb1(%rax)
72a:???0f 29 50 a1 ???movaps %xmm2,0xffffffffffffffa1(%rax)
72e:???0f 29 48 91 ???movaps %xmm1,0xffffffffffffff91(%rax)
732:???0f 29 40 81 ???movaps %xmm0,0xffffffffffffff81(%rax)
736:???48 89 b5 40 ff ff ff ???mov %rsi,0xffffffffffffff40(%rbp)
73d:???b8 00 00 00 00 ???mov $0x0,%eax
742:???c9 ???leaveq
743:???c3 ???retq
I think it strange that why GCC refers to xmm registers.And I found no resolutions from GCC doc-book.Any help is appreciated.
Re:Strange code generation by x86_64-pc-linux-gnu-gcc
Posted: Wed Apr 26, 2006 4:13 am
by Pype.Clicker
hendric wrote:
6b1: 48 89 e5 mov %rsp,%rbp
6b4: 48 81 ec d0 00 00 00 sub $0xd0,%rsp
6bb: 48 89 bd 48 ff ff ff mov %rdi,0xffffffffffffff48(%rbp)
6c2: 48 89 95 60 ff ff ff mov %rdx,0xffffffffffffff60(%rbp)
6c9: 48 89 8d 68 ff ff ff mov %rcx,0xffffffffffffff68(%rbp)
Do you see any reason why the compiler felt obliged to add prefixes (0x48 is a x86_64 prefix in the spirit of 0x66 and 0x67 on ia32, no?) everywhere ?
6ef: 48 8d 04 95 00 00 00 lea 0x0(,%rdx,4),%rax
6f6: 00
6f7: 48 c7 85 38 ff ff ff movq $0x0,0xffffffffffffff38(%rbp)
6fe: 00 00 00 00
that sounds highly suspicious to me, such as if the disassembler didn't get what was going on and has a trailing (and unused) nul byte.
... or have you observed that "objdump" likes to split disassembly over 2 lines when the individual bytes for one operation grows over N bytes ?
702: 48 29 85 38 ff ff ff sub %rax,0xffffffffffffff38(%rbp)
709: 48 8d 45 ff lea 0xffffffffffffffff(%rbp),%rax
70d: 48 8b 95 38 ff ff ff mov 0xffffffffffffff38(%rbp),%rdx
714: ff e2 jmpq *%edx
Hm, the "jmpq" is inconditionnal, i suppose, that means whatever comes after this is just padding... right ?
If you ask me, the whole thing looks terribly like a exception setup/resume code ...
Re:Strange code generation by x86_64-pc-linux-gnu-gcc
Posted: Wed Apr 26, 2006 4:58 am
by durand
Yeah, be careful of the output from objdump. I've had situations myself where the disassembled output is not correct. This is very obvious when disassembling real mode code. If you check the bug reports for that, you'll see a lot of them.
This is probably unrelated to your problem, just letting someone know.
Re:Strange code generation by x86_64-pc-linux-gnu-gcc
Posted: Wed Apr 26, 2006 5:39 am
by Pype.Clicker
just a thought: what objdump do you use for that ? one you rebuilt yourself (when i'm toying with a cross-compiler, i usually have to use a cross-objdump aswell) or a native one for your platform ?
Maybe you want to compare that objdump with the output of "gcc <yourfile> -S" which only produce the assembly code and doesn't go further.
Re:Strange code generation by x86_64-pc-linux-gnu-gcc
Posted: Wed Apr 26, 2006 8:24 am
by Colonel Kernel
I've had the same kind of problems, which is why I use ndisasm instead of objdump... Is there anything similar for x86-64?
Re:Strange code generation by x86_64-pc-linux-gnu-gcc
Posted: Wed Apr 26, 2006 10:32 pm
by hendric
Pype.Clicker wrote:
hendric wrote:
6b1: 48 89 e5 mov %rsp,%rbp
6b4: 48 81 ec d0 00 00 00 sub $0xd0,%rsp
6bb: 48 89 bd 48 ff ff ff mov %rdi,0xffffffffffffff48(%rbp)
6c2: 48 89 95 60 ff ff ff mov %rdx,0xffffffffffffff60(%rbp)
6c9: 48 89 8d 68 ff ff ff mov %rcx,0xffffffffffffff68(%rbp)
Do you see any reason why the compiler felt obliged to add prefixes (0x48 is a x86_64 prefix in the spirit of 0x66 and 0x67 on ia32, no?) everywhere ?
Yea I found that gcc added REX prefix everywhere but the program worked very well.
6ef: 48 8d 04 95 00 00 00 lea 0x0(,%rdx,4),%rax
6f6: 00
6f7: 48 c7 85 38 ff ff ff movq $0x0,0xffffffffffffff38(%rbp)
6fe: 00 00 00 00
that sounds highly suspicious to me, such as if the disassembler didn't get what was going on and has a trailing (and unused) nul byte.
... or have you observed that "objdump" likes to split disassembly over 2 lines when the individual bytes for one operation grows over N bytes ?
Yea I observed the situation.But I do not know why objdump split the disassembly.
702: 48 29 85 38 ff ff ff sub %rax,0xffffffffffffff38(%rbp)
709: 48 8d 45 ff lea 0xffffffffffffffff(%rbp),%rax
70d: 48 8b 95 38 ff ff ff mov 0xffffffffffffff38(%rbp),%rdx
714: ff e2 jmpq *%edx
Hm, the "jmpq" is inconditionnal, i suppose, that means whatever comes after this is just padding... right ?
If you ask me, the whole thing looks terribly like a exception setup/resume code ...
I felt highly strange about the jmp instruction.The function early_kprintf is an empty function but I don't know why gcc generated so many code even though I enabled O3.Maybe you are right,the data after jmp instruction maybe padding data,there's no reason for gcc to refer to xmm registers!
Re:Strange code generation by x86_64-pc-linux-gnu-gcc
Posted: Wed Apr 26, 2006 10:41 pm
by hendric
Colonel Kernel wrote:
I've had the same kind of problems, which is why I use ndisasm instead of objdump... Is there anything similar for x86-64?
As far as I know,ndisasm can only disassemble i8086 disassembly but x86_64.
Maybe you want to compare that objdump with the output of "gcc <yourfile> -S" which only produce the assembly code and doesn't go further.
Yea I 've tried about it.The assembly generated by gcc is the same to objdump.But I still found no resolutions about the "relocation truncated to fit" error because I don't know what to relocate
Re:Strange code generation by x86_64-pc-linux-gnu-gcc
Posted: Wed Apr 26, 2006 11:41 pm
by Candy
Probably nothing, but did you use x86_64-pc-linux-ld or ld?
Re:Strange code generation by x86_64-pc-linux-gnu-gcc
Posted: Wed Apr 26, 2006 11:50 pm
by hendric
Candy wrote:
Probably nothing, but did you use x86_64-pc-linux-ld or ld?
I used x86_64-pc-linux-gnu-ld as my linker.
Re:Strange code generation by x86_64-pc-linux-gnu-gcc
Posted: Thu Apr 27, 2006 1:02 am
by guest
Truncating relocations usually occurs when mixing different code types (eg. 16bit and 32bit). You may want to check all your GCC and LD commands, make sure they're all in -m64 mode. Be sure that any assembly is written in YASM "[BITS 64]" with the "-m amd64 -f elf64" commandline or AT&T (x86_64-pc-linux-gnu-as) ".code 64"
[If Pype.Clicker is right, you may also want to throw in "-fno-exceptions" on gcc and "-nostdlib -lgcc" on ld commandlines]
Re:Strange code generation by x86_64-pc-linux-gnu-gcc
Posted: Thu Apr 27, 2006 9:56 pm
by hendric
guest wrote:
Truncating relocations usually occurs when mixing different code types (eg. 16bit and 32bit). You may want to check all your GCC and LD commands, make sure they're all in -m64 mode. Be sure that any assembly is written in YASM "[BITS 64]" with the "-m amd64 -f elf64" commandline or AT&T (x86_64-pc-linux-gnu-as) ".code 64"
[If Pype.Clicker is right, you may also want to throw in "-fno-exceptions" on gcc and "-nostdlib -lgcc" on ld commandlines]
I've followed your suggestion but it was not effective. But I found gcc under x86_64 really has different behavior from normal gcc . Say, gcc under x86_64 uses 3 registers to pass parameter even thouth cdecl attribute is specified,at least for functions with ramdon parameters.
I feel disappointed at x86_64 gcc. I decide to implement early_kprintf directly via assembly
Re:Strange code generation by x86_64-pc-linux-gnu-gcc
Posted: Fri Apr 28, 2006 2:48 am
by Candy
hendric wrote:
I've followed your suggestion but it was not effective. But I found gcc under x86_64 really has different behavior from normal gcc . Say, gcc under x86_64 uses 3 registers to pass parameter even thouth cdecl attribute is specified,at least for functions with ramdon parameters.
I feel disappointed at x86_64 gcc. I decide to implement early_kprintf directly via assembly
Try reading the 64-bit ABI, which specifies exactly what you noticed. It's nearly identical to the IA64 ABI, which you can find easily on google.