토요일, 8월 02, 2008

entry point가 되는 _start 함수 구현

entry point가 되는 _start 함수 구현

Source:
http://honeypod.blogspot.com/2007/12/dynamically-linked-hello-world-for.html
http://socmaster.homelinux.org/~dasomoli/blog/114


entry point가 되는 _start 함수 구현


Dynamically linked "Hello, world!" for Android

This article describes the step-by-step procedure to compile and run the dynamically linked "Hello, world!" for Android. I confirmed this procedure only on my host (Fedora 8). Sorry for Windows and Mac users.

I would like to appreciate developers who posted useful messages on Android Developers and Android Internal news groups. Especially I would like to thank to Benno who provided busybox and strace binary which work on Android.

I would like to suggest you to read the "Native C applications for Android" written by Benno before reading this article.

I hope this article is useful for all Android developers.


1. Get toolchains from CodeSourcery(Choose ARM GNU/Linux and IA32 GNU/Linux). The following description assumes that the bin directory of toolchains is added to your PATH.

2. Get strace, busybox and system image of Android from Benno's site. Copy strace and busybox to the runnning emulator. Deploy the system image on your disk. The following description assumes the system image is deployed under ~/tmp/android.

3. Prepare source files.

hello.c:

#include

int main(int argc, char **argv) {
printf("Hello, world!\n");
return 0;
}

start.c:

#include
extern int main(int argc, char **argv);

void _start(int argc, char **argv)
{
exit (main (argc, argv));
}



4. Compile these source files.

$ arm-none-linux-gnueabi-gcc -c hello.c
$ arm-none-linux-gnueabi-gcc -c start.c
$ arm-none-linux-gnueabi-ld \
--entry=_start \
--dynamic-linker /system/bin/linker -nostdlib \
-rpath /system/lib -rpath ~/tmp/android/system/lib \
-L ~/tmp/android/system/lib -lc -o hello hello.o start.o



The --entry option gives the entry point of program. You can omit this option in this case because the default is _start. The --dynamic-linker option gives the place of dynamic linker. Give it from the viewpoint of the running program on Android. The -nostdlib option prevents ld from searching other library paths rather than the ones given on the command line. The first -rpath gives the place where dynamic linker search libraries. Give it from the viewpoint of the running program on Android. The second -rpath gives the place where ld search libraries needed by the library which has already loaded. Give it from the viewpoint of ld on your host.The -L option the place where ld searches the library which is given by -l option at compile time.


5. Copy binary to Android. The following description assumes that there is /data/hello directory on Android. The '#' is the prompt of Android shell.

$ adb push hello /data/hello/
# cd /data/hello
# ./hello Hello, world!



6. Check by strace whether the program ends in success.

# strace ./hello
execve("./hello", ["./hello"], [/* 9 vars */]) = 0
getpid() = 1803
syscall_983045(0xb0016b48, 0xb0013760, 0x3e4, 0, 0xbea0ae48, 0x1, 0, 0xf0005,
0xb0013760, 0, 0, 0xbea0ae44, 0, 0xbea0adf8, 0xb0000d89, 0xb00016ec, 0x10,
0xb0016b48, 0, 0, 0, 0xeb48, 0xcd1f8, 0xcd1d0, 0, 0, 0, 0, 0, 0, 0, 0) = 0
gettid() = 1803
sigaction(SIGILL, {0xb0001469, [], SA_RESTART}, {SIG_DFL}, 0) = 0
sigaction(SIGABRT, {0xb0001469, [], SA_RESTART}, {SIG_DFL}, 0) = 0
sigaction(SIGBUS, {0xb0001469, [], SA_RESTART}, {SIG_DFL}, 0) = 0
sigaction(SIGFPE, {0xb0001469, [], SA_RESTART}, {SIG_DFL}, 0) = 0
sigaction(SIGSEGV, {0xb0001469, [], SA_RESTART}, {SIG_DFL}, 0) = 0
sigaction(SIGSTKFLT, {0xb0001469, [], SA_RESTART}, {SIG_DFL}, 0) = 0
open("libc.so", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or
directory)
open("/system/lib/libc.so", O_RDONLY|O_LARGEFILE) = 3
lseek(3, -8, SEEK_END) = 231908
read(3, "\0\0\340\257PRE ", 8) = 8
mmap2(0xafe00000, 233472, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 3, 0) =
0xafe00000
close(3) = 0
mmap2(0xafe39000, 45056, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0,
0) = 0xafe39000
mprotect(0xafe00000, 221184, PROT_READ|PROT_EXEC) = 0
mprotect(0, 0, PROT_READ|PROT_EXEC) = 0
fstat64(1, {st_mode=S_IFREG|0666, st_size=1337, ...}) = 0
brk(0) = 0x11000
brk(0x11000) = 0x11000
brk(0x13000) = 0x13000
exit_group(0) = ?
Process 1803 detached



You see exit_group(0) at the end. The program ended in success.

7. To see memory map, modify hello.c.


#include
#include

int main(int argc, char **argv) {
printf("Hello, world!\n");
for(;;) sleep(1); // Zzz...
return 0;
}



This program sleeps until killed.

# ./hello &
# Hello, world!

# ps | grep hello
root 1944 450 472 184 00000000 00008318 R ./hello
# cat /proc/1944/maps
00008000-00009000 r-xp 00000000 1f:01 775 /data/hello/hello
00010000-00011000 rw-p 00000000 1f:01 775 /data/hello/hello
00011000-00013000 rwxp 00011000 00:00 0 [heap]
afe00000-afe36000 r-xp 00000000 1f:00 365 /system/lib/libc.so
afe36000-afe39000 rwxp 00036000 1f:00 365 /system/lib/libc.so
afe39000-afe44000 rw-p afe39000 00:00 0
b0000000-b0014000 rwxp 00000000 1f:00 272 /system/bin/linker
b0014000-b0019000 rwxp b0014000 00:00 0
bea6f000-bea84000 rw-p befeb000 00:00 0 [stack]

# kill 1944

-----
Cheers,
June

댓글 없음:

댓글 쓰기