LCOV - code coverage report
Current view: top level - libdwfl - libdwflP.h (source / functions) Hit Total Coverage
Test: elfutils-0.173 Lines: 23 29 79.3 %
Date: 2018-06-29 23:49:12 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       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      378288 :   const struct Dwfl_Lines *lines = ((const void *) line
     328      377648 :                                     - offsetof (struct Dwfl_Lines,
     329             :                                                 idx[line->idx]));
     330      377648 :   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   622829811 :   return addr + mod->main_bias;
     338             : }
     339             : 
     340             : static inline GElf_Addr
     341             : dwfl_deadjust_address (Dwfl_Module *mod, GElf_Addr addr)
     342             : {
     343        2055 :   return addr - mod->main_bias;
     344             : }
     345             : 
     346             : static inline Dwarf_Addr
     347      211599 : dwfl_adjusted_dwarf_addr (Dwfl_Module *mod, Dwarf_Addr addr)
     348             : {
     349      423198 :   return dwfl_adjusted_address (mod, (addr
     350      211599 :                                       - mod->debug.address_sync
     351      211599 :                                       + mod->main.address_sync));
     352             : }
     353             : 
     354             : static inline Dwarf_Addr
     355         345 : dwfl_deadjust_dwarf_addr (Dwfl_Module *mod, Dwarf_Addr addr)
     356             : {
     357         690 :   return (dwfl_deadjust_address (mod, addr)
     358         345 :           - mod->main.address_sync
     359         345 :           + mod->debug.address_sync);
     360             : }
     361             : 
     362             : static inline Dwarf_Addr
     363        2163 : dwfl_adjusted_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr)
     364             : {
     365        4326 :   return dwfl_adjusted_address (mod, (addr
     366        2163 :                                       - mod->aux_sym.address_sync
     367        2163 :                                       + mod->main.address_sync));
     368             : }
     369             : 
     370             : static inline Dwarf_Addr
     371           0 : dwfl_deadjust_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr)
     372             : {
     373           0 :   return (dwfl_deadjust_address (mod, addr)
     374           0 :           - mod->main.address_sync
     375           0 :           + mod->aux_sym.address_sync);
     376             : }
     377             : 
     378             : static inline GElf_Addr
     379   619574291 : dwfl_adjusted_st_value (Dwfl_Module *mod, Elf *symelf, GElf_Addr addr)
     380             : {
     381   619582710 :   if (symelf == mod->main.elf)
     382   619574291 :     return dwfl_adjusted_address (mod, addr);
     383        8419 :   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        1710 : dwfl_deadjust_st_value (Dwfl_Module *mod, Elf *symelf, GElf_Addr addr)
     390             : {
     391           0 :   if (symelf == mod->main.elf)
     392        1710 :     return dwfl_deadjust_address (mod, addr);
     393           0 :   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             : /* Fetch PT_DYNAMIC P_VADDR from ELF and store it to *VADDRP.  Return success.
     630             :    *VADDRP is not modified if the function fails.  */
     631             : extern bool __libdwfl_dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp)
     632             :   internal_function;
     633             : 
     634             : /* These are working nicely for --core, but are not ready to be
     635             :    exported interfaces quite yet.  */
     636             : 
     637             : /* Type of callback function ...
     638             :  */
     639             : typedef bool Dwfl_Memory_Callback (Dwfl *dwfl, int segndx,
     640             :                                    void **buffer, size_t *buffer_available,
     641             :                                    GElf_Addr vaddr, size_t minread, void *arg);
     642             : 
     643             : /* Type of callback function ...
     644             :  */
     645             : typedef bool Dwfl_Module_Callback (Dwfl_Module *mod, void **userdata,
     646             :                                    const char *name, Dwarf_Addr base,
     647             :                                    void **buffer, size_t *buffer_available,
     648             :                                    GElf_Off cost, GElf_Off worthwhile,
     649             :                                    GElf_Off whole, GElf_Off contiguous,
     650             :                                    void *arg, Elf **elfp);
     651             : 
     652             : /* One shared library (or executable) info from DT_DEBUG link map.  */
     653             : struct r_debug_info_module
     654             : {
     655             :   struct r_debug_info_module *next;
     656             :   /* FD is -1 iff ELF is NULL.  */
     657             :   int fd;
     658             :   Elf *elf;
     659             :   GElf_Addr l_ld;
     660             :   /* START and END are both zero if not valid.  */
     661             :   GElf_Addr start, end;
     662             :   bool disk_file_has_build_id;
     663             :   char name[0];
     664             : };
     665             : 
     666             : /* Information gathered from DT_DEBUG by dwfl_link_map_report hinted to
     667             :    dwfl_segment_report_module.  */
     668             : struct r_debug_info
     669             : {
     670             :   struct r_debug_info_module *module;
     671             : };
     672             : 
     673             : /* ...
     674             :  */
     675             : extern int dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
     676             :                                        Dwfl_Memory_Callback *memory_callback,
     677             :                                        void *memory_callback_arg,
     678             :                                        Dwfl_Module_Callback *read_eagerly,
     679             :                                        void *read_eagerly_arg,
     680             :                                        const void *note_file,
     681             :                                        size_t note_file_size,
     682             :                                        const struct r_debug_info *r_debug_info);
     683             : 
     684             : /* Report a module for entry in the dynamic linker's struct link_map list.
     685             :    For each link_map entry, if an existing module resides at its address,
     686             :    this just modifies that module's name and suggested file name.  If
     687             :    no such module exists, this calls dwfl_report_elf on the l_name string.
     688             : 
     689             :    If AUXV is not null, it points to AUXV_SIZE bytes of auxiliary vector
     690             :    data as contained in an NT_AUXV note or read from a /proc/pid/auxv
     691             :    file.  When this is available, it guides the search.  If AUXV is null
     692             :    or the memory it points to is not accessible, then this search can
     693             :    only find where to begin if the correct executable file was
     694             :    previously reported and preloaded as with dwfl_report_elf.
     695             : 
     696             :    Fill in R_DEBUG_INFO if it is not NULL.  It should be cleared by the
     697             :    caller, this function does not touch fields it does not need to modify.
     698             :    If R_DEBUG_INFO is not NULL then no modules get added to DWFL, caller
     699             :    has to add them from filled in R_DEBUG_INFO.
     700             : 
     701             :    Returns the number of modules found, or -1 for errors.  */
     702             : extern int dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
     703             :                                  Dwfl_Memory_Callback *memory_callback,
     704             :                                  void *memory_callback_arg,
     705             :                                  struct r_debug_info *r_debug_info);
     706             : 
     707             : 
     708             : /* Avoid PLT entries.  */
     709             : INTDECL (dwfl_begin)
     710             : INTDECL (dwfl_errmsg)
     711             : INTDECL (dwfl_errno)
     712             : INTDECL (dwfl_addrmodule)
     713             : INTDECL (dwfl_addrsegment)
     714             : INTDECL (dwfl_addrdwarf)
     715             : INTDECL (dwfl_addrdie)
     716             : INTDECL (dwfl_core_file_attach)
     717             : INTDECL (dwfl_core_file_report)
     718             : INTDECL (dwfl_getmodules)
     719             : INTDECL (dwfl_module_addrdie)
     720             : INTDECL (dwfl_module_address_section)
     721             : INTDECL (dwfl_module_addrinfo)
     722             : INTDECL (dwfl_module_addrsym)
     723             : INTDECL (dwfl_module_build_id)
     724             : INTDECL (dwfl_module_getdwarf)
     725             : INTDECL (dwfl_module_getelf)
     726             : INTDECL (dwfl_module_getsym)
     727             : INTDECL (dwfl_module_getsym_info)
     728             : INTDECL (dwfl_module_getsymtab)
     729             : INTDECL (dwfl_module_getsymtab_first_global)
     730             : INTDECL (dwfl_module_getsrc)
     731             : INTDECL (dwfl_module_report_build_id)
     732             : INTDECL (dwfl_report_elf)
     733             : INTDECL (dwfl_report_begin)
     734             : INTDECL (dwfl_report_begin_add)
     735             : INTDECL (dwfl_report_module)
     736             : INTDECL (dwfl_report_segment)
     737             : INTDECL (dwfl_report_offline)
     738             : INTDECL (dwfl_report_end)
     739             : INTDECL (dwfl_build_id_find_elf)
     740             : INTDECL (dwfl_build_id_find_debuginfo)
     741             : INTDECL (dwfl_standard_find_debuginfo)
     742             : INTDECL (dwfl_link_map_report)
     743             : INTDECL (dwfl_linux_kernel_find_elf)
     744             : INTDECL (dwfl_linux_kernel_module_section_address)
     745             : INTDECL (dwfl_linux_proc_attach)
     746             : INTDECL (dwfl_linux_proc_report)
     747             : INTDECL (dwfl_linux_proc_maps_report)
     748             : INTDECL (dwfl_linux_proc_find_elf)
     749             : INTDECL (dwfl_linux_kernel_report_kernel)
     750             : INTDECL (dwfl_linux_kernel_report_modules)
     751             : INTDECL (dwfl_linux_kernel_report_offline)
     752             : INTDECL (dwfl_offline_section_address)
     753             : INTDECL (dwfl_module_relocate_address)
     754             : INTDECL (dwfl_module_dwarf_cfi)
     755             : INTDECL (dwfl_module_eh_cfi)
     756             : INTDECL (dwfl_attach_state)
     757             : INTDECL (dwfl_pid)
     758             : INTDECL (dwfl_thread_dwfl)
     759             : INTDECL (dwfl_thread_tid)
     760             : INTDECL (dwfl_frame_thread)
     761             : INTDECL (dwfl_thread_state_registers)
     762             : INTDECL (dwfl_thread_state_register_pc)
     763             : INTDECL (dwfl_getthread_frames)
     764             : INTDECL (dwfl_getthreads)
     765             : INTDECL (dwfl_thread_getframes)
     766             : INTDECL (dwfl_frame_pc)
     767             : 
     768             : /* Leading arguments standard to callbacks passed a Dwfl_Module.  */
     769             : #define MODCB_ARGS(mod) (mod), &(mod)->userdata, (mod)->name, (mod)->low_addr
     770             : #define CBFAIL          (errno ? DWFL_E (ERRNO, errno) : DWFL_E_CB);
     771             : 
     772             : 
     773             : /* The default used by dwfl_standard_find_debuginfo.  */
     774             : #define DEFAULT_DEBUGINFO_PATH ":.debug:/usr/lib/debug"
     775             : 
     776             : 
     777             : #endif  /* libdwflP.h */

Generated by: LCOV version 1.13