Coverage Report

Created: 2025-07-12 06:44

/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 */