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