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