tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_die.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2 
       
     3   Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
       
     4   Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved.
       
     5 
       
     6   This program is free software; you can redistribute it and/or modify it
       
     7   under the terms of version 2.1 of the GNU Lesser General Public License 
       
     8   as published by the Free Software Foundation.
       
     9 
       
    10   This program is distributed in the hope that it would be useful, but
       
    11   WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
       
    13 
       
    14   Further, this software is distributed without any warranty that it is
       
    15   free of the rightful claim of any third person regarding infringement 
       
    16   or the like.  Any license provided herein, whether implied or 
       
    17   otherwise, applies only to this software file.  Patent licenses, if
       
    18   any, provided herein do not apply to combinations of this program with 
       
    19   other software, or any other product whatsoever.  
       
    20 
       
    21   You should have received a copy of the GNU Lesser General Public 
       
    22   License along with this program; if not, write the Free Software 
       
    23   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
       
    24   USA.
       
    25 
       
    26   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
       
    27   Mountain View, CA 94043, or:
       
    28 
       
    29   http://www.sgi.com
       
    30 
       
    31   For further information regarding this notice, see:
       
    32 
       
    33   http://oss.sgi.com/projects/GenInfo/NoticeExplan
       
    34 
       
    35 */
       
    36 
       
    37 
       
    38 
       
    39 #include "config.h"
       
    40 #include "libdwarfdefs.h"
       
    41 #include <stdio.h>
       
    42 #include <string.h>
       
    43 #include "pro_incl.h"
       
    44 #include "pro_die.h"
       
    45 
       
    46 #ifndef R_MIPS_NONE
       
    47 #define R_MIPS_NONE 0
       
    48 #endif
       
    49 
       
    50 /* adds an attribute to a die */
       
    51 void _dwarf_pro_add_at_to_die(Dwarf_P_Die die, Dwarf_P_Attribute attr);
       
    52 
       
    53 /*----------------------------------------------------------------------------
       
    54 	This function creates a new die. 
       
    55 	tag: tag of the new die to be created
       
    56 	parent,child,left,right: specify neighbors of the new die. Only
       
    57 	    one of these may be non-null
       
    58 -----------------------------------------------------------------------------*/
       
    59 Dwarf_P_Die
       
    60 dwarf_new_die(Dwarf_P_Debug dbg,
       
    61 	      Dwarf_Tag tag,
       
    62 	      Dwarf_P_Die parent,
       
    63 	      Dwarf_P_Die child,
       
    64 	      Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error)
       
    65 {
       
    66     Dwarf_P_Die new_die, ret_die;
       
    67 
       
    68     new_die = (Dwarf_P_Die)
       
    69 	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Die_s));
       
    70     if (new_die == NULL) {
       
    71 	DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_ALLOC,
       
    72 			  (Dwarf_P_Die) DW_DLV_BADADDR);
       
    73     }
       
    74     new_die->di_parent = NULL;
       
    75     new_die->di_left = NULL;
       
    76     new_die->di_right = NULL;
       
    77     new_die->di_child = NULL;
       
    78     new_die->di_tag = tag;
       
    79     new_die->di_dbg = dbg;
       
    80     new_die->di_marker = 0;
       
    81     ret_die = 
       
    82         dwarf_die_link(new_die, parent, child, left, right, error);
       
    83     return ret_die;
       
    84 }
       
    85 
       
    86 /*----------------------------------------------------------------------------
       
    87 	This function links up a die to specified neighbors
       
    88 	parent,child,left,right: specify neighbors of the new die. Only
       
    89 	    one of these may be non-null
       
    90 -----------------------------------------------------------------------------*/
       
    91 Dwarf_P_Die
       
    92 dwarf_die_link(Dwarf_P_Die new_die,
       
    93 	       Dwarf_P_Die parent,
       
    94 	       Dwarf_P_Die child,
       
    95 	       Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error)
       
    96 {
       
    97     int n_nulls;		/* to count # of non null neighbors */
       
    98     Dwarf_P_Die orig;
       
    99 
       
   100     n_nulls = 0;
       
   101     if (parent != NULL) {
       
   102         n_nulls++;
       
   103         if (new_die->di_parent != NULL) {
       
   104               DWARF_P_DBG_ERROR(NULL, DW_DLE_LINK_LOOP,
       
   105                     (Dwarf_P_Die) DW_DLV_BADADDR);
       
   106         }
       
   107         new_die->di_parent = parent;
       
   108         if (parent->di_child) {	/* got to traverse the child's siblings 
       
   109 				 */
       
   110             Dwarf_P_Die curdie;
       
   111 
       
   112             curdie = parent->di_child;
       
   113             orig = curdie;
       
   114             while (curdie->di_right) {
       
   115                 curdie = curdie->di_right;
       
   116                 if (curdie == orig || curdie == curdie->di_right) {
       
   117                     DWARF_P_DBG_ERROR(NULL, DW_DLE_LINK_LOOP,
       
   118                        (Dwarf_P_Die) DW_DLV_BADADDR);
       
   119                 }
       
   120             }
       
   121             curdie->di_right = new_die;	/* attach to sibling list */
       
   122             new_die->di_left = curdie;	/* back pointer */
       
   123 	} else
       
   124 	    parent->di_child = new_die;
       
   125     }
       
   126     if (child != NULL) {
       
   127         n_nulls++;
       
   128         new_die->di_child = child;
       
   129         if (child->di_parent) {
       
   130 	    DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS,
       
   131 			      (Dwarf_P_Die) DW_DLV_BADADDR);
       
   132         } else {
       
   133 	    child->di_parent = new_die;
       
   134         }
       
   135     }
       
   136     if (left != NULL) {
       
   137 	n_nulls++;
       
   138 	new_die->di_left = left;
       
   139 	if (left->di_right)	/* there's already a right sibl, lets
       
   140 				   insert */
       
   141 	    new_die->di_right = left->di_right;
       
   142 	left->di_right = new_die;
       
   143 	/* add parent pointer */
       
   144 	if (new_die->di_parent) {
       
   145 	    DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS,
       
   146 			      (Dwarf_P_Die) DW_DLV_BADADDR);
       
   147 	} else
       
   148 	    new_die->di_parent = left->di_parent;
       
   149     }
       
   150     if (right != NULL) {
       
   151 	n_nulls++;
       
   152 	new_die->di_right = right;
       
   153 	if (right->di_left)	/* left sibl exists, try inserting */
       
   154 	    new_die->di_left = right->di_left;
       
   155 	right->di_left = new_die;
       
   156 	if (new_die->di_parent) {
       
   157 	    DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS,
       
   158 			      (Dwarf_P_Die) DW_DLV_BADADDR);
       
   159 	} else
       
   160 	    new_die->di_parent = right->di_parent;
       
   161     }
       
   162     if (n_nulls > 1) {		/* multiple neighbors, error */
       
   163 	DWARF_P_DBG_ERROR(NULL, DW_DLE_EXTRA_NEIGHBORS,
       
   164 			  (Dwarf_P_Die) DW_DLV_BADADDR);
       
   165     }
       
   166     return new_die;
       
   167 
       
   168 }
       
   169 
       
   170 Dwarf_Unsigned
       
   171 dwarf_add_die_marker(Dwarf_P_Debug dbg,
       
   172 		     Dwarf_P_Die die,
       
   173 		     Dwarf_Unsigned marker,
       
   174 		     Dwarf_Error * error)
       
   175 {
       
   176     if (die == NULL) {
       
   177 	DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT);
       
   178     }
       
   179     die->di_marker = marker;
       
   180     return 0;
       
   181 }
       
   182 
       
   183 		     
       
   184 Dwarf_Unsigned
       
   185 dwarf_get_die_marker(Dwarf_P_Debug dbg,
       
   186 		     Dwarf_P_Die die,
       
   187 		     Dwarf_Unsigned * marker,
       
   188 		     Dwarf_Error * error)
       
   189 {
       
   190     if (die == NULL) {
       
   191 	DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT);
       
   192     }
       
   193     *marker = die->di_marker;
       
   194     return 0;
       
   195 }
       
   196 
       
   197 		     
       
   198 		     
       
   199 
       
   200 /*----------------------------------------------------------------------------
       
   201 	This function adds a die to dbg struct. It should be called using 
       
   202 	the root of all the dies.
       
   203 -----------------------------------------------------------------------------*/
       
   204 Dwarf_Unsigned
       
   205 dwarf_add_die_to_debug(Dwarf_P_Debug dbg,
       
   206 		       Dwarf_P_Die first_die, Dwarf_Error * error)
       
   207 {
       
   208     if (first_die == NULL) {
       
   209 	DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT);
       
   210     }
       
   211     if (first_die->di_tag != DW_TAG_compile_unit) {
       
   212 	DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_TAG, DW_DLV_NOCOUNT);
       
   213     }
       
   214     dbg->de_dies = first_die;
       
   215     return 0;
       
   216 }
       
   217 
       
   218 int
       
   219 _dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg,
       
   220 			    Dwarf_P_Die first_die, Dwarf_Error * error)
       
   221 {
       
   222     Dwarf_P_Attribute new_attr;
       
   223     int uwordb_size = dbg->de_offset_size;
       
   224 
       
   225     /* Add AT_stmt_list attribute */
       
   226     new_attr = (Dwarf_P_Attribute)
       
   227 	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
       
   228     if (new_attr == NULL) {
       
   229 	DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_NOCOUNT);
       
   230     }
       
   231 
       
   232     new_attr->ar_attribute = DW_AT_stmt_list;
       
   233     new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form;
       
   234     new_attr->ar_rel_type = dbg->de_offset_reloc;
       
   235 
       
   236     new_attr->ar_nbytes = uwordb_size;
       
   237     new_attr->ar_next = NULL;
       
   238     new_attr->ar_reloc_len = uwordb_size;
       
   239     new_attr->ar_data = (char *)
       
   240 	_dwarf_p_get_alloc(dbg, uwordb_size);
       
   241     if (new_attr->ar_data == NULL) {
       
   242 	DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT);
       
   243     }
       
   244     {
       
   245 	Dwarf_Unsigned du = 0;
       
   246 
       
   247 	WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data,
       
   248 			(const void *) &du, sizeof(du), uwordb_size);
       
   249     }
       
   250 
       
   251     _dwarf_pro_add_at_to_die(first_die, new_attr);
       
   252     return 0;
       
   253 }
       
   254 
       
   255 /*-----------------------------------------------------------------------------
       
   256 	Add AT_name attribute to die
       
   257 ------------------------------------------------------------------------------*/
       
   258 Dwarf_P_Attribute
       
   259 dwarf_add_AT_name(Dwarf_P_Die die, char *name, Dwarf_Error * error)
       
   260 {
       
   261     Dwarf_P_Attribute new_attr;
       
   262 
       
   263     if (die == NULL) {
       
   264 	DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL,
       
   265 			  (Dwarf_P_Attribute) DW_DLV_BADADDR);
       
   266     }
       
   267     new_attr = (Dwarf_P_Attribute)
       
   268 	_dwarf_p_get_alloc(die->di_dbg,sizeof(struct Dwarf_P_Attribute_s));
       
   269     if (new_attr == NULL) {
       
   270 	DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC,
       
   271 			  (Dwarf_P_Attribute) DW_DLV_BADADDR);
       
   272     }
       
   273 
       
   274     /* fill in the information */
       
   275     new_attr->ar_attribute = DW_AT_name;
       
   276     /* assume that form is string, no debug_str yet */
       
   277     new_attr->ar_attribute_form = DW_FORM_string;
       
   278     new_attr->ar_nbytes = strlen(name) + 1;
       
   279     new_attr->ar_next = NULL;
       
   280     new_attr->ar_reloc_len = 0;
       
   281     new_attr->ar_data = (char *)
       
   282 	_dwarf_p_get_alloc(die->di_dbg, strlen(name)+1);
       
   283     if (new_attr->ar_data == NULL) {
       
   284 	DWARF_P_DBG_ERROR(NULL, DW_DLE_STRING_ALLOC,
       
   285 			  (Dwarf_P_Attribute) DW_DLV_BADADDR);
       
   286     }
       
   287     strcpy(new_attr->ar_data, name);
       
   288 
       
   289     new_attr->ar_rel_type = R_MIPS_NONE;
       
   290 
       
   291     /* add attribute to the die */
       
   292     _dwarf_pro_add_at_to_die(die, new_attr);
       
   293     return new_attr;
       
   294 }
       
   295 
       
   296 
       
   297 /*-----------------------------------------------------------------------------
       
   298 	Add AT_comp_dir attribute to die
       
   299 ------------------------------------------------------------------------------*/
       
   300 Dwarf_P_Attribute
       
   301 dwarf_add_AT_comp_dir(Dwarf_P_Die ownerdie,
       
   302 		      char *current_working_directory,
       
   303 		      Dwarf_Error * error)
       
   304 {
       
   305     Dwarf_P_Attribute new_attr;
       
   306 
       
   307     if (ownerdie == NULL) {
       
   308 	DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL,
       
   309 			  (Dwarf_P_Attribute) DW_DLV_BADADDR);
       
   310     }
       
   311     new_attr = (Dwarf_P_Attribute)
       
   312 	_dwarf_p_get_alloc(ownerdie->di_dbg,sizeof(struct Dwarf_P_Attribute_s));
       
   313     if (new_attr == NULL) {
       
   314 	DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC,
       
   315 			  (Dwarf_P_Attribute) DW_DLV_BADADDR);
       
   316     }
       
   317 
       
   318     /* fill in the information */
       
   319     new_attr->ar_attribute = DW_AT_comp_dir;
       
   320     /* assume that form is string, no debug_str yet */
       
   321     new_attr->ar_attribute_form = DW_FORM_string;
       
   322     new_attr->ar_nbytes = strlen(current_working_directory) + 1;
       
   323     new_attr->ar_next = NULL;
       
   324     new_attr->ar_reloc_len = 0;
       
   325     new_attr->ar_data = (char *)
       
   326 	_dwarf_p_get_alloc(ownerdie->di_dbg, strlen(current_working_directory)+1);
       
   327     if (new_attr->ar_data == NULL) {
       
   328 	DWARF_P_DBG_ERROR(NULL, DW_DLE_STRING_ALLOC,
       
   329 			  (Dwarf_P_Attribute) DW_DLV_BADADDR);
       
   330     }
       
   331     strcpy(new_attr->ar_data, current_working_directory);
       
   332 
       
   333     new_attr->ar_rel_type = R_MIPS_NONE;
       
   334 
       
   335     /* add attribute to the die */
       
   336     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
       
   337     return new_attr;
       
   338 }
       
   339 
       
   340 int
       
   341 _dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg,
       
   342 		      Dwarf_P_Die die,
       
   343 		      Dwarf_Unsigned offset, Dwarf_Error * error)
       
   344 {
       
   345     Dwarf_P_Attribute new_attr;
       
   346     int uwordb_size = dbg->de_offset_size;
       
   347 
       
   348     if (die == NULL) {
       
   349 	DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, -1);
       
   350     }
       
   351     new_attr = (Dwarf_P_Attribute)
       
   352 	_dwarf_p_get_alloc(dbg,sizeof(struct Dwarf_P_Attribute_s));
       
   353     if (new_attr == NULL) {
       
   354 	DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, -1);
       
   355     }
       
   356 
       
   357     /* fill in the information */
       
   358     new_attr->ar_attribute = DW_AT_MIPS_fde;
       
   359     new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form;;
       
   360     new_attr->ar_rel_type = dbg->de_offset_reloc;
       
   361     new_attr->ar_nbytes = uwordb_size;
       
   362     new_attr->ar_next = NULL;
       
   363     new_attr->ar_reloc_len = uwordb_size;
       
   364     new_attr->ar_data = (char *)
       
   365 	_dwarf_p_get_alloc(dbg, uwordb_size);
       
   366     if (new_attr->ar_data == NULL) {
       
   367 	DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT);
       
   368     }
       
   369     {
       
   370 	Dwarf_Unsigned du = offset;
       
   371 
       
   372 	WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data,
       
   373 			(const void *) &du, sizeof(du), uwordb_size);
       
   374     }
       
   375 
       
   376     _dwarf_pro_add_at_to_die(die, new_attr);
       
   377 
       
   378     return 0;
       
   379 }
       
   380 
       
   381 int
       
   382 _dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg,
       
   383 			     Dwarf_P_Die die,
       
   384 			     Dwarf_Unsigned offset, Dwarf_Error * error)
       
   385 {
       
   386     Dwarf_P_Attribute new_attr;
       
   387     int uwordb_size = dbg->de_offset_size;
       
   388 
       
   389     if (die == NULL) {
       
   390 	DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, -1);
       
   391     }
       
   392     new_attr = (Dwarf_P_Attribute)
       
   393         _dwarf_p_get_alloc(dbg,sizeof(struct Dwarf_P_Attribute_s));
       
   394     if (new_attr == NULL) {
       
   395 	DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, -1);
       
   396     }
       
   397 
       
   398     /* fill in the information */
       
   399     new_attr->ar_attribute = DW_AT_macro_info;
       
   400     new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form;
       
   401     new_attr->ar_rel_type = dbg->de_offset_reloc;
       
   402 
       
   403     new_attr->ar_nbytes = uwordb_size;
       
   404     new_attr->ar_next = NULL;
       
   405     new_attr->ar_reloc_len = uwordb_size;
       
   406     new_attr->ar_data = (char *)
       
   407         _dwarf_p_get_alloc(dbg, uwordb_size);
       
   408     if (new_attr->ar_data == NULL) {
       
   409 	DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT);
       
   410     }
       
   411     {
       
   412 	Dwarf_Unsigned du = offset;
       
   413 
       
   414 	WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data,
       
   415 			(const void *) &du, sizeof(du), uwordb_size);
       
   416     }
       
   417 
       
   418     _dwarf_pro_add_at_to_die(die, new_attr);
       
   419 
       
   420     return 0;
       
   421 }
       
   422 
       
   423 
       
   424 void
       
   425 _dwarf_pro_add_at_to_die(Dwarf_P_Die die, Dwarf_P_Attribute attr)
       
   426 {
       
   427     if (die->di_last_attr) {
       
   428 	die->di_last_attr->ar_next = attr;
       
   429 	die->di_last_attr = attr;
       
   430 	die->di_n_attr++;
       
   431     } else {
       
   432 	die->di_n_attr = 1;
       
   433 	die->di_attrs = die->di_last_attr = attr;
       
   434     }
       
   435 }