æå ã«x64ãã·ã³ãããªãç¶æ³ã§ARMç°å¢ãç¨æãããã¨ããå ´åã以ä¸ã®ãããªé¸æè¢ãèããããã
- 宿©ãç¨æããï¼Raspberry PiãAndroid端æ«ãªã©ï¼
- ãéããããã使ãã®ã«æéãããã
- QEMUã®ã·ã¹ãã ã¨ãã¥ã¬ã¼ã·ã§ã³ã使ã
- åç¾æ§ãé«ã䏿¹ãéã
- QEMUã®ã¦ã¼ã¶ã¢ã¼ãã¨ãã¥ã¬ã¼ã·ã§ã³ã使ãï¼åèï¼
- åç¾æ§ã¯ã·ã¹ãã ã¨ãã¥ã¬ã¼ã·ã§ã³ã«æ¯ã¹å£ãã軽ããå®è¡æãgdbãããã°æã®ã©ã¤ãã©ãªãã¹æå®ãããç ©é
- QEMUã®ã¦ã¼ã¶ã¢ã¼ãã¨ãã¥ã¬ã¼ã·ã§ã³ã«binfmtã¨chrootãçµã¿åããã¦ä½¿ãï¼åè1ãåè2ï¼
- 軽ãä¸ã«ã©ã¤ãã©ãªãã¹ã®æå®ãä¸è¦ã ããchrootç°å¢ä¸ã«å種ããã°ã©ã ãç¨æããã®ã«æéãããã
- QEMUã®ã¦ã¼ã¶ã¢ã¼ãã¨ãã¥ã¬ã¼ã·ã§ã³ã«binfmtã¨ã³ã³ããä»®æ³åãçµã¿åããã¦ä½¿ãï¼åèï¼
- 軽ãä¸ã«ã©ã¤ãã©ãªãã¹ã®æå®ãä¸è¦ãããã«å種ããã±ã¼ã¸ã¤ã³ã¹ãã¼ã«æ¸ã¿ã®ã¤ã¡ã¼ã¸ã¨ãã¦æ±ãã
ããã§ã¯æå¾ã®é¸æè¢ã«ããã¦ãã³ã³ããä»®æ³åã«Dockerãå©ç¨ããå ´åã®ARMç°å¢æ§ç¯ã«ã¤ãã¦è¨ãã Dockerèªä½ã®ã¤ã³ã¹ãã¼ã«ãå©ç¨æ¹æ³ã«ã¤ãã¦ã¯ãDockerã使ã£ã¦ã¿ãããåç §ã ãã¹ãOSã«ã¯Ubuntu 14.04.1 LTS amd64ï¼x86_64ï¼çã使ç¨ãã¦ããã
qemu-user-staticã®ã¤ã³ã¹ãã¼ã«
ã¾ãããã¹ãOSã«ã¦ã¼ã¶ã¢ã¼ãã¨ãã¥ã¬ã¼ã·ã§ã³ãè¡ãQEMUãã¤ã³ã¹ãã¼ã«ããã
$ sudo apt-get install qemu-user-static
Dockerã¤ã¡ã¼ã¸ã®ãã¦ã³ãã¼ã
次ã®ãªãã¸ããªãããbinfmtè¨å®æ¸ã¿ã®Dockerã¤ã¡ã¼ã¸ãå©ç¨ã§ããã
ãããªãDockerfileããã¤ã¡ã¼ã¸ã使ãã¦ãåé¡ãªãããããã§ã¯å¾ã ã®ãã¨ãèãä¸å¼ãã¦ã³ãã¼ããã¦ããã
$ sudo docker pull mazzolino/armhf-ubuntu
ã³ã³ãã¤ã©çã¤ã³ã¹ãã¼ã«æ¸ã¿ã¤ã¡ã¼ã¸ã®ä½æ
ä¸ã§ãã¦ã³ãã¼ãããDockerã¤ã¡ã¼ã¸ããã¼ã¹ã«ãå¿ è¦ãªããã±ã¼ã¸ã®ã¤ã³ã¹ãã¼ã«æé ãDockerfileã¨ãã¦è¨è¿°ããã ãã ãç¾æç¹ã«ããã¦14.04ã¨ããã¿ã°ããã§ã¯bashçã®ã³ãã³ãããã¾ãå®è¡ã§ããªãã£ããããããã§ã¯ä»£ããã«latestã使ç¨ããã
$ vi Dockerfile $ cat Dockerfile FROM mazzolino/armhf-ubuntu:latest RUN apt-get update && apt-get -y upgrade RUN apt-get -y install build-essential gdb python git $ sudo docker build -t 'user/armhf-ubuntu:latest' . $ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE user/armhf-ubuntu latest de8aa0360ee1 11 minutes ago 568.9 MB
ã³ã³ããã®ä½æ
使ããããã±ã¼ã¸ã¤ã³ã¹ãã¼ã«æ¸ã¿Dockerã¤ã¡ã¼ã¸ããã¨ã«ãubuntu-arm
ã¨ããååã®ã³ã³ããã使ãèµ·åããã
$ sudo docker run --name ubuntu-arm -i -t user/armhf-ubuntu:latest /bin/bash root@c7b94bb2fc1e:/# uname -a Linux c7b94bb2fc1e 2.6.32 #57-Ubuntu SMP Tue Jul 15 03:51:08 UTC 2014 armv7l armv7l armv7l GNU/Linux root@c7b94bb2fc1e:/# lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 14.04.2 LTS Release: 14.04 Codename: trusty root@c7b94bb2fc1e:/# file /bin/bash /bin/bash: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=f8059e177cfff17568e8957e78cb3b997ef23f93, stripped root@c7b94bb2fc1e:/# exit [email protected]:~/tmp/docker/ubuntu-arm $ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c7b94bb2fc1e user/armhf-ubuntu:latest /bin/bash 23 seconds ago Exited (0) 3 seconds ago ubuntu-arm
ã³ãã³ãã®å®è¡çµæãããARMã¨ãã¥ã¬ã¼ã·ã§ã³ç°å¢ã¨ãã¦å®è¡ã§ãã¦ãããã¨ããããã
ããã°ã©ã ã®ã³ã³ãã¤ã«ãå®è¡
ããããã¦ã³ã³ãããèµ·åããç°¡åãªããã°ã©ã ãã³ã³ãã¤ã«ãå®è¡ãã¦ã¿ãã
$ sudo docker start -a -i ubuntu-arm root@c7b94bb2fc1e:/# vi hello.c root@c7b94bb2fc1e:/# cat hello.c #include <stdio.h> int main() { puts("Hello, world!"); return 0; } root@c7b94bb2fc1e:/# gcc hello.c root@c7b94bb2fc1e:/# ./a.out Hello, world! root@c7b94bb2fc1e:/# file a.out a.out: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=d44febb8922097957fa5a3f8e7d84e58efc9af6e, not stripped
ARMãã¤ããªã¨ãã¦ã³ã³ãã¤ã«ãå®è¡ã§ãã¦ãããã¨ã確èªã§ããã
readelfã«ããELFæ å ±è¡¨ç¤º
readelfã³ãã³ãã使ã£ã¦ãELFãªãã¸ã§ã¯ãã®å種æ å ±ã表示ãã¦ã¿ãã
root@c7b94bb2fc1e:/# readelf -a a.out ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: ARM Version: 0x1 Entry point address: 0x8315 Start of program headers: 52 (bytes into file) Start of section headers: 4500 (bytes into file) Flags: 0x5000402, has entry point, Version5 EABI, hard-float ABI Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 9 Size of section headers: 40 (bytes) Number of section headers: 30 Section header string table index: 27 (snip)
objdumpã«ãããã£ã¹ã¢ã»ã³ãã«
objdumpã³ãã³ãã使ã£ã¦ãå®è¡ãã¡ã¤ã«ããã£ã¹ã¢ã»ã³ãã«ãã¦ã¿ãã
root@c7b94bb2fc1e:/# objdump -d a.out a.out: file format elf32-littlearm Disassembly of section .init: 000082c4 <_init>: 82c4: e92d4008 push {r3, lr} 82c8: eb00001d bl 8344 <call_weak_fn> 82cc: e8bd8008 pop {r3, pc} (snip)
straceç¸å½ã®ã·ã¹ãã ã³ã¼ã«ãã¬ã¼ã¹
QEMUã®ã¦ã¼ã¶ã¢ã¼ãã¨ãã¥ã¬ã¼ã·ã§ã³ã§ã¯ãptraceã·ã¹ãã ã³ã¼ã«ãnetlinkã使ããªãï¼åèï¼ã ããªãã¡ãptraceã·ã¹ãã ã³ã¼ã«ã使ç¨ããstraceãltraceã使ããã¨ãã§ããªãã
ãã ããstraceã«ã¤ãã¦ã¯qemu-arm-staticã³ãã³ãã«straceç¸å½ã®ãªãã·ã§ã³ãç¨æããã¦ããã®ã§ããã代æ¿ã¨ãã¦å©ç¨ãããã¨ãã§ããã
root@c7b94bb2fc1e:/# qemu-arm-static -strace a.out 23 brk(NULL) = 0x00012000 23 uname(0xf6fff930) = 0 23 access("/etc/ld.so.nohwcap",F_OK) = -1 errno=2 (No such file or directory) 23 mmap2(NULL,8192,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0xf67dc000 23 access("/etc/ld.so.preload",R_OK) = -1 errno=2 (No such file or directory) 23 open("/etc/ld.so.cache",O_RDONLY|O_CLOEXEC) = 3 (snip)
代æ¿ã¨ãã¦ååãªçµæãå¾ããã¦ãããã¨ã確èªã§ããã
gdbã«ãããããã°
straceåæ§ãgdbãptraceã·ã¹ãã ã³ã¼ã«ã使ãããç´æ¥å©ç¨ãããã¨ãã§ããªãã ããã«ã¤ãã¦ããqemu-arm-staticã«GDBã®ãªã¢ã¼ããããã°ç¨ãªãã·ã§ã³ãç¨æããã¦ããã代æ¿ã¨ãã¦å©ç¨ãããã¨ãã§ããã
ã¾ããTCPã®1234çªãã¼ãã使ããªã¢ã¼ããããã°ã®æºåãããã
root@c7b94bb2fc1e:/# qemu-arm-static -g 1234 a.out & [1] 24 root@c7b94bb2fc1e:/# netstat -antp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:1234 0.0.0.0:* LISTEN -
次ã«ãgdbä¸ã§target remote :1234
ãå®è¡ãããã¨ã§LISTENç¶æ
ã®ãã¼ãã«æ¥ç¶ããã
ããã§ã¯gdbã®-ex
ãªãã·ã§ã³ã使ããgdbã®èµ·åã«åããã¦ãªã¢ã¼ããããã°ãéå§ããã
root@c7b94bb2fc1e:/# gdb -q -ex "target remote :1234" a.out Reading symbols from a.out...(no debugging symbols found)...done. Remote debugging using :1234 Reading symbols from /lib/ld-linux-armhf.so.3...Reading symbols from /usr/lib/debug//lib/arm-linux-gnueabihf/ld-2.19.so...done. done. Loaded symbols for /lib/ld-linux-armhf.so.3 0xf67debc0 in _start () from /lib/ld-linux-armhf.so.3 (gdb) disas Dump of assembler code for function _start: => 0xf67debc0 <+0>: ldr.w r10, [pc, #104] ; 0xf67dec2c <_dl_start_user+94> 0xf67debc4 <+4>: ldr.w r4, [pc, #104] ; 0xf67dec30 <_dl_start_user+98> 0xf67debc8 <+8>: mov r0, sp 0xf67debca <+10>: bl 0xf67e1880 <_dl_start> End of assembler dump. (gdb) b main Breakpoint 1 at 0x83f8 (gdb) c Continuing. Breakpoint 1, 0x000083f8 in main () (gdb) disas Dump of assembler code for function main: 0x000083f0 <+0>: push {r7, lr} 0x000083f2 <+2>: add r7, sp, #0 0x000083f4 <+4>: movw r0, #33880 ; 0x8458 => 0x000083f8 <+8>: movt r0, #0 0x000083fc <+12>: blx 0x82e4 <puts> 0x00008400 <+16>: movs r3, #0 0x00008402 <+18>: mov r0, r3 0x00008404 <+20>: pop {r7, pc} End of assembler dump. (gdb) c Continuing. Hello, world! [Inferior 1 (Remote target) exited normally] (gdb) quit [1]+ Done qemu-arm-static -g 1234 a.out
æ¥ç¶ã«æåãããã£ã¹ã¢ã»ã³ãã«çµæã¨ãã¦ARMå½ä»¤ã表示ããã¦ãããã¨ã確èªã§ããã
ã·ã§ã«é¢æ°ãå®ç¾©ãã¦ã¿ã
straceããã³gdbãæè»½ã«ä½¿ããããã«ããããã.bashrc
ã«æ¬¡ã®ãããªã·ã§ã«é¢æ°ãæ¸ãã¦ããã¨ä¾¿å©ã§ããã
if [[ -n "$PS1" ]]; then qemu-strace() { qemu-arm-static -strace "$@" } qemu-gdb() { qemu-arm-static -g 1234 "${!#}" <&0 & gdb -ex "target remote :1234" "$@" </dev/tty } fi
.bashrc
ã®èªã¿è¾¼ã¿ã®ãã䏿¦ã³ã³ãããç«ã¡ä¸ãç´ããå®éã«ä½¿ã£ã¦ã¿ãã¨æ¬¡ã®ããã«ãªãã
root@c7b94bb2fc1e:/# exit $ sudo docker start -a -i ubuntu-arm root@c7b94bb2fc1e:/# qemu-strace ./a.out 9 brk(NULL) = 0x00012000 9 uname(0xf6fff930) = 0 9 access("/etc/ld.so.nohwcap",F_OK) = -1 errno=2 (No such file or directory) 9 mmap2(NULL,8192,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0xf67dc000 9 access("/etc/ld.so.preload",R_OK) = -1 errno=2 (No such file or directory) 9 open("/etc/ld.so.cache",O_RDONLY|O_CLOEXEC) = 3 (snip) root@c7b94bb2fc1e:/# qemu-gdb -q ./a.out [1] 11 Reading symbols from ./a.out...(no debugging symbols found)...done. Remote debugging using :1234 Reading symbols from /lib/ld-linux-armhf.so.3...Reading symbols from /usr/lib/debug//lib/arm-linux-gnueabihf/ld-2.19.so...done. done. Loaded symbols for /lib/ld-linux-armhf.so.3 0xf67debc0 in _start () from /lib/ld-linux-armhf.so.3 (gdb) c Continuing. Hello, world! [Inferior 1 (Remote target) exited normally] (gdb) quit [1]+ Done qemu-arm-static -g 1234 "${!#}" 0<&0
ãªãã·ã§ã³æå®ãç°¡ç¥åãå®è¡ã§ãã¦ãããã¨ã確èªã§ããã