Blame libdwfl/libdwflP.h

Packit 032894
/* Internal definitions for libdwfl.
Packit 032894
   Copyright (C) 2005-2015, 2018 Red Hat, Inc.
Packit 032894
   This file is part of elfutils.
Packit 032894
Packit 032894
   This file is free software; you can redistribute it and/or modify
Packit 032894
   it under the terms of either
Packit 032894
Packit 032894
     * the GNU Lesser General Public License as published by the Free
Packit 032894
       Software Foundation; either version 3 of the License, or (at
Packit 032894
       your option) any later version
Packit 032894
Packit 032894
   or
Packit 032894
Packit 032894
     * the GNU General Public License as published by the Free
Packit 032894
       Software Foundation; either version 2 of the License, or (at
Packit 032894
       your option) any later version
Packit 032894
Packit 032894
   or both in parallel, as here.
Packit 032894
Packit 032894
   elfutils is distributed in the hope that it will be useful, but
Packit 032894
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 032894
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 032894
   General Public License for more details.
Packit 032894
Packit 032894
   You should have received copies of the GNU General Public License and
Packit 032894
   the GNU Lesser General Public License along with this program.  If
Packit 032894
   not, see <http://www.gnu.org/licenses/>.  */
Packit 032894
Packit 032894
#ifndef _LIBDWFLP_H
Packit 032894
#define _LIBDWFLP_H	1
Packit 032894
Packit 032894
#include <libdwfl.h>
Packit 032894
#include <libebl.h>
Packit 032894
#include <assert.h>
Packit 032894
#include <dirent.h>
Packit 032894
#include <errno.h>
Packit 032894
#include <stdbool.h>
Packit 032894
#include <stdlib.h>
Packit 032894
#include <string.h>
Packit 032894
Packit 032894
#include "../libdw/libdwP.h"	/* We need its INTDECLs.  */
Packit 032894
#include "../libdwelf/libdwelfP.h"
Packit 032894
#include "../debuginfod/debuginfod.h"
Packit 032894
Packit 032894
typedef struct Dwfl_Process Dwfl_Process;
Packit 032894
Packit 032894
/* gettext helper macros.  */
Packit 032894
#define _(Str) dgettext ("elfutils", Str)
Packit 032894
Packit 032894
#define DWFL_ERRORS							      \
Packit 032894
  DWFL_ERROR (NOERROR, N_("no error"))					      \
Packit 032894
  DWFL_ERROR (UNKNOWN_ERROR, N_("unknown error"))			      \
Packit 032894
  DWFL_ERROR (NOMEM, N_("out of memory"))				      \
Packit 032894
  DWFL_ERROR (ERRNO, N_("See errno"))					      \
Packit 032894
  DWFL_ERROR (LIBELF, N_("See elf_errno"))				      \
Packit 032894
  DWFL_ERROR (LIBDW, N_("See dwarf_errno"))				      \
Packit 032894
  DWFL_ERROR (LIBEBL, N_("See ebl_errno (XXX missing)"))		      \
Packit 032894
  DWFL_ERROR (ZLIB, N_("gzip decompression failed"))			      \
Packit 032894
  DWFL_ERROR (BZLIB, N_("bzip2 decompression failed"))			      \
Packit 032894
  DWFL_ERROR (LZMA, N_("LZMA decompression failed"))			      \
Packit 032894
  DWFL_ERROR (UNKNOWN_MACHINE, N_("no support library found for machine"))    \
Packit 032894
  DWFL_ERROR (NOREL, N_("Callbacks missing for ET_REL file"))		      \
Packit 032894
  DWFL_ERROR (BADRELTYPE, N_("Unsupported relocation type"))		      \
Packit 032894
  DWFL_ERROR (BADRELOFF, N_("r_offset is bogus"))			      \
Packit 032894
  DWFL_ERROR (BADSTROFF, N_("offset out of range"))			      \
Packit 032894
  DWFL_ERROR (RELUNDEF, N_("relocation refers to undefined symbol"))	      \
Packit 032894
  DWFL_ERROR (CB, N_("Callback returned failure"))			      \
Packit 032894
  DWFL_ERROR (NO_DWARF, N_("No DWARF information found"))		      \
Packit 032894
  DWFL_ERROR (NO_SYMTAB, N_("No symbol table found"))			      \
Packit 032894
  DWFL_ERROR (NO_PHDR, N_("No ELF program headers"))			      \
Packit 032894
  DWFL_ERROR (OVERLAP, N_("address range overlaps an existing module"))	      \
Packit 032894
  DWFL_ERROR (ADDR_OUTOFRANGE, N_("address out of range"))		      \
Packit 032894
  DWFL_ERROR (NO_MATCH, N_("no matching address range"))		      \
Packit 032894
  DWFL_ERROR (TRUNCATED, N_("image truncated"))				      \
Packit 032894
  DWFL_ERROR (ALREADY_ELF, N_("ELF file opened"))			      \
Packit 032894
  DWFL_ERROR (BADELF, N_("not a valid ELF file"))			      \
Packit 032894
  DWFL_ERROR (WEIRD_TYPE, N_("cannot handle DWARF type description"))	      \
Packit 032894
  DWFL_ERROR (WRONG_ID_ELF, N_("ELF file does not match build ID"))	      \
Packit 032894
  DWFL_ERROR (BAD_PRELINK, N_("corrupt .gnu.prelink_undo section data"))      \
Packit 032894
  DWFL_ERROR (LIBEBL_BAD, N_("Internal error due to ebl"))		      \
Packit 032894
  DWFL_ERROR (CORE_MISSING, N_("Missing data in core file"))		      \
Packit 032894
  DWFL_ERROR (INVALID_REGISTER, N_("Invalid register"))			      \
Packit 032894
  DWFL_ERROR (PROCESS_MEMORY_READ, N_("Error reading process memory"))	      \
Packit 032894
  DWFL_ERROR (PROCESS_NO_ARCH, N_("Couldn't find architecture of any ELF"))   \
Packit 032894
  DWFL_ERROR (PARSE_PROC, N_("Error parsing /proc filesystem"))		      \
Packit 032894
  DWFL_ERROR (INVALID_DWARF, N_("Invalid DWARF"))			      \
Packit 032894
  DWFL_ERROR (UNSUPPORTED_DWARF, N_("Unsupported DWARF"))		      \
Packit 032894
  DWFL_ERROR (NEXT_THREAD_FAIL, N_("Unable to find more threads"))	      \
Packit 032894
  DWFL_ERROR (ATTACH_STATE_CONFLICT, N_("Dwfl already has attached state"))   \
Packit 032894
  DWFL_ERROR (NO_ATTACH_STATE, N_("Dwfl has no attached state"))	      \
Packit 032894
  DWFL_ERROR (NO_UNWIND, N_("Unwinding not supported for this architecture")) \
Packit 032894
  DWFL_ERROR (INVALID_ARGUMENT, N_("Invalid argument"))			      \
Packit 032894
  DWFL_ERROR (NO_CORE_FILE, N_("Not an ET_CORE ELF file"))
Packit 032894
Packit 032894
#define DWFL_ERROR(name, text) DWFL_E_##name,
Packit 032894
typedef enum { DWFL_ERRORS DWFL_E_NUM } Dwfl_Error;
Packit 032894
#undef	DWFL_ERROR
Packit 032894
Packit 032894
#define OTHER_ERROR(name)	((unsigned int) DWFL_E_##name << 16)
Packit 032894
#define DWFL_E(name, errno)	(OTHER_ERROR (name) | (errno))
Packit 032894
Packit 032894
extern int __libdwfl_canon_error (Dwfl_Error) internal_function;
Packit 032894
extern void __libdwfl_seterrno (Dwfl_Error) internal_function;
Packit 032894
Packit 032894
/* Resources we might keep for the user about the core file that the
Packit 032894
   Dwfl might have been created from.  Can currently only be set
Packit 032894
   through std-argp.  */
Packit 032894
struct Dwfl_User_Core
Packit 032894
{
Packit 032894
  char *executable_for_core;	/* --executable if --core was specified.  */
Packit 032894
  Elf *core;                    /* non-NULL if we need to free it.  */
Packit 032894
  int fd;                       /* close if >= 0.  */
Packit 032894
};
Packit 032894
Packit 032894
struct Dwfl
Packit 032894
{
Packit 032894
  const Dwfl_Callbacks *callbacks;
Packit 032894
  debuginfod_client *debuginfod;
Packit 032894
Packit 032894
  Dwfl_Module *modulelist;    /* List in order used by full traversals.  */
Packit 032894
Packit 032894
  Dwfl_Process *process;
Packit 032894
  Dwfl_Error attacherr;      /* Previous error attaching process.  */
Packit 032894
Packit 032894
  GElf_Addr offline_next_address;
Packit 032894
Packit 032894
  GElf_Addr segment_align;	/* Smallest granularity of segments.  */
Packit 032894
Packit 032894
  /* Binary search table in three parallel malloc'd arrays.  */
Packit 032894
  size_t lookup_elts;		/* Elements in use.  */
Packit 032894
  size_t lookup_alloc;		/* Elements allococated.  */
Packit 032894
  GElf_Addr *lookup_addr;	/* Start address of segment.  */
Packit 032894
  Dwfl_Module **lookup_module;	/* Module associated with segment, or null.  */
Packit 032894
  int *lookup_segndx;		/* User segment index, or -1.  */
Packit Service 35cfd5
  int next_segndx;
Packit 032894
Packit 032894
  struct Dwfl_User_Core *user_core;
Packit 032894
};
Packit 032894
Packit 032894
#define OFFLINE_REDZONE		0x10000
Packit 032894
Packit 032894
struct dwfl_file
Packit 032894
{
Packit 032894
  char *name;
Packit 032894
  int fd;
Packit 032894
  bool valid;			/* The build ID note has been matched.  */
Packit 032894
  bool relocated;		/* Partial relocation of all sections done.  */
Packit 032894
Packit 032894
  Elf *elf;
Packit 032894
Packit 032894
  /* This is the lowest p_vaddr in this ELF file, aligned to p_align.
Packit 032894
     For a file without phdrs, this is zero.  */
Packit 032894
  GElf_Addr vaddr;
Packit 032894
Packit 032894
  /* This is an address chosen for synchronization between the main file
Packit 032894
     and the debug file.  See dwfl_module_getdwarf.c for how it's chosen.  */
Packit 032894
  GElf_Addr address_sync;
Packit 032894
};
Packit 032894
Packit 032894
struct Dwfl_Module
Packit 032894
{
Packit 032894
  Dwfl *dwfl;
Packit 032894
  struct Dwfl_Module *next;	/* Link on Dwfl.modulelist.  */
Packit 032894
Packit 032894
  void *userdata;
Packit 032894
Packit 032894
  char *name;			/* Iterator name for this module.  */
Packit 032894
  GElf_Addr low_addr, high_addr;
Packit 032894
Packit 032894
  struct dwfl_file main, debug, aux_sym;
Packit 032894
  GElf_Addr main_bias;
Packit 032894
  Ebl *ebl;
Packit 032894
  GElf_Half e_type;		/* GElf_Ehdr.e_type cache.  */
Packit 032894
  Dwfl_Error elferr;		/* Previous failure to open main file.  */
Packit 032894
Packit 032894
  struct dwfl_relocation *reloc_info; /* Relocatable sections.  */
Packit 032894
Packit 032894
  struct dwfl_file *symfile;	/* Either main or debug.  */
Packit 032894
  Elf_Data *symdata;		/* Data in the ELF symbol table section.  */
Packit 032894
  Elf_Data *aux_symdata;	/* Data in the auxiliary ELF symbol table.  */
Packit 032894
  size_t syments;		/* sh_size / sh_entsize of that section.  */
Packit 032894
  size_t aux_syments;		/* sh_size / sh_entsize of aux_sym section.  */
Packit 032894
  int first_global;		/* Index of first global symbol of table.  */
Packit 032894
  int aux_first_global;		/* Index of first global of aux_sym table.  */
Packit 032894
  Elf_Data *symstrdata;		/* Data for its string table.  */
Packit 032894
  Elf_Data *aux_symstrdata;	/* Data for aux_sym string table.  */
Packit 032894
  Elf_Data *symxndxdata;	/* Data in the extended section index table. */
Packit 032894
  Elf_Data *aux_symxndxdata;	/* Data in the extended auxiliary table. */
Packit 032894
Packit 032894
  char *elfdir;			/* The dir where we found the main Elf.  */
Packit 032894
Packit 032894
  Dwarf *dw;			/* libdw handle for its debugging info.  */
Packit 032894
  Dwarf *alt;			/* Dwarf used for dwarf_setalt, or NULL.  */
Packit 032894
  int alt_fd; 			/* descriptor, only valid when alt != NULL.  */
Packit 032894
  Elf *alt_elf; 		/* Elf for alt Dwarf.  */
Packit 032894
Packit 032894
  Dwfl_Error symerr;		/* Previous failure to load symbols.  */
Packit 032894
  Dwfl_Error dwerr;		/* Previous failure to load DWARF.  */
Packit 032894
Packit 032894
  /* Known CU's in this module.  */
Packit 032894
  struct dwfl_cu *first_cu, **cu;
Packit 032894
Packit 032894
  void *lazy_cu_root;		/* Table indexed by Dwarf_Off of CU.  */
Packit 032894
Packit 032894
  struct dwfl_arange *aranges;	/* Mapping of addresses in module to CUs.  */
Packit 032894
Packit 032894
  void *build_id_bits;		/* malloc'd copy of build ID bits.  */
Packit 032894
  GElf_Addr build_id_vaddr;	/* Address where they reside, 0 if unknown.  */
Packit 032894
  int build_id_len;		/* -1 for prior failure, 0 if unset.  */
Packit 032894
Packit 032894
  unsigned int ncu;
Packit 032894
  unsigned int lazycu;		/* Possible users, deleted when none left.  */
Packit 032894
  unsigned int naranges;
Packit 032894
Packit 032894
  Dwarf_CFI *dwarf_cfi;		/* Cached DWARF CFI for this module.  */
Packit 032894
  Dwarf_CFI *eh_cfi;		/* Cached EH CFI for this module.  */
Packit 032894
Packit 032894
  int segment;			/* Index of first segment table entry.  */
Packit 032894
  bool gc;			/* Mark/sweep flag.  */
Packit 032894
  bool is_executable;		/* Use Dwfl::executable_for_core?  */
Packit 032894
};
Packit 032894
Packit 032894
/* This holds information common for all the threads/tasks/TIDs of one process
Packit 032894
   for backtraces.  */
Packit 032894
Packit 032894
struct Dwfl_Process
Packit 032894
{
Packit 032894
  struct Dwfl *dwfl;
Packit 032894
  pid_t pid;
Packit 032894
  const Dwfl_Thread_Callbacks *callbacks;
Packit 032894
  void *callbacks_arg;
Packit 032894
  struct ebl *ebl;
Packit 032894
  bool ebl_close:1;
Packit 032894
};
Packit 032894
Packit 032894
/* See its typedef in libdwfl.h.  */
Packit 032894
Packit 032894
struct Dwfl_Thread
Packit 032894
{
Packit 032894
  Dwfl_Process *process;
Packit 032894
  pid_t tid;
Packit 032894
  /* Bottom (innermost) frame while we're initializing, NULL afterwards.  */
Packit 032894
  Dwfl_Frame *unwound;
Packit 032894
  void *callbacks_arg;
Packit 032894
};
Packit 032894
Packit 032894
/* See its typedef in libdwfl.h.  */
Packit 032894
Packit 032894
struct Dwfl_Frame
Packit 032894
{
Packit 032894
  Dwfl_Thread *thread;
Packit 032894
  /* Previous (outer) frame.  */
Packit 032894
  Dwfl_Frame *unwound;
Packit 032894
  bool signal_frame : 1;
Packit 032894
  bool initial_frame : 1;
Packit 032894
  enum
Packit 032894
  {
Packit 032894
    /* This structure is still being initialized or there was an error
Packit 032894
       initializing it.  */
Packit 032894
    DWFL_FRAME_STATE_ERROR,
Packit 032894
    /* PC field is valid.  */
Packit 032894
    DWFL_FRAME_STATE_PC_SET,
Packit 032894
    /* PC field is undefined, this means the next (inner) frame was the
Packit 032894
       outermost frame.  */
Packit 032894
    DWFL_FRAME_STATE_PC_UNDEFINED
Packit 032894
  } pc_state;
Packit 032894
  /* Either initialized from appropriate REGS element or on some archs
Packit 032894
     initialized separately as the return address has no DWARF register.  */
Packit 032894
  Dwarf_Addr pc;
Packit 032894
  /* (1 << X) bitmask where 0 <= X < ebl_frame_nregs.  */
Packit 032894
  uint64_t regs_set[3];
Packit 032894
  /* REGS array size is ebl_frame_nregs.
Packit 032894
     REGS_SET tells which of the REGS are valid.  */
Packit 032894
  Dwarf_Addr regs[];
Packit 032894
};
Packit 032894
Packit 032894
/* Fetch value from Dwfl_Frame->regs indexed by DWARF REGNO.
Packit 032894
   No error code is set if the function returns FALSE.  */
Packit 032894
bool __libdwfl_frame_reg_get (Dwfl_Frame *state, unsigned regno,
Packit 032894
			      Dwarf_Addr *val)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Store value to Dwfl_Frame->regs indexed by DWARF REGNO.
Packit 032894
   No error code is set if the function returns FALSE.  */
Packit 032894
bool __libdwfl_frame_reg_set (Dwfl_Frame *state, unsigned regno,
Packit 032894
			      Dwarf_Addr val)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Information cached about each CU in Dwfl_Module.dw.  */
Packit 032894
struct dwfl_cu
Packit 032894
{
Packit 032894
  /* This caches libdw information about the CU.  It's also the
Packit 032894
     address passed back to users, so we take advantage of the
Packit 032894
     fact that it's placed first to cast back.  */
Packit 032894
  Dwarf_Die die;
Packit 032894
Packit 032894
  Dwfl_Module *mod;		/* Pointer back to containing module.  */
Packit 032894
Packit 032894
  struct dwfl_cu *next;		/* CU immediately following in the file.  */
Packit 032894
Packit 032894
  struct Dwfl_Lines *lines;
Packit 032894
};
Packit 032894
Packit 032894
struct Dwfl_Lines
Packit 032894
{
Packit 032894
  struct dwfl_cu *cu;
Packit 032894
Packit 032894
  /* This is what the opaque Dwfl_Line * pointers we pass to users are.
Packit 032894
     We need to recover pointers to our struct dwfl_cu and a record in
Packit 032894
     libdw's Dwarf_Line table.  To minimize the memory used in addition
Packit 032894
     to libdw's Dwarf_Lines buffer, we just point to our own index in
Packit 032894
     this table, and have one pointer back to the CU.  The indices here
Packit 032894
     match those in libdw's Dwarf_CU.lines->info table.  */
Packit 032894
  struct Dwfl_Line
Packit 032894
  {
Packit 032894
    unsigned int idx;		/* My index in the dwfl_cu.lines table.  */
Packit 032894
  } idx[0];
Packit 032894
};
Packit 032894
Packit 032894
static inline struct dwfl_cu *
Packit 032894
dwfl_linecu_inline (const Dwfl_Line *line)
Packit 032894
{
Packit 032894
  const struct Dwfl_Lines *lines = ((const void *) line
Packit 032894
				    - offsetof (struct Dwfl_Lines,
Packit 032894
						idx[line->idx]));
Packit 032894
  return lines->cu;
Packit 032894
}
Packit 032894
#define dwfl_linecu dwfl_linecu_inline
Packit 032894
Packit 032894
static inline GElf_Addr
Packit 032894
dwfl_adjusted_address (Dwfl_Module *mod, GElf_Addr addr)
Packit 032894
{
Packit 032894
  return addr + mod->main_bias;
Packit 032894
}
Packit 032894
Packit 032894
static inline GElf_Addr
Packit 032894
dwfl_deadjust_address (Dwfl_Module *mod, GElf_Addr addr)
Packit 032894
{
Packit 032894
  return addr - mod->main_bias;
Packit 032894
}
Packit 032894
Packit 032894
static inline Dwarf_Addr
Packit 032894
dwfl_adjusted_dwarf_addr (Dwfl_Module *mod, Dwarf_Addr addr)
Packit 032894
{
Packit 032894
  return dwfl_adjusted_address (mod, (addr
Packit 032894
				      - mod->debug.address_sync
Packit 032894
				      + mod->main.address_sync));
Packit 032894
}
Packit 032894
Packit 032894
static inline Dwarf_Addr
Packit 032894
dwfl_deadjust_dwarf_addr (Dwfl_Module *mod, Dwarf_Addr addr)
Packit 032894
{
Packit 032894
  return (dwfl_deadjust_address (mod, addr)
Packit 032894
	  - mod->main.address_sync
Packit 032894
	  + mod->debug.address_sync);
Packit 032894
}
Packit 032894
Packit 032894
static inline Dwarf_Addr
Packit 032894
dwfl_adjusted_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr)
Packit 032894
{
Packit 032894
  return dwfl_adjusted_address (mod, (addr
Packit 032894
				      - mod->aux_sym.address_sync
Packit 032894
				      + mod->main.address_sync));
Packit 032894
}
Packit 032894
Packit 032894
static inline Dwarf_Addr
Packit 032894
dwfl_deadjust_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr)
Packit 032894
{
Packit 032894
  return (dwfl_deadjust_address (mod, addr)
Packit 032894
	  - mod->main.address_sync
Packit 032894
	  + mod->aux_sym.address_sync);
Packit 032894
}
Packit 032894
Packit 032894
static inline GElf_Addr
Packit 032894
dwfl_adjusted_st_value (Dwfl_Module *mod, Elf *symelf, GElf_Addr addr)
Packit 032894
{
Packit 032894
  if (symelf == mod->main.elf)
Packit 032894
    return dwfl_adjusted_address (mod, addr);
Packit 032894
  if (symelf == mod->debug.elf)
Packit 032894
    return dwfl_adjusted_dwarf_addr (mod, addr);
Packit 032894
  return dwfl_adjusted_aux_sym_addr (mod, addr);
Packit 032894
}
Packit 032894
Packit 032894
static inline GElf_Addr
Packit 032894
dwfl_deadjust_st_value (Dwfl_Module *mod, Elf *symelf, GElf_Addr addr)
Packit 032894
{
Packit 032894
  if (symelf == mod->main.elf)
Packit 032894
    return dwfl_deadjust_address (mod, addr);
Packit 032894
  if (symelf == mod->debug.elf)
Packit 032894
    return dwfl_deadjust_dwarf_addr (mod, addr);
Packit 032894
  return dwfl_deadjust_aux_sym_addr (mod, addr);
Packit 032894
}
Packit 032894
Packit 032894
/* This describes a contiguous address range that lies in a single CU.
Packit 032894
   We condense runs of Dwarf_Arange entries for the same CU into this.  */
Packit 032894
struct dwfl_arange
Packit 032894
{
Packit 032894
  struct dwfl_cu *cu;
Packit 032894
  size_t arange;		/* Index in Dwarf_Aranges.  */
Packit 032894
};
Packit 032894
Packit 032894
#define __LIBDWFL_REMOTE_MEM_CACHE_SIZE 4096
Packit 032894
/* Structure for caching remote memory reads as used by __libdwfl_pid_arg.  */
Packit 032894
struct __libdwfl_remote_mem_cache
Packit 032894
{
Packit 032894
  Dwarf_Addr addr; /* Remote address.  */
Packit 032894
  Dwarf_Off len;   /* Zero if cleared, otherwise likely 4K. */
Packit 032894
  unsigned char buf[__LIBDWFL_REMOTE_MEM_CACHE_SIZE]; /* The actual cache.  */
Packit 032894
};
Packit 032894
Packit 032894
/* Structure used for keeping track of ptrace attaching a thread.
Packit 032894
   Shared by linux-pid-attach and linux-proc-maps.  If it has been setup
Packit 032894
   then get the instance through __libdwfl_get_pid_arg.  */
Packit 032894
struct __libdwfl_pid_arg
Packit 032894
{
Packit 032894
  /* /proc/PID/task/.  */
Packit 032894
  DIR *dir;
Packit 032894
  /* Elf for /proc/PID/exe.  Set to NULL if it couldn't be opened.  */
Packit 032894
  Elf *elf;
Packit 032894
  /* Remote memory cache, NULL if there is no memory cached.
Packit 032894
     Should be cleared on detachment (because that makes the thread
Packit 032894
     runnable and the cache invalid).  */
Packit 032894
  struct __libdwfl_remote_mem_cache *mem_cache;
Packit 032894
  /* fd for /proc/PID/exe.  Set to -1 if it couldn't be opened.  */
Packit 032894
  int elf_fd;
Packit 032894
  /* It is 0 if not used.  */
Packit 032894
  pid_t tid_attached;
Packit 032894
  /* Valid only if TID_ATTACHED is not zero.  */
Packit 032894
  bool tid_was_stopped;
Packit 032894
  /* True if threads are ptrace stopped by caller.  */
Packit 032894
  bool assume_ptrace_stopped;
Packit 032894
};
Packit 032894
Packit 032894
/* If DWfl is not NULL and a Dwfl_Process has been setup that has
Packit 032894
   Dwfl_Thread_Callbacks set to pid_thread_callbacks, then return the
Packit 032894
   callbacks_arg, which will be a struct __libdwfl_pid_arg.  Otherwise
Packit 032894
   returns NULL.  */
Packit 032894
extern struct __libdwfl_pid_arg *__libdwfl_get_pid_arg (Dwfl *dwfl)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Makes sure the given tid is attached. On success returns true and
Packit 032894
   sets tid_was_stopped.  */
Packit 032894
extern bool __libdwfl_ptrace_attach (pid_t tid, bool *tid_was_stoppedp)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Detaches a tid that was attached through
Packit 032894
   __libdwfl_ptrace_attach. Must be given the tid_was_stopped as set
Packit 032894
   by __libdwfl_ptrace_attach.  */
Packit 032894
extern void __libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
Packit 032894
/* Internal wrapper for old dwfl_module_getsym and new dwfl_module_getsym_info.
Packit 032894
   adjust_st_value set to true returns adjusted SYM st_value, set to false
Packit 032894
   it will not adjust SYM at all, but does match against resolved *ADDR. */
Packit 032894
extern const char *__libdwfl_getsym (Dwfl_Module *mod, int ndx, GElf_Sym *sym,
Packit 032894
				     GElf_Addr *addr, GElf_Word *shndxp,
Packit 032894
				     Elf **elfp, Dwarf_Addr *biasp,
Packit 032894
				     bool *resolved, bool adjust_st_value)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
extern void __libdwfl_module_free (Dwfl_Module *mod) internal_function;
Packit 032894
Packit 032894
/* Find the main ELF file, update MOD->elferr and/or MOD->main.elf.  */
Packit 032894
extern void __libdwfl_getelf (Dwfl_Module *mod) internal_function;
Packit 032894
Packit 032894
/* Process relocations in debugging sections in an ET_REL file.
Packit 032894
   FILE must be opened with ELF_C_READ_MMAP_PRIVATE or ELF_C_READ,
Packit 032894
   to make it possible to relocate the data in place (or ELF_C_RDWR or
Packit 032894
   ELF_C_RDWR_MMAP if you intend to modify the Elf file on disk).  After
Packit 032894
   this, dwarf_begin_elf on FILE will read the relocated data.
Packit 032894
Packit 032894
   When DEBUG is false, apply partial relocation to all sections.  */
Packit 032894
extern Dwfl_Error __libdwfl_relocate (Dwfl_Module *mod, Elf *file, bool debug)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Find the section index in mod->main.elf that contains the given
Packit 032894
   *ADDR.  Adjusts *ADDR to be section relative on success, returns
Packit 032894
   SHN_UNDEF on failure.  */
Packit 032894
extern size_t __libdwfl_find_section_ndx (Dwfl_Module *mod, Dwarf_Addr *addr)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Process (simple) relocations in arbitrary section TSCN of an ET_REL file.
Packit 032894
   RELOCSCN is SHT_REL or SHT_RELA and TSCN is its sh_info target section.  */
Packit 032894
extern Dwfl_Error __libdwfl_relocate_section (Dwfl_Module *mod, Elf *relocated,
Packit 032894
					      Elf_Scn *relocscn, Elf_Scn *tscn,
Packit 032894
					      bool partial)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Adjust *VALUE from section-relative to absolute.
Packit 032894
   MOD->dwfl->callbacks->section_address is called to determine the actual
Packit 032894
   address of a loaded section.  */
Packit 032894
extern Dwfl_Error __libdwfl_relocate_value (Dwfl_Module *mod, Elf *elf,
Packit 032894
					    size_t *shstrndx_cache,
Packit 032894
					    Elf32_Word shndx,
Packit 032894
					    GElf_Addr *value)
Packit 032894
     internal_function;
Packit 032894
Packit 032894
/* Ensure that MOD->ebl is set up.  */
Packit 032894
extern Dwfl_Error __libdwfl_module_getebl (Dwfl_Module *mod) internal_function;
Packit 032894
Packit 032894
/* Install a new Dwarf_CFI in *SLOT (MOD->eh_cfi or MOD->dwarf_cfi).  */
Packit 032894
extern Dwarf_CFI *__libdwfl_set_cfi (Dwfl_Module *mod, Dwarf_CFI **slot,
Packit 032894
				     Dwarf_CFI *cfi)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Iterate through all the CU's in the module.  Start by passing a null
Packit 032894
   LASTCU, and then pass the last *CU returned.  Success return with null
Packit 032894
   *CU no more CUs.  */
Packit 032894
extern Dwfl_Error __libdwfl_nextcu (Dwfl_Module *mod, struct dwfl_cu *lastcu,
Packit 032894
				    struct dwfl_cu **cu) internal_function;
Packit 032894
Packit 032894
/* Find the CU by address.  */
Packit 032894
extern Dwfl_Error __libdwfl_addrcu (Dwfl_Module *mod, Dwarf_Addr addr,
Packit 032894
				    struct dwfl_cu **cu) internal_function;
Packit 032894
Packit 032894
/* Ensure that CU->lines (and CU->cu->lines) is set up.  */
Packit 032894
extern Dwfl_Error __libdwfl_cu_getsrclines (struct dwfl_cu *cu)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Look in ELF for an NT_GNU_BUILD_ID note.  Store it to BUILD_ID_BITS,
Packit 032894
   its vaddr in ELF to BUILD_ID_VADDR (it is unrelocated, even if MOD is not
Packit 032894
   NULL) and store length to BUILD_ID_LEN.  Returns -1 for errors, 1 if it was
Packit 032894
   stored and 0 if no note is found.  MOD may be NULL, MOD must be non-NULL
Packit 032894
   only if ELF is ET_REL.  */
Packit 032894
extern int __libdwfl_find_elf_build_id (Dwfl_Module *mod, Elf *elf,
Packit 032894
					const void **build_id_bits,
Packit 032894
					GElf_Addr *build_id_elfaddr,
Packit 032894
					int *build_id_len)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Look in ELF for an NT_GNU_BUILD_ID note.  If SET is true, store it
Packit 032894
   in MOD and return its length.  If SET is false, instead compare it
Packit 032894
   to that stored in MOD and return 2 if they match, 1 if they do not.
Packit 032894
   Returns -1 for errors, 0 if no note is found.  */
Packit 032894
extern int __libdwfl_find_build_id (Dwfl_Module *mod, bool set, Elf *elf)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Open a main or debuginfo file by its build ID, returns the fd.  */
Packit 032894
extern int __libdwfl_open_mod_by_build_id (Dwfl_Module *mod, bool debug,
Packit 032894
					   char **file_name) internal_function;
Packit 032894
Packit 032894
/* Same, but takes an explicit build_id, can also be used for alt debug.  */
Packit 032894
extern int __libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug,
Packit 032894
				       char **file_name, const size_t id_len,
Packit 032894
				       const uint8_t *id) internal_function;
Packit 032894
Packit 032894
extern uint32_t __libdwfl_crc32 (uint32_t crc, unsigned char *buf, size_t len)
Packit 032894
  attribute_hidden;
Packit 032894
extern int __libdwfl_crc32_file (int fd, uint32_t *resp) attribute_hidden;
Packit 032894
Packit 032894
Packit 032894
/* Given ELF and some parameters return TRUE if the *P return value parameters
Packit 032894
   have been successfully filled in.  Any of the *P parameters can be NULL.  */
Packit 032894
extern bool __libdwfl_elf_address_range (Elf *elf, GElf_Addr base,
Packit 032894
					 bool add_p_vaddr, bool sanity,
Packit 032894
					 GElf_Addr *vaddrp,
Packit 032894
					 GElf_Addr *address_syncp,
Packit 032894
					 GElf_Addr *startp, GElf_Addr *endp,
Packit 032894
					 GElf_Addr *biasp, GElf_Half *e_typep)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Meat of dwfl_report_elf, given elf_begin just called.
Packit 032894
   Consumes ELF on success, not on failure.  */
Packit 032894
extern Dwfl_Module *__libdwfl_report_elf (Dwfl *dwfl, const char *name,
Packit 032894
					  const char *file_name, int fd,
Packit 032894
					  Elf *elf, GElf_Addr base,
Packit 032894
					  bool add_p_vaddr, bool sanity)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Meat of dwfl_report_offline.  */
Packit 032894
extern Dwfl_Module *__libdwfl_report_offline (Dwfl *dwfl, const char *name,
Packit 032894
					      const char *file_name,
Packit 032894
					      int fd, bool closefd,
Packit 032894
					      int (*predicate) (const char *,
Packit 032894
								const char *))
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Free PROCESS.  Unlink and free also any structures it references.  */
Packit 032894
extern void __libdwfl_process_free (Dwfl_Process *process)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Update STATE->unwound for the unwound frame.
Packit 032894
   On error STATE->unwound == NULL
Packit 032894
   or STATE->unwound->pc_state == DWFL_FRAME_STATE_ERROR;
Packit 032894
   in such case dwfl_errno () is set.
Packit 032894
   If STATE->unwound->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED
Packit 032894
   then STATE was the last valid frame.  */
Packit 032894
extern void __libdwfl_frame_unwind (Dwfl_Frame *state)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Align segment START downwards or END upwards addresses according to DWFL.  */
Packit 032894
extern GElf_Addr __libdwfl_segment_start (Dwfl *dwfl, GElf_Addr start)
Packit 032894
  internal_function;
Packit 032894
extern GElf_Addr __libdwfl_segment_end (Dwfl *dwfl, GElf_Addr end)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Decompression wrappers: decompress whole file into memory.  */
Packit 032894
extern Dwfl_Error __libdw_gunzip  (int fd, off_t start_offset,
Packit 032894
				   void *mapped, size_t mapped_size,
Packit 032894
				   void **whole, size_t *whole_size)
Packit 032894
  internal_function;
Packit 032894
extern Dwfl_Error __libdw_bunzip2 (int fd, off_t start_offset,
Packit 032894
				   void *mapped, size_t mapped_size,
Packit 032894
				   void **whole, size_t *whole_size)
Packit 032894
  internal_function;
Packit 032894
extern Dwfl_Error __libdw_unlzma (int fd, off_t start_offset,
Packit 032894
				  void *mapped, size_t mapped_size,
Packit 032894
				  void **whole, size_t *whole_size)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Skip the image header before a file image: updates *START_OFFSET.  */
Packit 032894
extern Dwfl_Error __libdw_image_header (int fd, off_t *start_offset,
Packit 032894
					void *mapped, size_t mapped_size)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Open Elf handle on *FDP.  This handles decompression and checks
Packit 032894
   elf_kind.  Succeed only for ELF_K_ELF, or also ELF_K_AR if ARCHIVE_OK.
Packit 032894
   Returns DWFL_E_NOERROR and sets *ELFP on success, resets *FDP to -1 if
Packit 032894
   it's no longer used.  Resets *FDP on failure too iff CLOSE_ON_FAIL.  */
Packit 032894
extern Dwfl_Error __libdw_open_file (int *fdp, Elf **elfp,
Packit 032894
				     bool close_on_fail, bool archive_ok)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Same as __libdw_open_file, but never closes the given file
Packit 032894
   descriptor and ELF_K_AR is always an acceptable type.  */
Packit 032894
extern Dwfl_Error __libdw_open_elf (int fd, Elf **elfp) internal_function;
Packit 032894
Packit 032894
/* Fetch PT_DYNAMIC P_VADDR from ELF and store it to *VADDRP.  Return success.
Packit 032894
   *VADDRP is not modified if the function fails.  */
Packit 032894
extern bool __libdwfl_dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp)
Packit 032894
  internal_function;
Packit 032894
Packit 032894
/* Internal interface to libdebuginfod (if installed).  */
Packit 032894
int
Packit 032894
__libdwfl_debuginfod_find_executable (Dwfl *dwfl,
Packit 032894
				      const unsigned char *build_id_bits,
Packit 032894
				      size_t build_id_len);
Packit 032894
int
Packit 032894
__libdwfl_debuginfod_find_debuginfo (Dwfl *dwfl,
Packit 032894
				     const unsigned char *build_id_bits,
Packit 032894
				     size_t build_id_len);
Packit 032894
void
Packit 032894
__libdwfl_debuginfod_end (debuginfod_client *c);
Packit 032894
Packit 032894
Packit 032894
/* These are working nicely for --core, but are not ready to be
Packit 032894
   exported interfaces quite yet.  */
Packit 032894
Packit 032894
/* Type of callback function ...
Packit 032894
 */
Packit 032894
typedef bool Dwfl_Memory_Callback (Dwfl *dwfl, int segndx,
Packit 032894
				   void **buffer, size_t *buffer_available,
Packit 032894
				   GElf_Addr vaddr, size_t minread, void *arg);
Packit 032894
Packit 032894
/* Type of callback function ...
Packit 032894
 */
Packit 032894
typedef bool Dwfl_Module_Callback (Dwfl_Module *mod, void **userdata,
Packit 032894
				   const char *name, Dwarf_Addr base,
Packit 032894
				   void **buffer, size_t *buffer_available,
Packit 032894
				   GElf_Off cost, GElf_Off worthwhile,
Packit 032894
				   GElf_Off whole, GElf_Off contiguous,
Packit 032894
				   void *arg, Elf **elfp);
Packit 032894
Packit 032894
/* One shared library (or executable) info from DT_DEBUG link map.  */
Packit 032894
struct r_debug_info_module
Packit 032894
{
Packit 032894
  struct r_debug_info_module *next;
Packit 032894
  /* FD is -1 iff ELF is NULL.  */
Packit 032894
  int fd;
Packit 032894
  Elf *elf;
Packit 032894
  GElf_Addr l_ld;
Packit 032894
  /* START and END are both zero if not valid.  */
Packit 032894
  GElf_Addr start, end;
Packit 032894
  bool disk_file_has_build_id;
Packit 032894
  char name[0];
Packit 032894
};
Packit 032894
Packit 032894
/* Information gathered from DT_DEBUG by dwfl_link_map_report hinted to
Packit 032894
   dwfl_segment_report_module.  */
Packit 032894
struct r_debug_info
Packit 032894
{
Packit 032894
  struct r_debug_info_module *module;
Packit 032894
};
Packit 032894
Packit 032894
/* ...
Packit 032894
 */
Packit 032894
extern int dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
Packit 032894
				       Dwfl_Memory_Callback *memory_callback,
Packit 032894
				       void *memory_callback_arg,
Packit 032894
				       Dwfl_Module_Callback *read_eagerly,
Packit 032894
				       void *read_eagerly_arg,
Packit 032894
				       const void *note_file,
Packit 032894
				       size_t note_file_size,
Packit 032894
				       const struct r_debug_info *r_debug_info);
Packit 032894
Packit 032894
/* Report a module for entry in the dynamic linker's struct link_map list.
Packit 032894
   For each link_map entry, if an existing module resides at its address,
Packit 032894
   this just modifies that module's name and suggested file name.  If
Packit 032894
   no such module exists, this calls dwfl_report_elf on the l_name string.
Packit 032894
Packit 032894
   If AUXV is not null, it points to AUXV_SIZE bytes of auxiliary vector
Packit 032894
   data as contained in an NT_AUXV note or read from a /proc/pid/auxv
Packit 032894
   file.  When this is available, it guides the search.  If AUXV is null
Packit 032894
   or the memory it points to is not accessible, then this search can
Packit 032894
   only find where to begin if the correct executable file was
Packit 032894
   previously reported and preloaded as with dwfl_report_elf.
Packit 032894
Packit 032894
   Fill in R_DEBUG_INFO if it is not NULL.  It should be cleared by the
Packit 032894
   caller, this function does not touch fields it does not need to modify.
Packit 032894
   If R_DEBUG_INFO is not NULL then no modules get added to DWFL, caller
Packit 032894
   has to add them from filled in R_DEBUG_INFO.
Packit 032894
Packit 032894
   Returns the number of modules found, or -1 for errors.  */
Packit 032894
extern int dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
Packit 032894
				 Dwfl_Memory_Callback *memory_callback,
Packit 032894
				 void *memory_callback_arg,
Packit 032894
				 struct r_debug_info *r_debug_info);
Packit 032894
Packit 032894
Packit 032894
/* Avoid PLT entries.  */
Packit 032894
INTDECL (dwfl_begin)
Packit 032894
INTDECL (dwfl_errmsg)
Packit 032894
INTDECL (dwfl_errno)
Packit 032894
INTDECL (dwfl_addrmodule)
Packit 032894
INTDECL (dwfl_addrsegment)
Packit 032894
INTDECL (dwfl_addrdwarf)
Packit 032894
INTDECL (dwfl_addrdie)
Packit 032894
INTDECL (dwfl_core_file_attach)
Packit 032894
INTDECL (dwfl_core_file_report)
Packit 032894
INTDECL (dwfl_getmodules)
Packit 032894
INTDECL (dwfl_module_addrdie)
Packit 032894
INTDECL (dwfl_module_address_section)
Packit 032894
INTDECL (dwfl_module_addrinfo)
Packit 032894
INTDECL (dwfl_module_addrsym)
Packit 032894
INTDECL (dwfl_module_build_id)
Packit 032894
INTDECL (dwfl_module_getdwarf)
Packit 032894
INTDECL (dwfl_module_getelf)
Packit 032894
INTDECL (dwfl_module_getsym)
Packit 032894
INTDECL (dwfl_module_getsym_info)
Packit 032894
INTDECL (dwfl_module_getsymtab)
Packit 032894
INTDECL (dwfl_module_getsymtab_first_global)
Packit 032894
INTDECL (dwfl_module_getsrc)
Packit 032894
INTDECL (dwfl_module_report_build_id)
Packit 032894
INTDECL (dwfl_report_elf)
Packit 032894
INTDECL (dwfl_report_begin)
Packit 032894
INTDECL (dwfl_report_begin_add)
Packit 032894
INTDECL (dwfl_report_module)
Packit 032894
INTDECL (dwfl_report_segment)
Packit 032894
INTDECL (dwfl_report_offline)
Packit 032894
INTDECL (dwfl_report_end)
Packit 032894
INTDECL (dwfl_build_id_find_elf)
Packit 032894
INTDECL (dwfl_build_id_find_debuginfo)
Packit 032894
INTDECL (dwfl_standard_find_debuginfo)
Packit 032894
INTDECL (dwfl_link_map_report)
Packit 032894
INTDECL (dwfl_linux_kernel_find_elf)
Packit 032894
INTDECL (dwfl_linux_kernel_module_section_address)
Packit 032894
INTDECL (dwfl_linux_proc_attach)
Packit 032894
INTDECL (dwfl_linux_proc_report)
Packit 032894
INTDECL (dwfl_linux_proc_maps_report)
Packit 032894
INTDECL (dwfl_linux_proc_find_elf)
Packit 032894
INTDECL (dwfl_linux_kernel_report_kernel)
Packit 032894
INTDECL (dwfl_linux_kernel_report_modules)
Packit 032894
INTDECL (dwfl_linux_kernel_report_offline)
Packit 032894
INTDECL (dwfl_offline_section_address)
Packit 032894
INTDECL (dwfl_module_relocate_address)
Packit 032894
INTDECL (dwfl_module_dwarf_cfi)
Packit 032894
INTDECL (dwfl_module_eh_cfi)
Packit 032894
INTDECL (dwfl_attach_state)
Packit 032894
INTDECL (dwfl_pid)
Packit 032894
INTDECL (dwfl_thread_dwfl)
Packit 032894
INTDECL (dwfl_thread_tid)
Packit 032894
INTDECL (dwfl_frame_thread)
Packit 032894
INTDECL (dwfl_thread_state_registers)
Packit 032894
INTDECL (dwfl_thread_state_register_pc)
Packit 032894
INTDECL (dwfl_getthread_frames)
Packit 032894
INTDECL (dwfl_getthreads)
Packit 032894
INTDECL (dwfl_thread_getframes)
Packit 032894
INTDECL (dwfl_frame_pc)
Packit 032894
Packit 032894
/* Leading arguments standard to callbacks passed a Dwfl_Module.  */
Packit 032894
#define MODCB_ARGS(mod)	(mod), &(mod)->userdata, (mod)->name, (mod)->low_addr
Packit 032894
#define CBFAIL		(errno ? DWFL_E (ERRNO, errno) : DWFL_E_CB);
Packit 032894
Packit 032894
Packit 032894
/* The default used by dwfl_standard_find_debuginfo.  */
Packit 032894
#define DEFAULT_DEBUGINFO_PATH ":.debug:/usr/lib/debug"
Packit 032894
Packit 032894
Packit 032894
#endif	/* libdwflP.h */