mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-10 21:47:06 +00:00
351 lines
11 KiB
C
351 lines
11 KiB
C
|
|
/*--------------------------------------------------------------------*/
|
|
/*--- Format-neutral storage of and querying of info acquired from ---*/
|
|
/*--- ELF/XCOFF stabs/dwarf1/dwarf2 debug info. ---*/
|
|
/*--- priv_storage.h ---*/
|
|
/*--------------------------------------------------------------------*/
|
|
|
|
/*
|
|
This file is part of Valgrind, a dynamic binary instrumentation
|
|
framework.
|
|
|
|
Copyright (C) 2000-2007 Julian Seward
|
|
jseward@acm.org
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the
|
|
License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
02111-1307, USA.
|
|
|
|
The GNU General Public License is contained in the file COPYING.
|
|
*/
|
|
/*
|
|
Stabs reader greatly improved by Nick Nethercote, Apr 02.
|
|
This module was also extensively hacked on by Jeremy Fitzhardinge
|
|
and Tom Hughes.
|
|
*/
|
|
/* See comment at top of debuginfo.c for explanation of
|
|
the _svma / _avma / _image / _bias naming scheme.
|
|
*/
|
|
/* Note this is not freestanding; needs pub_core_xarray.h to be
|
|
included before it. */
|
|
|
|
#ifndef __PRIV_STORAGE_H
|
|
#define __PRIV_STORAGE_H
|
|
|
|
/* --------------------- SYMBOLS --------------------- */
|
|
|
|
/* A structure to hold an ELF/XCOFF symbol (very crudely). */
|
|
typedef
|
|
struct {
|
|
Addr addr; /* lowest address of entity */
|
|
Addr tocptr; /* ppc64-linux only: value that R2 should have */
|
|
UInt size; /* size in bytes */
|
|
UChar *name; /* name */
|
|
}
|
|
DiSym;
|
|
|
|
/* --------------------- SRCLOCS --------------------- */
|
|
|
|
/* Line count at which overflow happens, due to line numbers being
|
|
stored as shorts in `struct nlist' in a.out.h. */
|
|
#define LINENO_OVERFLOW (1 << (sizeof(short) * 8))
|
|
|
|
#define LINENO_BITS 20
|
|
#define LOC_SIZE_BITS (32 - LINENO_BITS)
|
|
#define MAX_LINENO ((1 << LINENO_BITS) - 1)
|
|
|
|
/* Unlikely to have any lines with instruction ranges > 4096 bytes */
|
|
#define MAX_LOC_SIZE ((1 << LOC_SIZE_BITS) - 1)
|
|
|
|
/* Number used to detect line number overflows; if one line is
|
|
60000-odd smaller than the previous, is was probably an overflow.
|
|
*/
|
|
#define OVERFLOW_DIFFERENCE (LINENO_OVERFLOW - 5000)
|
|
|
|
/* A structure to hold addr-to-source info for a single line. There
|
|
can be a lot of these, hence the dense packing. */
|
|
typedef
|
|
struct {
|
|
/* Word 1 */
|
|
Addr addr; /* lowest address for this line */
|
|
/* Word 2 */
|
|
UShort size:LOC_SIZE_BITS; /* # bytes; we catch overflows of this */
|
|
UInt lineno:LINENO_BITS; /* source line number, or zero */
|
|
/* Word 3 */
|
|
UChar* filename; /* source filename */
|
|
/* Word 4 */
|
|
UChar* dirname; /* source directory name */
|
|
}
|
|
DiLoc;
|
|
|
|
/* --------------------- CF INFO --------------------- */
|
|
|
|
/* A structure to summarise DWARF2/3 CFA info for the code address
|
|
range [base .. base+len-1]. In short, if you know (sp,fp,ip) at
|
|
some point and ip is in the range [base .. base+len-1], it tells
|
|
you how to calculate (sp,fp) for the caller of the current frame
|
|
and also ra, the return address of the current frame.
|
|
|
|
First off, calculate CFA, the Canonical Frame Address, thusly:
|
|
|
|
cfa = case cfa_how of
|
|
CFIC_SPREL -> sp + cfa_off
|
|
CFIC_FPREL -> fp + cfa_off
|
|
CFIR_EXPR -> expr whose index is in cfa_off
|
|
|
|
Once that is done, the previous frame's sp/fp values and this
|
|
frame's ra value can be calculated like this:
|
|
|
|
old_sp/fp/ra
|
|
= case sp/fp/ra_how of
|
|
CFIR_UNKNOWN -> we don't know, sorry
|
|
CFIR_SAME -> same as it was before (sp/fp only)
|
|
CFIR_CFAREL -> cfa + sp/fp/ra_off
|
|
CFIR_MEMCFAREL -> *( cfa + sp/fp/ra_off )
|
|
CFIR_EXPR -> expr whose index is in sp/fp/ra_off
|
|
*/
|
|
|
|
#define CFIC_SPREL ((UChar)1)
|
|
#define CFIC_FPREL ((UChar)2)
|
|
#define CFIC_EXPR ((UChar)3)
|
|
|
|
#define CFIR_UNKNOWN ((UChar)4)
|
|
#define CFIR_SAME ((UChar)5)
|
|
#define CFIR_CFAREL ((UChar)6)
|
|
#define CFIR_MEMCFAREL ((UChar)7)
|
|
#define CFIR_EXPR ((UChar)8)
|
|
|
|
typedef
|
|
struct {
|
|
Addr base;
|
|
UInt len;
|
|
UChar cfa_how; /* a CFIC_ value */
|
|
UChar ra_how; /* a CFIR_ value */
|
|
UChar sp_how; /* a CFIR_ value */
|
|
UChar fp_how; /* a CFIR_ value */
|
|
Int cfa_off;
|
|
Int ra_off;
|
|
Int sp_off;
|
|
Int fp_off;
|
|
}
|
|
DiCfSI;
|
|
|
|
|
|
typedef
|
|
enum {
|
|
Cop_Add=0x321,
|
|
Cop_Sub,
|
|
Cop_And,
|
|
Cop_Mul
|
|
}
|
|
CfiOp;
|
|
|
|
typedef
|
|
enum {
|
|
Creg_SP=0x213,
|
|
Creg_FP,
|
|
Creg_IP
|
|
}
|
|
CfiReg;
|
|
|
|
typedef
|
|
enum {
|
|
Cex_Undef=0x123,
|
|
Cex_Deref,
|
|
Cex_Const,
|
|
Cex_Binop,
|
|
Cex_CfiReg,
|
|
Cex_DwReg
|
|
}
|
|
CfiExprTag;
|
|
|
|
typedef
|
|
struct {
|
|
CfiExprTag tag;
|
|
union {
|
|
struct {
|
|
} Undef;
|
|
struct {
|
|
Int ixAddr;
|
|
} Deref;
|
|
struct {
|
|
UWord con;
|
|
} Const;
|
|
struct {
|
|
CfiOp op;
|
|
Int ixL;
|
|
Int ixR;
|
|
} Binop;
|
|
struct {
|
|
CfiReg reg;
|
|
} CfiReg;
|
|
struct {
|
|
Int reg;
|
|
} DwReg;
|
|
}
|
|
Cex;
|
|
}
|
|
CfiExpr;
|
|
|
|
extern Int ML_(CfiExpr_Undef) ( XArray* dst );
|
|
extern Int ML_(CfiExpr_Deref) ( XArray* dst, Int ixAddr );
|
|
extern Int ML_(CfiExpr_Const) ( XArray* dst, UWord con );
|
|
extern Int ML_(CfiExpr_Binop) ( XArray* dst, CfiOp op, Int ixL, Int ixR );
|
|
extern Int ML_(CfiExpr_CfiReg)( XArray* dst, CfiReg reg );
|
|
extern Int ML_(CfiExpr_DwReg) ( XArray* dst, Int reg );
|
|
|
|
extern void ML_(ppCfiExpr)( XArray* src, Int ix );
|
|
|
|
/* --------------------- SEGINFO --------------------- */
|
|
|
|
/* This is the top-level data type. It's a structure which contains
|
|
information pertaining to one mapped text segment. This type is
|
|
exported only abstractly - in pub_tool_debuginfo.h. */
|
|
|
|
#define SEGINFO_STRCHUNKSIZE (64*1024)
|
|
|
|
struct _SegInfo {
|
|
struct _SegInfo* next; /* list of SegInfos */
|
|
|
|
/* Description of the mapped segment. */
|
|
Addr text_start_avma;
|
|
UInt text_size;
|
|
UChar* filename; /* in mallocville */
|
|
UChar* memname; /* malloc'd. AIX5 only: .a member name */
|
|
OffT foffset; /* file offset for mapped text section - UNUSED */
|
|
UChar* soname;
|
|
|
|
/* An expandable array of symbols. */
|
|
DiSym* symtab;
|
|
UInt symtab_used;
|
|
UInt symtab_size;
|
|
/* An expandable array of locations. */
|
|
DiLoc* loctab;
|
|
UInt loctab_used;
|
|
UInt loctab_size;
|
|
/* An expandable array of CFI summary info records. Also includes
|
|
summary address bounds, showing the min and max address covered
|
|
by any of the records, as an aid to fast searching. And, if the
|
|
records require any expression nodes, they are stored in
|
|
cfsi_exprs. */
|
|
DiCfSI* cfsi;
|
|
UInt cfsi_used;
|
|
UInt cfsi_size;
|
|
Addr cfsi_minaddr;
|
|
Addr cfsi_maxaddr;
|
|
XArray* cfsi_exprs; /* XArray of CfSiExpr */
|
|
|
|
/* Expandable arrays of characters -- the string table. Pointers
|
|
into this are stable (the arrays are not reallocated). */
|
|
struct strchunk {
|
|
UInt strtab_used;
|
|
struct strchunk *next;
|
|
UChar strtab[SEGINFO_STRCHUNKSIZE];
|
|
} *strchunks;
|
|
|
|
/* 'text_bias' is what needs to be added to an address in the
|
|
address space of the library as stored on disk [a so-called
|
|
stated VMA] (which is not 0-based for executables or prelinked
|
|
libraries) to get an address in memory for the object loaded at
|
|
'text_start_avma'. At least for text symbols. */
|
|
OffT text_bias;
|
|
|
|
/* Bounds of data, BSS, PLT, GOT and OPD (for ppc64-linux) so that
|
|
tools can see what section an address is in. In the running
|
|
image! */
|
|
Addr plt_start_avma;
|
|
UInt plt_size;
|
|
Addr got_start_avma;
|
|
UInt got_size;
|
|
Addr opd_start_avma;
|
|
UInt opd_size;
|
|
Addr data_start_avma;
|
|
UInt data_size;
|
|
Addr bss_start_avma;
|
|
UInt bss_size;
|
|
|
|
/* Used for debugging only - indicate what stuff to dump whilst
|
|
reading stuff into the seginfo. Are computed as early in the
|
|
lifetime of the SegInfo as possible. Use these when deciding
|
|
what to spew out; do not use the global VG_(clo_blah) flags. */
|
|
Bool trace_symtab; /* symbols, our style */
|
|
Bool trace_cfi; /* dwarf frame unwind, our style */
|
|
Bool ddump_syms; /* mimic /usr/bin/readelf --syms */
|
|
Bool ddump_line; /* mimic /usr/bin/readelf --debug-dump=line */
|
|
Bool ddump_frames; /* mimic /usr/bin/readelf --debug-dump=frames */
|
|
};
|
|
|
|
/* --------------------- functions --------------------- */
|
|
|
|
/* ------ Adding ------ */
|
|
|
|
/* Add a symbol to si's symbol table. */
|
|
extern void ML_(addSym) ( struct _SegInfo* si, DiSym* sym );
|
|
|
|
/* Add a line-number record to a SegInfo. */
|
|
extern
|
|
void ML_(addLineInfo) ( struct _SegInfo* si,
|
|
UChar* filename,
|
|
UChar* dirname, /* NULL is allowable */
|
|
Addr this, Addr next, Int lineno, Int entry);
|
|
|
|
/* Add a CFI summary record. The supplied DiCfSI is copied. */
|
|
extern void ML_(addDiCfSI) ( struct _SegInfo* si, DiCfSI* cfsi );
|
|
|
|
/* Add a string to the string table of a SegInfo. If len==-1,
|
|
ML_(addStr) will itself measure the length of the string. */
|
|
extern UChar* ML_(addStr) ( struct _SegInfo* si, UChar* str, Int len );
|
|
|
|
/* Canonicalise the tables held by 'si', in preparation for use. Call
|
|
this after finishing adding entries to these tables. */
|
|
extern void ML_(canonicaliseTables) ( struct _SegInfo* si );
|
|
|
|
/* ------ Searching ------ */
|
|
|
|
/* Find a symbol-table index containing the specified pointer, or -1
|
|
if not found. Binary search. */
|
|
extern Int ML_(search_one_symtab) ( struct _SegInfo* si, Addr ptr,
|
|
Bool match_anywhere_in_fun );
|
|
|
|
/* Find a location-table index containing the specified pointer, or -1
|
|
if not found. Binary search. */
|
|
extern Int ML_(search_one_loctab) ( struct _SegInfo* si, Addr ptr );
|
|
|
|
/* Find a CFI-table index containing the specified pointer, or -1 if
|
|
not found. Binary search. */
|
|
extern Int ML_(search_one_cfitab) ( struct _SegInfo* si, Addr ptr );
|
|
|
|
/* ------ Misc ------ */
|
|
|
|
/* Show a non-fatal debug info reading error. Use vg_panic if
|
|
terminal. */
|
|
extern void ML_(symerr) ( HChar* msg );
|
|
|
|
/* Print a symbol. */
|
|
extern void ML_(ppSym) ( Int idx, DiSym* sym );
|
|
|
|
/* Print a call-frame-info summary. */
|
|
extern void ML_(ppDiCfSI) ( XArray* /* of CfiExpr */ exprs, DiCfSI* si );
|
|
|
|
|
|
#define TRACE_SYMTAB(format, args...) \
|
|
if (si->trace_symtab) { VG_(printf)(format, ## args); }
|
|
|
|
|
|
#endif /* ndef __PRIV_STORAGE_H */
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/*--- end ---*/
|
|
/*--------------------------------------------------------------------*/
|