251 lines
6.4 KiB
Plaintext
251 lines
6.4 KiB
Plaintext
|
# iBoot gdb macros
|
||
|
#
|
||
|
# Vaguely inspired by the 'kgm' package.
|
||
|
#
|
||
|
|
||
|
set print asm-demangle on
|
||
|
set cp-abi gnu-v2
|
||
|
set kaslr-memory-search off
|
||
|
|
||
|
echo Loading iBoot GDB macros package. Type "help igm" for more info.\n
|
||
|
|
||
|
define igm
|
||
|
printf ""
|
||
|
echo These are the gdb macros for iBoot debugging. Type "help igm" for more info.\n
|
||
|
end
|
||
|
|
||
|
document igm
|
||
|
| These are the iBoot gdb macros. These gdb macros are intended to be
|
||
|
| used when debugging iBoot via jtag.
|
||
|
|
|
||
|
| The following macros are available in this package:
|
||
|
|
|
||
|
| showtasks Display a list of tasks
|
||
|
| switchtotask Switch to different task
|
||
|
| showallstacks Show stack of each tasks
|
||
|
|
|
||
|
| showheap Show blocks allocated in the heap
|
||
|
|
|
||
|
| Type "help <macro>" for more specific help on a particular macro.
|
||
|
| Type "show user <macro>" to see what the macro is really doing.
|
||
|
end
|
||
|
|
||
|
set $igm_mtype = sizeof(void *)
|
||
|
set $igm_lp64 = ($igm_mtype == 8)
|
||
|
|
||
|
# Print a pointer
|
||
|
define showptr
|
||
|
if ($igm_lp64)
|
||
|
printf "0x%016llx", $arg0
|
||
|
else
|
||
|
printf "0x%08x", $arg0
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# Traverse a list expected to be the queue_entry list from a task, and print anything
|
||
|
# found on the list that is not a task; it should be the event being waited on.
|
||
|
define print_non_tasks_in_list
|
||
|
set $igm_ntil_terminal = (struct list_node *)$arg0
|
||
|
set $igm_ntil_cursor = $igm_ntil_terminal->next
|
||
|
while ($igm_ntil_cursor != $igm_ntil_terminal)
|
||
|
if ($igm_lp64)
|
||
|
set $igm_ntil_task = (struct task *)((void *)$igm_ntil_cursor - 20)
|
||
|
if ($igm_ntil_task != 0x7461736b)
|
||
|
set $igm_ntil_event = (struct task_event *)((void *)$igm_ntil_cursor - 8)
|
||
|
showptr $igm_ntil_event
|
||
|
end
|
||
|
else
|
||
|
set $igm_ntil_task = (struct task *)((void *)$igm_ntil_cursor - 12)
|
||
|
if ($igm_ntil_task != 0x7461736b)
|
||
|
set $igm_ntil_event = (struct task_event *)((void *)$igm_ntil_cursor - 8)
|
||
|
showptr $igm_ntil_event
|
||
|
end
|
||
|
end
|
||
|
set $igm_ntil_cursor = $igm_ntil_cursor->next
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
define showtask
|
||
|
showptr $arg0
|
||
|
set $igm_task = (struct task *)$arg0
|
||
|
if (($igm_task->magic != 0x7461736b) || ($igm_task->magic2 != 0x74736b32))
|
||
|
printf " not a valid task\n"
|
||
|
else
|
||
|
printf " %16s: ", &$igm_task->name
|
||
|
if ($igm_task->state == 0)
|
||
|
printf "INITIAL"
|
||
|
end
|
||
|
if ($igm_task->state == 1)
|
||
|
printf "READY"
|
||
|
end
|
||
|
if ($igm_task->state == 2)
|
||
|
printf "RUNNING"
|
||
|
end
|
||
|
if ($igm_task->state == 3)
|
||
|
printf "BLOCKED on event "
|
||
|
print_non_tasks_in_list &$igm_task->queue_node
|
||
|
end
|
||
|
if ($igm_task->state == 4)
|
||
|
printf "SLEEPING for "
|
||
|
printf "%lluus ", $igm_task->sleep_callout.delay
|
||
|
printf "@ 0x%016llx", $igm_task->sleep_callout.sched_ticks
|
||
|
end
|
||
|
if ($igm_task->state == 5)
|
||
|
printf "FINISHED"
|
||
|
end
|
||
|
printf "\n"
|
||
|
end
|
||
|
end
|
||
|
|
||
|
define showtasks
|
||
|
showtask &bootstrap_task
|
||
|
set $igm_task_cursor = (struct list_node *)task_list->next
|
||
|
while $igm_task_cursor != &task_list
|
||
|
if ($igm_lp64)
|
||
|
set $igm_task_task = ((void *)$igm_task_cursor - 8)
|
||
|
else
|
||
|
set $igm_task_task = ((void *)$igm_task_cursor - 4)
|
||
|
end
|
||
|
showtask $igm_task_task
|
||
|
set $igm_task_cursor = $igm_task_cursor->next
|
||
|
end
|
||
|
end
|
||
|
|
||
|
document showtasks
|
||
|
| Print a summary listing of all tasks.
|
||
|
end
|
||
|
|
||
|
define dobacktrace
|
||
|
set $_task = (struct task*)$arg0
|
||
|
set $_fp = (void **)$_task->arch.fp
|
||
|
printf "%s: \n", $_task->name
|
||
|
while $_fp != 0
|
||
|
set $_pc = *($_fp + 1)
|
||
|
x/i $_pc
|
||
|
set $_fp = (void**)*$_fp
|
||
|
end
|
||
|
end
|
||
|
|
||
|
define showallstacks
|
||
|
if ($igm_lp64)
|
||
|
set $igm_task_cursor = (struct list_node *)task_list->next
|
||
|
while $igm_task_cursor != &task_list
|
||
|
if ($igm_lp64)
|
||
|
set $igm_task_task = ((void *)$igm_task_cursor - 8)
|
||
|
else
|
||
|
set $igm_task_task = ((void *)$igm_task_cursor - 4)
|
||
|
end
|
||
|
dobacktrace $igm_task_task
|
||
|
printf "-------------------------------------\n"
|
||
|
set $igm_task_cursor = $igm_task_cursor->next
|
||
|
end
|
||
|
else
|
||
|
printf "XXX Not supported yet\n"
|
||
|
end
|
||
|
end
|
||
|
|
||
|
document showallstacks
|
||
|
| Routine to print out the stack for each tasks in the system.
|
||
|
end
|
||
|
|
||
|
# XXX doesn't seems to work
|
||
|
define switchtotask
|
||
|
printf "XXX Not supported yet\n"
|
||
|
set $igm_newtask = (struct task *)$arg0
|
||
|
if (($igm_newtask->magic != 0x7461736b) || ($igm_newtask->magic2 != 0x74736b32))
|
||
|
printf "not a valid task\n"
|
||
|
else
|
||
|
if ($igm_lp64)
|
||
|
set $igm_arch_state = &$igm_newtask->arch
|
||
|
set $r16 = $igm_arch_state->regs[15]
|
||
|
set $r17 = $igm_arch_state->regs[16]
|
||
|
set $r19 = $igm_arch_state->regs[18]
|
||
|
set $r20 = $igm_arch_state->regs[19]
|
||
|
set $r21 = $igm_arch_state->regs[20]
|
||
|
set $r22 = $igm_arch_state->regs[21]
|
||
|
set $r23 = $igm_arch_state->regs[22]
|
||
|
set $r24 = $igm_arch_state->regs[23]
|
||
|
set $r25 = $igm_arch_state->regs[24]
|
||
|
set $r26 = $igm_arch_state->regs[25]
|
||
|
set $r27 = $igm_arch_state->regs[26]
|
||
|
set $r28 = $igm_arch_state->regs[27]
|
||
|
set $r29 = $igm_arch_state->fp
|
||
|
set $r30 = $igm_arch_state->lr
|
||
|
set $r31 = $igm_arch_state->sp
|
||
|
flushregs
|
||
|
flushstack
|
||
|
else
|
||
|
set $igm_arch_state = &$igm_newtask->arch
|
||
|
set $r4 = $igm_arch_state->regs[0]
|
||
|
set $r5 = $igm_arch_state->regs[1]
|
||
|
set $r6 = $igm_arch_state->regs[2]
|
||
|
set $r7 = $igm_arch_state->regs[3]
|
||
|
set $r8 = $igm_arch_state->regs[4]
|
||
|
set $r9 = $igm_arch_state->regs[5]
|
||
|
set $r10 = $igm_arch_state->regs[6]
|
||
|
set $r11 = $igm_arch_state->regs[7]
|
||
|
set $r13 = $igm_arch_state->regs[8]
|
||
|
set $r14 = $igm_arch_state->regs[9]
|
||
|
flushregs
|
||
|
flushstack
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
document switchtotask
|
||
|
Syntax: switchtotask <task address>
|
||
|
| Sets GDB's idea of the current task to <task address>
|
||
|
end
|
||
|
|
||
|
define show_heap_chunk
|
||
|
set $chunk_ptr = (struct chunk_data *)$arg0
|
||
|
printf "chunk @"
|
||
|
showptr $chunk_ptr->chunk_base
|
||
|
printf "/0x%x\n", $chunk_ptr->chunk_size
|
||
|
|
||
|
printf " block size type ptr len\n"
|
||
|
set $index = 1
|
||
|
while $index != 0
|
||
|
|
||
|
# compute the block pointer from the index
|
||
|
set $block_ptr = (struct heap_block *)($chunk_ptr->chunk_base + $index)
|
||
|
|
||
|
if $block_ptr->this_size == 1
|
||
|
# this is the end of the chunk
|
||
|
loop_break
|
||
|
end
|
||
|
|
||
|
# print block address and size
|
||
|
showptr $block_ptr
|
||
|
printf " 0x%08x", $block_ptr->this_size
|
||
|
|
||
|
# decode and print block contents
|
||
|
if $block_ptr->this_free != 0
|
||
|
printf " free "
|
||
|
else
|
||
|
printf " malloc "
|
||
|
showptr $block_ptr + 1
|
||
|
end
|
||
|
printf " 0x%08x\n", ($block_ptr->this_size - 1) * sizeof(struct heap_block)
|
||
|
|
||
|
# XXX range-check
|
||
|
set $index = $index + $block_ptr->this_size
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
define showheap
|
||
|
# Iterate chunks and print these first
|
||
|
# XXX might be good to have the heap use more unique names
|
||
|
set $chunk_iterator = 0
|
||
|
while $chunk_iterator < chunk_count
|
||
|
show_heap_chunk &lead[$chunk_iterator]
|
||
|
set $chunk_iterator = $chunk_iterator + 1
|
||
|
end
|
||
|
end
|
||
|
|
||
|
document showheap
|
||
|
| Print the contents of the heap.
|
||
|
end
|