This is the DWARF for the first successfully-executed GNU Infinity note, as described here. It’s a reimplementation of the libthread_db function
# Input stack: # 0: lwpid # 1: pid # 2: __stack_user 0: DW_OP_pick 2 2: DW_OP_deref 3: DW_OP_bra libpthread_is_initialized 6: DW_OP_eq 7: DW_OP_bra is_main_thread 10: DW_OP_lit1 # TD_ERR 11: DW_OP_skip to end is_main_thread: 14: DW_OP_drop 15: DW_OP_lit0 # NULL 16: DW_OP_lit0 # TD_OK 17: DW_OP_skip to end libpthread_is_initialized: 20: DW_OP_lit25 # FS 21: DW_OP_GNU_get_thread_area 22: DW_OP_bra get_thread_area_failed 25: DW_OP_rot 26: DW_OP_drop 27: DW_OP_drop 28: DW_OP_lit0 # TD_OK 29: DW_OP_skip to end get_thread_area_failed: 32: DW_OP_drop 33: DW_OP_drop 34: DW_OP_lit1 # TD_ERR # Output stack: # 0: TD_OK or TD_ERR # 1: if TD_OK: handle used to identify thread # else: undefined
This is valid for all
CONST_THREAD_AREA architectures, i.e. arm, aarch64, mips, microblaze, m68k and x86_64.
REGISTER_THREAD_AREA architectures will differ following
libpthread_is_initialized. x86_64 could theoretically have its own implementation using
DW_OP_bregx 0(%fs.base) but GDB doesn’t know about
%fs.base right now so that’s an optimization for the future.
__stack_user on the stack is an automatic argument. Function notes have a list of automatic arguments that are pushed to the stack, currently before the user pushes their arguments but I may rearrange that so that automatic arguments come after. The caller just pushes PID and LWPID and calls the function.
Infinity functions are going to have to be able to call other functions if I’m going to replace
td_ta_thr_iter–which I am. Once that’s in the
DW_OP_GNU_get_thread_area extension will be replaced by some “call Infinity function” extension, with
ps_get_thread_area being a special function provided by the infrastructure. That’s probably the only DWARF extension Infinity will need. I’ll likely replace the PID argument here with a second special function
ps_getpid too. The PID argument works quite naturally here, but it’s required in other places where it’s not so natural.
I don’t have a compiler/assembler for this yet. I got the above code into libpthread.so by embedding a bunch of assembler in one of the C source files. I will write something to generate functions more conveniently and once this done only the
INFINITY_EXPORT lines will exist in glibc’s C sources.