---
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 畫面

* 對應 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