Skip to content

Commit 4caa767

Browse files
committed
First commit
0 parents  commit 4caa767

10 files changed

+47871
-0
lines changed

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
*.o
2+
*.so
3+
main
4+
mainc
5+
maind

build

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/bash
2+
3+
#make sure the linux shared library loader is able to find our library.
4+
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
5+
6+
#build libtest.so first
7+
gcc -fpic -g -c test.c
8+
gcc -shared test.o -o libtest.so
9+
10+
#generate asm file for inspection
11+
objdump -d -M intel libtest.so > test.asm
12+
13+
#next build main.c
14+
gcc -g main.c -L. -ltest -o mainc
15+
16+
#generate asm file for inspection
17+
objdump -d -M intel mainc > mainc.asm
18+
19+
#next build main.d
20+
dmd -g -c main.d
21+
gcc main.o -L. -ltest -lphobos2 -lrt -o maind
22+
23+
#generate asm file for inspection
24+
objdump -d -M intel maind > maind.asm

main.c

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include "stdio.h"
2+
#include "test.h"
3+
4+
//From x86_64 System V EABI Spec...
5+
//rdi - 1st arg
6+
//rsi - 2nd arg
7+
//rdx - 3rd arg or 2nd return reg
8+
//rcx - 4th arg
9+
//r8 - 5th arg
10+
//r9 - 6th arg
11+
//rax - 1st return reg
12+
13+
14+
// 0000000000400634 <main>:
15+
// 400634: 55 push rbp
16+
// 400635: 48 89 e5 mov rbp,rsp
17+
// 400638: 48 83 ec 30 sub rsp,0x30 //end of function prologue
18+
// 40063c: c7 45 f0 ef be ad de mov DWORD PTR [rbp-0x10],0xdeadbeef //*(rbp-0x10) = p1 = 0xdeadbeef
19+
// 400643: c7 45 f4 00 00 00 00 mov DWORD PTR [rbp-0xc],0x0 //*(rbp-0xc) = 0
20+
// 40064a: c7 45 fc 64 00 00 00 mov DWORD PTR [rbp-0x4],0x64 //*(rbp-0x4) = p2 = 0x64
21+
// 400651: 8b 55 fc mov edx,DWORD PTR [rbp-0x4] //edx = p2
22+
// 400654: 48 8b 45 f0 mov rax,QWORD PTR [rbp-0x10] //rax = p1
23+
// 400658: 89 d6 mov esi,edx //esi = edx = p2
24+
// 40065a: 48 89 c7 mov rdi,rax //rdi = rax = p1
25+
// 40065d: e8 de fe ff ff call 400540 <test@plt> //test(rdi = p1, rsi = esi = p2) //Where is the retptr?
26+
// 400662: 48 89 c1 mov rcx,rax //rcx = rax
27+
// 400665: 89 d0 mov eax,edx //eax = edx
28+
// 400667: 48 89 4d d0 mov QWORD PTR [rbp-0x30],rcx //*(rbp-0x30) = rcx
29+
// 40066b: 89 45 d8 mov DWORD PTR [rbp-0x28],eax //*(rbp-0x28) = eax
30+
// 40066e: 48 8b 45 d0 mov rax,QWORD PTR [rbp-0x30] //rax = *(rbp-0x30)
31+
// 400672: 48 89 45 e0 mov QWORD PTR [rbp-0x20],rax //*(rbp-0x20) = rax
32+
// 400676: 48 8b 45 d8 mov rax,QWORD PTR [rbp-0x28] //rax = *(rbp-0x28)
33+
// 40067a: 48 89 45 e8 mov QWORD PTR [rbp-0x18],rax //*(rbp-0x18) = rax
34+
// 40067e: 8b 55 e8 mov edx,DWORD PTR [rbp-0x18] //edx = *(rbp-0x18)
35+
// 400681: 48 8b 4d e0 mov rcx,QWORD PTR [rbp-0x20] //rcx = *(rbp-0x20)
36+
// 400685: b8 9c 07 40 00 mov eax,0x40079c //eax = 0x40079c
37+
// 40068a: 48 89 ce mov rsi,rcx //rsi = rcx
38+
// 40068d: 48 89 c7 mov rdi,rax //rdi = rax
39+
// 400690: b8 00 00 00 00 mov eax,0x0 //eax = 0
40+
// 400695: e8 86 fe ff ff call 400520 <printf@plt> //printf(fmt, ts.data, ts.flags)
41+
// 40069a: b8 00 00 00 00 mov eax,0x0 //eax = 0 //return 0;
42+
// 40069f: c9 leave //
43+
// 4006a0: c3 ret //
44+
45+
int main()
46+
{
47+
void *p1 = (void*)0xDEADBEEF;
48+
unsigned p2 = 100; //0x64
49+
50+
TestStruct ts = test(p1, p2);
51+
52+
printf("ts.data=%p\nts.flags=%u\n", ts.data, ts.flags);
53+
return 0;
54+
}

main.d

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import std.stdio;
2+
import test;
3+
4+
//From x86_64 System V EABI Spec...
5+
//rdi - 1st arg
6+
//rsi - 2nd arg
7+
//rdx - 3rd arg or 2nd return reg
8+
//rcx - 4th arg
9+
//r8 - 5th arg
10+
//r9 - 6th arg
11+
//rax - 1st return reg
12+
13+
//ASM code appears to be generated correctly for small sized return values
14+
//extern (C) void* test(void* p1, uint p2);
15+
//0000000000401f18 <_Dmain>:
16+
// 401f18: 55 push rbp
17+
// 401f19: 48 8b ec mov rbp,rsp //end of function prologue
18+
// 401f1c: 48 b8 ef be ad de 00 movabs rax,0xdeadbeef //rax = 0xdeadbeef (=p1)
19+
// 401f23: 00 00 00
20+
// 401f26: b9 64 00 00 00 mov ecx,0x64 //ecx = 0x64 (=p2)
21+
// 401f2b: 48 89 ce mov rsi,rcx //rsi = rcx = ecx = p2
22+
// 401f2e: 48 89 c7 mov rdi,rax //rdi = rax = p1
23+
// 401f31: e8 d2 fc ff ff call 401c08 <test@plt> //test(rdi = p1, rsi = p2 )
24+
25+
//This is the problem case...
26+
//extern (C) TestStruct test(void* p1, uint p2);
27+
//0000000000401f18 <_Dmain>:
28+
// 401f18: 55 push rbp
29+
// 401f19: 48 8b ec mov rbp,rsp
30+
// 401f1c: 48 83 ec 10 sub rsp,0x10 //rsp -= 0x10 //reserve space for the return value
31+
//we can only allocate 8 byte chunks on the 64 bit stack
32+
//hence we have to allocate 16 (0x10) bytes even though we
33+
//just need 12 (=TestStruct.sizeof)
34+
// 401f20: 48 b8 ef be ad de 00 movabs rax,0xdeadbeef //rax = 0xdeadbeef
35+
// 401f27: 00 00 00
36+
// 401f2a: b9 64 00 00 00 mov ecx,0x64 //ecx = p2
37+
// 401f2f: 48 89 ca mov rdx,rcx //rdx = rcx = ecx = p2
38+
// 401f32: 48 89 c6 mov rsi,rax //rsi = rax = p1
39+
// 401f35: 48 8d 7d f0 lea rdi,[rbp-0x10] //rdi = rbp-0x10 = retptr //BUG?
40+
// 401f39: e8 ca fc ff ff call 401c08 <test@plt> //test(rdi = retptr, rsi = p1, rdx = p2 )
41+
42+
//Dont know why the ASM code changed from above to the following (maybe optimisation failed?)!
43+
//0000000000401f18 <_Dmain>:
44+
// 401f18: 55 push rbp
45+
// 401f19: 48 8b ec mov rbp,rsp
46+
// 401f1c: 48 83 ec 20 sub rsp,0x20 //rsp -= 0x20 (=32)//reserve space for the locals and return value from test()
47+
//32 = TestStruct.sizeof(=12) + (void*).sizeof(=8) + uint.sizeof (=4)
48+
//It appears that the return value is directly stored in the TestStruct local var
49+
//hence TestStruct is not allocated twice
50+
// 401f20: 48 b8 ef be ad de 00 movabs rax,0xdeadbeef //rax = 0xdeadbeef
51+
// 401f27: 00 00 00
52+
// 401f2a: 48 89 45 e0 mov QWORD PTR [rbp-0x20],rax //p1 = *(rbp-0x20) ~ rax ~ 0xdeadbeef
53+
// 401f2e: b9 64 00 00 00 mov ecx,0x64 //ecx = 0x64
54+
// 401f33: 89 4d e8 mov DWORD PTR [rbp-0x18],ecx //p2 = *(rbp-0x18) ~ ecx ~ 0x64
55+
// 401f36: 48 89 ca mov rdx,rcx //rdx = rcx ~ ecx ~ p2
56+
// 401f39: 48 89 c6 mov rsi,rax //rsi = rax ~ p1
57+
// 401f3c: 48 8d 7d f0 lea rdi,[rbp-0x10] //rdi = *(rbp-0x10) ~ retptr?
58+
// 401f40: e8 c3 fc ff ff call 401c08 <test@plt> //test(rdi = retptr, rsi = p1, rdx = p2)
59+
// 401f45: ff 35 7d 3f 02 00 push QWORD PTR [rip+0x23f7d] # 425ec8 <_TMP0+0x8> //format string?
60+
// 401f4b: ff 35 6f 3f 02 00 push QWORD PTR [rip+0x23f6f] # 425ec0 <_TMP0>
61+
// 401f51: 48 8b 75 f0 mov rsi,QWORD PTR [rbp-0x10] //rsi = *retptr ~ ts.data
62+
// 401f55: 8b 7d f8 mov edi,DWORD PTR [rbp-0x8] //edi = *(retptr-0x8) ~ ts.flags
63+
// 401f58: e8 0b 00 00 00 call 401f68 <_D3std5stdio22__T8writeflnTAyaTPvTkZ8writeflnFAyaPvkZv>
64+
// 401f5d: 48 83 c4 10 add rsp,0x10
65+
// 401f61: 31 c0 xor eax,eax
66+
// 401f63: c9 leave
67+
// 401f64: c3 ret
68+
void main()
69+
{
70+
void *p1 = cast(void*)0xDEADBEEF;
71+
uint p2 = 100;//0x64
72+
73+
TestStruct ts = test.test(p1, p2);
74+
75+
writefln("ts.data=%s\nts.flags=%s", ts.data, ts.flags);
76+
}

0 commit comments

Comments
 (0)