1da0c48c4Sopenharmony_ci/* Internal definitions for libdwfl. 2da0c48c4Sopenharmony_ci Copyright (C) 2005-2015, 2018 Red Hat, Inc. 3da0c48c4Sopenharmony_ci This file is part of elfutils. 4da0c48c4Sopenharmony_ci 5da0c48c4Sopenharmony_ci This file is free software; you can redistribute it and/or modify 6da0c48c4Sopenharmony_ci it under the terms of either 7da0c48c4Sopenharmony_ci 8da0c48c4Sopenharmony_ci * the GNU Lesser General Public License as published by the Free 9da0c48c4Sopenharmony_ci Software Foundation; either version 3 of the License, or (at 10da0c48c4Sopenharmony_ci your option) any later version 11da0c48c4Sopenharmony_ci 12da0c48c4Sopenharmony_ci or 13da0c48c4Sopenharmony_ci 14da0c48c4Sopenharmony_ci * the GNU General Public License as published by the Free 15da0c48c4Sopenharmony_ci Software Foundation; either version 2 of the License, or (at 16da0c48c4Sopenharmony_ci your option) any later version 17da0c48c4Sopenharmony_ci 18da0c48c4Sopenharmony_ci or both in parallel, as here. 19da0c48c4Sopenharmony_ci 20da0c48c4Sopenharmony_ci elfutils is distributed in the hope that it will be useful, but 21da0c48c4Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 22da0c48c4Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23da0c48c4Sopenharmony_ci General Public License for more details. 24da0c48c4Sopenharmony_ci 25da0c48c4Sopenharmony_ci You should have received copies of the GNU General Public License and 26da0c48c4Sopenharmony_ci the GNU Lesser General Public License along with this program. If 27da0c48c4Sopenharmony_ci not, see <http://www.gnu.org/licenses/>. */ 28da0c48c4Sopenharmony_ci 29da0c48c4Sopenharmony_ci#ifndef _LIBDWFLP_H 30da0c48c4Sopenharmony_ci#define _LIBDWFLP_H 1 31da0c48c4Sopenharmony_ci 32da0c48c4Sopenharmony_ci#include <libdwfl.h> 33da0c48c4Sopenharmony_ci#include <libebl.h> 34da0c48c4Sopenharmony_ci#include <assert.h> 35da0c48c4Sopenharmony_ci#include <dirent.h> 36da0c48c4Sopenharmony_ci#include <errno.h> 37da0c48c4Sopenharmony_ci#include <stdbool.h> 38da0c48c4Sopenharmony_ci#include <stdlib.h> 39da0c48c4Sopenharmony_ci#include <string.h> 40da0c48c4Sopenharmony_ci 41da0c48c4Sopenharmony_ci#include "../libdw/libdwP.h" /* We need its INTDECLs. */ 42da0c48c4Sopenharmony_ci#include "../libdwelf/libdwelfP.h" 43da0c48c4Sopenharmony_ci 44da0c48c4Sopenharmony_ci#ifdef ENABLE_LIBDEBUGINFOD 45da0c48c4Sopenharmony_ci#include "../debuginfod/debuginfod.h" 46da0c48c4Sopenharmony_ci#endif 47da0c48c4Sopenharmony_ci 48da0c48c4Sopenharmony_citypedef struct Dwfl_Process Dwfl_Process; 49da0c48c4Sopenharmony_ci 50da0c48c4Sopenharmony_ci#define DWFL_ERRORS \ 51da0c48c4Sopenharmony_ci DWFL_ERROR (NOERROR, N_("no error")) \ 52da0c48c4Sopenharmony_ci DWFL_ERROR (UNKNOWN_ERROR, N_("unknown error")) \ 53da0c48c4Sopenharmony_ci DWFL_ERROR (NOMEM, N_("out of memory")) \ 54da0c48c4Sopenharmony_ci DWFL_ERROR (ERRNO, N_("See errno")) \ 55da0c48c4Sopenharmony_ci DWFL_ERROR (LIBELF, N_("See elf_errno")) \ 56da0c48c4Sopenharmony_ci DWFL_ERROR (LIBDW, N_("See dwarf_errno")) \ 57da0c48c4Sopenharmony_ci DWFL_ERROR (LIBEBL, N_("See ebl_errno (XXX missing)")) \ 58da0c48c4Sopenharmony_ci DWFL_ERROR (ZLIB, N_("gzip decompression failed")) \ 59da0c48c4Sopenharmony_ci DWFL_ERROR (BZLIB, N_("bzip2 decompression failed")) \ 60da0c48c4Sopenharmony_ci DWFL_ERROR (LZMA, N_("LZMA decompression failed")) \ 61da0c48c4Sopenharmony_ci DWFL_ERROR (ZSTD, N_("zstd decompression failed")) \ 62da0c48c4Sopenharmony_ci DWFL_ERROR (UNKNOWN_MACHINE, N_("no support library found for machine")) \ 63da0c48c4Sopenharmony_ci DWFL_ERROR (NOREL, N_("Callbacks missing for ET_REL file")) \ 64da0c48c4Sopenharmony_ci DWFL_ERROR (BADRELTYPE, N_("Unsupported relocation type")) \ 65da0c48c4Sopenharmony_ci DWFL_ERROR (BADRELOFF, N_("r_offset is bogus")) \ 66da0c48c4Sopenharmony_ci DWFL_ERROR (BADSTROFF, N_("offset out of range")) \ 67da0c48c4Sopenharmony_ci DWFL_ERROR (RELUNDEF, N_("relocation refers to undefined symbol")) \ 68da0c48c4Sopenharmony_ci DWFL_ERROR (CB, N_("Callback returned failure")) \ 69da0c48c4Sopenharmony_ci DWFL_ERROR (NO_DWARF, N_("No DWARF information found")) \ 70da0c48c4Sopenharmony_ci DWFL_ERROR (NO_SYMTAB, N_("No symbol table found")) \ 71da0c48c4Sopenharmony_ci DWFL_ERROR (NO_PHDR, N_("No ELF program headers")) \ 72da0c48c4Sopenharmony_ci DWFL_ERROR (OVERLAP, N_("address range overlaps an existing module")) \ 73da0c48c4Sopenharmony_ci DWFL_ERROR (ADDR_OUTOFRANGE, N_("address out of range")) \ 74da0c48c4Sopenharmony_ci DWFL_ERROR (NO_MATCH, N_("no matching address range")) \ 75da0c48c4Sopenharmony_ci DWFL_ERROR (TRUNCATED, N_("image truncated")) \ 76da0c48c4Sopenharmony_ci DWFL_ERROR (ALREADY_ELF, N_("ELF file opened")) \ 77da0c48c4Sopenharmony_ci DWFL_ERROR (BADELF, N_("not a valid ELF file")) \ 78da0c48c4Sopenharmony_ci DWFL_ERROR (WEIRD_TYPE, N_("cannot handle DWARF type description")) \ 79da0c48c4Sopenharmony_ci DWFL_ERROR (WRONG_ID_ELF, N_("ELF file does not match build ID")) \ 80da0c48c4Sopenharmony_ci DWFL_ERROR (BAD_PRELINK, N_("corrupt .gnu.prelink_undo section data")) \ 81da0c48c4Sopenharmony_ci DWFL_ERROR (LIBEBL_BAD, N_("Internal error due to ebl")) \ 82da0c48c4Sopenharmony_ci DWFL_ERROR (CORE_MISSING, N_("Missing data in core file")) \ 83da0c48c4Sopenharmony_ci DWFL_ERROR (INVALID_REGISTER, N_("Invalid register")) \ 84da0c48c4Sopenharmony_ci DWFL_ERROR (REGISTER_VAL_UNKNOWN, N_("Unknown register value")) \ 85da0c48c4Sopenharmony_ci DWFL_ERROR (PROCESS_MEMORY_READ, N_("Error reading process memory")) \ 86da0c48c4Sopenharmony_ci DWFL_ERROR (PROCESS_NO_ARCH, N_("Couldn't find architecture of any ELF")) \ 87da0c48c4Sopenharmony_ci DWFL_ERROR (PARSE_PROC, N_("Error parsing /proc filesystem")) \ 88da0c48c4Sopenharmony_ci DWFL_ERROR (INVALID_DWARF, N_("Invalid DWARF")) \ 89da0c48c4Sopenharmony_ci DWFL_ERROR (UNSUPPORTED_DWARF, N_("Unsupported DWARF")) \ 90da0c48c4Sopenharmony_ci DWFL_ERROR (NEXT_THREAD_FAIL, N_("Unable to find more threads")) \ 91da0c48c4Sopenharmony_ci DWFL_ERROR (ATTACH_STATE_CONFLICT, N_("Dwfl already has attached state")) \ 92da0c48c4Sopenharmony_ci DWFL_ERROR (NO_ATTACH_STATE, N_("Dwfl has no attached state")) \ 93da0c48c4Sopenharmony_ci DWFL_ERROR (NO_UNWIND, N_("Unwinding not supported for this architecture")) \ 94da0c48c4Sopenharmony_ci DWFL_ERROR (INVALID_ARGUMENT, N_("Invalid argument")) \ 95da0c48c4Sopenharmony_ci DWFL_ERROR (NO_CORE_FILE, N_("Not an ET_CORE ELF file")) 96da0c48c4Sopenharmony_ci 97da0c48c4Sopenharmony_ci#define DWFL_ERROR(name, text) DWFL_E_##name, 98da0c48c4Sopenharmony_citypedef enum { DWFL_ERRORS DWFL_E_NUM } Dwfl_Error; 99da0c48c4Sopenharmony_ci#undef DWFL_ERROR 100da0c48c4Sopenharmony_ci 101da0c48c4Sopenharmony_ci#define OTHER_ERROR(name) ((unsigned int) DWFL_E_##name << 16) 102da0c48c4Sopenharmony_ci#define DWFL_E(name, errno) (OTHER_ERROR (name) | (errno)) 103da0c48c4Sopenharmony_ci 104da0c48c4Sopenharmony_ciextern int __libdwfl_canon_error (Dwfl_Error) internal_function; 105da0c48c4Sopenharmony_ciextern void __libdwfl_seterrno (Dwfl_Error) internal_function; 106da0c48c4Sopenharmony_ci 107da0c48c4Sopenharmony_ci/* Resources we might keep for the user about the core file that the 108da0c48c4Sopenharmony_ci Dwfl might have been created from. Can currently only be set 109da0c48c4Sopenharmony_ci through std-argp. */ 110da0c48c4Sopenharmony_cistruct Dwfl_User_Core 111da0c48c4Sopenharmony_ci{ 112da0c48c4Sopenharmony_ci char *executable_for_core; /* --executable if --core was specified. */ 113da0c48c4Sopenharmony_ci Elf *core; /* non-NULL if we need to free it. */ 114da0c48c4Sopenharmony_ci int fd; /* close if >= 0. */ 115da0c48c4Sopenharmony_ci}; 116da0c48c4Sopenharmony_ci 117da0c48c4Sopenharmony_cistruct Dwfl 118da0c48c4Sopenharmony_ci{ 119da0c48c4Sopenharmony_ci const Dwfl_Callbacks *callbacks; 120da0c48c4Sopenharmony_ci#ifdef ENABLE_LIBDEBUGINFOD 121da0c48c4Sopenharmony_ci debuginfod_client *debuginfod; 122da0c48c4Sopenharmony_ci#endif 123da0c48c4Sopenharmony_ci Dwfl_Module *modulelist; /* List in order used by full traversals. */ 124da0c48c4Sopenharmony_ci 125da0c48c4Sopenharmony_ci Dwfl_Process *process; 126da0c48c4Sopenharmony_ci Dwfl_Error attacherr; /* Previous error attaching process. */ 127da0c48c4Sopenharmony_ci 128da0c48c4Sopenharmony_ci GElf_Addr offline_next_address; 129da0c48c4Sopenharmony_ci 130da0c48c4Sopenharmony_ci GElf_Addr segment_align; /* Smallest granularity of segments. */ 131da0c48c4Sopenharmony_ci 132da0c48c4Sopenharmony_ci /* Binary search table in three parallel malloc'd arrays. */ 133da0c48c4Sopenharmony_ci size_t lookup_elts; /* Elements in use. */ 134da0c48c4Sopenharmony_ci size_t lookup_alloc; /* Elements allococated. */ 135da0c48c4Sopenharmony_ci GElf_Addr *lookup_addr; /* Start address of segment. */ 136da0c48c4Sopenharmony_ci Dwfl_Module **lookup_module; /* Module associated with segment, or null. */ 137da0c48c4Sopenharmony_ci int *lookup_segndx; /* User segment index, or -1. */ 138da0c48c4Sopenharmony_ci int next_segndx; 139da0c48c4Sopenharmony_ci 140da0c48c4Sopenharmony_ci struct Dwfl_User_Core *user_core; 141da0c48c4Sopenharmony_ci}; 142da0c48c4Sopenharmony_ci 143da0c48c4Sopenharmony_ci#define OFFLINE_REDZONE 0x10000 144da0c48c4Sopenharmony_ci 145da0c48c4Sopenharmony_cistruct dwfl_file 146da0c48c4Sopenharmony_ci{ 147da0c48c4Sopenharmony_ci char *name; 148da0c48c4Sopenharmony_ci int fd; 149da0c48c4Sopenharmony_ci bool valid; /* The build ID note has been matched. */ 150da0c48c4Sopenharmony_ci bool relocated; /* Partial relocation of all sections done. */ 151da0c48c4Sopenharmony_ci 152da0c48c4Sopenharmony_ci Elf *elf; 153da0c48c4Sopenharmony_ci 154da0c48c4Sopenharmony_ci /* This is the lowest p_vaddr in this ELF file, aligned to p_align. 155da0c48c4Sopenharmony_ci For a file without phdrs, this is zero. */ 156da0c48c4Sopenharmony_ci GElf_Addr vaddr; 157da0c48c4Sopenharmony_ci 158da0c48c4Sopenharmony_ci /* This is an address chosen for synchronization between the main file 159da0c48c4Sopenharmony_ci and the debug file. See dwfl_module_getdwarf.c for how it's chosen. */ 160da0c48c4Sopenharmony_ci GElf_Addr address_sync; 161da0c48c4Sopenharmony_ci}; 162da0c48c4Sopenharmony_ci 163da0c48c4Sopenharmony_cistruct Dwfl_Module 164da0c48c4Sopenharmony_ci{ 165da0c48c4Sopenharmony_ci Dwfl *dwfl; 166da0c48c4Sopenharmony_ci struct Dwfl_Module *next; /* Link on Dwfl.modulelist. */ 167da0c48c4Sopenharmony_ci 168da0c48c4Sopenharmony_ci void *userdata; 169da0c48c4Sopenharmony_ci 170da0c48c4Sopenharmony_ci char *name; /* Iterator name for this module. */ 171da0c48c4Sopenharmony_ci GElf_Addr low_addr, high_addr; 172da0c48c4Sopenharmony_ci 173da0c48c4Sopenharmony_ci struct dwfl_file main, debug, aux_sym; 174da0c48c4Sopenharmony_ci GElf_Addr main_bias; 175da0c48c4Sopenharmony_ci Ebl *ebl; 176da0c48c4Sopenharmony_ci GElf_Half e_type; /* GElf_Ehdr.e_type cache. */ 177da0c48c4Sopenharmony_ci Dwfl_Error elferr; /* Previous failure to open main file. */ 178da0c48c4Sopenharmony_ci 179da0c48c4Sopenharmony_ci struct dwfl_relocation *reloc_info; /* Relocatable sections. */ 180da0c48c4Sopenharmony_ci 181da0c48c4Sopenharmony_ci struct dwfl_file *symfile; /* Either main or debug. */ 182da0c48c4Sopenharmony_ci Elf_Data *symdata; /* Data in the ELF symbol table section. */ 183da0c48c4Sopenharmony_ci Elf_Data *aux_symdata; /* Data in the auxiliary ELF symbol table. */ 184da0c48c4Sopenharmony_ci size_t syments; /* sh_size / sh_entsize of that section. */ 185da0c48c4Sopenharmony_ci size_t aux_syments; /* sh_size / sh_entsize of aux_sym section. */ 186da0c48c4Sopenharmony_ci int first_global; /* Index of first global symbol of table. */ 187da0c48c4Sopenharmony_ci int aux_first_global; /* Index of first global of aux_sym table. */ 188da0c48c4Sopenharmony_ci Elf_Data *symstrdata; /* Data for its string table. */ 189da0c48c4Sopenharmony_ci Elf_Data *aux_symstrdata; /* Data for aux_sym string table. */ 190da0c48c4Sopenharmony_ci Elf_Data *symxndxdata; /* Data in the extended section index table. */ 191da0c48c4Sopenharmony_ci Elf_Data *aux_symxndxdata; /* Data in the extended auxiliary table. */ 192da0c48c4Sopenharmony_ci 193da0c48c4Sopenharmony_ci char *elfdir; /* The dir where we found the main Elf. */ 194da0c48c4Sopenharmony_ci 195da0c48c4Sopenharmony_ci Dwarf *dw; /* libdw handle for its debugging info. */ 196da0c48c4Sopenharmony_ci Dwarf *alt; /* Dwarf used for dwarf_setalt, or NULL. */ 197da0c48c4Sopenharmony_ci int alt_fd; /* descriptor, only valid when alt != NULL. */ 198da0c48c4Sopenharmony_ci Elf *alt_elf; /* Elf for alt Dwarf. */ 199da0c48c4Sopenharmony_ci 200da0c48c4Sopenharmony_ci Dwfl_Error symerr; /* Previous failure to load symbols. */ 201da0c48c4Sopenharmony_ci Dwfl_Error dwerr; /* Previous failure to load DWARF. */ 202da0c48c4Sopenharmony_ci 203da0c48c4Sopenharmony_ci /* Known CU's in this module. */ 204da0c48c4Sopenharmony_ci struct dwfl_cu *first_cu, **cu; 205da0c48c4Sopenharmony_ci 206da0c48c4Sopenharmony_ci void *lazy_cu_root; /* Table indexed by Dwarf_Off of CU. */ 207da0c48c4Sopenharmony_ci 208da0c48c4Sopenharmony_ci struct dwfl_arange *aranges; /* Mapping of addresses in module to CUs. */ 209da0c48c4Sopenharmony_ci 210da0c48c4Sopenharmony_ci void *build_id_bits; /* malloc'd copy of build ID bits. */ 211da0c48c4Sopenharmony_ci GElf_Addr build_id_vaddr; /* Address where they reside, 0 if unknown. */ 212da0c48c4Sopenharmony_ci int build_id_len; /* -1 for prior failure, 0 if unset. */ 213da0c48c4Sopenharmony_ci 214da0c48c4Sopenharmony_ci unsigned int ncu; 215da0c48c4Sopenharmony_ci unsigned int lazycu; /* Possible users, deleted when none left. */ 216da0c48c4Sopenharmony_ci unsigned int naranges; 217da0c48c4Sopenharmony_ci 218da0c48c4Sopenharmony_ci Dwarf_CFI *dwarf_cfi; /* Cached DWARF CFI for this module. */ 219da0c48c4Sopenharmony_ci Dwarf_CFI *eh_cfi; /* Cached EH CFI for this module. */ 220da0c48c4Sopenharmony_ci 221da0c48c4Sopenharmony_ci int segment; /* Index of first segment table entry. */ 222da0c48c4Sopenharmony_ci bool gc; /* Mark/sweep flag. */ 223da0c48c4Sopenharmony_ci bool is_executable; /* Use Dwfl::executable_for_core? */ 224da0c48c4Sopenharmony_ci}; 225da0c48c4Sopenharmony_ci 226da0c48c4Sopenharmony_ci/* This holds information common for all the threads/tasks/TIDs of one process 227da0c48c4Sopenharmony_ci for backtraces. */ 228da0c48c4Sopenharmony_ci 229da0c48c4Sopenharmony_cistruct Dwfl_Process 230da0c48c4Sopenharmony_ci{ 231da0c48c4Sopenharmony_ci struct Dwfl *dwfl; 232da0c48c4Sopenharmony_ci pid_t pid; 233da0c48c4Sopenharmony_ci const Dwfl_Thread_Callbacks *callbacks; 234da0c48c4Sopenharmony_ci void *callbacks_arg; 235da0c48c4Sopenharmony_ci struct ebl *ebl; 236da0c48c4Sopenharmony_ci bool ebl_close:1; 237da0c48c4Sopenharmony_ci}; 238da0c48c4Sopenharmony_ci 239da0c48c4Sopenharmony_ci/* See its typedef in libdwfl.h. */ 240da0c48c4Sopenharmony_ci 241da0c48c4Sopenharmony_cistruct Dwfl_Thread 242da0c48c4Sopenharmony_ci{ 243da0c48c4Sopenharmony_ci Dwfl_Process *process; 244da0c48c4Sopenharmony_ci pid_t tid; 245da0c48c4Sopenharmony_ci /* Bottom (innermost) frame while we're initializing, NULL afterwards. */ 246da0c48c4Sopenharmony_ci Dwfl_Frame *unwound; 247da0c48c4Sopenharmony_ci void *callbacks_arg; 248da0c48c4Sopenharmony_ci}; 249da0c48c4Sopenharmony_ci 250da0c48c4Sopenharmony_ci/* See its typedef in libdwfl.h. */ 251da0c48c4Sopenharmony_ci 252da0c48c4Sopenharmony_cistruct Dwfl_Frame 253da0c48c4Sopenharmony_ci{ 254da0c48c4Sopenharmony_ci Dwfl_Thread *thread; 255da0c48c4Sopenharmony_ci /* Previous (outer) frame. */ 256da0c48c4Sopenharmony_ci Dwfl_Frame *unwound; 257da0c48c4Sopenharmony_ci bool signal_frame : 1; 258da0c48c4Sopenharmony_ci bool initial_frame : 1; 259da0c48c4Sopenharmony_ci enum 260da0c48c4Sopenharmony_ci { 261da0c48c4Sopenharmony_ci /* This structure is still being initialized or there was an error 262da0c48c4Sopenharmony_ci initializing it. */ 263da0c48c4Sopenharmony_ci DWFL_FRAME_STATE_ERROR, 264da0c48c4Sopenharmony_ci /* PC field is valid. */ 265da0c48c4Sopenharmony_ci DWFL_FRAME_STATE_PC_SET, 266da0c48c4Sopenharmony_ci /* PC field is undefined, this means the next (inner) frame was the 267da0c48c4Sopenharmony_ci outermost frame. */ 268da0c48c4Sopenharmony_ci DWFL_FRAME_STATE_PC_UNDEFINED 269da0c48c4Sopenharmony_ci } pc_state; 270da0c48c4Sopenharmony_ci /* Either initialized from appropriate REGS element or on some archs 271da0c48c4Sopenharmony_ci initialized separately as the return address has no DWARF register. */ 272da0c48c4Sopenharmony_ci Dwarf_Addr pc; 273da0c48c4Sopenharmony_ci /* (1 << X) bitmask where 0 <= X < ebl_frame_nregs. */ 274da0c48c4Sopenharmony_ci uint64_t regs_set[3]; 275da0c48c4Sopenharmony_ci /* REGS array size is ebl_frame_nregs. 276da0c48c4Sopenharmony_ci REGS_SET tells which of the REGS are valid. */ 277da0c48c4Sopenharmony_ci Dwarf_Addr regs[]; 278da0c48c4Sopenharmony_ci}; 279da0c48c4Sopenharmony_ci 280da0c48c4Sopenharmony_ci/* Fetch value from Dwfl_Frame->regs indexed by DWARF REGNO. The 281da0c48c4Sopenharmony_ci function returns 0 on success, -1 on error (invalid DWARF register 282da0c48c4Sopenharmony_ci number), 1 if the value of the register in the frame is unknown. 283da0c48c4Sopenharmony_ci Even on error, no error code is set. */ 284da0c48c4Sopenharmony_ciint __libdwfl_frame_reg_get (Dwfl_Frame *state, unsigned regno, 285da0c48c4Sopenharmony_ci Dwarf_Addr *val) 286da0c48c4Sopenharmony_ci internal_function; 287da0c48c4Sopenharmony_ci 288da0c48c4Sopenharmony_ci/* Store value to Dwfl_Frame->regs indexed by DWARF REGNO. 289da0c48c4Sopenharmony_ci No error code is set if the function returns FALSE. */ 290da0c48c4Sopenharmony_cibool __libdwfl_frame_reg_set (Dwfl_Frame *state, unsigned regno, 291da0c48c4Sopenharmony_ci Dwarf_Addr val) 292da0c48c4Sopenharmony_ci internal_function; 293da0c48c4Sopenharmony_ci 294da0c48c4Sopenharmony_ci/* Information cached about each CU in Dwfl_Module.dw. */ 295da0c48c4Sopenharmony_cistruct dwfl_cu 296da0c48c4Sopenharmony_ci{ 297da0c48c4Sopenharmony_ci /* This caches libdw information about the CU. It's also the 298da0c48c4Sopenharmony_ci address passed back to users, so we take advantage of the 299da0c48c4Sopenharmony_ci fact that it's placed first to cast back. */ 300da0c48c4Sopenharmony_ci Dwarf_Die die; 301da0c48c4Sopenharmony_ci 302da0c48c4Sopenharmony_ci Dwfl_Module *mod; /* Pointer back to containing module. */ 303da0c48c4Sopenharmony_ci 304da0c48c4Sopenharmony_ci struct dwfl_cu *next; /* CU immediately following in the file. */ 305da0c48c4Sopenharmony_ci 306da0c48c4Sopenharmony_ci struct Dwfl_Lines *lines; 307da0c48c4Sopenharmony_ci}; 308da0c48c4Sopenharmony_ci 309da0c48c4Sopenharmony_cistruct Dwfl_Lines 310da0c48c4Sopenharmony_ci{ 311da0c48c4Sopenharmony_ci struct dwfl_cu *cu; 312da0c48c4Sopenharmony_ci 313da0c48c4Sopenharmony_ci /* This is what the opaque Dwfl_Line * pointers we pass to users are. 314da0c48c4Sopenharmony_ci We need to recover pointers to our struct dwfl_cu and a record in 315da0c48c4Sopenharmony_ci libdw's Dwarf_Line table. To minimize the memory used in addition 316da0c48c4Sopenharmony_ci to libdw's Dwarf_Lines buffer, we just point to our own index in 317da0c48c4Sopenharmony_ci this table, and have one pointer back to the CU. The indices here 318da0c48c4Sopenharmony_ci match those in libdw's Dwarf_CU.lines->info table. */ 319da0c48c4Sopenharmony_ci struct Dwfl_Line 320da0c48c4Sopenharmony_ci { 321da0c48c4Sopenharmony_ci unsigned int idx; /* My index in the dwfl_cu.lines table. */ 322da0c48c4Sopenharmony_ci } idx[0]; 323da0c48c4Sopenharmony_ci}; 324da0c48c4Sopenharmony_ci 325da0c48c4Sopenharmony_cistatic inline struct dwfl_cu * 326da0c48c4Sopenharmony_cidwfl_linecu_inline (const Dwfl_Line *line) 327da0c48c4Sopenharmony_ci{ 328da0c48c4Sopenharmony_ci const struct Dwfl_Lines *lines = ((const void *) line 329da0c48c4Sopenharmony_ci - offsetof (struct Dwfl_Lines, 330da0c48c4Sopenharmony_ci idx[line->idx])); 331da0c48c4Sopenharmony_ci return lines->cu; 332da0c48c4Sopenharmony_ci} 333da0c48c4Sopenharmony_ci#define dwfl_linecu dwfl_linecu_inline 334da0c48c4Sopenharmony_ci 335da0c48c4Sopenharmony_cistatic inline GElf_Addr 336da0c48c4Sopenharmony_cidwfl_adjusted_address (Dwfl_Module *mod, GElf_Addr addr) 337da0c48c4Sopenharmony_ci{ 338da0c48c4Sopenharmony_ci return addr + mod->main_bias; 339da0c48c4Sopenharmony_ci} 340da0c48c4Sopenharmony_ci 341da0c48c4Sopenharmony_cistatic inline GElf_Addr 342da0c48c4Sopenharmony_cidwfl_deadjust_address (Dwfl_Module *mod, GElf_Addr addr) 343da0c48c4Sopenharmony_ci{ 344da0c48c4Sopenharmony_ci return addr - mod->main_bias; 345da0c48c4Sopenharmony_ci} 346da0c48c4Sopenharmony_ci 347da0c48c4Sopenharmony_cistatic inline Dwarf_Addr 348da0c48c4Sopenharmony_cidwfl_adjusted_dwarf_addr (Dwfl_Module *mod, Dwarf_Addr addr) 349da0c48c4Sopenharmony_ci{ 350da0c48c4Sopenharmony_ci return dwfl_adjusted_address (mod, (addr 351da0c48c4Sopenharmony_ci - mod->debug.address_sync 352da0c48c4Sopenharmony_ci + mod->main.address_sync)); 353da0c48c4Sopenharmony_ci} 354da0c48c4Sopenharmony_ci 355da0c48c4Sopenharmony_cistatic inline Dwarf_Addr 356da0c48c4Sopenharmony_cidwfl_deadjust_dwarf_addr (Dwfl_Module *mod, Dwarf_Addr addr) 357da0c48c4Sopenharmony_ci{ 358da0c48c4Sopenharmony_ci return (dwfl_deadjust_address (mod, addr) 359da0c48c4Sopenharmony_ci - mod->main.address_sync 360da0c48c4Sopenharmony_ci + mod->debug.address_sync); 361da0c48c4Sopenharmony_ci} 362da0c48c4Sopenharmony_ci 363da0c48c4Sopenharmony_cistatic inline Dwarf_Addr 364da0c48c4Sopenharmony_cidwfl_adjusted_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr) 365da0c48c4Sopenharmony_ci{ 366da0c48c4Sopenharmony_ci return dwfl_adjusted_address (mod, (addr 367da0c48c4Sopenharmony_ci - mod->aux_sym.address_sync 368da0c48c4Sopenharmony_ci + mod->main.address_sync)); 369da0c48c4Sopenharmony_ci} 370da0c48c4Sopenharmony_ci 371da0c48c4Sopenharmony_cistatic inline Dwarf_Addr 372da0c48c4Sopenharmony_cidwfl_deadjust_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr) 373da0c48c4Sopenharmony_ci{ 374da0c48c4Sopenharmony_ci return (dwfl_deadjust_address (mod, addr) 375da0c48c4Sopenharmony_ci - mod->main.address_sync 376da0c48c4Sopenharmony_ci + mod->aux_sym.address_sync); 377da0c48c4Sopenharmony_ci} 378da0c48c4Sopenharmony_ci 379da0c48c4Sopenharmony_cistatic inline GElf_Addr 380da0c48c4Sopenharmony_cidwfl_adjusted_st_value (Dwfl_Module *mod, Elf *symelf, GElf_Addr addr) 381da0c48c4Sopenharmony_ci{ 382da0c48c4Sopenharmony_ci if (symelf == mod->main.elf) 383da0c48c4Sopenharmony_ci return dwfl_adjusted_address (mod, addr); 384da0c48c4Sopenharmony_ci if (symelf == mod->debug.elf) 385da0c48c4Sopenharmony_ci return dwfl_adjusted_dwarf_addr (mod, addr); 386da0c48c4Sopenharmony_ci return dwfl_adjusted_aux_sym_addr (mod, addr); 387da0c48c4Sopenharmony_ci} 388da0c48c4Sopenharmony_ci 389da0c48c4Sopenharmony_cistatic inline GElf_Addr 390da0c48c4Sopenharmony_cidwfl_deadjust_st_value (Dwfl_Module *mod, Elf *symelf, GElf_Addr addr) 391da0c48c4Sopenharmony_ci{ 392da0c48c4Sopenharmony_ci if (symelf == mod->main.elf) 393da0c48c4Sopenharmony_ci return dwfl_deadjust_address (mod, addr); 394da0c48c4Sopenharmony_ci if (symelf == mod->debug.elf) 395da0c48c4Sopenharmony_ci return dwfl_deadjust_dwarf_addr (mod, addr); 396da0c48c4Sopenharmony_ci return dwfl_deadjust_aux_sym_addr (mod, addr); 397da0c48c4Sopenharmony_ci} 398da0c48c4Sopenharmony_ci 399da0c48c4Sopenharmony_ci/* This describes a contiguous address range that lies in a single CU. 400da0c48c4Sopenharmony_ci We condense runs of Dwarf_Arange entries for the same CU into this. */ 401da0c48c4Sopenharmony_cistruct dwfl_arange 402da0c48c4Sopenharmony_ci{ 403da0c48c4Sopenharmony_ci struct dwfl_cu *cu; 404da0c48c4Sopenharmony_ci size_t arange; /* Index in Dwarf_Aranges. */ 405da0c48c4Sopenharmony_ci}; 406da0c48c4Sopenharmony_ci 407da0c48c4Sopenharmony_ci#define __LIBDWFL_REMOTE_MEM_CACHE_SIZE 4096 408da0c48c4Sopenharmony_ci/* Structure for caching remote memory reads as used by __libdwfl_pid_arg. */ 409da0c48c4Sopenharmony_cistruct __libdwfl_remote_mem_cache 410da0c48c4Sopenharmony_ci{ 411da0c48c4Sopenharmony_ci Dwarf_Addr addr; /* Remote address. */ 412da0c48c4Sopenharmony_ci Dwarf_Off len; /* Zero if cleared, otherwise likely 4K. */ 413da0c48c4Sopenharmony_ci unsigned char buf[__LIBDWFL_REMOTE_MEM_CACHE_SIZE]; /* The actual cache. */ 414da0c48c4Sopenharmony_ci}; 415da0c48c4Sopenharmony_ci 416da0c48c4Sopenharmony_ci/* Structure used for keeping track of ptrace attaching a thread. 417da0c48c4Sopenharmony_ci Shared by linux-pid-attach and linux-proc-maps. If it has been setup 418da0c48c4Sopenharmony_ci then get the instance through __libdwfl_get_pid_arg. */ 419da0c48c4Sopenharmony_cistruct __libdwfl_pid_arg 420da0c48c4Sopenharmony_ci{ 421da0c48c4Sopenharmony_ci /* /proc/PID/task/. */ 422da0c48c4Sopenharmony_ci DIR *dir; 423da0c48c4Sopenharmony_ci /* Elf for /proc/PID/exe. Set to NULL if it couldn't be opened. */ 424da0c48c4Sopenharmony_ci Elf *elf; 425da0c48c4Sopenharmony_ci /* Remote memory cache, NULL if there is no memory cached. 426da0c48c4Sopenharmony_ci Should be cleared on detachment (because that makes the thread 427da0c48c4Sopenharmony_ci runnable and the cache invalid). */ 428da0c48c4Sopenharmony_ci struct __libdwfl_remote_mem_cache *mem_cache; 429da0c48c4Sopenharmony_ci /* fd for /proc/PID/exe. Set to -1 if it couldn't be opened. */ 430da0c48c4Sopenharmony_ci int elf_fd; 431da0c48c4Sopenharmony_ci /* It is 0 if not used. */ 432da0c48c4Sopenharmony_ci pid_t tid_attached; 433da0c48c4Sopenharmony_ci /* Valid only if TID_ATTACHED is not zero. */ 434da0c48c4Sopenharmony_ci bool tid_was_stopped; 435da0c48c4Sopenharmony_ci /* True if threads are ptrace stopped by caller. */ 436da0c48c4Sopenharmony_ci bool assume_ptrace_stopped; 437da0c48c4Sopenharmony_ci}; 438da0c48c4Sopenharmony_ci 439da0c48c4Sopenharmony_ci/* If DWfl is not NULL and a Dwfl_Process has been setup that has 440da0c48c4Sopenharmony_ci Dwfl_Thread_Callbacks set to pid_thread_callbacks, then return the 441da0c48c4Sopenharmony_ci callbacks_arg, which will be a struct __libdwfl_pid_arg. Otherwise 442da0c48c4Sopenharmony_ci returns NULL. */ 443da0c48c4Sopenharmony_ciextern struct __libdwfl_pid_arg *__libdwfl_get_pid_arg (Dwfl *dwfl) 444da0c48c4Sopenharmony_ci internal_function; 445da0c48c4Sopenharmony_ci 446da0c48c4Sopenharmony_ci/* Makes sure the given tid is attached. On success returns true and 447da0c48c4Sopenharmony_ci sets tid_was_stopped. */ 448da0c48c4Sopenharmony_ciextern bool __libdwfl_ptrace_attach (pid_t tid, bool *tid_was_stoppedp) 449da0c48c4Sopenharmony_ci internal_function; 450da0c48c4Sopenharmony_ci 451da0c48c4Sopenharmony_ci/* Detaches a tid that was attached through 452da0c48c4Sopenharmony_ci __libdwfl_ptrace_attach. Must be given the tid_was_stopped as set 453da0c48c4Sopenharmony_ci by __libdwfl_ptrace_attach. */ 454da0c48c4Sopenharmony_ciextern void __libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped) 455da0c48c4Sopenharmony_ci internal_function; 456da0c48c4Sopenharmony_ci 457da0c48c4Sopenharmony_ci 458da0c48c4Sopenharmony_ci/* Internal wrapper for old dwfl_module_getsym and new dwfl_module_getsym_info. 459da0c48c4Sopenharmony_ci adjust_st_value set to true returns adjusted SYM st_value, set to false 460da0c48c4Sopenharmony_ci it will not adjust SYM at all, but does match against resolved *ADDR. */ 461da0c48c4Sopenharmony_ciextern const char *__libdwfl_getsym (Dwfl_Module *mod, int ndx, GElf_Sym *sym, 462da0c48c4Sopenharmony_ci GElf_Addr *addr, GElf_Word *shndxp, 463da0c48c4Sopenharmony_ci Elf **elfp, Dwarf_Addr *biasp, 464da0c48c4Sopenharmony_ci bool *resolved, bool adjust_st_value) 465da0c48c4Sopenharmony_ci internal_function; 466da0c48c4Sopenharmony_ci 467da0c48c4Sopenharmony_ciextern void __libdwfl_module_free (Dwfl_Module *mod) internal_function; 468da0c48c4Sopenharmony_ci 469da0c48c4Sopenharmony_ci/* Find the main ELF file, update MOD->elferr and/or MOD->main.elf. */ 470da0c48c4Sopenharmony_ciextern void __libdwfl_getelf (Dwfl_Module *mod) internal_function; 471da0c48c4Sopenharmony_ci 472da0c48c4Sopenharmony_ci/* Process relocations in debugging sections in an ET_REL file. 473da0c48c4Sopenharmony_ci FILE must be opened with ELF_C_READ_MMAP_PRIVATE or ELF_C_READ, 474da0c48c4Sopenharmony_ci to make it possible to relocate the data in place (or ELF_C_RDWR or 475da0c48c4Sopenharmony_ci ELF_C_RDWR_MMAP if you intend to modify the Elf file on disk). After 476da0c48c4Sopenharmony_ci this, dwarf_begin_elf on FILE will read the relocated data. 477da0c48c4Sopenharmony_ci 478da0c48c4Sopenharmony_ci When DEBUG is false, apply partial relocation to all sections. */ 479da0c48c4Sopenharmony_ciextern Dwfl_Error __libdwfl_relocate (Dwfl_Module *mod, Elf *file, bool debug) 480da0c48c4Sopenharmony_ci internal_function; 481da0c48c4Sopenharmony_ci 482da0c48c4Sopenharmony_ci/* Find the section index in mod->main.elf that contains the given 483da0c48c4Sopenharmony_ci *ADDR. Adjusts *ADDR to be section relative on success, returns 484da0c48c4Sopenharmony_ci SHN_UNDEF on failure. */ 485da0c48c4Sopenharmony_ciextern size_t __libdwfl_find_section_ndx (Dwfl_Module *mod, Dwarf_Addr *addr) 486da0c48c4Sopenharmony_ci internal_function; 487da0c48c4Sopenharmony_ci 488da0c48c4Sopenharmony_ci/* Process (simple) relocations in arbitrary section TSCN of an ET_REL file. 489da0c48c4Sopenharmony_ci RELOCSCN is SHT_REL or SHT_RELA and TSCN is its sh_info target section. */ 490da0c48c4Sopenharmony_ciextern Dwfl_Error __libdwfl_relocate_section (Dwfl_Module *mod, Elf *relocated, 491da0c48c4Sopenharmony_ci Elf_Scn *relocscn, Elf_Scn *tscn, 492da0c48c4Sopenharmony_ci bool partial) 493da0c48c4Sopenharmony_ci internal_function; 494da0c48c4Sopenharmony_ci 495da0c48c4Sopenharmony_ci/* Adjust *VALUE from section-relative to absolute. 496da0c48c4Sopenharmony_ci MOD->dwfl->callbacks->section_address is called to determine the actual 497da0c48c4Sopenharmony_ci address of a loaded section. */ 498da0c48c4Sopenharmony_ciextern Dwfl_Error __libdwfl_relocate_value (Dwfl_Module *mod, Elf *elf, 499da0c48c4Sopenharmony_ci size_t *shstrndx_cache, 500da0c48c4Sopenharmony_ci Elf32_Word shndx, 501da0c48c4Sopenharmony_ci GElf_Addr *value) 502da0c48c4Sopenharmony_ci internal_function; 503da0c48c4Sopenharmony_ci 504da0c48c4Sopenharmony_ci/* Ensure that MOD->ebl is set up. */ 505da0c48c4Sopenharmony_ciextern Dwfl_Error __libdwfl_module_getebl (Dwfl_Module *mod) internal_function; 506da0c48c4Sopenharmony_ci 507da0c48c4Sopenharmony_ci/* Install a new Dwarf_CFI in *SLOT (MOD->eh_cfi or MOD->dwarf_cfi). */ 508da0c48c4Sopenharmony_ciextern Dwarf_CFI *__libdwfl_set_cfi (Dwfl_Module *mod, Dwarf_CFI **slot, 509da0c48c4Sopenharmony_ci Dwarf_CFI *cfi) 510da0c48c4Sopenharmony_ci internal_function; 511da0c48c4Sopenharmony_ci 512da0c48c4Sopenharmony_ci/* Iterate through all the CU's in the module. Start by passing a null 513da0c48c4Sopenharmony_ci LASTCU, and then pass the last *CU returned. Success return with null 514da0c48c4Sopenharmony_ci *CU no more CUs. */ 515da0c48c4Sopenharmony_ciextern Dwfl_Error __libdwfl_nextcu (Dwfl_Module *mod, struct dwfl_cu *lastcu, 516da0c48c4Sopenharmony_ci struct dwfl_cu **cu) internal_function; 517da0c48c4Sopenharmony_ci 518da0c48c4Sopenharmony_ci/* Find the CU by address. */ 519da0c48c4Sopenharmony_ciextern Dwfl_Error __libdwfl_addrcu (Dwfl_Module *mod, Dwarf_Addr addr, 520da0c48c4Sopenharmony_ci struct dwfl_cu **cu) internal_function; 521da0c48c4Sopenharmony_ci 522da0c48c4Sopenharmony_ci/* Ensure that CU->lines (and CU->cu->lines) is set up. */ 523da0c48c4Sopenharmony_ciextern Dwfl_Error __libdwfl_cu_getsrclines (struct dwfl_cu *cu) 524da0c48c4Sopenharmony_ci internal_function; 525da0c48c4Sopenharmony_ci 526da0c48c4Sopenharmony_ci/* Look in ELF for an NT_GNU_BUILD_ID note. Store it to BUILD_ID_BITS, 527da0c48c4Sopenharmony_ci its vaddr in ELF to BUILD_ID_VADDR (it is unrelocated, even if MOD is not 528da0c48c4Sopenharmony_ci NULL) and store length to BUILD_ID_LEN. Returns -1 for errors, 1 if it was 529da0c48c4Sopenharmony_ci stored and 0 if no note is found. MOD may be NULL, MOD must be non-NULL 530da0c48c4Sopenharmony_ci only if ELF is ET_REL. */ 531da0c48c4Sopenharmony_ciextern int __libdwfl_find_elf_build_id (Dwfl_Module *mod, Elf *elf, 532da0c48c4Sopenharmony_ci const void **build_id_bits, 533da0c48c4Sopenharmony_ci GElf_Addr *build_id_elfaddr, 534da0c48c4Sopenharmony_ci int *build_id_len) 535da0c48c4Sopenharmony_ci internal_function; 536da0c48c4Sopenharmony_ci 537da0c48c4Sopenharmony_ci/* Look in ELF for an NT_GNU_BUILD_ID note. If SET is true, store it 538da0c48c4Sopenharmony_ci in MOD and return its length. If SET is false, instead compare it 539da0c48c4Sopenharmony_ci to that stored in MOD and return 2 if they match, 1 if they do not. 540da0c48c4Sopenharmony_ci Returns -1 for errors, 0 if no note is found. */ 541da0c48c4Sopenharmony_ciextern int __libdwfl_find_build_id (Dwfl_Module *mod, bool set, Elf *elf) 542da0c48c4Sopenharmony_ci internal_function; 543da0c48c4Sopenharmony_ci 544da0c48c4Sopenharmony_ci/* Open a main or debuginfo file by its build ID, returns the fd. */ 545da0c48c4Sopenharmony_ciextern int __libdwfl_open_mod_by_build_id (Dwfl_Module *mod, bool debug, 546da0c48c4Sopenharmony_ci char **file_name) internal_function; 547da0c48c4Sopenharmony_ci 548da0c48c4Sopenharmony_ci/* Same, but takes an explicit build_id, can also be used for alt debug. */ 549da0c48c4Sopenharmony_ciextern int __libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug, 550da0c48c4Sopenharmony_ci char **file_name, const size_t id_len, 551da0c48c4Sopenharmony_ci const uint8_t *id) internal_function; 552da0c48c4Sopenharmony_ci 553da0c48c4Sopenharmony_ciextern uint32_t __libdwfl_crc32 (uint32_t crc, unsigned char *buf, size_t len) 554da0c48c4Sopenharmony_ci attribute_hidden; 555da0c48c4Sopenharmony_ciextern int __libdwfl_crc32_file (int fd, uint32_t *resp) attribute_hidden; 556da0c48c4Sopenharmony_ci 557da0c48c4Sopenharmony_ci 558da0c48c4Sopenharmony_ci/* Given ELF and some parameters return TRUE if the *P return value parameters 559da0c48c4Sopenharmony_ci have been successfully filled in. Any of the *P parameters can be NULL. */ 560da0c48c4Sopenharmony_ciextern bool __libdwfl_elf_address_range (Elf *elf, GElf_Addr base, 561da0c48c4Sopenharmony_ci bool add_p_vaddr, bool sanity, 562da0c48c4Sopenharmony_ci GElf_Addr *vaddrp, 563da0c48c4Sopenharmony_ci GElf_Addr *address_syncp, 564da0c48c4Sopenharmony_ci GElf_Addr *startp, GElf_Addr *endp, 565da0c48c4Sopenharmony_ci GElf_Addr *biasp, GElf_Half *e_typep) 566da0c48c4Sopenharmony_ci internal_function; 567da0c48c4Sopenharmony_ci 568da0c48c4Sopenharmony_ci/* Meat of dwfl_report_elf, given elf_begin just called. 569da0c48c4Sopenharmony_ci Consumes ELF on success, not on failure. */ 570da0c48c4Sopenharmony_ciextern Dwfl_Module *__libdwfl_report_elf (Dwfl *dwfl, const char *name, 571da0c48c4Sopenharmony_ci const char *file_name, int fd, 572da0c48c4Sopenharmony_ci Elf *elf, GElf_Addr base, 573da0c48c4Sopenharmony_ci bool add_p_vaddr, bool sanity) 574da0c48c4Sopenharmony_ci internal_function; 575da0c48c4Sopenharmony_ci 576da0c48c4Sopenharmony_ci/* Meat of dwfl_report_offline. */ 577da0c48c4Sopenharmony_ciextern Dwfl_Module *__libdwfl_report_offline (Dwfl *dwfl, const char *name, 578da0c48c4Sopenharmony_ci const char *file_name, 579da0c48c4Sopenharmony_ci int fd, bool closefd, 580da0c48c4Sopenharmony_ci int (*predicate) (const char *, 581da0c48c4Sopenharmony_ci const char *)) 582da0c48c4Sopenharmony_ci internal_function; 583da0c48c4Sopenharmony_ci 584da0c48c4Sopenharmony_ci/* Free PROCESS. Unlink and free also any structures it references. */ 585da0c48c4Sopenharmony_ciextern void __libdwfl_process_free (Dwfl_Process *process) 586da0c48c4Sopenharmony_ci internal_function; 587da0c48c4Sopenharmony_ci 588da0c48c4Sopenharmony_ci/* Update STATE->unwound for the unwound frame. 589da0c48c4Sopenharmony_ci On error STATE->unwound == NULL 590da0c48c4Sopenharmony_ci or STATE->unwound->pc_state == DWFL_FRAME_STATE_ERROR; 591da0c48c4Sopenharmony_ci in such case dwfl_errno () is set. 592da0c48c4Sopenharmony_ci If STATE->unwound->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED 593da0c48c4Sopenharmony_ci then STATE was the last valid frame. */ 594da0c48c4Sopenharmony_ciextern void __libdwfl_frame_unwind (Dwfl_Frame *state) 595da0c48c4Sopenharmony_ci internal_function; 596da0c48c4Sopenharmony_ci 597da0c48c4Sopenharmony_ci/* Align segment START downwards or END upwards addresses according to DWFL. */ 598da0c48c4Sopenharmony_ciextern GElf_Addr __libdwfl_segment_start (Dwfl *dwfl, GElf_Addr start) 599da0c48c4Sopenharmony_ci internal_function; 600da0c48c4Sopenharmony_ciextern GElf_Addr __libdwfl_segment_end (Dwfl *dwfl, GElf_Addr end) 601da0c48c4Sopenharmony_ci internal_function; 602da0c48c4Sopenharmony_ci 603da0c48c4Sopenharmony_ci/* Decompression wrappers: decompress whole file into memory. */ 604da0c48c4Sopenharmony_ciextern Dwfl_Error __libdw_gunzip (int fd, off_t start_offset, 605da0c48c4Sopenharmony_ci void *mapped, size_t mapped_size, 606da0c48c4Sopenharmony_ci void **whole, size_t *whole_size) 607da0c48c4Sopenharmony_ci internal_function; 608da0c48c4Sopenharmony_ciextern Dwfl_Error __libdw_bunzip2 (int fd, off_t start_offset, 609da0c48c4Sopenharmony_ci void *mapped, size_t mapped_size, 610da0c48c4Sopenharmony_ci void **whole, size_t *whole_size) 611da0c48c4Sopenharmony_ci internal_function; 612da0c48c4Sopenharmony_ciextern Dwfl_Error __libdw_unlzma (int fd, off_t start_offset, 613da0c48c4Sopenharmony_ci void *mapped, size_t mapped_size, 614da0c48c4Sopenharmony_ci void **whole, size_t *whole_size) 615da0c48c4Sopenharmony_ci internal_function; 616da0c48c4Sopenharmony_ciextern Dwfl_Error __libdw_unzstd (int fd, off_t start_offset, 617da0c48c4Sopenharmony_ci void *mapped, size_t mapped_size, 618da0c48c4Sopenharmony_ci void **whole, size_t *whole_size) 619da0c48c4Sopenharmony_ci internal_function; 620da0c48c4Sopenharmony_ci 621da0c48c4Sopenharmony_ci/* Skip the image header before a file image: updates *START_OFFSET. */ 622da0c48c4Sopenharmony_ciextern Dwfl_Error __libdw_image_header (int fd, off_t *start_offset, 623da0c48c4Sopenharmony_ci void *mapped, size_t mapped_size) 624da0c48c4Sopenharmony_ci internal_function; 625da0c48c4Sopenharmony_ci 626da0c48c4Sopenharmony_ci/* Open Elf handle on *FDP. This handles decompression and checks 627da0c48c4Sopenharmony_ci elf_kind. Succeed only for ELF_K_ELF, or also ELF_K_AR if ARCHIVE_OK. 628da0c48c4Sopenharmony_ci Returns DWFL_E_NOERROR and sets *ELFP on success, resets *FDP to -1 if 629da0c48c4Sopenharmony_ci it's no longer used. Resets *FDP on failure too iff CLOSE_ON_FAIL. */ 630da0c48c4Sopenharmony_ciextern Dwfl_Error __libdw_open_file (int *fdp, Elf **elfp, 631da0c48c4Sopenharmony_ci bool close_on_fail, bool archive_ok) 632da0c48c4Sopenharmony_ci internal_function; 633da0c48c4Sopenharmony_ci 634da0c48c4Sopenharmony_ci/* Same as __libdw_open_file, but opens Elf handle from memory region. */ 635da0c48c4Sopenharmony_ciextern Dwfl_Error __libdw_open_elf_memory (char *data, size_t size, Elf **elfp, 636da0c48c4Sopenharmony_ci bool archive_ok) 637da0c48c4Sopenharmony_ci internal_function; 638da0c48c4Sopenharmony_ci 639da0c48c4Sopenharmony_ci/* Same as __libdw_open_file, but never closes the given file 640da0c48c4Sopenharmony_ci descriptor and ELF_K_AR is always an acceptable type. */ 641da0c48c4Sopenharmony_ciextern Dwfl_Error __libdw_open_elf (int fd, Elf **elfp) internal_function; 642da0c48c4Sopenharmony_ci 643da0c48c4Sopenharmony_ci/* Fetch PT_DYNAMIC P_VADDR from ELF and store it to *VADDRP. Return success. 644da0c48c4Sopenharmony_ci *VADDRP is not modified if the function fails. */ 645da0c48c4Sopenharmony_ciextern bool __libdwfl_dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp) 646da0c48c4Sopenharmony_ci internal_function; 647da0c48c4Sopenharmony_ci 648da0c48c4Sopenharmony_ci#ifdef ENABLE_LIBDEBUGINFOD 649da0c48c4Sopenharmony_ci/* Internal interface to libdebuginfod (if installed). */ 650da0c48c4Sopenharmony_ciint 651da0c48c4Sopenharmony_ci__libdwfl_debuginfod_find_executable (Dwfl *dwfl, 652da0c48c4Sopenharmony_ci const unsigned char *build_id_bits, 653da0c48c4Sopenharmony_ci size_t build_id_len); 654da0c48c4Sopenharmony_ciint 655da0c48c4Sopenharmony_ci__libdwfl_debuginfod_find_debuginfo (Dwfl *dwfl, 656da0c48c4Sopenharmony_ci const unsigned char *build_id_bits, 657da0c48c4Sopenharmony_ci size_t build_id_len); 658da0c48c4Sopenharmony_civoid 659da0c48c4Sopenharmony_ci__libdwfl_debuginfod_end (debuginfod_client *c); 660da0c48c4Sopenharmony_ci#endif 661da0c48c4Sopenharmony_ci 662da0c48c4Sopenharmony_ci 663da0c48c4Sopenharmony_ci/* These are working nicely for --core, but are not ready to be 664da0c48c4Sopenharmony_ci exported interfaces quite yet. */ 665da0c48c4Sopenharmony_ci 666da0c48c4Sopenharmony_ci/* Type of callback function ... 667da0c48c4Sopenharmony_ci */ 668da0c48c4Sopenharmony_citypedef bool Dwfl_Memory_Callback (Dwfl *dwfl, int segndx, 669da0c48c4Sopenharmony_ci void **buffer, size_t *buffer_available, 670da0c48c4Sopenharmony_ci GElf_Addr vaddr, size_t minread, void *arg); 671da0c48c4Sopenharmony_ci 672da0c48c4Sopenharmony_ci/* Type of callback function ... 673da0c48c4Sopenharmony_ci */ 674da0c48c4Sopenharmony_citypedef bool Dwfl_Module_Callback (Dwfl_Module *mod, void **userdata, 675da0c48c4Sopenharmony_ci const char *name, Dwarf_Addr base, 676da0c48c4Sopenharmony_ci void **buffer, size_t *buffer_available, 677da0c48c4Sopenharmony_ci GElf_Off cost, GElf_Off worthwhile, 678da0c48c4Sopenharmony_ci GElf_Off whole, GElf_Off contiguous, 679da0c48c4Sopenharmony_ci void *arg, Elf **elfp); 680da0c48c4Sopenharmony_ci 681da0c48c4Sopenharmony_ci/* One shared library (or executable) info from DT_DEBUG link map. */ 682da0c48c4Sopenharmony_cistruct r_debug_info_module 683da0c48c4Sopenharmony_ci{ 684da0c48c4Sopenharmony_ci struct r_debug_info_module *next; 685da0c48c4Sopenharmony_ci /* FD is -1 iff ELF is NULL. */ 686da0c48c4Sopenharmony_ci int fd; 687da0c48c4Sopenharmony_ci Elf *elf; 688da0c48c4Sopenharmony_ci GElf_Addr l_ld; 689da0c48c4Sopenharmony_ci /* START and END are both zero if not valid. */ 690da0c48c4Sopenharmony_ci GElf_Addr start, end; 691da0c48c4Sopenharmony_ci bool disk_file_has_build_id; 692da0c48c4Sopenharmony_ci char name[0]; 693da0c48c4Sopenharmony_ci}; 694da0c48c4Sopenharmony_ci 695da0c48c4Sopenharmony_ci/* Information gathered from DT_DEBUG by dwfl_link_map_report hinted to 696da0c48c4Sopenharmony_ci dwfl_segment_report_module. */ 697da0c48c4Sopenharmony_cistruct r_debug_info 698da0c48c4Sopenharmony_ci{ 699da0c48c4Sopenharmony_ci struct r_debug_info_module *module; 700da0c48c4Sopenharmony_ci}; 701da0c48c4Sopenharmony_ci 702da0c48c4Sopenharmony_ci/* ... 703da0c48c4Sopenharmony_ci */ 704da0c48c4Sopenharmony_ciextern int dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, 705da0c48c4Sopenharmony_ci Dwfl_Memory_Callback *memory_callback, 706da0c48c4Sopenharmony_ci void *memory_callback_arg, 707da0c48c4Sopenharmony_ci Dwfl_Module_Callback *read_eagerly, 708da0c48c4Sopenharmony_ci void *read_eagerly_arg, 709da0c48c4Sopenharmony_ci size_t maxread, 710da0c48c4Sopenharmony_ci const void *note_file, 711da0c48c4Sopenharmony_ci size_t note_file_size, 712da0c48c4Sopenharmony_ci const struct r_debug_info *r_debug_info); 713da0c48c4Sopenharmony_ci 714da0c48c4Sopenharmony_ci/* Report a module for entry in the dynamic linker's struct link_map list. 715da0c48c4Sopenharmony_ci For each link_map entry, if an existing module resides at its address, 716da0c48c4Sopenharmony_ci this just modifies that module's name and suggested file name. If 717da0c48c4Sopenharmony_ci no such module exists, this calls dwfl_report_elf on the l_name string. 718da0c48c4Sopenharmony_ci 719da0c48c4Sopenharmony_ci If AUXV is not null, it points to AUXV_SIZE bytes of auxiliary vector 720da0c48c4Sopenharmony_ci data as contained in an NT_AUXV note or read from a /proc/pid/auxv 721da0c48c4Sopenharmony_ci file. When this is available, it guides the search. If AUXV is null 722da0c48c4Sopenharmony_ci or the memory it points to is not accessible, then this search can 723da0c48c4Sopenharmony_ci only find where to begin if the correct executable file was 724da0c48c4Sopenharmony_ci previously reported and preloaded as with dwfl_report_elf. 725da0c48c4Sopenharmony_ci 726da0c48c4Sopenharmony_ci Fill in R_DEBUG_INFO if it is not NULL. It should be cleared by the 727da0c48c4Sopenharmony_ci caller, this function does not touch fields it does not need to modify. 728da0c48c4Sopenharmony_ci If R_DEBUG_INFO is not NULL then no modules get added to DWFL, caller 729da0c48c4Sopenharmony_ci has to add them from filled in R_DEBUG_INFO. 730da0c48c4Sopenharmony_ci 731da0c48c4Sopenharmony_ci Returns the number of modules found, or -1 for errors. */ 732da0c48c4Sopenharmony_ciextern int dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size, 733da0c48c4Sopenharmony_ci Dwfl_Memory_Callback *memory_callback, 734da0c48c4Sopenharmony_ci void *memory_callback_arg, 735da0c48c4Sopenharmony_ci struct r_debug_info *r_debug_info); 736da0c48c4Sopenharmony_ci 737da0c48c4Sopenharmony_ci 738da0c48c4Sopenharmony_ci/* Avoid PLT entries. */ 739da0c48c4Sopenharmony_ciINTDECL (dwfl_begin) 740da0c48c4Sopenharmony_ciINTDECL (dwfl_errmsg) 741da0c48c4Sopenharmony_ciINTDECL (dwfl_errno) 742da0c48c4Sopenharmony_ciINTDECL (dwfl_addrmodule) 743da0c48c4Sopenharmony_ciINTDECL (dwfl_addrsegment) 744da0c48c4Sopenharmony_ciINTDECL (dwfl_addrdwarf) 745da0c48c4Sopenharmony_ciINTDECL (dwfl_addrdie) 746da0c48c4Sopenharmony_ciINTDECL (dwfl_core_file_attach) 747da0c48c4Sopenharmony_ciINTDECL (dwfl_core_file_report) 748da0c48c4Sopenharmony_ciINTDECL (dwfl_getmodules) 749da0c48c4Sopenharmony_ciINTDECL (dwfl_module_addrdie) 750da0c48c4Sopenharmony_ciINTDECL (dwfl_module_address_section) 751da0c48c4Sopenharmony_ciINTDECL (dwfl_module_addrinfo) 752da0c48c4Sopenharmony_ciINTDECL (dwfl_module_addrsym) 753da0c48c4Sopenharmony_ciINTDECL (dwfl_module_build_id) 754da0c48c4Sopenharmony_ciINTDECL (dwfl_module_getdwarf) 755da0c48c4Sopenharmony_ciINTDECL (dwfl_module_getelf) 756da0c48c4Sopenharmony_ciINTDECL (dwfl_module_getsym) 757da0c48c4Sopenharmony_ciINTDECL (dwfl_module_getsym_info) 758da0c48c4Sopenharmony_ciINTDECL (dwfl_module_getsymtab) 759da0c48c4Sopenharmony_ciINTDECL (dwfl_module_getsymtab_first_global) 760da0c48c4Sopenharmony_ciINTDECL (dwfl_module_getsrc) 761da0c48c4Sopenharmony_ciINTDECL (dwfl_module_report_build_id) 762da0c48c4Sopenharmony_ciINTDECL (dwfl_report_elf) 763da0c48c4Sopenharmony_ciINTDECL (dwfl_report_begin) 764da0c48c4Sopenharmony_ciINTDECL (dwfl_report_begin_add) 765da0c48c4Sopenharmony_ciINTDECL (dwfl_report_module) 766da0c48c4Sopenharmony_ciINTDECL (dwfl_report_segment) 767da0c48c4Sopenharmony_ciINTDECL (dwfl_report_offline) 768da0c48c4Sopenharmony_ciINTDECL (dwfl_report_offline_memory) 769da0c48c4Sopenharmony_ciINTDECL (dwfl_report_end) 770da0c48c4Sopenharmony_ciINTDECL (dwfl_build_id_find_elf) 771da0c48c4Sopenharmony_ciINTDECL (dwfl_build_id_find_debuginfo) 772da0c48c4Sopenharmony_ciINTDECL (dwfl_standard_find_debuginfo) 773da0c48c4Sopenharmony_ciINTDECL (dwfl_link_map_report) 774da0c48c4Sopenharmony_ciINTDECL (dwfl_linux_kernel_find_elf) 775da0c48c4Sopenharmony_ciINTDECL (dwfl_linux_kernel_module_section_address) 776da0c48c4Sopenharmony_ciINTDECL (dwfl_linux_proc_attach) 777da0c48c4Sopenharmony_ciINTDECL (dwfl_linux_proc_report) 778da0c48c4Sopenharmony_ciINTDECL (dwfl_linux_proc_maps_report) 779da0c48c4Sopenharmony_ciINTDECL (dwfl_linux_proc_find_elf) 780da0c48c4Sopenharmony_ciINTDECL (dwfl_linux_kernel_report_kernel) 781da0c48c4Sopenharmony_ciINTDECL (dwfl_linux_kernel_report_modules) 782da0c48c4Sopenharmony_ciINTDECL (dwfl_linux_kernel_report_offline) 783da0c48c4Sopenharmony_ciINTDECL (dwfl_offline_section_address) 784da0c48c4Sopenharmony_ciINTDECL (dwfl_module_relocate_address) 785da0c48c4Sopenharmony_ciINTDECL (dwfl_module_dwarf_cfi) 786da0c48c4Sopenharmony_ciINTDECL (dwfl_module_eh_cfi) 787da0c48c4Sopenharmony_ciINTDECL (dwfl_attach_state) 788da0c48c4Sopenharmony_ciINTDECL (dwfl_pid) 789da0c48c4Sopenharmony_ciINTDECL (dwfl_thread_dwfl) 790da0c48c4Sopenharmony_ciINTDECL (dwfl_thread_tid) 791da0c48c4Sopenharmony_ciINTDECL (dwfl_frame_thread) 792da0c48c4Sopenharmony_ciINTDECL (dwfl_thread_state_registers) 793da0c48c4Sopenharmony_ciINTDECL (dwfl_thread_state_register_pc) 794da0c48c4Sopenharmony_ciINTDECL (dwfl_getthread_frames) 795da0c48c4Sopenharmony_ciINTDECL (dwfl_getthreads) 796da0c48c4Sopenharmony_ciINTDECL (dwfl_thread_getframes) 797da0c48c4Sopenharmony_ciINTDECL (dwfl_frame_pc) 798da0c48c4Sopenharmony_ciINTDECL (dwfl_frame_reg) 799da0c48c4Sopenharmony_ciINTDECL (dwfl_get_debuginfod_client) 800da0c48c4Sopenharmony_ci 801da0c48c4Sopenharmony_ci/* Leading arguments standard to callbacks passed a Dwfl_Module. */ 802da0c48c4Sopenharmony_ci#define MODCB_ARGS(mod) (mod), &(mod)->userdata, (mod)->name, (mod)->low_addr 803da0c48c4Sopenharmony_ci#define CBFAIL (errno ? DWFL_E (ERRNO, errno) : DWFL_E_CB); 804da0c48c4Sopenharmony_ci 805da0c48c4Sopenharmony_ci 806da0c48c4Sopenharmony_ci/* The default used by dwfl_standard_find_debuginfo. */ 807da0c48c4Sopenharmony_ci#define DEFAULT_DEBUGINFO_PATH ":.debug:/usr/lib/debug" 808da0c48c4Sopenharmony_ci 809da0c48c4Sopenharmony_ci 810da0c48c4Sopenharmony_ci#endif /* libdwflP.h */ 811