3 Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
4 Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
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.
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.
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.
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,
26 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
27 Mountain View, CA 94043, or:
31 For further information regarding this notice, see:
33 http://oss.sgi.com/projects/GenInfo/NoticeExplan
40 #include "libdwarfdefs.h"
50 /* adds an attribute to a die */
51 void _dwarf_pro_add_at_to_die(Dwarf_P_Die die
, Dwarf_P_Attribute attr
);
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 -----------------------------------------------------------------------------*/
60 dwarf_new_die(Dwarf_P_Debug dbg
,
64 Dwarf_P_Die left
, Dwarf_P_Die right
, Dwarf_Error
* error
)
66 Dwarf_P_Die ret_die
= 0;
68 Dwarf_P_Die 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
);
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_last_child
= NULL
;
79 new_die
->di_tag
= tag
;
80 new_die
->di_dbg
= dbg
;
81 new_die
->di_marker
= 0;
83 dwarf_die_link(new_die
, parent
, child
, left
, right
, error
);
87 /*----------------------------------------------------------------------------
88 This function links up a die to specified neighbors
89 parent,child,left,right: specify neighbors of the new die. Only
90 one of these may be non-null
91 -----------------------------------------------------------------------------*/
93 dwarf_die_link(Dwarf_P_Die new_die
,
96 Dwarf_P_Die left
, Dwarf_P_Die right
, Dwarf_Error
* error
)
98 /* Count the # of non null neighbors. */
101 if (parent
!= NULL
) {
103 if (new_die
->di_parent
!= NULL
) {
104 DWARF_P_DBG_ERROR(NULL
, DW_DLE_LINK_LOOP
,
105 (Dwarf_P_Die
) DW_DLV_BADADDR
);
107 new_die
->di_parent
= parent
;
108 if (parent
->di_child
) {
110 /* di_last_child identifies the last sibling, the
111 die we want to attach new_die to. */
112 /* ASSERT: if di_child is set so is di_last_child. */
113 Dwarf_P_Die former_lastchild
= parent
->di_last_child
;
114 parent
->di_last_child
= new_die
;
115 /* Attach to the new die to end of the sibling list. */
116 former_lastchild
->di_right
= new_die
;
117 new_die
->di_left
= former_lastchild
;
119 parent
->di_child
= new_die
;
120 parent
->di_last_child
= new_die
;
125 new_die
->di_child
= child
;
126 new_die
->di_last_child
= child
;
127 if (child
->di_parent
) {
128 DWARF_P_DBG_ERROR(NULL
, DW_DLE_PARENT_EXISTS
,
129 (Dwarf_P_Die
) DW_DLV_BADADDR
);
131 child
->di_parent
= new_die
;
136 new_die
->di_left
= left
;
137 if (left
->di_right
) {
138 /* There's already a right sibling of left,
139 insert the new die in the list. */
140 new_die
->di_right
= left
->di_right
;
141 left
->di_right
->di_left
= new_die
;
143 left
->di_right
= new_die
;
144 if (new_die
->di_parent
) {
145 DWARF_P_DBG_ERROR(NULL
, DW_DLE_PARENT_EXISTS
,
146 (Dwarf_P_Die
) DW_DLV_BADADDR
);
148 new_die
->di_parent
= left
->di_parent
;
153 new_die
->di_right
= right
;
154 if (right
->di_left
) {
155 /* There is already a left sibling of the right die,
156 insert the new die in the list. */
157 new_die
->di_left
= right
->di_left
;
158 right
->di_left
->di_right
= new_die
;
160 right
->di_left
= new_die
;
161 if (new_die
->di_parent
) {
162 DWARF_P_DBG_ERROR(NULL
, DW_DLE_PARENT_EXISTS
,
163 (Dwarf_P_Die
) DW_DLV_BADADDR
);
165 new_die
->di_parent
= right
->di_parent
;
169 /* Multiple neighbors! error! */
170 DWARF_P_DBG_ERROR(NULL
, DW_DLE_EXTRA_NEIGHBORS
,
171 (Dwarf_P_Die
) DW_DLV_BADADDR
);
178 dwarf_add_die_marker(Dwarf_P_Debug dbg
,
180 Dwarf_Unsigned marker
,
184 DWARF_P_DBG_ERROR(dbg
, DW_DLE_DIE_NULL
, DW_DLV_NOCOUNT
);
186 die
->di_marker
= marker
;
192 dwarf_get_die_marker(Dwarf_P_Debug dbg
,
194 Dwarf_Unsigned
* marker
,
198 DWARF_P_DBG_ERROR(dbg
, DW_DLE_DIE_NULL
, DW_DLV_NOCOUNT
);
200 *marker
= die
->di_marker
;
205 /*----------------------------------------------------------------------------
206 This function adds a die to dbg struct. It should be called using
207 the root of all the dies.
208 -----------------------------------------------------------------------------*/
210 dwarf_add_die_to_debug(Dwarf_P_Debug dbg
,
211 Dwarf_P_Die first_die
, Dwarf_Error
* error
)
213 if (first_die
== NULL
) {
214 DWARF_P_DBG_ERROR(dbg
, DW_DLE_DIE_NULL
, DW_DLV_NOCOUNT
);
216 if (first_die
->di_tag
!= DW_TAG_compile_unit
) {
217 DWARF_P_DBG_ERROR(dbg
, DW_DLE_WRONG_TAG
, DW_DLV_NOCOUNT
);
219 dbg
->de_dies
= first_die
;
224 _dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg
,
225 Dwarf_P_Die first_die
, Dwarf_Error
* error
)
227 Dwarf_P_Attribute new_attr
;
228 int uwordb_size
= dbg
->de_offset_size
;
230 /* Add AT_stmt_list attribute */
231 new_attr
= (Dwarf_P_Attribute
)
232 _dwarf_p_get_alloc(dbg
, sizeof(struct Dwarf_P_Attribute_s
));
233 if (new_attr
== NULL
) {
234 DWARF_P_DBG_ERROR(NULL
, DW_DLE_ATTR_ALLOC
, DW_DLV_NOCOUNT
);
237 new_attr
->ar_attribute
= DW_AT_stmt_list
;
238 new_attr
->ar_attribute_form
= dbg
->de_ar_data_attribute_form
;
239 new_attr
->ar_rel_type
= dbg
->de_offset_reloc
;
241 new_attr
->ar_nbytes
= uwordb_size
;
242 new_attr
->ar_next
= NULL
;
243 new_attr
->ar_reloc_len
= uwordb_size
;
244 new_attr
->ar_data
= (char *)
245 _dwarf_p_get_alloc(dbg
, uwordb_size
);
246 if (new_attr
->ar_data
== NULL
) {
247 DWARF_P_DBG_ERROR(NULL
, DW_DLE_ADDR_ALLOC
, DW_DLV_NOCOUNT
);
250 Dwarf_Unsigned du
= 0;
252 WRITE_UNALIGNED(dbg
, (void *) new_attr
->ar_data
,
253 (const void *) &du
, sizeof(du
), uwordb_size
);
256 _dwarf_pro_add_at_to_die(first_die
, new_attr
);
260 /*-----------------------------------------------------------------------------
261 Add AT_name attribute to die
262 ------------------------------------------------------------------------------*/
264 dwarf_add_AT_name(Dwarf_P_Die die
, char *name
, Dwarf_Error
* error
)
266 Dwarf_P_Attribute new_attr
;
269 DWARF_P_DBG_ERROR(NULL
, DW_DLE_DIE_NULL
,
270 (Dwarf_P_Attribute
) DW_DLV_BADADDR
);
272 new_attr
= (Dwarf_P_Attribute
)
273 _dwarf_p_get_alloc(die
->di_dbg
,sizeof(struct Dwarf_P_Attribute_s
));
274 if (new_attr
== NULL
) {
275 DWARF_P_DBG_ERROR(NULL
, DW_DLE_ATTR_ALLOC
,
276 (Dwarf_P_Attribute
) DW_DLV_BADADDR
);
279 /* fill in the information */
280 new_attr
->ar_attribute
= DW_AT_name
;
281 /* assume that form is string, no debug_str yet */
282 new_attr
->ar_attribute_form
= DW_FORM_string
;
283 new_attr
->ar_nbytes
= strlen(name
) + 1;
284 new_attr
->ar_next
= NULL
;
285 new_attr
->ar_reloc_len
= 0;
286 new_attr
->ar_data
= (char *)
287 _dwarf_p_get_alloc(die
->di_dbg
, strlen(name
)+1);
288 if (new_attr
->ar_data
== NULL
) {
289 DWARF_P_DBG_ERROR(NULL
, DW_DLE_STRING_ALLOC
,
290 (Dwarf_P_Attribute
) DW_DLV_BADADDR
);
292 strcpy(new_attr
->ar_data
, name
);
294 new_attr
->ar_rel_type
= R_MIPS_NONE
;
296 /* add attribute to the die */
297 _dwarf_pro_add_at_to_die(die
, new_attr
);
302 /*-----------------------------------------------------------------------------
303 Add AT_comp_dir attribute to die
304 ------------------------------------------------------------------------------*/
306 dwarf_add_AT_comp_dir(Dwarf_P_Die ownerdie
,
307 char *current_working_directory
,
310 Dwarf_P_Attribute new_attr
;
312 if (ownerdie
== NULL
) {
313 DWARF_P_DBG_ERROR(NULL
, DW_DLE_DIE_NULL
,
314 (Dwarf_P_Attribute
) DW_DLV_BADADDR
);
316 new_attr
= (Dwarf_P_Attribute
)
317 _dwarf_p_get_alloc(ownerdie
->di_dbg
,
318 sizeof(struct Dwarf_P_Attribute_s
));
319 if (new_attr
== NULL
) {
320 DWARF_P_DBG_ERROR(NULL
, DW_DLE_ATTR_ALLOC
,
321 (Dwarf_P_Attribute
) DW_DLV_BADADDR
);
324 /* fill in the information */
325 new_attr
->ar_attribute
= DW_AT_comp_dir
;
326 /* assume that form is string, no debug_str yet */
327 new_attr
->ar_attribute_form
= DW_FORM_string
;
328 new_attr
->ar_nbytes
= strlen(current_working_directory
) + 1;
329 new_attr
->ar_next
= NULL
;
330 new_attr
->ar_reloc_len
= 0;
331 new_attr
->ar_data
= (char *)
332 _dwarf_p_get_alloc(ownerdie
->di_dbg
,
333 strlen(current_working_directory
)+1);
334 if (new_attr
->ar_data
== NULL
) {
335 DWARF_P_DBG_ERROR(NULL
, DW_DLE_STRING_ALLOC
,
336 (Dwarf_P_Attribute
) DW_DLV_BADADDR
);
338 strcpy(new_attr
->ar_data
, current_working_directory
);
340 new_attr
->ar_rel_type
= R_MIPS_NONE
;
342 /* add attribute to the die */
343 _dwarf_pro_add_at_to_die(ownerdie
, new_attr
);
348 _dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg
,
350 Dwarf_Unsigned offset
, Dwarf_Error
* error
)
352 Dwarf_P_Attribute new_attr
;
353 int uwordb_size
= dbg
->de_offset_size
;
356 DWARF_P_DBG_ERROR(NULL
, DW_DLE_DIE_NULL
, -1);
358 new_attr
= (Dwarf_P_Attribute
)
359 _dwarf_p_get_alloc(dbg
,sizeof(struct Dwarf_P_Attribute_s
));
360 if (new_attr
== NULL
) {
361 DWARF_P_DBG_ERROR(NULL
, DW_DLE_ATTR_ALLOC
, -1);
364 /* fill in the information */
365 new_attr
->ar_attribute
= DW_AT_MIPS_fde
;
366 new_attr
->ar_attribute_form
= dbg
->de_ar_data_attribute_form
;;
367 new_attr
->ar_rel_type
= dbg
->de_offset_reloc
;
368 new_attr
->ar_nbytes
= uwordb_size
;
369 new_attr
->ar_next
= NULL
;
370 new_attr
->ar_reloc_len
= uwordb_size
;
371 new_attr
->ar_data
= (char *)
372 _dwarf_p_get_alloc(dbg
, uwordb_size
);
373 if (new_attr
->ar_data
== NULL
) {
374 DWARF_P_DBG_ERROR(NULL
, DW_DLE_ADDR_ALLOC
, DW_DLV_NOCOUNT
);
377 Dwarf_Unsigned du
= offset
;
379 WRITE_UNALIGNED(dbg
, (void *) new_attr
->ar_data
,
380 (const void *) &du
, sizeof(du
), uwordb_size
);
383 _dwarf_pro_add_at_to_die(die
, new_attr
);
389 _dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg
,
391 Dwarf_Unsigned offset
, Dwarf_Error
* error
)
393 Dwarf_P_Attribute new_attr
;
394 int uwordb_size
= dbg
->de_offset_size
;
397 DWARF_P_DBG_ERROR(NULL
, DW_DLE_DIE_NULL
, -1);
399 new_attr
= (Dwarf_P_Attribute
)
400 _dwarf_p_get_alloc(dbg
,sizeof(struct Dwarf_P_Attribute_s
));
401 if (new_attr
== NULL
) {
402 DWARF_P_DBG_ERROR(NULL
, DW_DLE_ATTR_ALLOC
, -1);
405 /* fill in the information */
406 new_attr
->ar_attribute
= DW_AT_macro_info
;
407 new_attr
->ar_attribute_form
= dbg
->de_ar_data_attribute_form
;
408 new_attr
->ar_rel_type
= dbg
->de_offset_reloc
;
410 new_attr
->ar_nbytes
= uwordb_size
;
411 new_attr
->ar_next
= NULL
;
412 new_attr
->ar_reloc_len
= uwordb_size
;
413 new_attr
->ar_data
= (char *)
414 _dwarf_p_get_alloc(dbg
, uwordb_size
);
415 if (new_attr
->ar_data
== NULL
) {
416 DWARF_P_DBG_ERROR(NULL
, DW_DLE_ADDR_ALLOC
, DW_DLV_NOCOUNT
);
419 Dwarf_Unsigned du
= offset
;
421 WRITE_UNALIGNED(dbg
, (void *) new_attr
->ar_data
,
422 (const void *) &du
, sizeof(du
), uwordb_size
);
425 _dwarf_pro_add_at_to_die(die
, new_attr
);
432 _dwarf_pro_add_at_to_die(Dwarf_P_Die die
, Dwarf_P_Attribute attr
)
434 if (die
->di_last_attr
) {
435 die
->di_last_attr
->ar_next
= attr
;
436 die
->di_last_attr
= attr
;
440 die
->di_attrs
= die
->di_last_attr
= attr
;