Lines Matching +full:resume +full:- +full:offset
1 // SPDX-License-Identifier: GPL-2.0
9 * Copyright (C) 2002-2007 Hewlett-Packard Co
10 * Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
31 #include <libunwind-ptrace.h>
65 /* Pointer-encoding formats: */
67 #define DW_EH_PE_ptr 0x00 /* pointer-sized unsigned value */
68 #define DW_EH_PE_udata4 0x03 /* unsigned 32-bit value */
69 #define DW_EH_PE_udata8 0x04 /* unsigned 64-bit value */
70 #define DW_EH_PE_sdata4 0x0b /* signed 32-bit value */
71 #define DW_EH_PE_sdata8 0x0c /* signed 64-bit value */
73 /* Pointer-encoding application: */
82 #define DW_EH_PE_funcrel 0x40 /* start-of-procedure-relative */
105 return -EINVAL; \
135 return -EINVAL; in __dw_read_encoded_value()
155 return -EINVAL; in __dw_read_encoded_value()
166 return -EINVAL; \
176 u64 offset = 0; in elf_section_offset() local
189 offset = shdr.sh_offset; in elf_section_offset()
193 return offset; in elf_section_offset()
230 * The rest of the header is variable-length and consists of the
250 u64 offset, u64 *table_data, u64 *segbase, in unwind_spec_ehframe() argument
258 r = dso__data_read_offset(dso, machine, offset, in unwind_spec_ehframe()
261 return -EINVAL; in unwind_spec_ehframe()
267 *segbase = offset; in unwind_spec_ehframe()
268 *table_data = (enc - (u8 *) &hdr) + offset; in unwind_spec_ehframe()
276 int ret = -EINVAL, fd; in read_unwind_spec_eh_frame()
277 u64 offset = dso->data.eh_frame_hdr_offset; in read_unwind_spec_eh_frame() local
279 if (offset == 0) { in read_unwind_spec_eh_frame()
282 return -EINVAL; in read_unwind_spec_eh_frame()
285 offset = elf_section_offset(fd, ".eh_frame_hdr"); in read_unwind_spec_eh_frame()
286 dso->data.eh_frame_hdr_offset = offset; in read_unwind_spec_eh_frame()
290 if (offset) in read_unwind_spec_eh_frame()
291 ret = unwind_spec_ehframe(dso, machine, offset, in read_unwind_spec_eh_frame()
300 struct machine *machine, u64 *offset) in read_unwind_spec_debug_frame() argument
303 u64 ofs = dso->data.debug_frame_offset; in read_unwind_spec_debug_frame()
306 * - dso in read_unwind_spec_debug_frame()
307 * - debug pointed by symsrc_filename in read_unwind_spec_debug_frame()
308 * - gnu_debuglink, which doesn't necessary in read_unwind_spec_debug_frame()
319 fd = open(dso->symsrc_filename, O_RDONLY); in read_unwind_spec_debug_frame()
332 machine->root_dir, debuglink, PATH_MAX); in read_unwind_spec_debug_frame()
342 if (dso->symsrc_filename != NULL) { in read_unwind_spec_debug_frame()
346 dso->symsrc_filename, in read_unwind_spec_debug_frame()
348 zfree(&dso->symsrc_filename); in read_unwind_spec_debug_frame()
350 dso->symsrc_filename = debuglink; in read_unwind_spec_debug_frame()
356 dso->data.debug_frame_offset = ofs; in read_unwind_spec_debug_frame()
359 *offset = ofs; in read_unwind_spec_debug_frame()
360 if (*offset) in read_unwind_spec_debug_frame()
363 return -EINVAL; in read_unwind_spec_debug_frame()
370 return thread__find_map(ui->thread, PERF_RECORD_MISC_USER, ip, &al); in find_map()
381 int ret = -EINVAL; in find_proc_info()
384 if (!map || !map->dso) in find_proc_info()
385 return -EINVAL; in find_proc_info()
387 pr_debug("unwind: find_proc_info dso %s\n", map->dso->name); in find_proc_info()
390 if (!read_unwind_spec_eh_frame(map->dso, ui->machine, in find_proc_info()
394 di.start_ip = map->start; in find_proc_info()
395 di.end_ip = map->end; in find_proc_info()
396 di.u.rti.segbase = map->start + segbase - map->pgoff; in find_proc_info()
397 di.u.rti.table_data = map->start + table_data - map->pgoff; in find_proc_info()
407 !read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) { in find_proc_info()
408 int fd = dso__data_get_fd(map->dso, ui->machine); in find_proc_info()
409 int is_exec = elf_is_exec(fd, map->dso->name); in find_proc_info()
410 unw_word_t base = is_exec ? 0 : map->start; in find_proc_info()
414 dso__data_put_fd(map->dso); in find_proc_info()
416 symfile = map->dso->symsrc_filename ?: map->dso->name; in find_proc_info()
420 map->start, map->end)) in find_proc_info()
436 return -UNW_EINVAL; in access_fpreg()
443 return -UNW_ENOINFO; in get_dyn_info_list_addr()
446 static int resume(unw_addr_space_t __maybe_unused as, in resume() function
450 pr_err("unwind: resume unsupported\n"); in resume()
451 return -UNW_EINVAL; in resume()
461 return -UNW_EINVAL; in get_proc_name()
473 return -1; in access_dso_mem()
476 if (!map->dso) in access_dso_mem()
477 return -1; in access_dso_mem()
479 size = dso__data_read_addr(map->dso, map, ui->machine, in access_dso_mem()
490 struct stack_dump *stack = &ui->sample->user_stack; in access_mem()
492 int offset; in access_mem() local
496 if (__write || !stack || !ui->sample->user_regs.regs) { in access_mem()
501 ret = perf_reg_value(&start, &ui->sample->user_regs, in access_mem()
506 end = start + stack->size; in access_mem()
510 return -EINVAL; in access_mem()
516 " 0x%" PRIx64 "-0x%" PRIx64 "\n", in access_mem()
524 offset = addr - start; in access_mem()
525 *valp = *(unw_word_t *)&stack->data[offset]; in access_mem()
526 pr_debug("unwind: access_mem addr %p val %lx, offset %d\n", in access_mem()
527 (void *) (uintptr_t) addr, (unsigned long)*valp, offset); in access_mem()
545 if (!ui->sample->user_regs.regs) { in access_reg()
552 return -EINVAL; in access_reg()
554 ret = perf_reg_value(&val, &ui->sample->user_regs, id); in access_reg()
584 al.sym ? al.sym->name : "''", in entry()
586 al.map ? al.map->map_ip(al.map, ip) : (u64) 0); in entry()
615 .resume = resume,
621 maps->addr_space = unw_create_addr_space(&accessors, 0); in _unwind__prepare_access()
622 if (!maps->addr_space) { in _unwind__prepare_access()
624 return -ENOMEM; in _unwind__prepare_access()
627 unw_set_caching_policy(maps->addr_space, UNW_CACHE_GLOBAL); in _unwind__prepare_access()
633 unw_flush_cache(maps->addr_space, 0, 0); in _unwind__flush_access()
638 unw_destroy_addr_space(maps->addr_space); in _unwind__finish_access()
650 ret = perf_reg_value(&val, &ui->sample->user_regs, in get_entries()
661 if (max_stack - 1 > 0) { in get_entries()
662 WARN_ONCE(!ui->thread, "WARNING: ui->thread is NULL"); in get_entries()
663 addr_space = ui->thread->maps->addr_space; in get_entries()
666 return -1; in get_entries()
676 * Decrement the IP for any non-activation frames. in get_entries()
683 --ips[i]; in get_entries()
698 j = max_stack - i - 1; in get_entries()
699 ret = ips[j] ? entry(ips[j], ui->thread, cb, arg) : 0; in get_entries()
712 .machine = thread->maps->machine, in _unwind__get_entries()
715 if (!data->user_regs.regs) in _unwind__get_entries()
716 return -EINVAL; in _unwind__get_entries()
719 return -EINVAL; in _unwind__get_entries()