--- title: uClibc ld.so source code 解析 tags: uClibc lang: zh_tw --- # uClibc `ld.so` source code 解析 * 版本: 0.9.33.2 * binary 是從 NETGEAR R9000 Firmware 中取出 * source code 從網路下載 ## Start * 先上 IDA 畫面 ![](https://i.imgur.com/gltqgtY.png) * 對應 source code 位於 `ldso/ldso/arm/dl-startup.h` ```c #if !defined(__thumb__) __asm__( " .text\n" " .globl _start\n" " .type _start,%function\n" "_start:\n" " @ at start time, all the args are on the stack\n" " mov r0, sp\n" " bl _dl_start\n" " @ returns user entry point in r0\n" " mov r6, r0\n" " @ we are PIC code, so get global offset table\n" " ldr sl, .L_GET_GOT\n" " add sl, pc, sl\n" ".L_GOT_GOT:\n" " @ See if we were run as a command with the executable file\n" " @ name as an extra leading argument.\n" " ldr r4, .L_SKIP_ARGS\n" " ldr r4, [sl, r4]\n" " @ get the original arg count\n" " ldr r1, [sp]\n" " @ subtract _dl_skip_args from it\n" " sub r1, r1, r4\n" " @ adjust the stack pointer to skip them\n" " add sp, sp, r4, lsl #2\n" " @ get the argv address\n" " add r2, sp, #4\n" " @ store the new argc in the new stack location\n" " str r1, [sp]\n" " @ compute envp\n" " add r3, r2, r1, lsl #2\n" " add r3, r3, #4\n" "\n\n" " @ load the finalizer function\n" " ldr r0, .L_FINI_PROC\n" " ldr r0, [sl, r0]\n" " @ jump to the user_s entry point\n" #if defined(__USE_BX__) " bx r6\n" #else " mov pc, r6\n" #endif ".L_GET_GOT:\n" " .word _GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n" ".L_SKIP_ARGS:\n" " .word _dl_skip_args(GOTOFF)\n" ".L_FINI_PROC:\n" " .word _dl_fini(GOT)\n" "\n\n" " .size _start,.-_start\n" ".previous\n" ); #else ``` * 從註解可以看出來最後一行是移動到 user entry point