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