1da0c48c4Sopenharmony_ci/* Interfaces for libdwfl. 2da0c48c4Sopenharmony_ci Copyright (C) 2005-2010, 2013 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 _LIBDWFL_H 30da0c48c4Sopenharmony_ci#define _LIBDWFL_H 1 31da0c48c4Sopenharmony_ci 32da0c48c4Sopenharmony_ci#include "libdw.h" 33da0c48c4Sopenharmony_ci#include <stdio.h> 34da0c48c4Sopenharmony_ci 35da0c48c4Sopenharmony_ci/* Handle for a session using the library. */ 36da0c48c4Sopenharmony_citypedef struct Dwfl Dwfl; 37da0c48c4Sopenharmony_ci 38da0c48c4Sopenharmony_ci/* Handle for a module. */ 39da0c48c4Sopenharmony_citypedef struct Dwfl_Module Dwfl_Module; 40da0c48c4Sopenharmony_ci 41da0c48c4Sopenharmony_ci/* Handle describing a line record. */ 42da0c48c4Sopenharmony_citypedef struct Dwfl_Line Dwfl_Line; 43da0c48c4Sopenharmony_ci 44da0c48c4Sopenharmony_ci/* This holds information common for all the frames of one backtrace for 45da0c48c4Sopenharmony_ci a particular thread/task/TID. Several threads belong to one Dwfl. */ 46da0c48c4Sopenharmony_citypedef struct Dwfl_Thread Dwfl_Thread; 47da0c48c4Sopenharmony_ci 48da0c48c4Sopenharmony_ci/* This holds everything we know about the state of the frame at a particular 49da0c48c4Sopenharmony_ci PC location described by an FDE belonging to Dwfl_Thread. */ 50da0c48c4Sopenharmony_citypedef struct Dwfl_Frame Dwfl_Frame; 51da0c48c4Sopenharmony_ci 52da0c48c4Sopenharmony_ci/* Handle for debuginfod-client connection. */ 53da0c48c4Sopenharmony_citypedef struct debuginfod_client debuginfod_client; 54da0c48c4Sopenharmony_ci 55da0c48c4Sopenharmony_ci/* Callbacks. */ 56da0c48c4Sopenharmony_citypedef struct 57da0c48c4Sopenharmony_ci{ 58da0c48c4Sopenharmony_ci int (*find_elf) (Dwfl_Module *mod, void **userdata, 59da0c48c4Sopenharmony_ci const char *modname, Dwarf_Addr base, 60da0c48c4Sopenharmony_ci char **file_name, Elf **elfp); 61da0c48c4Sopenharmony_ci 62da0c48c4Sopenharmony_ci int (*find_debuginfo) (Dwfl_Module *mod, void **userdata, 63da0c48c4Sopenharmony_ci const char *modname, Dwarf_Addr base, 64da0c48c4Sopenharmony_ci const char *file_name, 65da0c48c4Sopenharmony_ci const char *debuglink_file, GElf_Word debuglink_crc, 66da0c48c4Sopenharmony_ci char **debuginfo_file_name); 67da0c48c4Sopenharmony_ci 68da0c48c4Sopenharmony_ci /* Fill *ADDR with the loaded address of the section called SECNAME in 69da0c48c4Sopenharmony_ci the given module. Use (Dwarf_Addr) -1 if this section is omitted from 70da0c48c4Sopenharmony_ci accessible memory. This is called exactly once for each SHF_ALLOC 71da0c48c4Sopenharmony_ci section that relocations affecting DWARF data refer to, so it can 72da0c48c4Sopenharmony_ci easily be used to collect state about the sections referenced. */ 73da0c48c4Sopenharmony_ci int (*section_address) (Dwfl_Module *mod, void **userdata, 74da0c48c4Sopenharmony_ci const char *modname, Dwarf_Addr base, 75da0c48c4Sopenharmony_ci const char *secname, 76da0c48c4Sopenharmony_ci GElf_Word shndx, const GElf_Shdr *shdr, 77da0c48c4Sopenharmony_ci Dwarf_Addr *addr); 78da0c48c4Sopenharmony_ci 79da0c48c4Sopenharmony_ci char **debuginfo_path; /* See dwfl_standard_find_debuginfo. */ 80da0c48c4Sopenharmony_ci} Dwfl_Callbacks; 81da0c48c4Sopenharmony_ci 82da0c48c4Sopenharmony_ci 83da0c48c4Sopenharmony_ci#ifdef __cplusplus 84da0c48c4Sopenharmony_ciextern "C" { 85da0c48c4Sopenharmony_ci#endif 86da0c48c4Sopenharmony_ci 87da0c48c4Sopenharmony_ci/* Start a new session with the library. */ 88da0c48c4Sopenharmony_ciextern Dwfl *dwfl_begin (const Dwfl_Callbacks *callbacks) 89da0c48c4Sopenharmony_ci __nonnull_attribute__ (1); 90da0c48c4Sopenharmony_ci 91da0c48c4Sopenharmony_ci 92da0c48c4Sopenharmony_ci/* End a session. */ 93da0c48c4Sopenharmony_ciextern void dwfl_end (Dwfl *); 94da0c48c4Sopenharmony_ci 95da0c48c4Sopenharmony_ci/* Return implementation's version string suitable for printing. */ 96da0c48c4Sopenharmony_ciextern const char *dwfl_version (Dwfl *); 97da0c48c4Sopenharmony_ci 98da0c48c4Sopenharmony_ci/* Return error code of last failing function call. This value is kept 99da0c48c4Sopenharmony_ci separately for each thread. */ 100da0c48c4Sopenharmony_ciextern int dwfl_errno (void); 101da0c48c4Sopenharmony_ci 102da0c48c4Sopenharmony_ci/* Return error string for ERROR. If ERROR is zero, return error string 103da0c48c4Sopenharmony_ci for most recent error or NULL if none occurred. If ERROR is -1 the 104da0c48c4Sopenharmony_ci behaviour is similar to the last case except that not NULL but a legal 105da0c48c4Sopenharmony_ci string is returned. */ 106da0c48c4Sopenharmony_ciextern const char *dwfl_errmsg (int err); 107da0c48c4Sopenharmony_ci 108da0c48c4Sopenharmony_ci 109da0c48c4Sopenharmony_ci/* Start reporting the current set of segments and modules to the library. 110da0c48c4Sopenharmony_ci All existing segments are wiped. Existing modules are marked to be 111da0c48c4Sopenharmony_ci deleted, and will not be found via dwfl_addrmodule et al if they are not 112da0c48c4Sopenharmony_ci re-reported before dwfl_report_end is called. */ 113da0c48c4Sopenharmony_ciextern void dwfl_report_begin (Dwfl *dwfl); 114da0c48c4Sopenharmony_ci 115da0c48c4Sopenharmony_ci/* Report that segment NDX begins at PHDR->p_vaddr + BIAS. 116da0c48c4Sopenharmony_ci If NDX is < 0, the value succeeding the last call's NDX 117da0c48c4Sopenharmony_ci is used instead (zero on the first call). IDENT is ignored. 118da0c48c4Sopenharmony_ci 119da0c48c4Sopenharmony_ci If nonzero, the smallest PHDR->p_align value seen sets the 120da0c48c4Sopenharmony_ci effective page size for the address space DWFL describes. 121da0c48c4Sopenharmony_ci This is the granularity at which reported module boundary 122da0c48c4Sopenharmony_ci addresses will be considered to fall in or out of a segment. 123da0c48c4Sopenharmony_ci 124da0c48c4Sopenharmony_ci Returns -1 for errors, or NDX (or its assigned replacement) on success. 125da0c48c4Sopenharmony_ci 126da0c48c4Sopenharmony_ci Reporting segments at all is optional. Its only benefit to the caller is to 127da0c48c4Sopenharmony_ci offer this quick lookup via dwfl_addrsegment, or use other segment-based 128da0c48c4Sopenharmony_ci calls. */ 129da0c48c4Sopenharmony_ciextern int dwfl_report_segment (Dwfl *dwfl, int ndx, 130da0c48c4Sopenharmony_ci const GElf_Phdr *phdr, GElf_Addr bias, 131da0c48c4Sopenharmony_ci const void *ident); 132da0c48c4Sopenharmony_ci 133da0c48c4Sopenharmony_ci/* Report that a module called NAME spans addresses [START, END). 134da0c48c4Sopenharmony_ci Returns the module handle, either existing or newly allocated, 135da0c48c4Sopenharmony_ci or returns a null pointer for an allocation error. */ 136da0c48c4Sopenharmony_ciextern Dwfl_Module *dwfl_report_module (Dwfl *dwfl, const char *name, 137da0c48c4Sopenharmony_ci Dwarf_Addr start, Dwarf_Addr end); 138da0c48c4Sopenharmony_ci 139da0c48c4Sopenharmony_ci/* Report a module to address BASE with start and end addresses computed 140da0c48c4Sopenharmony_ci from the ELF program headers in the given file - see the table below. 141da0c48c4Sopenharmony_ci FD may be -1 to open FILE_NAME. On success, FD is consumed by the 142da0c48c4Sopenharmony_ci library, and the `find_elf' callback will not be used for this module. 143da0c48c4Sopenharmony_ci ADD_P_VADDR BASE 144da0c48c4Sopenharmony_ci ET_EXEC ignored ignored 145da0c48c4Sopenharmony_ci ET_DYN false absolute address where to place the file 146da0c48c4Sopenharmony_ci true start address relative to ELF's phdr p_vaddr 147da0c48c4Sopenharmony_ci ET_REL ignored absolute address where to place the file 148da0c48c4Sopenharmony_ci ET_CORE ignored ignored 149da0c48c4Sopenharmony_ci ET_DYN ELF phdr p_vaddr address can be non-zero if the shared library 150da0c48c4Sopenharmony_ci has been prelinked by tool prelink(8). */ 151da0c48c4Sopenharmony_ciextern Dwfl_Module *dwfl_report_elf (Dwfl *dwfl, const char *name, 152da0c48c4Sopenharmony_ci const char *file_name, int fd, 153da0c48c4Sopenharmony_ci GElf_Addr base, bool add_p_vaddr); 154da0c48c4Sopenharmony_ci 155da0c48c4Sopenharmony_ci/* Similar, but report the module for offline use. All ET_EXEC files 156da0c48c4Sopenharmony_ci being reported must be reported before any relocatable objects. 157da0c48c4Sopenharmony_ci If this is used, dwfl_report_module and dwfl_report_elf may not be 158da0c48c4Sopenharmony_ci used in the same reporting session. */ 159da0c48c4Sopenharmony_ciextern Dwfl_Module *dwfl_report_offline (Dwfl *dwfl, const char *name, 160da0c48c4Sopenharmony_ci const char *file_name, int fd); 161da0c48c4Sopenharmony_ci 162da0c48c4Sopenharmony_ci/* Similar, but report ELF from memory region. */ 163da0c48c4Sopenharmony_ciextern Dwfl_Module *dwfl_report_offline_memory (Dwfl *dwfl, const char *name, 164da0c48c4Sopenharmony_ci const char *file_name, 165da0c48c4Sopenharmony_ci char *data, size_t size); 166da0c48c4Sopenharmony_ci 167da0c48c4Sopenharmony_ci/* Finish reporting the current set of modules to the library. 168da0c48c4Sopenharmony_ci If REMOVED is not null, it's called for each module that 169da0c48c4Sopenharmony_ci existed before but was not included in the current report. 170da0c48c4Sopenharmony_ci Returns a nonzero return value from the callback. 171da0c48c4Sopenharmony_ci The callback may call dwfl_report_module; doing so with the 172da0c48c4Sopenharmony_ci details of the module being removed prevents its removal. 173da0c48c4Sopenharmony_ci DWFL cannot be used until this function has returned zero. */ 174da0c48c4Sopenharmony_ciextern int dwfl_report_end (Dwfl *dwfl, 175da0c48c4Sopenharmony_ci int (*removed) (Dwfl_Module *, void *, 176da0c48c4Sopenharmony_ci const char *, Dwarf_Addr, 177da0c48c4Sopenharmony_ci void *arg), 178da0c48c4Sopenharmony_ci void *arg); 179da0c48c4Sopenharmony_ci 180da0c48c4Sopenharmony_ci/* Start reporting additional modules to the library. No calls but 181da0c48c4Sopenharmony_ci dwfl_report_* can be made on DWFL until dwfl_report_end is called. 182da0c48c4Sopenharmony_ci This is like dwfl_report_begin, but all the old modules are kept on. 183da0c48c4Sopenharmony_ci More dwfl_report_* calls can follow to add more modules. 184da0c48c4Sopenharmony_ci When dwfl_report_end is called, no old modules will be removed. */ 185da0c48c4Sopenharmony_ciextern void dwfl_report_begin_add (Dwfl *dwfl); 186da0c48c4Sopenharmony_ci 187da0c48c4Sopenharmony_ci 188da0c48c4Sopenharmony_ci/* Return the name of the module, and for each non-null argument store 189da0c48c4Sopenharmony_ci interesting details: *USERDATA is a location for storing your own 190da0c48c4Sopenharmony_ci pointer, **USERDATA is initially null; *START and *END give the address 191da0c48c4Sopenharmony_ci range covered by the module; *DWBIAS is the address bias for debugging 192da0c48c4Sopenharmony_ci information, and *SYMBIAS for symbol table entries (either is -1 if not 193da0c48c4Sopenharmony_ci yet accessed); *MAINFILE is the name of the ELF file, and *DEBUGFILE the 194da0c48c4Sopenharmony_ci name of the debuginfo file (might be equal to *MAINFILE; either is null 195da0c48c4Sopenharmony_ci if not yet accessed). */ 196da0c48c4Sopenharmony_ciextern const char *dwfl_module_info (Dwfl_Module *mod, void ***userdata, 197da0c48c4Sopenharmony_ci Dwarf_Addr *start, Dwarf_Addr *end, 198da0c48c4Sopenharmony_ci Dwarf_Addr *dwbias, Dwarf_Addr *symbias, 199da0c48c4Sopenharmony_ci const char **mainfile, 200da0c48c4Sopenharmony_ci const char **debugfile); 201da0c48c4Sopenharmony_ci 202da0c48c4Sopenharmony_ci/* Iterate through the modules, starting the walk with OFFSET == 0. 203da0c48c4Sopenharmony_ci Calls *CALLBACK for each module as long as it returns DWARF_CB_OK. 204da0c48c4Sopenharmony_ci When *CALLBACK returns another value, the walk stops and the 205da0c48c4Sopenharmony_ci return value can be passed as OFFSET to resume it. Returns 0 when 206da0c48c4Sopenharmony_ci there are no more modules, or -1 for errors. */ 207da0c48c4Sopenharmony_ciextern ptrdiff_t dwfl_getmodules (Dwfl *dwfl, 208da0c48c4Sopenharmony_ci int (*callback) (Dwfl_Module *, void **, 209da0c48c4Sopenharmony_ci const char *, Dwarf_Addr, 210da0c48c4Sopenharmony_ci void *arg), 211da0c48c4Sopenharmony_ci void *arg, 212da0c48c4Sopenharmony_ci ptrdiff_t offset); 213da0c48c4Sopenharmony_ci 214da0c48c4Sopenharmony_ci/* Find the module containing the given address. */ 215da0c48c4Sopenharmony_ciextern Dwfl_Module *dwfl_addrmodule (Dwfl *dwfl, Dwarf_Addr address); 216da0c48c4Sopenharmony_ci 217da0c48c4Sopenharmony_ci/* Find the segment, if any, and module, if any, containing ADDRESS. 218da0c48c4Sopenharmony_ci Returns a segment index returned by dwfl_report_segment, or -1 219da0c48c4Sopenharmony_ci if no segment matches the address. Regardless of the return value, 220da0c48c4Sopenharmony_ci *MOD is always set to the module containing ADDRESS, or to null. */ 221da0c48c4Sopenharmony_ciextern int dwfl_addrsegment (Dwfl *dwfl, Dwarf_Addr address, Dwfl_Module **mod); 222da0c48c4Sopenharmony_ci 223da0c48c4Sopenharmony_ci 224da0c48c4Sopenharmony_ci 225da0c48c4Sopenharmony_ci/* Report the known build ID bits associated with a module. 226da0c48c4Sopenharmony_ci If VADDR is nonzero, it gives the absolute address where those 227da0c48c4Sopenharmony_ci bits are found within the module. This can be called at any 228da0c48c4Sopenharmony_ci time, but is usually used immediately after dwfl_report_module. 229da0c48c4Sopenharmony_ci Once the module's main ELF file is opened, the ID note found 230da0c48c4Sopenharmony_ci there takes precedence and cannot be changed. */ 231da0c48c4Sopenharmony_ciextern int dwfl_module_report_build_id (Dwfl_Module *mod, 232da0c48c4Sopenharmony_ci const unsigned char *bits, size_t len, 233da0c48c4Sopenharmony_ci GElf_Addr vaddr) 234da0c48c4Sopenharmony_ci __nonnull_attribute__ (2); 235da0c48c4Sopenharmony_ci 236da0c48c4Sopenharmony_ci/* Extract the build ID bits associated with a module. 237da0c48c4Sopenharmony_ci Returns -1 for errors, 0 if no ID is known, or the number of ID bytes. 238da0c48c4Sopenharmony_ci When an ID is found, *BITS points to it; *VADDR is the absolute address 239da0c48c4Sopenharmony_ci at which the ID bits are found within the module, or 0 if unknown. 240da0c48c4Sopenharmony_ci 241da0c48c4Sopenharmony_ci This returns 0 when the module's main ELF file has not yet been loaded 242da0c48c4Sopenharmony_ci and its build ID bits were not reported. To ensure the ID is always 243da0c48c4Sopenharmony_ci returned when determinable, call dwfl_module_getelf first. */ 244da0c48c4Sopenharmony_ciextern int dwfl_module_build_id (Dwfl_Module *mod, 245da0c48c4Sopenharmony_ci const unsigned char **bits, GElf_Addr *vaddr) 246da0c48c4Sopenharmony_ci __nonnull_attribute__ (2, 3); 247da0c48c4Sopenharmony_ci 248da0c48c4Sopenharmony_ci 249da0c48c4Sopenharmony_ci/*** Standard callbacks ***/ 250da0c48c4Sopenharmony_ci 251da0c48c4Sopenharmony_ci/* These standard find_elf and find_debuginfo callbacks are 252da0c48c4Sopenharmony_ci controlled by a string specifying directories to look in. 253da0c48c4Sopenharmony_ci If `debuginfo_path' is set in the Dwfl_Callbacks structure 254da0c48c4Sopenharmony_ci and the char * it points to is not null, that supplies the 255da0c48c4Sopenharmony_ci string. Otherwise a default path is used. 256da0c48c4Sopenharmony_ci 257da0c48c4Sopenharmony_ci If the first character of the string is + or - that enables or 258da0c48c4Sopenharmony_ci disables CRC32 checksum validation when it's necessary. The 259da0c48c4Sopenharmony_ci remainder of the string is composed of elements separated by 260da0c48c4Sopenharmony_ci colons. Each element can start with + or - to override the 261da0c48c4Sopenharmony_ci global checksum behavior. This flag is never relevant when 262da0c48c4Sopenharmony_ci working with build IDs, but it's always parsed in the path 263da0c48c4Sopenharmony_ci string. The remainder of the element indicates a directory. 264da0c48c4Sopenharmony_ci 265da0c48c4Sopenharmony_ci Searches by build ID consult only the elements naming absolute 266da0c48c4Sopenharmony_ci directory paths. They look under those directories for a link 267da0c48c4Sopenharmony_ci named ".build-id/xx/yy" or ".build-id/xx/yy.debug", where "xxyy" 268da0c48c4Sopenharmony_ci is the lower-case hexadecimal representation of the ID bytes. 269da0c48c4Sopenharmony_ci 270da0c48c4Sopenharmony_ci In searches for debuginfo by name, if the remainder of the 271da0c48c4Sopenharmony_ci element is empty, the directory containing the main file is 272da0c48c4Sopenharmony_ci tried; if it's an absolute path name, the absolute directory path 273da0c48c4Sopenharmony_ci (and any subdirectory of that path) containing the main file is 274da0c48c4Sopenharmony_ci taken as a subdirectory of this path; a relative path name is taken 275da0c48c4Sopenharmony_ci as a subdirectory of the directory containing the main file. 276da0c48c4Sopenharmony_ci Hence for /usr/bin/ls, the default string ":.debug:/usr/lib/debug" 277da0c48c4Sopenharmony_ci says to look in /usr/bin, then /usr/bin/.debug, then the path subdirs 278da0c48c4Sopenharmony_ci under /usr/lib/debug, in the order /usr/lib/debug/usr/bin, then 279da0c48c4Sopenharmony_ci /usr/lib/debug/bin, and finally /usr/lib/debug, for the file name in 280da0c48c4Sopenharmony_ci the .gnu_debuglink section (or "ls.debug" if none was found). */ 281da0c48c4Sopenharmony_ci 282da0c48c4Sopenharmony_ci/* Standard find_elf callback function working solely on build ID. 283da0c48c4Sopenharmony_ci This can be tried first by any find_elf callback, to use the 284da0c48c4Sopenharmony_ci bits passed to dwfl_module_report_build_id, if any. */ 285da0c48c4Sopenharmony_ciextern int dwfl_build_id_find_elf (Dwfl_Module *, void **, 286da0c48c4Sopenharmony_ci const char *, Dwarf_Addr, 287da0c48c4Sopenharmony_ci char **, Elf **); 288da0c48c4Sopenharmony_ci 289da0c48c4Sopenharmony_ci/* Standard find_debuginfo callback function working solely on build ID. 290da0c48c4Sopenharmony_ci This can be tried first by any find_debuginfo callback, 291da0c48c4Sopenharmony_ci to use the build ID bits from the main file when present. */ 292da0c48c4Sopenharmony_ciextern int dwfl_build_id_find_debuginfo (Dwfl_Module *, void **, 293da0c48c4Sopenharmony_ci const char *, Dwarf_Addr, 294da0c48c4Sopenharmony_ci const char *, const char *, 295da0c48c4Sopenharmony_ci GElf_Word, char **); 296da0c48c4Sopenharmony_ci 297da0c48c4Sopenharmony_ci/* Standard find_debuginfo callback function. 298da0c48c4Sopenharmony_ci If a build ID is available, this tries first to use that. 299da0c48c4Sopenharmony_ci If there is no build ID or no valid debuginfo found by ID, 300da0c48c4Sopenharmony_ci it searches the debuginfo path by name, as described above. 301da0c48c4Sopenharmony_ci Any file found in the path is validated by build ID if possible, 302da0c48c4Sopenharmony_ci or else by CRC32 checksum if enabled, and skipped if it does not match. */ 303da0c48c4Sopenharmony_ciextern int dwfl_standard_find_debuginfo (Dwfl_Module *, void **, 304da0c48c4Sopenharmony_ci const char *, Dwarf_Addr, 305da0c48c4Sopenharmony_ci const char *, const char *, 306da0c48c4Sopenharmony_ci GElf_Word, char **); 307da0c48c4Sopenharmony_ci 308da0c48c4Sopenharmony_ci 309da0c48c4Sopenharmony_ci/* This callback must be used when using dwfl_offline_* to report modules, 310da0c48c4Sopenharmony_ci if ET_REL is to be supported. */ 311da0c48c4Sopenharmony_ciextern int dwfl_offline_section_address (Dwfl_Module *, void **, 312da0c48c4Sopenharmony_ci const char *, Dwarf_Addr, 313da0c48c4Sopenharmony_ci const char *, GElf_Word, 314da0c48c4Sopenharmony_ci const GElf_Shdr *, 315da0c48c4Sopenharmony_ci Dwarf_Addr *addr); 316da0c48c4Sopenharmony_ci 317da0c48c4Sopenharmony_ci 318da0c48c4Sopenharmony_ci/* Callbacks for working with kernel modules in the running Linux kernel. */ 319da0c48c4Sopenharmony_ciextern int dwfl_linux_kernel_find_elf (Dwfl_Module *, void **, 320da0c48c4Sopenharmony_ci const char *, Dwarf_Addr, 321da0c48c4Sopenharmony_ci char **, Elf **); 322da0c48c4Sopenharmony_ciextern int dwfl_linux_kernel_module_section_address (Dwfl_Module *, void **, 323da0c48c4Sopenharmony_ci const char *, Dwarf_Addr, 324da0c48c4Sopenharmony_ci const char *, GElf_Word, 325da0c48c4Sopenharmony_ci const GElf_Shdr *, 326da0c48c4Sopenharmony_ci Dwarf_Addr *addr); 327da0c48c4Sopenharmony_ci 328da0c48c4Sopenharmony_ci/* Call dwfl_report_elf for the running Linux kernel. 329da0c48c4Sopenharmony_ci Returns zero on success, -1 if dwfl_report_module failed, 330da0c48c4Sopenharmony_ci or an errno code if opening the kernel binary failed. */ 331da0c48c4Sopenharmony_ciextern int dwfl_linux_kernel_report_kernel (Dwfl *dwfl); 332da0c48c4Sopenharmony_ci 333da0c48c4Sopenharmony_ci/* Call dwfl_report_module for each kernel module in the running Linux kernel. 334da0c48c4Sopenharmony_ci Returns zero on success, -1 if dwfl_report_module failed, 335da0c48c4Sopenharmony_ci or an errno code if reading the list of modules failed. */ 336da0c48c4Sopenharmony_ciextern int dwfl_linux_kernel_report_modules (Dwfl *dwfl); 337da0c48c4Sopenharmony_ci 338da0c48c4Sopenharmony_ci/* Report a kernel and its modules found on disk, for offline use. 339da0c48c4Sopenharmony_ci If RELEASE starts with '/', it names a directory to look in; 340da0c48c4Sopenharmony_ci if not, it names a directory to find under /lib/modules/; 341da0c48c4Sopenharmony_ci if null, /lib/modules/`uname -r` is used. 342da0c48c4Sopenharmony_ci Returns zero on success, -1 if dwfl_report_module failed, 343da0c48c4Sopenharmony_ci or an errno code if finding the files on disk failed. 344da0c48c4Sopenharmony_ci 345da0c48c4Sopenharmony_ci If PREDICATE is not null, it is called with each module to be reported; 346da0c48c4Sopenharmony_ci its arguments are the module name, and the ELF file name or null if unknown, 347da0c48c4Sopenharmony_ci and its return value should be zero to skip the module, one to report it, 348da0c48c4Sopenharmony_ci or -1 to cause the call to fail and return errno. */ 349da0c48c4Sopenharmony_ciextern int dwfl_linux_kernel_report_offline (Dwfl *dwfl, const char *release, 350da0c48c4Sopenharmony_ci int (*predicate) (const char *, 351da0c48c4Sopenharmony_ci const char *)); 352da0c48c4Sopenharmony_ci 353da0c48c4Sopenharmony_ci/* Examine an ET_CORE file and report modules based on its contents. 354da0c48c4Sopenharmony_ci This can follow a dwfl_report_offline call to bootstrap the 355da0c48c4Sopenharmony_ci DT_DEBUG method of following the dynamic linker link_map chain, in 356da0c48c4Sopenharmony_ci case the core file does not contain enough of the executable's text 357da0c48c4Sopenharmony_ci segment to locate its PT_DYNAMIC in the dump. In such case you need to 358da0c48c4Sopenharmony_ci supply non-NULL EXECUTABLE, otherwise dynamic libraries will not be loaded 359da0c48c4Sopenharmony_ci into the DWFL map. This might call dwfl_report_elf on file names found in 360da0c48c4Sopenharmony_ci the dump if reading some link_map files is the only way to ascertain those 361da0c48c4Sopenharmony_ci modules' addresses. Returns the number of modules reported, or -1 for 362da0c48c4Sopenharmony_ci errors. */ 363da0c48c4Sopenharmony_ciextern int dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable); 364da0c48c4Sopenharmony_ci 365da0c48c4Sopenharmony_ci/* Call dwfl_report_module for each file mapped into the address space of PID. 366da0c48c4Sopenharmony_ci Returns zero on success, -1 if dwfl_report_module failed, 367da0c48c4Sopenharmony_ci or an errno code if opening the proc files failed. */ 368da0c48c4Sopenharmony_ciextern int dwfl_linux_proc_report (Dwfl *dwfl, pid_t pid); 369da0c48c4Sopenharmony_ci 370da0c48c4Sopenharmony_ci/* Similar, but reads an input stream in the format of Linux /proc/PID/maps 371da0c48c4Sopenharmony_ci files giving module layout, not the file for a live process. */ 372da0c48c4Sopenharmony_ciextern int dwfl_linux_proc_maps_report (Dwfl *dwfl, FILE *); 373da0c48c4Sopenharmony_ci 374da0c48c4Sopenharmony_ci/* Trivial find_elf callback for use with dwfl_linux_proc_report. 375da0c48c4Sopenharmony_ci This uses the module name as a file name directly and tries to open it 376da0c48c4Sopenharmony_ci if it begin with a slash, or handles the magic string "[vdso]". */ 377da0c48c4Sopenharmony_ciextern int dwfl_linux_proc_find_elf (Dwfl_Module *mod, void **userdata, 378da0c48c4Sopenharmony_ci const char *module_name, Dwarf_Addr base, 379da0c48c4Sopenharmony_ci char **file_name, Elf **); 380da0c48c4Sopenharmony_ci 381da0c48c4Sopenharmony_ci/* Standard argument parsing for using a standard callback set. */ 382da0c48c4Sopenharmony_cistruct argp; 383da0c48c4Sopenharmony_ciextern const struct argp *dwfl_standard_argp (void) __const_attribute__; 384da0c48c4Sopenharmony_ci 385da0c48c4Sopenharmony_ci 386da0c48c4Sopenharmony_ci/*** Relocation of addresses from Dwfl ***/ 387da0c48c4Sopenharmony_ci 388da0c48c4Sopenharmony_ci/* Return the number of relocatable bases associated with the module, 389da0c48c4Sopenharmony_ci which is zero for ET_EXEC and one for ET_DYN. Returns -1 for errors. */ 390da0c48c4Sopenharmony_ciextern int dwfl_module_relocations (Dwfl_Module *mod); 391da0c48c4Sopenharmony_ci 392da0c48c4Sopenharmony_ci/* Return the relocation base index associated with the *ADDRESS location, 393da0c48c4Sopenharmony_ci and adjust *ADDRESS to be an offset relative to that base. 394da0c48c4Sopenharmony_ci Returns -1 for errors. */ 395da0c48c4Sopenharmony_ciextern int dwfl_module_relocate_address (Dwfl_Module *mod, 396da0c48c4Sopenharmony_ci Dwarf_Addr *address); 397da0c48c4Sopenharmony_ci 398da0c48c4Sopenharmony_ci/* Return the ELF section name for the given relocation base index; 399da0c48c4Sopenharmony_ci if SHNDXP is not null, set *SHNDXP to the ELF section index. 400da0c48c4Sopenharmony_ci For ET_DYN, returns "" and sets *SHNDXP to SHN_ABS; the relocation 401da0c48c4Sopenharmony_ci base is the runtime start address reported for the module. 402da0c48c4Sopenharmony_ci Returns null for errors. */ 403da0c48c4Sopenharmony_ciextern const char *dwfl_module_relocation_info (Dwfl_Module *mod, 404da0c48c4Sopenharmony_ci unsigned int idx, 405da0c48c4Sopenharmony_ci GElf_Word *shndxp); 406da0c48c4Sopenharmony_ci 407da0c48c4Sopenharmony_ci/* Validate that ADDRESS and ADDRESS+OFFSET lie in a known module 408da0c48c4Sopenharmony_ci and both within the same contiguous region for relocation purposes. 409da0c48c4Sopenharmony_ci Returns zero for success and -1 for errors. */ 410da0c48c4Sopenharmony_ciextern int dwfl_validate_address (Dwfl *dwfl, 411da0c48c4Sopenharmony_ci Dwarf_Addr address, Dwarf_Sword offset); 412da0c48c4Sopenharmony_ci 413da0c48c4Sopenharmony_ci 414da0c48c4Sopenharmony_ci/*** ELF access functions ***/ 415da0c48c4Sopenharmony_ci 416da0c48c4Sopenharmony_ci/* Fetch the module main ELF file (where the allocated sections 417da0c48c4Sopenharmony_ci are found) for use with libelf. If successful, fills in *BIAS 418da0c48c4Sopenharmony_ci with the difference between addresses within the loaded module 419da0c48c4Sopenharmony_ci and those in symbol tables or Dwarf information referring to it. */ 420da0c48c4Sopenharmony_ciextern Elf *dwfl_module_getelf (Dwfl_Module *, GElf_Addr *bias) 421da0c48c4Sopenharmony_ci __nonnull_attribute__ (2); 422da0c48c4Sopenharmony_ci 423da0c48c4Sopenharmony_ci/* Return the number of symbols in the module's symbol table, 424da0c48c4Sopenharmony_ci or -1 for errors. */ 425da0c48c4Sopenharmony_ciextern int dwfl_module_getsymtab (Dwfl_Module *mod); 426da0c48c4Sopenharmony_ci 427da0c48c4Sopenharmony_ci/* Return the index of the first global symbol in the module's symbol 428da0c48c4Sopenharmony_ci table, or -1 for errors. In each symbol table, all symbols with 429da0c48c4Sopenharmony_ci STB_LOCAL binding precede the weak and global symbols. This 430da0c48c4Sopenharmony_ci function returns the symbol table index one greater than the last 431da0c48c4Sopenharmony_ci local symbol. */ 432da0c48c4Sopenharmony_ciextern int dwfl_module_getsymtab_first_global (Dwfl_Module *mod); 433da0c48c4Sopenharmony_ci 434da0c48c4Sopenharmony_ci/* Fetch one entry from the module's symbol table. On errors, returns 435da0c48c4Sopenharmony_ci NULL. If successful, fills in *SYM and returns the string for st_name. 436da0c48c4Sopenharmony_ci This works like gelf_getsym except that st_value is always adjusted to 437da0c48c4Sopenharmony_ci an absolute value based on the module's location, when the symbol is in 438da0c48c4Sopenharmony_ci an SHF_ALLOC section. If SHNDXP is non-null, it's set with the section 439da0c48c4Sopenharmony_ci index (whether from st_shndx or extended index table); in case of a 440da0c48c4Sopenharmony_ci symbol in a non-allocated section, *SHNDXP is instead set to -1. 441da0c48c4Sopenharmony_ci Note that since symbols can come from either the main, debug or auxiliary 442da0c48c4Sopenharmony_ci ELF symbol file (either dynsym or symtab) the section index can only 443da0c48c4Sopenharmony_ci be reliably used to compare against special section constants like 444da0c48c4Sopenharmony_ci SHN_UNDEF or SHN_ABS. It is recommended to use dwfl_module_getsym_info 445da0c48c4Sopenharmony_ci which doesn't have these deficiencies. */ 446da0c48c4Sopenharmony_ciextern const char *dwfl_module_getsym (Dwfl_Module *mod, int ndx, 447da0c48c4Sopenharmony_ci GElf_Sym *sym, GElf_Word *shndxp) 448da0c48c4Sopenharmony_ci __nonnull_attribute__ (3); 449da0c48c4Sopenharmony_ci 450da0c48c4Sopenharmony_ci/* Fetch one entry from the module's symbol table and the associated 451da0c48c4Sopenharmony_ci address value. On errors, returns NULL. If successful, fills in 452da0c48c4Sopenharmony_ci *SYM, *ADDR and returns the string for st_name. This works like 453da0c48c4Sopenharmony_ci gelf_getsym. *ADDR is set to the st_value adjusted to an absolute 454da0c48c4Sopenharmony_ci value based on the module's location, when the symbol is in an 455da0c48c4Sopenharmony_ci SHF_ALLOC section. For non-ET_REL files, if the arch uses function 456da0c48c4Sopenharmony_ci descriptors, and the st_value points to one, *ADDR will be resolved 457da0c48c4Sopenharmony_ci to the actual function entry address. The SYM->ST_VALUE itself 458da0c48c4Sopenharmony_ci isn't adjusted in any way. Fills in ELFP, if not NULL, with the 459da0c48c4Sopenharmony_ci ELF file the symbol originally came from. Note that symbols can 460da0c48c4Sopenharmony_ci come from either the main, debug or auxiliary ELF symbol file 461da0c48c4Sopenharmony_ci (either dynsym or symtab). If SHNDXP is non-null, it's set with 462da0c48c4Sopenharmony_ci the section index (whether from st_shndx or extended index table); 463da0c48c4Sopenharmony_ci in case of a symbol in a non-allocated section, *SHNDXP is instead 464da0c48c4Sopenharmony_ci set to -1. Fills in BIAS, if not NULL, with the difference between 465da0c48c4Sopenharmony_ci addresses within the loaded module and those in symbol table of the 466da0c48c4Sopenharmony_ci ELF file. Note that the address associated with the symbol might 467da0c48c4Sopenharmony_ci be in a different section than the returned symbol. The section in 468da0c48c4Sopenharmony_ci the main elf file in which returned ADDR falls can be found with 469da0c48c4Sopenharmony_ci dwfl_module_address_section. */ 470da0c48c4Sopenharmony_ciextern const char *dwfl_module_getsym_info (Dwfl_Module *mod, int ndx, 471da0c48c4Sopenharmony_ci GElf_Sym *sym, GElf_Addr *addr, 472da0c48c4Sopenharmony_ci GElf_Word *shndxp, 473da0c48c4Sopenharmony_ci Elf **elfp, Dwarf_Addr *bias) 474da0c48c4Sopenharmony_ci __nonnull_attribute__ (3, 4); 475da0c48c4Sopenharmony_ci 476da0c48c4Sopenharmony_ci/* Find the symbol that ADDRESS lies inside, and return its name. */ 477da0c48c4Sopenharmony_ciextern const char *dwfl_module_addrname (Dwfl_Module *mod, GElf_Addr address); 478da0c48c4Sopenharmony_ci 479da0c48c4Sopenharmony_ci/* Find the symbol associated with ADDRESS. Return its name or NULL 480da0c48c4Sopenharmony_ci when nothing was found. If the architecture uses function 481da0c48c4Sopenharmony_ci descriptors, and symbol st_value points to one, ADDRESS will be 482da0c48c4Sopenharmony_ci matched against either the adjusted st_value or the associated 483da0c48c4Sopenharmony_ci function entry value as described in dwfl_module_getsym_info. 484da0c48c4Sopenharmony_ci OFFSET will be filled in with the difference from the start of the 485da0c48c4Sopenharmony_ci symbol (or function entry), OFFSET cannot be NULL. SYM is filled 486da0c48c4Sopenharmony_ci in with the symbol associated with the matched ADDRESS, SYM cannot 487da0c48c4Sopenharmony_ci be NULL. The SYM->ST_VALUE itself isn't adjusted in any way. 488da0c48c4Sopenharmony_ci Fills in ELFP, if not NULL, with the ELF file the symbol originally 489da0c48c4Sopenharmony_ci came from. Note that symbols can come from either the main, debug 490da0c48c4Sopenharmony_ci or auxiliary ELF symbol file (either dynsym or symtab). If SHNDXP 491da0c48c4Sopenharmony_ci is non-null, it's set with the section index (whether from st_shndx 492da0c48c4Sopenharmony_ci or extended index table). Fills in BIAS, if not NULL, with the 493da0c48c4Sopenharmony_ci difference between addresses within the loaded module and those in 494da0c48c4Sopenharmony_ci symbol table of the ELF file. Note that the address matched 495da0c48c4Sopenharmony_ci against the symbol might be in a different section than the 496da0c48c4Sopenharmony_ci returned symbol. The section in the main elf file in ADDRESS falls 497da0c48c4Sopenharmony_ci can be found with dwfl_module_address_section. */ 498da0c48c4Sopenharmony_ciextern const char *dwfl_module_addrinfo (Dwfl_Module *mod, GElf_Addr address, 499da0c48c4Sopenharmony_ci GElf_Off *offset, GElf_Sym *sym, 500da0c48c4Sopenharmony_ci GElf_Word *shndxp, Elf **elfp, 501da0c48c4Sopenharmony_ci Dwarf_Addr *bias) 502da0c48c4Sopenharmony_ci __nonnull_attribute__ (3, 4); 503da0c48c4Sopenharmony_ci 504da0c48c4Sopenharmony_ci/* Find the symbol that ADDRESS lies inside, and return detailed 505da0c48c4Sopenharmony_ci information as for dwfl_module_getsym (above). Note that like 506da0c48c4Sopenharmony_ci dwfl_module_getsym this function also adjusts SYM->ST_VALUE to an 507da0c48c4Sopenharmony_ci absolute value based on the module's location. ADDRESS is only 508da0c48c4Sopenharmony_ci matched against this adjusted SYM->ST_VALUE. This means that 509da0c48c4Sopenharmony_ci depending on architecture this might only match symbols that 510da0c48c4Sopenharmony_ci represent function descriptor addresses (and not function entry 511da0c48c4Sopenharmony_ci addresses). For these reasons it is recommended to use 512da0c48c4Sopenharmony_ci dwfl_module_addrinfo instead. */ 513da0c48c4Sopenharmony_ciextern const char *dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr address, 514da0c48c4Sopenharmony_ci GElf_Sym *sym, GElf_Word *shndxp) 515da0c48c4Sopenharmony_ci __nonnull_attribute__ (3); 516da0c48c4Sopenharmony_ci 517da0c48c4Sopenharmony_ci/* Find the ELF section that *ADDRESS lies inside and return it. 518da0c48c4Sopenharmony_ci On success, adjusts *ADDRESS to be relative to the section, 519da0c48c4Sopenharmony_ci and sets *BIAS to the difference between addresses used in 520da0c48c4Sopenharmony_ci the returned section's headers and run-time addresses. */ 521da0c48c4Sopenharmony_ciextern Elf_Scn *dwfl_module_address_section (Dwfl_Module *mod, 522da0c48c4Sopenharmony_ci Dwarf_Addr *address, 523da0c48c4Sopenharmony_ci Dwarf_Addr *bias) 524da0c48c4Sopenharmony_ci __nonnull_attribute__ (2, 3); 525da0c48c4Sopenharmony_ci 526da0c48c4Sopenharmony_ci 527da0c48c4Sopenharmony_ci/*** Dwarf access functions ***/ 528da0c48c4Sopenharmony_ci 529da0c48c4Sopenharmony_ci/* Fetch the module's debug information for use with libdw. 530da0c48c4Sopenharmony_ci If successful, fills in *BIAS with the difference between 531da0c48c4Sopenharmony_ci addresses within the loaded module and those to use with libdw. */ 532da0c48c4Sopenharmony_ciextern Dwarf *dwfl_module_getdwarf (Dwfl_Module *, Dwarf_Addr *bias) 533da0c48c4Sopenharmony_ci __nonnull_attribute__ (2); 534da0c48c4Sopenharmony_ci 535da0c48c4Sopenharmony_ci/* Get the libdw handle for each module. */ 536da0c48c4Sopenharmony_ciextern ptrdiff_t dwfl_getdwarf (Dwfl *, 537da0c48c4Sopenharmony_ci int (*callback) (Dwfl_Module *, void **, 538da0c48c4Sopenharmony_ci const char *, Dwarf_Addr, 539da0c48c4Sopenharmony_ci Dwarf *, Dwarf_Addr, void *), 540da0c48c4Sopenharmony_ci void *arg, ptrdiff_t offset); 541da0c48c4Sopenharmony_ci 542da0c48c4Sopenharmony_ci/* Look up the module containing ADDR and return its debugging information, 543da0c48c4Sopenharmony_ci loading it if necessary. */ 544da0c48c4Sopenharmony_ciextern Dwarf *dwfl_addrdwarf (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Addr *bias) 545da0c48c4Sopenharmony_ci __nonnull_attribute__ (3); 546da0c48c4Sopenharmony_ci 547da0c48c4Sopenharmony_ci 548da0c48c4Sopenharmony_ci/* Find the CU containing ADDR and return its DIE. */ 549da0c48c4Sopenharmony_ciextern Dwarf_Die *dwfl_addrdie (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Addr *bias) 550da0c48c4Sopenharmony_ci __nonnull_attribute__ (3); 551da0c48c4Sopenharmony_ciextern Dwarf_Die *dwfl_module_addrdie (Dwfl_Module *mod, 552da0c48c4Sopenharmony_ci Dwarf_Addr addr, Dwarf_Addr *bias) 553da0c48c4Sopenharmony_ci __nonnull_attribute__ (3); 554da0c48c4Sopenharmony_ci 555da0c48c4Sopenharmony_ci/* Iterate through the CUs, start with null for LASTCU. */ 556da0c48c4Sopenharmony_ciextern Dwarf_Die *dwfl_nextcu (Dwfl *dwfl, Dwarf_Die *lastcu, Dwarf_Addr *bias) 557da0c48c4Sopenharmony_ci __nonnull_attribute__ (3); 558da0c48c4Sopenharmony_ciextern Dwarf_Die *dwfl_module_nextcu (Dwfl_Module *mod, 559da0c48c4Sopenharmony_ci Dwarf_Die *lastcu, Dwarf_Addr *bias) 560da0c48c4Sopenharmony_ci __nonnull_attribute__ (3); 561da0c48c4Sopenharmony_ci 562da0c48c4Sopenharmony_ci/* Return the module containing the CU DIE. */ 563da0c48c4Sopenharmony_ciextern Dwfl_Module *dwfl_cumodule (Dwarf_Die *cudie); 564da0c48c4Sopenharmony_ci 565da0c48c4Sopenharmony_ci 566da0c48c4Sopenharmony_ci/* Cache the source line information for the CU and return the 567da0c48c4Sopenharmony_ci number of Dwfl_Line entries it has. */ 568da0c48c4Sopenharmony_ciextern int dwfl_getsrclines (Dwarf_Die *cudie, size_t *nlines); 569da0c48c4Sopenharmony_ci 570da0c48c4Sopenharmony_ci/* Access one line number entry within the CU. */ 571da0c48c4Sopenharmony_ciextern Dwfl_Line *dwfl_onesrcline (Dwarf_Die *cudie, size_t idx); 572da0c48c4Sopenharmony_ci 573da0c48c4Sopenharmony_ci/* Get source for address. */ 574da0c48c4Sopenharmony_ciextern Dwfl_Line *dwfl_module_getsrc (Dwfl_Module *mod, Dwarf_Addr addr); 575da0c48c4Sopenharmony_ciextern Dwfl_Line *dwfl_getsrc (Dwfl *dwfl, Dwarf_Addr addr); 576da0c48c4Sopenharmony_ci 577da0c48c4Sopenharmony_ci/* Get address for source. */ 578da0c48c4Sopenharmony_ciextern int dwfl_module_getsrc_file (Dwfl_Module *mod, 579da0c48c4Sopenharmony_ci const char *fname, int lineno, int column, 580da0c48c4Sopenharmony_ci Dwfl_Line ***srcsp, size_t *nsrcs); 581da0c48c4Sopenharmony_ci 582da0c48c4Sopenharmony_ci/* Return the module containing this line record. */ 583da0c48c4Sopenharmony_ciextern Dwfl_Module *dwfl_linemodule (Dwfl_Line *line); 584da0c48c4Sopenharmony_ci 585da0c48c4Sopenharmony_ci/* Return the CU containing this line record. */ 586da0c48c4Sopenharmony_ciextern Dwarf_Die *dwfl_linecu (Dwfl_Line *line); 587da0c48c4Sopenharmony_ci 588da0c48c4Sopenharmony_ci/* Return the source file name and fill in other information. 589da0c48c4Sopenharmony_ci Arguments may be null for unneeded fields. */ 590da0c48c4Sopenharmony_ciextern const char *dwfl_lineinfo (Dwfl_Line *line, Dwarf_Addr *addr, 591da0c48c4Sopenharmony_ci int *linep, int *colp, 592da0c48c4Sopenharmony_ci Dwarf_Word *mtime, Dwarf_Word *length); 593da0c48c4Sopenharmony_ci 594da0c48c4Sopenharmony_ci /* Return the equivalent Dwarf_Line and the bias to apply to its address. */ 595da0c48c4Sopenharmony_ciextern Dwarf_Line *dwfl_dwarf_line (Dwfl_Line *line, Dwarf_Addr *bias); 596da0c48c4Sopenharmony_ci 597da0c48c4Sopenharmony_ci/* Return the compilation directory (AT_comp_dir) from this line's CU. */ 598da0c48c4Sopenharmony_ciextern const char *dwfl_line_comp_dir (Dwfl_Line *line); 599da0c48c4Sopenharmony_ci 600da0c48c4Sopenharmony_ci 601da0c48c4Sopenharmony_ci/*** Machine backend access functions ***/ 602da0c48c4Sopenharmony_ci 603da0c48c4Sopenharmony_ci/* Return location expression to find return value given a 604da0c48c4Sopenharmony_ci DW_TAG_subprogram, DW_TAG_subroutine_type, or similar DIE describing 605da0c48c4Sopenharmony_ci function itself (whose DW_AT_type attribute describes its return type). 606da0c48c4Sopenharmony_ci The given DIE must come from the given module. Returns -1 for errors. 607da0c48c4Sopenharmony_ci Returns zero if the function has no return value (e.g. "void" in C). 608da0c48c4Sopenharmony_ci Otherwise, *LOCOPS gets a location expression to find the return value, 609da0c48c4Sopenharmony_ci and returns the number of operations in the expression. The pointer is 610da0c48c4Sopenharmony_ci permanently allocated at least as long as the module is live. */ 611da0c48c4Sopenharmony_ciextern int dwfl_module_return_value_location (Dwfl_Module *mod, 612da0c48c4Sopenharmony_ci Dwarf_Die *functypedie, 613da0c48c4Sopenharmony_ci const Dwarf_Op **locops); 614da0c48c4Sopenharmony_ci 615da0c48c4Sopenharmony_ci/* Enumerate the DWARF register numbers and their names. 616da0c48c4Sopenharmony_ci For each register, CALLBACK gets its DWARF number, a string describing 617da0c48c4Sopenharmony_ci the register set (such as "integer" or "FPU"), a prefix used in 618da0c48c4Sopenharmony_ci assembler syntax (such as "%" or "$", may be ""), and the name for the 619da0c48c4Sopenharmony_ci register (contains identifier characters only, possibly all digits). 620da0c48c4Sopenharmony_ci The REGNAME string is valid only during the callback. */ 621da0c48c4Sopenharmony_ciextern int dwfl_module_register_names (Dwfl_Module *mod, 622da0c48c4Sopenharmony_ci int (*callback) (void *arg, 623da0c48c4Sopenharmony_ci int regno, 624da0c48c4Sopenharmony_ci const char *setname, 625da0c48c4Sopenharmony_ci const char *prefix, 626da0c48c4Sopenharmony_ci const char *regname, 627da0c48c4Sopenharmony_ci int bits, int type), 628da0c48c4Sopenharmony_ci void *arg); 629da0c48c4Sopenharmony_ci 630da0c48c4Sopenharmony_ci 631da0c48c4Sopenharmony_ci/* Find the CFI for this module. Returns NULL if there is no CFI. 632da0c48c4Sopenharmony_ci On success, fills in *BIAS with the difference between addresses 633da0c48c4Sopenharmony_ci within the loaded module and those in the CFI referring to it. 634da0c48c4Sopenharmony_ci The pointer returned can be used until the module is cleaned up. 635da0c48c4Sopenharmony_ci Calling these more than once returns the same pointers. 636da0c48c4Sopenharmony_ci 637da0c48c4Sopenharmony_ci dwfl_module_dwarf_cfi gets the '.debug_frame' information found with the 638da0c48c4Sopenharmony_ci rest of the DWARF information. dwfl_module_eh_cfi gets the '.eh_frame' 639da0c48c4Sopenharmony_ci information found linked into the text. A module might have either or 640da0c48c4Sopenharmony_ci both. */ 641da0c48c4Sopenharmony_ciextern Dwarf_CFI *dwfl_module_dwarf_cfi (Dwfl_Module *mod, Dwarf_Addr *bias); 642da0c48c4Sopenharmony_ciextern Dwarf_CFI *dwfl_module_eh_cfi (Dwfl_Module *mod, Dwarf_Addr *bias); 643da0c48c4Sopenharmony_ci 644da0c48c4Sopenharmony_ci 645da0c48c4Sopenharmony_citypedef struct 646da0c48c4Sopenharmony_ci{ 647da0c48c4Sopenharmony_ci /* Called to iterate through threads. Returns next TID (thread ID) on 648da0c48c4Sopenharmony_ci success, a negative number on failure and zero if there are no more 649da0c48c4Sopenharmony_ci threads. dwfl_errno () should be set if negative number has been 650da0c48c4Sopenharmony_ci returned. *THREAD_ARGP is NULL on first call, and may be optionally 651da0c48c4Sopenharmony_ci set by the implementation. The value set by the implementation will 652da0c48c4Sopenharmony_ci be passed in on the next call to NEXT_THREAD. THREAD_ARGP is never 653da0c48c4Sopenharmony_ci NULL. *THREAD_ARGP will be passed to set_initial_registers or 654da0c48c4Sopenharmony_ci thread_detach callbacks together with Dwfl_Thread *thread. This 655da0c48c4Sopenharmony_ci method must not be NULL. */ 656da0c48c4Sopenharmony_ci pid_t (*next_thread) (Dwfl *dwfl, void *dwfl_arg, void **thread_argp) 657da0c48c4Sopenharmony_ci __nonnull_attribute__ (1); 658da0c48c4Sopenharmony_ci 659da0c48c4Sopenharmony_ci /* Called to get a specific thread. Returns true if there is a 660da0c48c4Sopenharmony_ci thread with the given thread id number, returns false if no such 661da0c48c4Sopenharmony_ci thread exists and will set dwfl_errno in that case. THREAD_ARGP 662da0c48c4Sopenharmony_ci is never NULL. *THREAD_ARGP will be passed to 663da0c48c4Sopenharmony_ci set_initial_registers or thread_detach callbacks together with 664da0c48c4Sopenharmony_ci Dwfl_Thread *thread. This method may be NULL and will then be 665da0c48c4Sopenharmony_ci emulated using the next_thread callback. */ 666da0c48c4Sopenharmony_ci bool (*get_thread) (Dwfl *dwfl, pid_t tid, void *dwfl_arg, 667da0c48c4Sopenharmony_ci void **thread_argp) 668da0c48c4Sopenharmony_ci __nonnull_attribute__ (1); 669da0c48c4Sopenharmony_ci 670da0c48c4Sopenharmony_ci /* Called during unwinding to access memory (stack) state. Returns true for 671da0c48c4Sopenharmony_ci successfully read *RESULT or false and sets dwfl_errno () on failure. 672da0c48c4Sopenharmony_ci This method may be NULL - in such case dwfl_thread_getframes will return 673da0c48c4Sopenharmony_ci only the initial frame. */ 674da0c48c4Sopenharmony_ci bool (*memory_read) (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, 675da0c48c4Sopenharmony_ci void *dwfl_arg) 676da0c48c4Sopenharmony_ci __nonnull_attribute__ (1, 3); 677da0c48c4Sopenharmony_ci 678da0c48c4Sopenharmony_ci /* Called on initial unwind to get the initial register state of the first 679da0c48c4Sopenharmony_ci frame. Should call dwfl_thread_state_registers, possibly multiple times 680da0c48c4Sopenharmony_ci for different ranges and possibly also dwfl_thread_state_register_pc, to 681da0c48c4Sopenharmony_ci fill in initial (DWARF) register values. After this call, till at least 682da0c48c4Sopenharmony_ci thread_detach is called, the thread is assumed to be frozen, so that it is 683da0c48c4Sopenharmony_ci safe to unwind. Returns true on success or false and sets dwfl_errno () 684da0c48c4Sopenharmony_ci on failure. In the case of a failure thread_detach will not be called. 685da0c48c4Sopenharmony_ci This method must not be NULL. */ 686da0c48c4Sopenharmony_ci bool (*set_initial_registers) (Dwfl_Thread *thread, void *thread_arg) 687da0c48c4Sopenharmony_ci __nonnull_attribute__ (1); 688da0c48c4Sopenharmony_ci 689da0c48c4Sopenharmony_ci /* Called by dwfl_end. All thread_detach method calls have been already 690da0c48c4Sopenharmony_ci done. This method may be NULL. */ 691da0c48c4Sopenharmony_ci void (*detach) (Dwfl *dwfl, void *dwfl_arg) 692da0c48c4Sopenharmony_ci __nonnull_attribute__ (1); 693da0c48c4Sopenharmony_ci 694da0c48c4Sopenharmony_ci /* Called when unwinding is done. No callback will be called after 695da0c48c4Sopenharmony_ci this method has been called. Iff set_initial_registers was called for 696da0c48c4Sopenharmony_ci a TID and it returned success thread_detach will be called before the 697da0c48c4Sopenharmony_ci detach method above. This method may be NULL. */ 698da0c48c4Sopenharmony_ci void (*thread_detach) (Dwfl_Thread *thread, void *thread_arg) 699da0c48c4Sopenharmony_ci __nonnull_attribute__ (1); 700da0c48c4Sopenharmony_ci} Dwfl_Thread_Callbacks; 701da0c48c4Sopenharmony_ci 702da0c48c4Sopenharmony_ci/* PID is the process id associated with the DWFL state. Architecture of DWFL 703da0c48c4Sopenharmony_ci modules is specified by ELF, ELF must remain valid during DWFL lifetime. 704da0c48c4Sopenharmony_ci Use NULL ELF to detect architecture from DWFL, the function will then detect 705da0c48c4Sopenharmony_ci it from arbitrary Dwfl_Module of DWFL. DWFL_ARG is the callback backend 706da0c48c4Sopenharmony_ci state. DWFL_ARG will be provided to the callbacks. *THREAD_CALLBACKS 707da0c48c4Sopenharmony_ci function pointers must remain valid during lifetime of DWFL. Function 708da0c48c4Sopenharmony_ci returns true on success, false otherwise. */ 709da0c48c4Sopenharmony_cibool dwfl_attach_state (Dwfl *dwfl, Elf *elf, pid_t pid, 710da0c48c4Sopenharmony_ci const Dwfl_Thread_Callbacks *thread_callbacks, 711da0c48c4Sopenharmony_ci void *dwfl_arg) 712da0c48c4Sopenharmony_ci __nonnull_attribute__ (1, 4); 713da0c48c4Sopenharmony_ci 714da0c48c4Sopenharmony_ci/* Calls dwfl_attach_state with Dwfl_Thread_Callbacks setup for extracting 715da0c48c4Sopenharmony_ci thread state from the ELF core file. Returns the pid number extracted 716da0c48c4Sopenharmony_ci from the core file, or -1 for errors. */ 717da0c48c4Sopenharmony_ciextern int dwfl_core_file_attach (Dwfl *dwfl, Elf *elf); 718da0c48c4Sopenharmony_ci 719da0c48c4Sopenharmony_ci/* Calls dwfl_attach_state with Dwfl_Thread_Callbacks setup for extracting 720da0c48c4Sopenharmony_ci thread state from the proc file system. Uses ptrace to attach and stop 721da0c48c4Sopenharmony_ci the thread under inspection and detaches when thread_detach is called 722da0c48c4Sopenharmony_ci and unwinding for the thread is done, unless ASSUME_PTRACE_STOPPED is 723da0c48c4Sopenharmony_ci true. If ASSUME_PTRACE_STOPPED is true the caller should make sure that 724da0c48c4Sopenharmony_ci the thread is ptrace attached and stopped before unwinding by calling 725da0c48c4Sopenharmony_ci either dwfl_thread_getframes or dwfl_getthread_frames. Returns zero on 726da0c48c4Sopenharmony_ci success, -1 if dwfl_attach_state failed, or an errno code if opening the 727da0c48c4Sopenharmony_ci proc files failed. */ 728da0c48c4Sopenharmony_ciextern int dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, 729da0c48c4Sopenharmony_ci bool assume_ptrace_stopped); 730da0c48c4Sopenharmony_ci 731da0c48c4Sopenharmony_ci/* Return PID for the process associated with DWFL. Function returns -1 if 732da0c48c4Sopenharmony_ci dwfl_attach_state was not called for DWFL. */ 733da0c48c4Sopenharmony_cipid_t dwfl_pid (Dwfl *dwfl) 734da0c48c4Sopenharmony_ci __nonnull_attribute__ (1); 735da0c48c4Sopenharmony_ci 736da0c48c4Sopenharmony_ci/* Return DWFL from which THREAD was created using dwfl_getthreads. */ 737da0c48c4Sopenharmony_ciDwfl *dwfl_thread_dwfl (Dwfl_Thread *thread) 738da0c48c4Sopenharmony_ci __nonnull_attribute__ (1); 739da0c48c4Sopenharmony_ci 740da0c48c4Sopenharmony_ci/* Return positive TID (thread ID) for THREAD. This function never fails. */ 741da0c48c4Sopenharmony_cipid_t dwfl_thread_tid (Dwfl_Thread *thread) 742da0c48c4Sopenharmony_ci __nonnull_attribute__ (1); 743da0c48c4Sopenharmony_ci 744da0c48c4Sopenharmony_ci/* Return thread for frame STATE. This function never fails. */ 745da0c48c4Sopenharmony_ciDwfl_Thread *dwfl_frame_thread (Dwfl_Frame *state) 746da0c48c4Sopenharmony_ci __nonnull_attribute__ (1); 747da0c48c4Sopenharmony_ci 748da0c48c4Sopenharmony_ci/* Called by Dwfl_Thread_Callbacks.set_initial_registers implementation. 749da0c48c4Sopenharmony_ci For every known continuous block of registers <FIRSTREG..FIRSTREG+NREGS) 750da0c48c4Sopenharmony_ci (inclusive..exclusive) set their content to REGS (array of NREGS items). 751da0c48c4Sopenharmony_ci Function returns false if any of the registers has invalid number. */ 752da0c48c4Sopenharmony_cibool dwfl_thread_state_registers (Dwfl_Thread *thread, int firstreg, 753da0c48c4Sopenharmony_ci unsigned nregs, const Dwarf_Word *regs) 754da0c48c4Sopenharmony_ci __nonnull_attribute__ (1, 4); 755da0c48c4Sopenharmony_ci 756da0c48c4Sopenharmony_ci/* Called by Dwfl_Thread_Callbacks.set_initial_registers implementation. 757da0c48c4Sopenharmony_ci If PC is not contained among DWARF registers passed by 758da0c48c4Sopenharmony_ci dwfl_thread_state_registers on the target architecture pass the PC value 759da0c48c4Sopenharmony_ci here. */ 760da0c48c4Sopenharmony_civoid dwfl_thread_state_register_pc (Dwfl_Thread *thread, Dwarf_Word pc) 761da0c48c4Sopenharmony_ci __nonnull_attribute__ (1); 762da0c48c4Sopenharmony_ci 763da0c48c4Sopenharmony_ci/* Iterate through the threads for a process. Returns zero if all threads have 764da0c48c4Sopenharmony_ci been processed by the callback, returns -1 on error, or the value of the 765da0c48c4Sopenharmony_ci callback when not DWARF_CB_OK. -1 returned on error will set dwfl_errno (). 766da0c48c4Sopenharmony_ci Keeps calling the callback with the next thread while the callback returns 767da0c48c4Sopenharmony_ci DWARF_CB_OK, till there are no more threads. */ 768da0c48c4Sopenharmony_ciint dwfl_getthreads (Dwfl *dwfl, 769da0c48c4Sopenharmony_ci int (*callback) (Dwfl_Thread *thread, void *arg), 770da0c48c4Sopenharmony_ci void *arg) 771da0c48c4Sopenharmony_ci __nonnull_attribute__ (1, 2); 772da0c48c4Sopenharmony_ci 773da0c48c4Sopenharmony_ci/* Iterate through the frames for a thread. Returns zero if all frames 774da0c48c4Sopenharmony_ci have been processed by the callback, returns -1 on error, or the value of 775da0c48c4Sopenharmony_ci the callback when not DWARF_CB_OK. -1 returned on error will 776da0c48c4Sopenharmony_ci set dwfl_errno (). Some systems return error instead of zero on end of the 777da0c48c4Sopenharmony_ci backtrace, for cross-platform compatibility callers should consider error as 778da0c48c4Sopenharmony_ci a zero. Keeps calling the callback with the next frame while the callback 779da0c48c4Sopenharmony_ci returns DWARF_CB_OK, till there are no more frames. On start will call the 780da0c48c4Sopenharmony_ci set_initial_registers callback and on return will call the detach_thread 781da0c48c4Sopenharmony_ci callback of the Dwfl_Thread. */ 782da0c48c4Sopenharmony_ciint dwfl_thread_getframes (Dwfl_Thread *thread, 783da0c48c4Sopenharmony_ci int (*callback) (Dwfl_Frame *state, void *arg), 784da0c48c4Sopenharmony_ci void *arg) 785da0c48c4Sopenharmony_ci __nonnull_attribute__ (1, 2); 786da0c48c4Sopenharmony_ci 787da0c48c4Sopenharmony_ci/* Like dwfl_thread_getframes, but specifying the thread by its unique 788da0c48c4Sopenharmony_ci identifier number. Returns zero if all frames have been processed 789da0c48c4Sopenharmony_ci by the callback, returns -1 on error (and when no thread with 790da0c48c4Sopenharmony_ci the given thread id number exists), or the value of the callback 791da0c48c4Sopenharmony_ci when not DWARF_CB_OK. -1 returned on error will set dwfl_errno (). */ 792da0c48c4Sopenharmony_ciint dwfl_getthread_frames (Dwfl *dwfl, pid_t tid, 793da0c48c4Sopenharmony_ci int (*callback) (Dwfl_Frame *thread, void *arg), 794da0c48c4Sopenharmony_ci void *arg) 795da0c48c4Sopenharmony_ci __nonnull_attribute__ (1, 3); 796da0c48c4Sopenharmony_ci 797da0c48c4Sopenharmony_ci/* Return *PC (program counter) for thread-specific frame STATE. 798da0c48c4Sopenharmony_ci Set *ISACTIVATION according to DWARF frame "activation" definition. 799da0c48c4Sopenharmony_ci Typically you need to subtract 1 from *PC if *ACTIVATION is false to safely 800da0c48c4Sopenharmony_ci find function of the caller. ACTIVATION may be NULL. PC must not be NULL. 801da0c48c4Sopenharmony_ci Function returns false if it failed to find *PC. */ 802da0c48c4Sopenharmony_cibool dwfl_frame_pc (Dwfl_Frame *state, Dwarf_Addr *pc, bool *isactivation) 803da0c48c4Sopenharmony_ci __nonnull_attribute__ (1, 2); 804da0c48c4Sopenharmony_ci 805da0c48c4Sopenharmony_ci/* Get the value of the DWARF register number in the given frame. 806da0c48c4Sopenharmony_ci Returns zero on success, -1 on error (invalid DWARF register 807da0c48c4Sopenharmony_ci number) or 1 if the value of the register in the frame is unknown. */ 808da0c48c4Sopenharmony_ciint dwfl_frame_reg (Dwfl_Frame *state, unsigned regno, Dwarf_Word *val) 809da0c48c4Sopenharmony_ci __nonnull_attribute__ (1); 810da0c48c4Sopenharmony_ci 811da0c48c4Sopenharmony_ci/* Return the internal debuginfod-client connection handle for the DWFL session. 812da0c48c4Sopenharmony_ci When the client connection has not yet been initialized, it will be done on the 813da0c48c4Sopenharmony_ci first call to this function. If elfutils is compiled without support for debuginfod, 814da0c48c4Sopenharmony_ci NULL will be returned. 815da0c48c4Sopenharmony_ci */ 816da0c48c4Sopenharmony_ciextern debuginfod_client *dwfl_get_debuginfod_client (Dwfl *dwfl); 817da0c48c4Sopenharmony_ci 818da0c48c4Sopenharmony_ci#ifdef __cplusplus 819da0c48c4Sopenharmony_ci} 820da0c48c4Sopenharmony_ci#endif 821da0c48c4Sopenharmony_ci 822da0c48c4Sopenharmony_ci#endif /* libdwfl.h */ 823