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