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)    收藏  举报

导航