Lines Matching +full:frame +full:- +full:number
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2009 Matt Fleming <matt@console-pimps.org>
10 * - DWARF64 doesn't work.
11 * - Registers with DWARF_VAL_OFFSET rules aren't handled properly.
32 /* ... with 4 registers per frame. */
52 * dwarf_frame_alloc_reg - allocate memory for a DWARF register
53 * @frame: the DWARF frame whose list of registers we insert on
54 * @reg_num: the register number
57 * dwarf_reg_pool and insert it onto the (unsorted) linked-list of
58 * dwarf registers for @frame.
62 static struct dwarf_reg *dwarf_frame_alloc_reg(struct dwarf_frame *frame, in dwarf_frame_alloc_reg() argument
77 reg->number = reg_num; in dwarf_frame_alloc_reg()
78 reg->addr = 0; in dwarf_frame_alloc_reg()
79 reg->flags = 0; in dwarf_frame_alloc_reg()
81 list_add(®->link, &frame->reg_list); in dwarf_frame_alloc_reg()
86 static void dwarf_frame_free_regs(struct dwarf_frame *frame) in dwarf_frame_free_regs() argument
90 list_for_each_entry_safe(reg, n, &frame->reg_list, link) { in dwarf_frame_free_regs()
91 list_del(®->link); in dwarf_frame_free_regs()
97 * dwarf_frame_reg - return a DWARF register
98 * @frame: the DWARF frame to search in for @reg_num
99 * @reg_num: the register number to search for
101 * Lookup and return the dwarf reg @reg_num for this frame. Return
102 * NULL if @reg_num is an register invalid number.
104 static struct dwarf_reg *dwarf_frame_reg(struct dwarf_frame *frame, in dwarf_frame_reg() argument
109 list_for_each_entry(reg, &frame->reg_list, link) { in dwarf_frame_reg()
110 if (reg->number == reg_num) in dwarf_frame_reg()
118 * dwarf_read_addr - read dwarf data
123 * the native machine. We return the number of bytes read, which
126 * aligned. Return 'n' - the number of bytes read.
136 * dwarf_read_uleb128 - read unsigned LEB128 data
142 * encodings refer to section "7.6 - Variable Length Data". Return
143 * the number of bytes read.
173 * dwarf_read_leb128 - read signed LEB128 data
178 * C of the DWARF 3 spec. Return the number of bytes read.
202 /* The number of bits in a signed integer. */ in dwarf_read_leb128()
206 result |= (-1 << shift); in dwarf_read_leb128()
214 * dwarf_read_encoded_value - return the decoded value at @addr
221 * to @val and the number of bytes read is returned.
259 * dwarf_entry_len - return the length of an FDE or CIE
264 * the entry in @len. We return the number of bytes read. Return a
276 * An initial length field value in the range DW_LEN_EXT_LO - in dwarf_entry_len()
283 * The 64-bit length field immediately follows the in dwarf_entry_len()
284 * compulsory 32-bit length field. in dwarf_entry_len()
300 * dwarf_lookup_cie - locate the cie
315 if (cached_cie && cached_cie->cie_pointer == cie_ptr) { in dwarf_lookup_cie()
326 if (cie_ptr == cie_tmp->cie_pointer) { in dwarf_lookup_cie()
331 if (cie_ptr < cie_tmp->cie_pointer) in dwarf_lookup_cie()
332 rb_node = &(*rb_node)->rb_left; in dwarf_lookup_cie()
334 rb_node = &(*rb_node)->rb_right; in dwarf_lookup_cie()
344 * dwarf_lookup_fde - locate the FDE that covers pc
362 tmp_start = fde_tmp->initial_location; in dwarf_lookup_fde()
363 tmp_end = fde_tmp->initial_location + fde_tmp->address_range; in dwarf_lookup_fde()
366 rb_node = &(*rb_node)->rb_left; in dwarf_lookup_fde()
372 rb_node = &(*rb_node)->rb_right; in dwarf_lookup_fde()
383 * dwarf_cfa_execute_insns - execute instructions to calculate a CFA
388 * @frame: the instructions calculate the CFA for this frame
391 * Execute the Call Frame instruction sequence starting at
393 * how to calculate the Canonical Frame Address of a stackframe.
394 * Store the results in @frame.
400 struct dwarf_frame *frame, in dwarf_cfa_execute_insns() argument
410 while (current_insn < insn_end && frame->pc <= pc) { in dwarf_cfa_execute_insns()
420 delta *= cie->code_alignment_factor; in dwarf_cfa_execute_insns()
421 frame->pc += delta; in dwarf_cfa_execute_insns()
428 offset *= cie->data_alignment_factor; in dwarf_cfa_execute_insns()
429 regp = dwarf_frame_alloc_reg(frame, reg); in dwarf_cfa_execute_insns()
430 regp->addr = offset; in dwarf_cfa_execute_insns()
431 regp->flags |= DWARF_REG_OFFSET; in dwarf_cfa_execute_insns()
449 frame->pc += delta * cie->code_alignment_factor; in dwarf_cfa_execute_insns()
454 frame->pc += delta * cie->code_alignment_factor; in dwarf_cfa_execute_insns()
459 frame->pc += delta * cie->code_alignment_factor; in dwarf_cfa_execute_insns()
466 offset *= cie->data_alignment_factor; in dwarf_cfa_execute_insns()
475 regp = dwarf_frame_alloc_reg(frame, reg); in dwarf_cfa_execute_insns()
476 regp->flags |= DWARF_UNDEFINED; in dwarf_cfa_execute_insns()
480 &frame->cfa_register); in dwarf_cfa_execute_insns()
483 &frame->cfa_offset); in dwarf_cfa_execute_insns()
486 frame->flags |= DWARF_FRAME_CFA_REG_OFFSET; in dwarf_cfa_execute_insns()
490 &frame->cfa_register); in dwarf_cfa_execute_insns()
492 frame->flags |= DWARF_FRAME_CFA_REG_OFFSET; in dwarf_cfa_execute_insns()
497 frame->cfa_offset = offset; in dwarf_cfa_execute_insns()
503 frame->cfa_expr = current_insn; in dwarf_cfa_execute_insns()
504 frame->cfa_expr_len = expr_len; in dwarf_cfa_execute_insns()
507 frame->flags |= DWARF_FRAME_CFA_REG_EXP; in dwarf_cfa_execute_insns()
514 offset *= cie->data_alignment_factor; in dwarf_cfa_execute_insns()
515 regp = dwarf_frame_alloc_reg(frame, reg); in dwarf_cfa_execute_insns()
516 regp->flags |= DWARF_REG_OFFSET; in dwarf_cfa_execute_insns()
517 regp->addr = offset; in dwarf_cfa_execute_insns()
523 offset *= cie->data_alignment_factor; in dwarf_cfa_execute_insns()
524 regp = dwarf_frame_alloc_reg(frame, reg); in dwarf_cfa_execute_insns()
525 regp->flags |= DWARF_VAL_OFFSET; in dwarf_cfa_execute_insns()
526 regp->addr = offset; in dwarf_cfa_execute_insns()
536 offset *= cie->data_alignment_factor; in dwarf_cfa_execute_insns()
538 regp = dwarf_frame_alloc_reg(frame, reg); in dwarf_cfa_execute_insns()
539 regp->flags |= DWARF_REG_OFFSET; in dwarf_cfa_execute_insns()
540 regp->addr = -offset; in dwarf_cfa_execute_insns()
553 * dwarf_free_frame - free the memory allocated for @frame
554 * @frame: the frame to free
556 void dwarf_free_frame(struct dwarf_frame *frame) in dwarf_free_frame() argument
558 dwarf_frame_free_regs(frame); in dwarf_free_frame()
559 mempool_free(frame, dwarf_frame_pool); in dwarf_free_frame()
565 * dwarf_unwind_stack - unwind the stack
570 * Return a struct dwarf_frame representing the most recent frame
577 struct dwarf_frame *frame; in dwarf_unwind_stack() local
612 pc = ret_stack->ret; in dwarf_unwind_stack()
623 frame = mempool_alloc(dwarf_frame_pool, GFP_ATOMIC); in dwarf_unwind_stack()
624 if (!frame) { in dwarf_unwind_stack()
625 printk(KERN_ERR "Unable to allocate a dwarf frame\n"); in dwarf_unwind_stack()
629 INIT_LIST_HEAD(&frame->reg_list); in dwarf_unwind_stack()
630 frame->flags = 0; in dwarf_unwind_stack()
631 frame->prev = prev; in dwarf_unwind_stack()
632 frame->return_addr = 0; in dwarf_unwind_stack()
640 * a) pc has no asscociated DWARF frame info and so in dwarf_unwind_stack()
641 * we don't know how to unwind this frame. This is in dwarf_unwind_stack()
643 * frame that was called from some assembly code in dwarf_unwind_stack()
654 cie = dwarf_lookup_cie(fde->cie_pointer); in dwarf_unwind_stack()
656 frame->pc = fde->initial_location; in dwarf_unwind_stack()
659 dwarf_cfa_execute_insns(cie->initial_instructions, in dwarf_unwind_stack()
660 cie->instructions_end, cie, fde, in dwarf_unwind_stack()
661 frame, pc); in dwarf_unwind_stack()
664 dwarf_cfa_execute_insns(fde->instructions, fde->end, cie, in dwarf_unwind_stack()
665 fde, frame, pc); in dwarf_unwind_stack()
668 switch (frame->flags) { in dwarf_unwind_stack()
671 reg = dwarf_frame_reg(prev, frame->cfa_register); in dwarf_unwind_stack()
673 UNWINDER_BUG_ON(reg->flags != DWARF_REG_OFFSET); in dwarf_unwind_stack()
675 addr = prev->cfa + reg->addr; in dwarf_unwind_stack()
676 frame->cfa = __raw_readl(addr); in dwarf_unwind_stack()
683 * the Canonical Frame Address for this in dwarf_unwind_stack()
686 frame->cfa = dwarf_read_arch_reg(frame->cfa_register); in dwarf_unwind_stack()
689 frame->cfa += frame->cfa_offset; in dwarf_unwind_stack()
695 reg = dwarf_frame_reg(frame, DWARF_ARCH_RA_REG); in dwarf_unwind_stack()
702 if (!reg || reg->flags == DWARF_UNDEFINED) in dwarf_unwind_stack()
705 UNWINDER_BUG_ON(reg->flags != DWARF_REG_OFFSET); in dwarf_unwind_stack()
707 addr = frame->cfa + reg->addr; in dwarf_unwind_stack()
708 frame->return_addr = __raw_readl(addr); in dwarf_unwind_stack()
713 * Interrupts are tricky - the DWARF info needs to be _really_ in dwarf_unwind_stack()
716 * just after the frame pointer (r14) had been restored. The in dwarf_unwind_stack()
718 * reached by using the value of the frame pointer before it was in dwarf_unwind_stack()
725 if (prev && prev->pc == (unsigned long)ret_from_irq) in dwarf_unwind_stack()
726 frame->return_addr = 0; in dwarf_unwind_stack()
728 return frame; in dwarf_unwind_stack()
731 dwarf_free_frame(frame); in dwarf_unwind_stack()
746 return -ENOMEM; in dwarf_parse_cie()
748 cie->length = len; in dwarf_parse_cie()
756 cie->cie_pointer = (unsigned long)entry; in dwarf_parse_cie()
758 cie->version = *(char *)p++; in dwarf_parse_cie()
759 UNWINDER_BUG_ON(cie->version != 1); in dwarf_parse_cie()
761 cie->augmentation = p; in dwarf_parse_cie()
762 p += strlen(cie->augmentation) + 1; in dwarf_parse_cie()
764 count = dwarf_read_uleb128(p, &cie->code_alignment_factor); in dwarf_parse_cie()
767 count = dwarf_read_leb128(p, &cie->data_alignment_factor); in dwarf_parse_cie()
774 if (cie->version == 1) { in dwarf_parse_cie()
775 cie->return_address_reg = __raw_readb(p); in dwarf_parse_cie()
778 count = dwarf_read_uleb128(p, &cie->return_address_reg); in dwarf_parse_cie()
782 if (cie->augmentation[0] == 'z') { in dwarf_parse_cie()
784 cie->flags |= DWARF_CIE_Z_AUGMENTATION; in dwarf_parse_cie()
791 cie->initial_instructions = p + length; in dwarf_parse_cie()
792 cie->augmentation++; in dwarf_parse_cie()
795 while (*cie->augmentation) { in dwarf_parse_cie()
800 if (*cie->augmentation == 'L') { in dwarf_parse_cie()
802 cie->augmentation++; in dwarf_parse_cie()
803 } else if (*cie->augmentation == 'R') { in dwarf_parse_cie()
809 cie->encoding = *(char *)p++; in dwarf_parse_cie()
810 cie->augmentation++; in dwarf_parse_cie()
811 } else if (*cie->augmentation == 'P') { in dwarf_parse_cie()
818 } else if (*cie->augmentation == 'S') { in dwarf_parse_cie()
825 p = cie->initial_instructions; in dwarf_parse_cie()
831 cie->initial_instructions = p; in dwarf_parse_cie()
832 cie->instructions_end = end; in dwarf_parse_cie()
844 if (cie->cie_pointer < cie_tmp->cie_pointer) in dwarf_parse_cie()
845 rb_node = &parent->rb_left; in dwarf_parse_cie()
846 else if (cie->cie_pointer >= cie_tmp->cie_pointer) in dwarf_parse_cie()
847 rb_node = &parent->rb_right; in dwarf_parse_cie()
852 rb_link_node(&cie->node, parent, rb_node); in dwarf_parse_cie()
853 rb_insert_color(&cie->node, &cie_root); in dwarf_parse_cie()
857 list_add_tail(&cie->link, &mod->arch.cie_list); in dwarf_parse_cie()
879 return -ENOMEM; in dwarf_parse_fde()
881 fde->length = len; in dwarf_parse_fde()
887 fde->cie_pointer = (unsigned long)(p - entry_type - 4); in dwarf_parse_fde()
889 cie = dwarf_lookup_cie(fde->cie_pointer); in dwarf_parse_fde()
890 fde->cie = cie; in dwarf_parse_fde()
892 if (cie->encoding) in dwarf_parse_fde()
893 count = dwarf_read_encoded_value(p, &fde->initial_location, in dwarf_parse_fde()
894 cie->encoding); in dwarf_parse_fde()
896 count = dwarf_read_addr(p, &fde->initial_location); in dwarf_parse_fde()
900 if (cie->encoding) in dwarf_parse_fde()
901 count = dwarf_read_encoded_value(p, &fde->address_range, in dwarf_parse_fde()
902 cie->encoding & 0x0f); in dwarf_parse_fde()
904 count = dwarf_read_addr(p, &fde->address_range); in dwarf_parse_fde()
908 if (fde->cie->flags & DWARF_CIE_Z_AUGMENTATION) { in dwarf_parse_fde()
914 /* Call frame instructions. */ in dwarf_parse_fde()
915 fde->instructions = p; in dwarf_parse_fde()
916 fde->end = end; in dwarf_parse_fde()
928 start = fde->initial_location; in dwarf_parse_fde()
929 end = fde->initial_location + fde->address_range; in dwarf_parse_fde()
931 tmp_start = fde_tmp->initial_location; in dwarf_parse_fde()
932 tmp_end = fde_tmp->initial_location + fde_tmp->address_range; in dwarf_parse_fde()
937 rb_node = &parent->rb_left; in dwarf_parse_fde()
939 rb_node = &parent->rb_right; in dwarf_parse_fde()
944 rb_link_node(&fde->node, parent, rb_node); in dwarf_parse_fde()
945 rb_insert_color(&fde->node, &fde_root); in dwarf_parse_fde()
949 list_add_tail(&fde->link, &mod->arch.fde_list); in dwarf_parse_fde()
963 struct dwarf_frame *frame, *_frame; in dwarf_unwinder_dump() local
970 frame = dwarf_unwind_stack(return_addr, _frame); in dwarf_unwinder_dump()
975 _frame = frame; in dwarf_unwinder_dump()
977 if (!frame || !frame->return_addr) in dwarf_unwinder_dump()
980 return_addr = frame->return_addr; in dwarf_unwinder_dump()
981 ops->address(data, return_addr, 1); in dwarf_unwinder_dump()
984 if (frame) in dwarf_unwinder_dump()
985 dwarf_free_frame(frame); in dwarf_unwinder_dump()
989 .name = "dwarf-unwinder",
1017 * dwarf_parse_section - parse DWARF section
1050 err = -EINVAL; in dwarf_parse_section()
1094 char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; in module_dwarf_finalize()
1098 for (i = 1; i < hdr->e_shnum; i++) { in module_dwarf_finalize()
1109 if (i != hdr->e_shnum) { in module_dwarf_finalize()
1110 INIT_LIST_HEAD(&me->arch.cie_list); in module_dwarf_finalize()
1111 INIT_LIST_HEAD(&me->arch.fde_list); in module_dwarf_finalize()
1115 me->name); in module_dwarf_finalize()
1124 * module_dwarf_cleanup - remove FDE/CIEs associated with @mod
1138 list_for_each_entry_safe(cie, ctmp, &mod->arch.cie_list, link) { in module_dwarf_cleanup()
1139 list_del(&cie->link); in module_dwarf_cleanup()
1140 rb_erase(&cie->node, &cie_root); in module_dwarf_cleanup()
1148 list_for_each_entry_safe(fde, ftmp, &mod->arch.fde_list, link) { in module_dwarf_cleanup()
1149 list_del(&fde->link); in module_dwarf_cleanup()
1150 rb_erase(&fde->node, &fde_root); in module_dwarf_cleanup()
1159 * dwarf_unwinder_init - initialise the dwarf unwinder
1169 int err = -ENOMEM; in dwarf_unwinder_init()