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