sysconf
一、实现简介
1. Android Bionic 中 sysconf(_SC_PAGE_SIZE) 的实现
Android 使用 Bionic libc(非 glibc),实现路径有明显差异。总体链路:
sysconf(_SC_PAGE_SIZE) //bionic/libc/bionic/sysconf.cpp getauxval(AT_PAGESZ) //bionic/libc/bionic/getauxval.cpp 遍历 __libc_auxv[] //全局指针,指向初始栈上的 auxv ^ | 由 linker 在 execve 后、main() 前保存 ^ | 内核 create_elf_tables() //fs/binfmt_elf.c NEW_AUX_ENT(AT_PAGESZ, PAGE_SIZE) //编译期常量(如 4096)
结论:整个调用链零系统调用,最终就是遍历栈上内存中的一个小数组,找到 AT_PAGESZ 条目返回其值。
2. sysconf() 实现代码
//bionic/libc/bionic/sysconf.cpp long sysconf(int name) { switch (name) { case _SC_PAGESIZE: case _SC_PAGE_SIZE: return static_cast<long>(getauxval(AT_PAGESZ)); ... } }
getauxval() 实现:
//bionic/libc/bionic/getauxval.cpp extern "C" unsigned long getauxval(unsigned long type) { bool exists; unsigned long result = __bionic_getauxval(type, &exists); if (!exists) errno = ENOENT; return result; } __LIBC_HIDDEN__ unsigned long __bionic_getauxval(unsigned long type, bool* exists) { for (ElfW(auxv_t)* v = __libc_shared_globals()->auxv; v->a_type != AT_NULL; ++v) { if (v->a_type == type) { *exists = true; return v->a_un.a_val; } } *exists = false; return 0; }
__libc_shared_globals() 应该返回一个全局指针,指向初始栈上的辅助向量数组。
3. 全局指针的设置 — Bionic linker启动阶段
Android 的动态链接器 (/system/bin/linker64) 在 main() 之前运行,负责初始化 libc。进程启动时的初始栈布局(内核设置):
SP → argc argv[0..n] 指针数组 envp[0..m] 指针数组 auxv[] 辅助向量 <-- AT_PAGESZ=4096 在这里 AT_NULL 结束标志
实现位置:
//bionic/linker/linker_main.cpp linker的入口,内核跳入这里 extern "C" ElfW(Addr) __linker_init(void* raw_args) { KernelArgumentBlock args(raw_args); //args.auxv 指向栈上的 auxv 数组 ... } //bionic/libc/bionic/libc_init_dynamic.cpp(libc 初始化): __attribute__((constructor)) static void __libc_preinit(void) { // 从 linker 传递过来的 auxv 指针赋给全局变量,保存 auxv 指针,供后续 getauxval() 使用 __libc_auxv = ...; }
注: mm_struct 中的 saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */ 存储了这些信息。
posted on 2026-04-10 11:43 Hello-World3 阅读(0) 评论(0) 收藏 举报
浙公网安备 33010602011771号