链接程序和库指南

调试器导入接口

控制进程必须提供给 librtld_db.so.1 的导入接口在 /usr/include/proc_service.h 中定义。可以在 rdb 演示调试器中找到这些 proc_service 函数的实现样例。rtld-debugger 接口仅使用一部分可用的 proc_service 接口。将来版本的 rtld-debugger 接口可能会利用其他 proc_service 接口,而不会创建不兼容的更改。

当前 rtld-debugger 接口会使用以下接口:

ps_pauxv()

此函数可返回指向 auxv 向量副本的指针。

ps_err_e ps_pauxv(const struct ps_prochandle * ph, auxv_t ** aux);

由于 auxv 向量信息会复制到已分配的结构,因此只要 ps_prochandle 有效,便会保留指针。

ps_pread()

此函数可从目标进程中读取数据。


ps_err_e ps_pread(const struct ps_prochandle * ph, paddr_t addr,

        char * buf, int size);

size 字节从目标进程中的地址 addr 复制到 buf

ps_pwrite()

此函数可将数据写入目标进程。

ps_err_e ps_pwrite(const struct ps_prochandle * ph, paddr_t addr,

        char * buf, int size);

size 字节从 buf 复制到目标进程的地址 addr

ps_plog()

此函数通过 rtld-debugger 接口中的其他诊断信息调用。

void ps_plog(const char * fmt, ...);

控制进程会确定在何处或者是否记录此诊断信息。ps_plog() 的参数采用 printf(3C) 格式。

ps_pglobal_lookup()

此函数可在目标进程中搜索符号。

ps_err_e ps_pglobal_lookup(const struct ps_prochandle * ph,

        const char * obj, const char * name, ulong_t * sym_addr);

在目标进程 ph 的名为 obj 的目标文件内搜索名为 name 的符号。如果找到此符号,则将符号地址存储在 sym_addr 中。

ps_pglobal_sym()

此函数可在目标进程中搜索符号。

ps_err_e ps_pglobal_sym(const struct ps_prochandle * ph,

        const char * obj, const char * name, ps_sym_t * sym_desc);

在目标进程 ph 的名为 obj 的目标文件内搜索名为 name 的符号。如果找到此符号,则将符号描述符存储在 sym_desc 中。

如果在创建任何链接映射之前, rtld-debugger 接口需要在应用程序或运行时链接程序内查找符号,则可以使用 obj 的以下保留值:

#define PS_OBJ_EXEC ((const char *)0x0)  /* application id */

#define PS_OBJ_LDSO ((const char *)0x1)  /* runtime linker id */

控制进程可以使用以下伪代码将 procfs 文件系统用于这些目标文件:

ioctl(.., PIOCNAUXV, ...)       - obtain AUX vectors

ldsoaddr = auxv[AT_BASE];

ldsofd = ioctl(..., PIOCOPENM, &ldsoaddr);

 

/* process elf information found in ldsofd ... */

 

execfd = ioctl(.., PIOCOPENM, 0);

 

/* process elf information found in execfd ... */

找到文件描述符之后,控制程序即可检查 ELF 文件来查找其符号信息。