Lines Matching +full:reg +full:- +full:offset

1 /* SPDX-License-Identifier: GPL-2.0 */
14 #include "annotate-data.h"
18 #include "dwarf-regs.h"
83 static void pr_debug_location(Dwarf_Die *die, u64 pc, int reg) in pr_debug_location() argument
98 if (reg != DWARF_REG_PC && end <= pc) in pr_debug_location()
100 if (reg != DWARF_REG_PC && start > pc) in pr_debug_location()
104 switch (ops->atom) { in pr_debug_location()
106 pr_info("reg%d\n", ops->atom - DW_OP_reg0); in pr_debug_location()
109 pr_info("base=reg%d, offset=%#lx\n", in pr_debug_location()
110 ops->atom - DW_OP_breg0, (long)ops->number); in pr_debug_location()
113 pr_info("reg%ld\n", (long)ops->number); in pr_debug_location()
116 pr_info("base=reg%ld, offset=%#lx\n", in pr_debug_location()
117 (long)ops->number, (long)ops->number2); in pr_debug_location()
120 pr_info("use frame base, offset=%#lx\n", (long)ops->number); in pr_debug_location()
123 pr_info("address=%#lx\n", (long)ops->number); in pr_debug_location()
127 ops->atom, (long)ops->number); in pr_debug_location()
154 bool has_reg_type(struct type_state *state, int reg) in has_reg_type() argument
156 return (unsigned)reg < ARRAY_SIZE(state->regs); in has_reg_type()
162 INIT_LIST_HEAD(&state->stack_vars); in init_type_state()
165 state->regs[0].caller_saved = true; in init_type_state()
166 state->regs[1].caller_saved = true; in init_type_state()
167 state->regs[2].caller_saved = true; in init_type_state()
168 state->regs[4].caller_saved = true; in init_type_state()
169 state->regs[5].caller_saved = true; in init_type_state()
170 state->regs[8].caller_saved = true; in init_type_state()
171 state->regs[9].caller_saved = true; in init_type_state()
172 state->regs[10].caller_saved = true; in init_type_state()
173 state->regs[11].caller_saved = true; in init_type_state()
174 state->ret_reg = 0; in init_type_state()
175 state->stack_reg = X86_REG_SP; in init_type_state()
183 list_for_each_entry_safe(stack, tmp, &state->stack_vars, list) { in exit_type_state()
184 list_del(&stack->list); in exit_type_state()
193 * offset of the type entry in the .debug_info section.
202 if (key->self.size != type->self.size) in data_type_cmp()
203 return key->self.size - type->self.size; in data_type_cmp()
204 return strcmp(key->self.type_name, type->self.type_name); in data_type_cmp()
214 if (a->self.size != b->self.size) in data_type_less()
215 return a->self.size < b->self.size; in data_type_less()
216 return strcmp(a->self.type_name, b->self.type_name) < 0; in data_type_less()
264 member->type_name = strbuf_detach(&sb, NULL); in __add_member_cb()
265 /* member->var_name can be NULL */ in __add_member_cb()
268 if (asprintf(&member->var_name, "%s:%ld", in __add_member_cb()
270 member->var_name = NULL; in __add_member_cb()
272 member->var_name = strdup(dwarf_diename(die)); in __add_member_cb()
275 if (member->var_name == NULL) { in __add_member_cb()
280 member->size = size; in __add_member_cb()
281 member->offset = loc + parent->offset; in __add_member_cb()
282 INIT_LIST_HEAD(&member->children); in __add_member_cb()
283 list_add_tail(&member->node, &parent->children); in __add_member_cb()
301 die_find_child(type, __add_member_cb, &parent->self, &die_mem); in add_member_types()
308 list_for_each_entry_safe(child, tmp, &member->children, node) { in delete_members()
309 list_del(&child->node); in delete_members()
311 zfree(&child->type_name); in delete_members()
312 zfree(&child->var_name); in delete_members()
337 /* Check existing nodes in dso->data_types tree */ in dso__findnew_data_type()
354 result->self.type_name = type_name; in dso__findnew_data_type()
355 result->self.size = size; in dso__findnew_data_type()
356 INIT_LIST_HEAD(&result->self.children); in dso__findnew_data_type()
361 rb_add(&result->node, dso__data_types(dso), data_type_less); in dso__findnew_data_type()
370 if (dwarf_addrdie(di->dbg, pc, cu_die) != NULL) in find_cu_die()
379 while (dwarf_nextcu(di->dbg, off, &next_off, &header_size, in find_cu_die()
381 if (dwarf_offdie(di->dbg, off + header_size, cu_die) && in find_cu_die()
412 return "offset bigger than size"; in match_result_str()
480 Dwarf_Die *type_die, int reg, in check_variable() argument
481 int offset, bool is_fbreg) in check_variable() argument
487 if (reg == DWARF_REG_PC) in check_variable()
489 else if (reg == dloc->fbreg || is_fbreg) in check_variable()
491 else if (arch__is(dloc->arch, "x86") && reg == X86_REG_SP) in check_variable()
519 if ((unsigned)offset >= size) in check_variable()
526 int offset) in find_stack_state() argument
530 list_for_each_entry(stack, &state->stack_vars, list) { in find_stack_state()
531 if (offset == stack->offset) in find_stack_state()
534 if (stack->compound && stack->offset < offset && in find_stack_state()
535 offset < stack->offset + stack->size) in find_stack_state()
541 void set_stack_state(struct type_state_stack *stack, int offset, u8 kind, in set_stack_state() argument
552 stack->type = *type_die; in set_stack_state()
553 stack->size = size; in set_stack_state()
554 stack->offset = offset; in set_stack_state()
555 stack->kind = kind; in set_stack_state()
560 stack->compound = (kind != TSR_KIND_POINTER); in set_stack_state()
563 stack->compound = false; in set_stack_state()
569 int offset, u8 kind, in findnew_stack_state() argument
572 struct type_state_stack *stack = find_stack_state(state, offset); in findnew_stack_state()
575 set_stack_state(stack, offset, kind, type_die); in findnew_stack_state()
581 set_stack_state(stack, offset, kind, type_die); in findnew_stack_state()
582 list_add(&stack->list, &state->stack_vars); in findnew_stack_state()
603 if (gvar->start <= addr && addr < gvar->end) in global_var_cmp()
605 return gvar->start > addr ? -1 : 1; in global_var_cmp()
615 return gvar_a->start < gvar_b->start; in global_var_less()
620 struct dso *dso = map__dso(dloc->ms->map); in global_var__find()
633 struct dso *dso = map__dso(dloc->ms->map); in global_var__add()
644 gvar->name = name ? strdup(name) : NULL; in global_var__add()
645 if (name && gvar->name == NULL) { in global_var__add()
650 gvar->start = addr; in global_var__add()
651 gvar->end = addr + size; in global_var__add()
652 gvar->die_offset = dwarf_dieoffset(type_die); in global_var__add()
654 rb_add(&gvar->node, dso__global_vars(dso), global_var_less); in global_var__add()
667 zfree(&gvar->name); in global_var_type__tree_delete()
680 mem_addr = addr + map__reloc(dloc->ms->map); in get_global_var_info()
683 sym = thread__find_symbol_fb(dloc->thread, dloc->cpumode, in get_global_var_info()
686 *var_name = sym->name; in get_global_var_info()
687 /* Calculate type offset from the start of variable */ in get_global_var_info()
688 *var_offset = mem_addr - map__unmap_ip(al.map, sym->start); in get_global_var_info()
701 Dwarf *dwarf = dloc->di->dbg; in global_var__collect()
720 for (pos = var_types; pos; pos = pos->next) { in global_var__collect()
724 if (pos->reg != -1) in global_var__collect()
727 if (!dwarf_offdie(dwarf, pos->die_off, &type_die)) in global_var__collect()
730 if (!get_global_var_info(dloc, pos->addr, &var_name, in global_var__collect()
737 global_var__add(dloc, pos->addr, var_name, &type_die); in global_var__collect()
751 int offset; in get_global_var_type() local
754 struct dso *dso = map__dso(dloc->ms->map); in get_global_var_type()
762 if (!dwarf_offdie(dloc->di->dbg, gvar->die_offset, type_die)) in get_global_var_type()
765 *var_offset = var_addr - gvar->start; in get_global_var_type()
770 if (die_find_variable_by_addr(cu_die, var_addr, &var_die, &offset) && in get_global_var_type()
771 check_variable(dloc, &var_die, type_die, DWARF_REG_PC, offset, in get_global_var_type()
774 *var_offset = offset; in get_global_var_type()
781 pc = map__rip_2objdump(dloc->ms->map, ip); in get_global_var_type()
793 global_var__add(dloc, var_addr - *var_offset, var_name, type_die); in get_global_var_type()
799 return (die_a->cu == die_b->cu) && (die_a->addr == die_b->addr); in die_is_same()
803 * update_var_state - Update type state using given variables
807 * @insn_offset: instruction offset (for debug)
818 int fbreg = dloc->fbreg; in update_var_state()
821 if (dloc->fb_cfa) { in update_var_state()
822 if (die_get_cfa(dloc->di->dbg, addr, &fbreg, &fb_offset) < 0) in update_var_state()
823 fbreg = -1; in update_var_state()
826 for (var = var_types; var != NULL; var = var->next) { in update_var_state()
827 if (var->addr != addr) in update_var_state()
829 /* Get the type DIE using the offset */ in update_var_state()
830 if (!dwarf_offdie(dloc->di->dbg, var->die_off, &mem_die)) in update_var_state()
833 if (var->reg == DWARF_REG_FB || var->reg == fbreg) { in update_var_state()
834 int offset = var->offset; in update_var_state() local
837 if (var->reg != DWARF_REG_FB) in update_var_state()
838 offset -= fb_offset; in update_var_state()
840 stack = find_stack_state(state, offset); in update_var_state()
841 if (stack && stack->kind == TSR_KIND_TYPE && in update_var_state()
842 !is_better_type(&stack->type, &mem_die)) in update_var_state()
845 findnew_stack_state(state, offset, TSR_KIND_TYPE, in update_var_state()
848 pr_debug_dtp("var [%"PRIx64"] -%#x(stack)", in update_var_state()
849 insn_offset, -offset); in update_var_state()
851 } else if (has_reg_type(state, var->reg) && var->offset == 0) { in update_var_state()
852 struct type_state_reg *reg; in update_var_state() local
855 reg = &state->regs[var->reg]; in update_var_state()
857 if (reg->ok && reg->kind == TSR_KIND_TYPE && in update_var_state()
858 !is_better_type(&reg->type, &mem_die)) in update_var_state()
861 orig_type = reg->type; in update_var_state()
863 reg->type = mem_die; in update_var_state()
864 reg->kind = TSR_KIND_TYPE; in update_var_state()
865 reg->ok = true; in update_var_state()
867 pr_debug_dtp("var [%"PRIx64"] reg%d", in update_var_state()
868 insn_offset, var->reg); in update_var_state()
874 * is usually the case of container_of() macro with offset of 0. in update_var_state()
876 if (has_reg_type(state, reg->copied_from)) { in update_var_state()
879 copy_reg = &state->regs[reg->copied_from]; in update_var_state()
882 if (!copy_reg->ok || (copy_reg->kind != TSR_KIND_TYPE) || in update_var_state()
883 !die_is_same(&copy_reg->type, &orig_type) || in update_var_state()
884 !is_better_type(&copy_reg->type, &mem_die)) in update_var_state()
887 copy_reg->type = mem_die; in update_var_state()
889 pr_debug_dtp("var [%"PRIx64"] copyback reg%d", in update_var_state()
890 insn_offset, reg->copied_from); in update_var_state()
898 * update_insn_state - Update type state for an instruction
909 * Note that ops->reg2 is only available when both mem_ref and multi_regs
915 if (dloc->arch->update_insn_state) in update_insn_state()
916 dloc->arch->update_insn_state(state, dloc, cu_die, dl); in update_insn_state()
935 if (last_bb->end != first_bb->begin) { in prepend_basic_blocks()
936 pr_debug("prepend basic blocks: mismatched disasm line %"PRIx64" -> %"PRIx64"\n", in prepend_basic_blocks()
937 last_bb->end->al.offset, first_bb->begin->al.offset); in prepend_basic_blocks()
942 if (last_bb->begin == last_bb->end) { in prepend_basic_blocks()
943 list_del(&last_bb->list); in prepend_basic_blocks()
949 last_bb->end = list_prev_entry(last_bb->end, al.node); in prepend_basic_blocks()
960 list_del(&bb->list); in delete_basic_blocks()
974 if (var_types->addr == 0) in fixup_var_address()
975 var_types->addr = addr; in fixup_var_address()
977 var_types = var_types->next; in fixup_var_address()
984 struct die_var_type *next = var_types->next; in delete_var_types()
994 if (arch__is(dloc->arch, "x86")) { in setup_stack_canary()
995 dloc->op->segment = INSN_SEG_X86_GS; in setup_stack_canary()
996 dloc->op->imm = true; in setup_stack_canary()
997 dloc->op->offset = 40; in setup_stack_canary()
1003 * It returns PERF_TMR_BAIL_OUT when it looks up per-cpu variables which
1013 u32 insn_offset = dl->al.offset; in check_matching_type()
1014 int reg = dloc->op->reg1; in check_matching_type() local
1015 int offset = dloc->op->offset; in check_matching_type() local
1019 if (offset < 0) { in check_matching_type()
1020 offset = -offset; in check_matching_type()
1021 offset_sign = "-"; in check_matching_type()
1025 pr_debug_dtp("chk [%x] reg%d offset=%s%#x ok=%d kind=%d ", in check_matching_type()
1026 insn_offset, reg, offset_sign, offset, in check_matching_type()
1027 state->regs[reg].ok, state->regs[reg].kind); in check_matching_type()
1029 if (!state->regs[reg].ok) in check_matching_type()
1032 if (state->regs[reg].kind == TSR_KIND_TYPE) { in check_matching_type()
1037 die_get_typename_from_type(&state->regs[reg].type, &sb); in check_matching_type()
1045 if (!is_pointer_type(&state->regs[reg].type)) { in check_matching_type()
1046 if (dloc->op->offset < 0 && reg != state->stack_reg) in check_matching_type()
1053 if (__die_get_real_type(&state->regs[reg].type, type_die) == NULL) in check_matching_type()
1056 dloc->type_offset = dloc->op->offset; in check_matching_type()
1065 (unsigned)dloc->type_offset >= size) in check_matching_type()
1071 if (state->regs[reg].kind == TSR_KIND_POINTER) { in check_matching_type()
1078 *type_die = state->regs[reg].type; in check_matching_type()
1080 dloc->type_offset = dloc->op->offset; in check_matching_type()
1084 (unsigned)dloc->type_offset >= size) in check_matching_type()
1090 if (state->regs[reg].kind == TSR_KIND_CANARY) { in check_matching_type()
1103 if (state->regs[reg].kind == TSR_KIND_PERCPU_BASE) { in check_matching_type()
1104 u64 var_addr = dloc->op->offset; in check_matching_type()
1109 if (dloc->op->multi_regs) { in check_matching_type()
1110 int reg2 = dloc->op->reg2; in check_matching_type()
1112 if (dloc->op->reg2 == reg) in check_matching_type()
1113 reg2 = dloc->op->reg1; in check_matching_type()
1115 if (has_reg_type(state, reg2) && state->regs[reg2].ok && in check_matching_type()
1116 state->regs[reg2].kind == TSR_KIND_CONST) in check_matching_type()
1117 var_addr += state->regs[reg2].imm_value; in check_matching_type()
1120 if (get_global_var_type(cu_die, dloc, dloc->ip, var_addr, in check_matching_type()
1122 dloc->type_offset = var_offset; in check_matching_type()
1125 /* No need to retry per-cpu (global) variables */ in check_matching_type()
1130 if (reg == dloc->fbreg) { in check_matching_type()
1135 stack = find_stack_state(state, dloc->type_offset); in check_matching_type()
1148 if (stack->kind == TSR_KIND_CANARY) { in check_matching_type()
1153 if (stack->kind != TSR_KIND_TYPE) in check_matching_type()
1156 *type_die = stack->type; in check_matching_type()
1157 /* Update the type offset from the start of slot */ in check_matching_type()
1158 dloc->type_offset -= stack->offset; in check_matching_type()
1163 if (dloc->fb_cfa) { in check_matching_type()
1165 u64 pc = map__rip_2objdump(dloc->ms->map, dloc->ip); in check_matching_type()
1170 if (die_get_cfa(dloc->di->dbg, pc, &fbreg, &fboff) < 0) in check_matching_type()
1171 fbreg = -1; in check_matching_type()
1173 if (reg != fbreg) in check_matching_type()
1176 stack = find_stack_state(state, dloc->type_offset - fboff); in check_matching_type()
1189 if (stack->kind == TSR_KIND_CANARY) { in check_matching_type()
1194 if (stack->kind != TSR_KIND_TYPE) in check_matching_type()
1197 *type_die = stack->type; in check_matching_type()
1198 /* Update the type offset from the start of slot */ in check_matching_type()
1199 dloc->type_offset -= fboff + stack->offset; in check_matching_type()
1205 if (dso__kernel(map__dso(dloc->ms->map))) { in check_matching_type()
1208 /* Direct this-cpu access like "%gs:0x34740" */ in check_matching_type()
1209 if (dloc->op->segment == INSN_SEG_X86_GS && dloc->op->imm && in check_matching_type()
1210 arch__is(dloc->arch, "x86")) { in check_matching_type()
1211 pr_debug_dtp("this-cpu var"); in check_matching_type()
1213 addr = dloc->op->offset; in check_matching_type()
1215 if (get_global_var_type(cu_die, dloc, dloc->ip, addr, in check_matching_type()
1216 &offset, type_die)) { in check_matching_type()
1217 dloc->type_offset = offset; in check_matching_type()
1223 /* Access to global variable like "-0x7dcf0500(,%rdx,8)" */ in check_matching_type()
1224 if (dloc->op->offset < 0 && reg != state->stack_reg) { in check_matching_type()
1225 addr = (s64) dloc->op->offset; in check_matching_type()
1227 if (get_global_var_type(cu_die, dloc, dloc->ip, addr, in check_matching_type()
1228 &offset, type_die)) { in check_matching_type()
1231 dloc->type_offset = offset; in check_matching_type()
1249 struct symbol *sym = dloc->ms->sym; in find_data_type_insn()
1254 init_type_state(&state, dloc->arch); in find_data_type_insn()
1257 struct disasm_line *dl = bb->begin; in find_data_type_insn()
1259 BUG_ON(bb->begin->al.offset == -1 || bb->end->al.offset == -1); in find_data_type_insn()
1261 pr_debug_dtp("bb: [%"PRIx64" - %"PRIx64"]\n", in find_data_type_insn()
1262 bb->begin->al.offset, bb->end->al.offset); in find_data_type_insn()
1264 list_for_each_entry_from(dl, &notes->src->source, al.node) { in find_data_type_insn()
1265 u64 this_ip = sym->start + dl->al.offset; in find_data_type_insn()
1266 u64 addr = map__rip_2objdump(dloc->ms->map, this_ip); in find_data_type_insn()
1269 if (dl->al.offset == -1) in find_data_type_insn()
1273 update_var_state(&state, dloc, addr, dl->al.offset, var_types); in find_data_type_insn()
1275 if (this_ip == dloc->ip) { in find_data_type_insn()
1284 if (dl == bb->end) in find_data_type_insn()
1296 if ((arch__is(dloc->arch, "x86")) || (arch__is(dloc->arch, "powerpc"))) in arch_supports_insn_tracking()
1320 prev_dst_ip = dst_ip = dloc->ip; in find_data_type_block()
1321 for (int i = nr_scopes - 1; i >= 0; i--) { in find_data_type_block()
1331 src_ip = map__objdump_2rip(dloc->ms->map, start); in find_data_type_block()
1335 if (annotate_get_basic_blocks(dloc->ms->sym, src_ip, dst_ip, in find_data_type_block()
1344 src_ip - dloc->ms->sym->start, in find_data_type_block()
1345 dst_ip - dloc->ms->sym->start); in find_data_type_block()
1359 int offset = dloc->op->offset; in find_data_type_block() local
1362 if (offset < 0) { in find_data_type_block()
1363 offset = -offset; in find_data_type_block()
1364 offset_sign = "-"; in find_data_type_block()
1367 if (dloc->op->multi_regs) in find_data_type_block()
1368 snprintf(buf, sizeof(buf), "reg%d, reg%d", in find_data_type_block()
1369 dloc->op->reg1, dloc->op->reg2); in find_data_type_block()
1371 snprintf(buf, sizeof(buf), "reg%d", dloc->op->reg1); in find_data_type_block()
1373 pr_debug_dtp("found by insn track: %s%#x(%s) type-offset=%#x\n", in find_data_type_block()
1374 offset_sign, offset, buf, dloc->type_offset); in find_data_type_block()
1394 struct annotated_op_loc *loc = dloc->op; in find_data_type_die()
1397 int reg, offset = loc->offset; in find_data_type_die() local
1398 int ret = -1; in find_data_type_die()
1400 int fbreg = -1; in find_data_type_die()
1409 if (dloc->op->multi_regs) in find_data_type_die()
1410 snprintf(buf, sizeof(buf), "reg%d, reg%d", dloc->op->reg1, dloc->op->reg2); in find_data_type_die()
1411 else if (dloc->op->reg1 == DWARF_REG_PC) in find_data_type_die()
1414 snprintf(buf, sizeof(buf), "reg%d", dloc->op->reg1); in find_data_type_die()
1416 if (offset < 0) { in find_data_type_die()
1417 offset = -offset; in find_data_type_die()
1418 offset_sign = "-"; in find_data_type_die()
1421 pr_debug_dtp("-----------------------------------------------------------\n"); in find_data_type_die()
1423 offset_sign, offset, buf, in find_data_type_die()
1424 dloc->ms->sym->name, dloc->ip - dloc->ms->sym->start); in find_data_type_die()
1431 pc = map__rip_2objdump(dloc->ms->map, dloc->ip); in find_data_type_die()
1434 if (!find_cu_die(dloc->di, pc, &cu_die)) { in find_data_type_die()
1437 return -1; in find_data_type_die()
1440 reg = loc->reg1; in find_data_type_die()
1441 offset = loc->offset; in find_data_type_die()
1446 if (reg == DWARF_REG_PC) { in find_data_type_die()
1447 if (get_global_var_type(&cu_die, dloc, dloc->ip, dloc->var_addr, in find_data_type_die()
1448 &offset, type_die)) { in find_data_type_die()
1449 dloc->type_offset = offset; in find_data_type_die()
1452 dloc->var_addr, offset); in find_data_type_die()
1459 /* Get a list of nested scopes - i.e. (inlined) functions and blocks. */ in find_data_type_die()
1462 if (reg != DWARF_REG_PC && dwarf_hasattr(&scopes[0], DW_AT_frame_base)) { in find_data_type_die()
1466 /* Check if the 'reg' is assigned as frame base register */ in find_data_type_die()
1471 fbreg = dloc->fbreg = *block.data - DW_OP_reg0; in find_data_type_die()
1474 dloc->fb_cfa = true; in find_data_type_die()
1475 if (die_get_cfa(dloc->di->dbg, pc, &fbreg, in find_data_type_die()
1477 fbreg = -1; in find_data_type_die()
1484 dloc->fb_cfa, fbreg); in find_data_type_die()
1489 is_fbreg = (reg == fbreg); in find_data_type_die()
1491 offset = loc->offset - fb_offset; in find_data_type_die()
1493 /* Search from the inner-most scope to the outer */ in find_data_type_die()
1494 for (i = nr_scopes - 1; i >= 0; i--) { in find_data_type_die()
1496 int type_offset = offset; in find_data_type_die()
1498 if (reg == DWARF_REG_PC) { in find_data_type_die()
1499 if (!die_find_variable_by_addr(&scopes[i], dloc->var_addr, in find_data_type_die()
1504 if (!die_find_variable_by_reg(&scopes[i], pc, reg, in find_data_type_die()
1514 result = check_variable(dloc, &var_die, &mem_die, reg, type_offset, is_fbreg); in find_data_type_die()
1516 if (reg == DWARF_REG_PC) { in find_data_type_die()
1518 dloc->var_addr, type_offset); in find_data_type_die()
1519 } else if (reg == DWARF_REG_FB || is_fbreg) { in find_data_type_die()
1528 dloc->type_offset = type_offset; in find_data_type_die()
1535 pr_debug_location(&var_die, pc, reg); in find_data_type_die()
1539 if (!found && loc->multi_regs && reg == loc->reg1 && loc->reg1 != loc->reg2) { in find_data_type_die()
1540 reg = loc->reg2; in find_data_type_die()
1544 if (!found && reg != DWARF_REG_PC) { in find_data_type_die()
1581 ret = -1; in find_data_type_die()
1589 * find_data_type - Return a data type at the location
1593 * type it accesses. The exact location is expressed by (ip, reg, offset)
1595 * variables might update the @dloc->type_offset after finding the start of the
1597 * a declaration of the variable using var_name. In that case, @dloc->offset
1604 struct dso *dso = map__dso(dloc->ms->map); in find_data_type()
1608 * The type offset is the same as instruction offset by default. in find_data_type()
1609 * But when finding a global variable, the offset won't be valid. in find_data_type()
1611 dloc->type_offset = dloc->op->offset; in find_data_type()
1613 dloc->fbreg = -1; in find_data_type()
1626 sz += sizeof(struct type_hist_entry) * adt->self.size; in alloc_data_type_histograms()
1629 adt->histograms = calloc(nr_entries, sizeof(*adt->histograms)); in alloc_data_type_histograms()
1630 if (adt->histograms == NULL) in alloc_data_type_histograms()
1631 return -ENOMEM; in alloc_data_type_histograms()
1638 adt->histograms[i] = zalloc(sz); in alloc_data_type_histograms()
1639 if (adt->histograms[i] == NULL) in alloc_data_type_histograms()
1643 adt->nr_histograms = nr_entries; in alloc_data_type_histograms()
1647 while (--i >= 0) in alloc_data_type_histograms()
1648 zfree(&(adt->histograms[i])); in alloc_data_type_histograms()
1649 zfree(&adt->histograms); in alloc_data_type_histograms()
1650 return -ENOMEM; in alloc_data_type_histograms()
1655 for (int i = 0; i < adt->nr_histograms; i++) in delete_data_type_histograms()
1656 zfree(&(adt->histograms[i])); in delete_data_type_histograms()
1658 zfree(&adt->histograms); in delete_data_type_histograms()
1659 adt->nr_histograms = 0; in delete_data_type_histograms()
1671 delete_members(&pos->self); in annotated_data_type__tree_delete()
1673 zfree(&pos->self.type_name); in annotated_data_type__tree_delete()
1679 * annotated_data_type__update_samples - Update histogram
1682 * @offset: Offset in the type
1683 * @nr_samples: Number of samples at this offset
1684 * @period: Event count at this offset
1688 * than one samples at a certain offset.
1691 struct evsel *evsel, int offset, in annotated_data_type__update_samples() argument
1699 if (adt->histograms == NULL) { in annotated_data_type__update_samples()
1700 int nr = evsel->evlist->core.nr_entries; in annotated_data_type__update_samples()
1703 return -1; in annotated_data_type__update_samples()
1706 if (offset < 0 || offset >= adt->self.size) in annotated_data_type__update_samples()
1707 return -1; in annotated_data_type__update_samples()
1709 h = adt->histograms[evsel->core.idx]; in annotated_data_type__update_samples()
1711 h->nr_samples += nr_samples; in annotated_data_type__update_samples()
1712 h->addr[offset].nr_samples += nr_samples; in annotated_data_type__update_samples()
1713 h->period += period; in annotated_data_type__update_samples()
1714 h->addr[offset].period += period; in annotated_data_type__update_samples()
1720 struct dso *dso = map__dso(he->ms.map); in print_annotated_data_header()
1722 int nr_samples = he->stat.nr_events; in print_annotated_data_header()
1729 list_for_each_entry(pair, &he->pairs.head, pairs.node) in print_annotated_data_header()
1730 nr_samples += pair->stat.nr_events; in print_annotated_data_header()
1734 he->mem_type->self.type_name, dso__name(dso), nr_samples); in print_annotated_data_header()
1743 evsel__hists(pos)->stats.nr_samples == 0) in print_annotated_data_header()
1746 printf(" event[%d] = %s\n", i++, pos->name); in print_annotated_data_header()
1761 "offset", "size", "field"); in print_annotated_data_header()
1766 double percent = h->period ? (100.0 * period / h->period) : 0; in print_annotated_data_value()
1782 struct type_hist *h = mem_type->histograms[evsel->core.idx]; in print_annotated_data_type()
1789 h = mem_type->histograms[pos->core.idx]; in print_annotated_data_type()
1792 evsel__hists(pos)->stats.nr_samples == 0) in print_annotated_data_type()
1797 for (i = 0; i < member->size; i++) { in print_annotated_data_type()
1798 samples += h->addr[member->offset + i].nr_samples; in print_annotated_data_type()
1799 period += h->addr[member->offset + i].period; in print_annotated_data_type()
1806 member->offset, member->size, indent, "", member->type_name, in print_annotated_data_type()
1807 member->var_name ?: ""); in print_annotated_data_type()
1809 if (!list_empty(&member->children)) in print_annotated_data_type()
1812 list_for_each_entry(child, &member->children, node) in print_annotated_data_type()
1815 if (!list_empty(&member->children)) in print_annotated_data_type()
1823 print_annotated_data_type(he->mem_type, &he->mem_type->self, evsel, 0); in hist_entry__annotate_data_tty()