⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dwarfread.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 4 页
字号:
/* DWARF debugging format support for GDB.   Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.   Written by Fred Fish at Cygnus Support.  Portions based on dbxread.c,   mipsread.c, coffread.c, and dwarfread.c from a Data General SVR4 gdb port.This file is part of GDB.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  *//*  Important Note: This file is an adaptation of the original gdb dwarfread.c  file which supported dwarf version 1.  This file supports version 2 using  an SGI supplied libdwarf library.  Because of the interface change brought  on by using the library, and because of changes in the format, this file  is substantially changed from the original.  It was written by someone with  little knowledge of dwarf or gdb, so it is highly non-optimal and somewhat  convoluted due to its history.  In addition, all comments should be taken  with a large grain of salt as they may be left over from the original and  no longer apply.  One open question is whether it would be better to make use of the types  and globals sections to collect certain key information.  Note: need to check for places where dwarf_dealloc should be called but  isn't (for all child and sibling dies in particular).  Note: we use sym->global is a flag for typecasts since they don't follow  the normal conventions for our types, since they are constructed on the  fly and don't have a proper dwarf entry to anchor them.  */#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#ifdef sgi#include <dem.h>#endif#include <unistd.h>#include <stdlib.h>#include <string.h>#include <sys/file.h>#include "file_formats.h"#include "symbols.h"#include "simutil.h"#include "symfile.h"#include "assoctab.h"#include "tcl_init.h"#include "sim_error.h"    /* we're not depending on elf library, so provide some dummy defn */typedef void * Elf;#include "dwarf2.h"#include "libdwarf2.h"#define DIE_NAME(dip)	(((dip)->at_name != NULL) ? (dip)->at_name : "")#define IS_CAST(sym)	(sym->global != 0)int info_verbose;   typedef Dwarf_Off DIE_REF;	/* Reference to a DIE */typedef char BLOCK;struct dieinfo {  Dwarf_Die             ddie;           /* pointer to dwarf library die data */  Dwarf_Die             sibdie;         /* pointer to dwarf library die data */  Dwarf_Die             childdie;       /* pointer to dwarf library die data */  DIE_REF		die_ref;	/* Offset of this DIE in debug sect */  Dwarf_Half	        die_tag;	/* Tag for this DIE */  char *		at_name;  Dwarf_Off		at_type;};typedef struct Execfile {    ATHeader     head;    AssocTab    *srcs;    AssocTab    *globals;    AssocTab    *gStructs;    Dwarf_Debug  dwarf;} Execfile;typedef struct Srcfile {    ATHeader     head;    AssocTab    *globals;    VA           lopc;    VA           hipc;    DIE_REF      dieref;} Srcfile;typedef struct Global {    ATHeader   head;    DIE_REF    dieref;    Dwarf_Half dietag;} Global;static void scan_partial_symbols(Dwarf_Die, Execfile *exec, Srcfile *src );static void scan_compilation_units(Execfile *exec);static void basicdieinfo ( struct dieinfo *dip, Dwarf_Die ddie,			   DIE_REF dieref, Execfile *exec );static void freedieinfo( struct dieinfo *di, Execfile *exec );static void completedieinfo(struct dieinfo *, Execfile *exec, int verbose);static void decode_line_numbers(Dwarf_Die, VA *, VA *, Execfile *exec);static VA locval (Dwarf_Locdesc *);static VAlookup_line ( Srcfile *src, Execfile *exec, Dwarf_Unsigned targetline ){    struct dieinfo  di;    int             err;    Dwarf_Line     *linebuf;    Dwarf_Unsigned  lineno;    Dwarf_Unsigned  bestlineno;    Dwarf_Addr      lineaddr;    Dwarf_Addr      bestlineaddr;    Dwarf_Signed    cnt;    Dwarf_Error     rc;    int             i;    bestlineno = ~0;    bestlineaddr = 0;        basicdieinfo (&di, NULL, src->dieref, exec);    err = dwarf_srclines( di.ddie, &linebuf, &cnt, &rc );    freedieinfo(&di,exec);    if( err == DW_DLV_ERROR ) {	CPUWarning("dwarf_srclines failed: %s\n", dwarf_errmsg( rc ) );	ASSERT(0);    } else if( err == DW_DLV_OK ) {	for( i = 0; i < cnt; i++ ) {	    if( dwarf_lineno( linebuf[i], &lineno, &rc ) != DW_DLV_OK) {		CPUWarning("dwarf_lineno failed: %s\n", dwarf_errmsg( rc ) );		exit(-1);	    }	    if( dwarf_lineaddr( linebuf[i], &lineaddr, &rc) != DW_DLV_OK) {		CPUWarning("dwarf_lineaddr failed: %s\n", dwarf_errmsg( rc ) );		exit(-1);	    }	    if( (lineno <= bestlineno) && (lineno >= targetline) ) {		/* It doesn't seem like there is an easy way to deal with		 * line numbers of other files included in this file, such		 * as inlined source in .h's and that sort of thing.  The		 * best thing may be just to ignore line number info for		 * file other than our own		 */		char *name;		if( dwarf_linesrc( linebuf[i], &name, &rc) != DW_DLV_OK) {		    CPUWarning("dwarf_linesrc failed: %s\n", dwarf_errmsg(rc));		    exit(-1);		}		if( strcmp( src->head.label, StripPath(name) ) == 0 ) {		    bestlineno = lineno;		    bestlineaddr = lineaddr;		}		dwarf_dealloc( exec->dwarf, name, DW_DLA_STRING );	    }	    dwarf_dealloc( exec->dwarf, linebuf[i], DW_DLA_LINE );	}	dwarf_dealloc( exec->dwarf, linebuf, DW_DLA_LIST );    }    return bestlineaddr;}static voiddecode_line_numbers ( Dwarf_Die ddie, VA *lopc, VA *hipc, Execfile *exec ){    int             err;    Dwarf_Line     *linebuf;    Dwarf_Unsigned  lineno;    Dwarf_Addr      lineaddr;    Dwarf_Signed    cnt;    Dwarf_Error     rc;    int             i;    VA       lo, hi;    hi = 0;    lo = ~hi;    err = dwarf_srclines( ddie, &linebuf, &cnt, &rc );    if( err == DW_DLV_ERROR ) {	CPUWarning("dwarf_srclines failed: %s\n", dwarf_errmsg( rc ) );    } else if( err == DW_DLV_OK ) {	for( i = 0; i < cnt; i++ ) {	    if( dwarf_lineno( linebuf[i], &lineno, &rc ) != DW_DLV_OK) {		CPUWarning("dwarf_lineno failed: %s\n", dwarf_errmsg( rc ) );		exit(-1);	    }	    if( dwarf_lineaddr( linebuf[i], &lineaddr, &rc) != DW_DLV_OK) {		CPUWarning("dwarf_lineaddr failed: %s\n", dwarf_errmsg( rc ) );		exit(-1);	    }	    /* double purpose function: either record line numbers, or find low	     * and high pc values.  We can't do both because we need pc values	     * before it appears safe to record line numbers.	     */	    if( lopc == NULL ) {		/* we don't use this feature yet */		ASSERT(0);#if 0		/* It doesn't seem like there is an easy way to deal with		 * line numbers of other files included in this file, such		 * as inlined source in .h's and that sort of thing.  The		 * best thing may be just to ignore line number info for		 * file other than our own		 */		char *name;		if( dwarf_linesrc( linebuf[i], &name, &rc) != DW_DLV_OK) {		    CPUWarning("dwarf_linesrc failed: %s\n", dwarf_errmsg(rc));		    exit(-1);		}		if( !strcmp( current_subfile->name, name ) ) {		    record_line (current_subfile, lineno, lineaddr);		}		dwarf_dealloc( dwarf, name, DW_DLA_STRING );#endif	    } else {		if( lineaddr < lo )		    lo = lineaddr;		if( lineaddr > hi )		    hi = lineaddr;	    }	    dwarf_dealloc( exec->dwarf, linebuf[i], DW_DLA_LINE );	}  	dwarf_dealloc( exec->dwarf, linebuf, DW_DLA_LIST );    }    if( lopc != NULL )	*lopc = lo;    if( hipc != NULL )	*hipc = hi;}static VAlocval ( Dwarf_Locdesc *loc ){    VA  stack[64];    int        stacki;    int        loc_atom_code;    int        i;    Dwarf_Loc *locs;    int        numlocs;    stacki = 0;    stack[stacki] = 0;/*    isreg = 0; *//*    offreg = 0; */    locs = loc->ld_s;    numlocs = loc->ld_cents;    for( i = 0; i < numlocs; i++ ) {	loc_atom_code = locs[i].lr_atom;	switch (loc_atom_code) {	case DW_OP_addr:	    /* push address (relocated address) */	    stack[++stacki] = locs[i].lr_number;	    break;	case DW_OP_consts:	    stack[++stacki] = locs[i].lr_number;	    break;	case DW_OP_fbreg:#if 1#if 0	    offreg = 1;	    basereg = 29; /* FIXME: MIPS stack pointer hard coded */#endif#endif	    stack[++stacki] = locs[i].lr_number;	    break;	default:	    CPUWarning("Unimplemented location atom: %x\n", loc_atom_code);	    break;	}    }    return (stack[stacki]);}static DIE_REFGetTypeAbsOffset( Dwarf_Die ddie, Execfile *exec ){    Dwarf_Attribute  attr;    Dwarf_Off        type, abs, rel;    Dwarf_Error      rc;    if (dwarf_attr(ddie,DW_AT_type,&attr,&rc) != DW_DLV_OK) {	return 0;    }    if( dwarf_formref( attr, &type, &rc ) != DW_DLV_OK) {	CPUWarning("dwarf_formref failed: %s\n", dwarf_errmsg( rc ) );	ASSERT(0);    }    dwarf_dealloc( exec->dwarf, attr, DW_DLA_ATTR);    if( dwarf_dieoffset( ddie, &abs, &rc ) != DW_DLV_OK) {	CPUWarning("dwarf_dieoffset failed: %s\n", dwarf_errmsg( rc ) );	ASSERT(0);    }    if( dwarf_die_CU_offset( ddie, &rel, &rc ) != DW_DLV_OK) {	CPUWarning("dwarf_die_CU_offset failed: %s\n", dwarf_errmsg( rc ) );	ASSERT(0);    }    /* convert from cu-relative to absolute offset */    return (abs - rel) + type;}static VAGetLocation( Dwarf_Die ddie, Execfile *exec ){    Dwarf_Error      rc;    int              err;    Dwarf_Locdesc   *loclist;    Dwarf_Signed     signedtmp;    Dwarf_Attribute  attr;    VA               location;    if (dwarf_attr(ddie,DW_AT_location,&attr,&rc) != DW_DLV_OK) {	/* try member location */	if (dwarf_attr(ddie,DW_AT_data_member_location,&attr,&rc)!=DW_DLV_OK) {	    CPUWarning("no location list: %s\n", dwarf_errmsg( rc ) );	    ASSERT(0);	}    }    dwarf_loclist( attr, &loclist, &signedtmp, &rc );    if( signedtmp != 1 ) {	CPUWarning("location list size %lld != 1\n", signedtmp );	ASSERT(0);    }    location = locval(loclist);    dwarf_dealloc( exec->dwarf, loclist, DW_DLA_LOCDESC);    dwarf_dealloc( exec->dwarf, attr, DW_DLA_ATTR);    return location;}static intadd_global(struct dieinfo *di, AssocTab *tab){    Global *global;    global = (Global*)malloc(sizeof(Global));    global->head.label = SaveString(di->at_name);    global->dieref     = di->die_ref;    global->dietag     = di->die_tag;    return AssocTabEnter(tab, (ATHeader*)global);}/* release resources associated with die; not all are currently handled */static voidfreedieinfo( struct dieinfo *di, Execfile *exec ){    if( di->ddie ) dwarf_dealloc( exec->dwarf, di->ddie, DW_DLA_DIE );    if( di->sibdie ) dwarf_dealloc( exec->dwarf, di->sibdie, DW_DLA_DIE );    if( di->childdie ) dwarf_dealloc( exec->dwarf, di->childdie, DW_DLA_DIE );    if( di->at_name ) dwarf_dealloc( exec->dwarf, di->at_name, DW_DLA_STRING );}static voidFillInBasicType( Symb *sym, Dwarf_Die ddie, Dwarf_Unsigned *bitsize,		 Execfile *exec ){    Dwarf_Attribute  attr;    Dwarf_Unsigned   encoding, bytesize;    Dwarf_Off        type;    Dwarf_Error      rc;    struct dieinfo   di;    type = GetTypeAbsOffset( ddie, exec );    if( type == 0 ) {	/* no type, so do nothing */	return;    }    basicdieinfo (&di, NULL, type, exec);    ddie = di.ddie;    switch (di.die_tag) {    case DW_TAG_base_type:	/* for this we need the size and encoding to translate it to a	 * form that simos expects	 */	if( dwarf_bytesize( ddie, &bytesize, &rc ) != DW_DLV_OK) {	    CPUWarning("dwarf_bytesize failed: %s\n", dwarf_errmsg( rc ) );	    ASSERT(0);	}	*bitsize = 8*bytesize;	if (dwarf_attr(ddie,DW_AT_encoding,&attr,&rc) != DW_DLV_OK) {	    CPUWarning("dwarf_attr for type failed: %s\n", dwarf_errmsg(rc));	    ASSERT(0);	}	if( dwarf_formudata( attr, &encoding, &rc ) != DW_DLV_OK) {	    CPUWarning("dwarf_formref failed: %s\n", dwarf_errmsg( rc ) );	    ASSERT(0);	}	dwarf_dealloc( exec->dwarf, attr, DW_DLA_ATTR);	switch( encoding ) {	case DW_ATE_float:	    switch( bytesize ) {	    case 4:		sym->type[sym->nextt++] = tFloat;		break;	    case 8:		sym->type[sym->nextt++] = tDouble;		break;	    default:		ASSERT(0);		break;	    }	    break;	case DW_ATE_signed:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -