1/*
2
3  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
4
5  This program is free software; you can redistribute it and/or modify it
6  under the terms of version 2.1 of the GNU Lesser General Public License
7  as published by the Free Software Foundation.
8
9  This program is distributed in the hope that it would be useful, but
10  WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13  Further, this software is distributed without any warranty that it is
14  free of the rightful claim of any third person regarding infringement
15  or the like.  Any license provided herein, whether implied or
16  otherwise, applies only to this software file.  Patent licenses, if
17  any, provided herein do not apply to combinations of this program with
18  other software, or any other product whatsoever.
19
20  You should have received a copy of the GNU Lesser General Public
21  License along with this program; if not, write the Free Software
22  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
23  USA.
24
25  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
26  Mountain View, CA 94043, or:
27
28  http://www.sgi.com
29
30  For further information regarding this notice, see:
31
32  http://oss.sgi.com/projects/GenInfo/NoticeExplan
33
34*/
35
36
37
38#include "config.h"
39#include "libdwarfdefs.h"
40#include <stdio.h>
41#include <string.h>
42#include <limits.h>
43#include "pro_incl.h"
44#include "pro_expr.h"
45
46#ifndef R_MIPS_NONE
47#define R_MIPS_NONE 0
48#endif
49
50
51    /* Indicates no relocation needed. */
52#define NO_ELF_SYM_INDEX	0
53
54
55/* adds an attribute to a die */
56extern void _dwarf_pro_add_at_to_die(Dwarf_P_Die die,
57				     Dwarf_P_Attribute attr);
58
59/*
60    This function adds an attribute whose value is
61    a target address to the given die.  The attribute
62    is given the name provided by attr.  The address
63    is given in pc_value.
64*/
65/* old interface */
66Dwarf_P_Attribute
67dwarf_add_AT_targ_address(Dwarf_P_Debug dbg,
68			  Dwarf_P_Die ownerdie,
69			  Dwarf_Half attr,
70			  Dwarf_Unsigned pc_value,
71			  Dwarf_Signed sym_index, Dwarf_Error * error)
72{
73    return
74	dwarf_add_AT_targ_address_b(dbg,
75				    ownerdie,
76				    attr,
77				    pc_value,
78				    (Dwarf_Unsigned) sym_index, error);
79}
80
81/* new interface */
82Dwarf_P_Attribute
83dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg,
84			    Dwarf_P_Die ownerdie,
85			    Dwarf_Half attr,
86			    Dwarf_Unsigned pc_value,
87			    Dwarf_Unsigned sym_index,
88			    Dwarf_Error * error)
89{
90    Dwarf_P_Attribute new_attr;
91    int upointer_size = dbg->de_pointer_size;
92
93    if (dbg == NULL) {
94	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
95	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
96    }
97
98    if (ownerdie == NULL) {
99	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
100	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
101    }
102
103    if (attr != DW_AT_low_pc && attr != DW_AT_high_pc &&
104	attr != DW_AT_MIPS_loop_begin &&
105	attr != DW_AT_MIPS_tail_loop_begin &&
106	attr != DW_AT_MIPS_epilog_begin) {
107	_dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
108	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
109    }
110
111    new_attr = (Dwarf_P_Attribute)
112	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
113    if (new_attr == NULL) {
114	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
115	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
116    }
117
118    new_attr->ar_attribute = attr;
119    new_attr->ar_attribute_form = DW_FORM_addr;
120    new_attr->ar_nbytes = upointer_size;
121    new_attr->ar_rel_symidx = sym_index;
122    new_attr->ar_reloc_len = upointer_size;
123    new_attr->ar_next = 0;
124    if (sym_index != NO_ELF_SYM_INDEX)
125	new_attr->ar_rel_type = dbg->de_ptr_reloc;
126    else
127	new_attr->ar_rel_type = R_MIPS_NONE;
128
129    new_attr->ar_data = (char *)
130	_dwarf_p_get_alloc(dbg, upointer_size);
131    if (new_attr->ar_data == NULL) {
132	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
133	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
134    }
135    WRITE_UNALIGNED(dbg, new_attr->ar_data,
136		    (const void *) &pc_value,
137		    sizeof(pc_value), upointer_size);
138
139    /* add attribute to the die */
140    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
141    return new_attr;
142}
143
144
145/*
146    This function adds attributes whose value
147    is an unsigned constant.  It determines the
148    size of the value field from the value of
149    the constant.
150*/
151Dwarf_P_Attribute
152dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg,
153			    Dwarf_P_Die ownerdie,
154			    Dwarf_Half attr,
155			    Dwarf_Unsigned value, Dwarf_Error * error)
156{
157    Dwarf_P_Attribute new_attr;
158    Dwarf_Half attr_form;
159    Dwarf_Small size;
160
161    if (dbg == NULL) {
162	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
163	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
164    }
165
166    if (ownerdie == NULL) {
167	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
168	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
169    }
170
171    switch (attr) {
172    case DW_AT_ordering:
173    case DW_AT_byte_size:
174    case DW_AT_bit_offset:
175    case DW_AT_bit_size:
176    case DW_AT_inline:
177    case DW_AT_language:
178    case DW_AT_visibility:
179    case DW_AT_virtuality:
180    case DW_AT_accessibility:
181    case DW_AT_address_class:
182    case DW_AT_calling_convention:
183    case DW_AT_encoding:
184    case DW_AT_identifier_case:
185    case DW_AT_MIPS_loop_unroll_factor:
186    case DW_AT_MIPS_software_pipeline_depth:
187	break;
188
189    case DW_AT_decl_column:
190    case DW_AT_decl_file:
191    case DW_AT_decl_line:
192    case DW_AT_const_value:
193    case DW_AT_start_scope:
194    case DW_AT_stride_size:
195    case DW_AT_count:
196	break;
197
198    default:{
199	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
200	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
201	}
202    }
203
204    /*
205       Compute the number of bytes needed to hold constant. */
206    if (value <= UCHAR_MAX) {
207	attr_form = DW_FORM_data1;
208	size = 1;
209    } else if (value <= USHRT_MAX) {
210	attr_form = DW_FORM_data2;
211	size = 2;
212    } else if (value <= UINT_MAX) {
213	attr_form = DW_FORM_data4;
214	size = 4;
215    } else {
216	attr_form = DW_FORM_data8;
217	size = 8;
218    }
219
220    new_attr = (Dwarf_P_Attribute)
221	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
222    if (new_attr == NULL) {
223	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
224	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
225    }
226
227    new_attr->ar_attribute = attr;
228    new_attr->ar_attribute_form = attr_form;
229    new_attr->ar_rel_type = R_MIPS_NONE;
230    new_attr->ar_reloc_len = 0;	/* irrelevant: unused with R_MIPS_NONE */
231    new_attr->ar_nbytes = size;
232    new_attr->ar_next = 0;
233
234    new_attr->ar_data = (char *)
235	_dwarf_p_get_alloc(dbg, size);
236    if (new_attr->ar_data == NULL) {
237	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
238	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
239    }
240    WRITE_UNALIGNED(dbg, new_attr->ar_data,
241		    (const void *) &value, sizeof(value), size);
242
243    /* add attribute to the die */
244    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
245    return new_attr;
246}
247
248
249/*
250    This function adds attributes whose value
251    is an signed constant.  It determines the
252    size of the value field from the value of
253    the constant.
254*/
255Dwarf_P_Attribute
256dwarf_add_AT_signed_const(Dwarf_P_Debug dbg,
257			  Dwarf_P_Die ownerdie,
258			  Dwarf_Half attr,
259			  Dwarf_Signed value, Dwarf_Error * error)
260{
261    Dwarf_P_Attribute new_attr;
262    Dwarf_Half attr_form;
263    Dwarf_Small size;
264
265    if (dbg == NULL) {
266	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
267	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
268    }
269
270    if (ownerdie == NULL) {
271	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
272	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
273    }
274
275    switch (attr) {
276    case DW_AT_upper_bound:
277    case DW_AT_lower_bound:
278	break;
279
280    default:{
281	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
282	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
283	}
284    }
285
286    /*
287       Compute the number of bytes needed to hold constant. */
288    if (value >= SCHAR_MIN && value <= SCHAR_MAX) {
289	attr_form = DW_FORM_data1;
290	size = 1;
291    } else if (value >= SHRT_MIN && value <= SHRT_MAX) {
292	attr_form = DW_FORM_data2;
293	size = 2;
294    } else if (value >= INT_MIN && value <= INT_MAX) {
295	attr_form = DW_FORM_data4;
296	size = 4;
297    } else {
298	attr_form = DW_FORM_data8;
299	size = 8;
300    }
301
302    new_attr = (Dwarf_P_Attribute)
303	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
304    if (new_attr == NULL) {
305	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
306	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
307    }
308
309    new_attr->ar_attribute = attr;
310    new_attr->ar_attribute_form = attr_form;
311    new_attr->ar_rel_type = R_MIPS_NONE;
312    new_attr->ar_reloc_len = 0;	/* irrelevant: unused with R_MIPS_NONE */
313    new_attr->ar_nbytes = size;
314    new_attr->ar_next = 0;
315
316    new_attr->ar_data = (char *)
317	_dwarf_p_get_alloc(dbg, size);
318    if (new_attr->ar_data == NULL) {
319	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
320	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
321    }
322    WRITE_UNALIGNED(dbg, new_attr->ar_data,
323		    (const void *) &value, sizeof(value), size);
324
325    /* add attribute to the die */
326    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
327    return new_attr;
328}
329
330
331/*
332    This function adds attributes whose value
333    is a location expression.
334*/
335Dwarf_P_Attribute
336dwarf_add_AT_location_expr(Dwarf_P_Debug dbg,
337			   Dwarf_P_Die ownerdie,
338			   Dwarf_Half attr,
339			   Dwarf_P_Expr loc_expr, Dwarf_Error * error)
340{
341    char encode_buffer[ENCODE_SPACE_NEEDED];
342    int res;
343    Dwarf_P_Attribute new_attr;
344    Dwarf_Half attr_form;
345    char *len_str;
346    int len_size;
347    int block_size;
348    char *block_dest_ptr;
349    int do_len_as_int = 0;
350
351    if (dbg == NULL) {
352	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
353	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
354    }
355
356    if (ownerdie == NULL) {
357	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
358	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
359    }
360
361    if (loc_expr == NULL) {
362	_dwarf_p_error(dbg, error, DW_DLE_EXPR_NULL);
363	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
364    }
365
366    if (loc_expr->ex_dbg != dbg) {
367	_dwarf_p_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
368	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
369    }
370    block_size = loc_expr->ex_next_byte_offset;
371
372    switch (attr) {
373    case DW_AT_location:
374    case DW_AT_string_length:
375    case DW_AT_const_value:
376    case DW_AT_use_location:
377    case DW_AT_return_addr:
378    case DW_AT_data_member_location:
379    case DW_AT_frame_base:
380    case DW_AT_static_link:
381    case DW_AT_vtable_elem_location:
382	break;
383
384    default:{
385	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
386	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
387	}
388    }
389
390    /*
391       Compute the number of bytes needed to hold constant. */
392    if (block_size <= UCHAR_MAX) {
393	attr_form = DW_FORM_block1;
394	len_size = 1;
395	do_len_as_int = 1;
396    } else if (block_size <= USHRT_MAX) {
397	attr_form = DW_FORM_block2;
398	len_size = 2;
399	do_len_as_int = 1;
400    } else if (block_size <= UINT_MAX) {
401	attr_form = DW_FORM_block4;
402	len_size = 4;
403	do_len_as_int = 1;
404    } else {
405	attr_form = DW_FORM_block;
406	res = _dwarf_pro_encode_leb128_nm(block_size, &len_size,
407					  encode_buffer,
408					  sizeof(encode_buffer));
409	if (res != DW_DLV_OK) {
410	    _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
411	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
412	}
413	len_str = (char *) encode_buffer;
414    }
415
416    new_attr = (Dwarf_P_Attribute)
417	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
418    if (new_attr == NULL) {
419	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
420	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
421    }
422
423    new_attr->ar_attribute = attr;
424    new_attr->ar_attribute_form = attr_form;
425    new_attr->ar_reloc_len = dbg->de_pointer_size;
426    if (loc_expr->ex_reloc_sym_index != NO_ELF_SYM_INDEX) {
427	new_attr->ar_rel_type = dbg->de_ptr_reloc;
428    } else {
429	new_attr->ar_rel_type = R_MIPS_NONE;
430    }
431    new_attr->ar_rel_symidx = loc_expr->ex_reloc_sym_index;
432    new_attr->ar_rel_offset =
433	(Dwarf_Word) loc_expr->ex_reloc_offset + len_size;
434
435    new_attr->ar_nbytes = block_size + len_size;
436
437    new_attr->ar_next = 0;
438    new_attr->ar_data = block_dest_ptr =
439	(char *) _dwarf_p_get_alloc(dbg, block_size + len_size);
440    if (new_attr->ar_data == NULL) {
441	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
442	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
443    }
444
445    if (do_len_as_int) {
446	WRITE_UNALIGNED(dbg, block_dest_ptr, (const void *) &block_size,
447			sizeof(block_size), len_size);
448    } else {
449	/* is uleb number form */
450	memcpy(block_dest_ptr, len_str, len_size);
451    }
452    block_dest_ptr += len_size;
453    memcpy(block_dest_ptr, &(loc_expr->ex_byte_stream[0]), block_size);
454
455    /* add attribute to the die */
456    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
457    return new_attr;
458}
459
460
461/*
462    This function adds attributes of reference class.
463    The references here are local CU references,
464    not DW_FORM_ref_addr.
465    The offset field is 4 bytes for 32-bit objects,
466    and 8-bytes for 64-bit objects.  Otherdie is the
467    that is referenced by ownerdie.
468
469    For reference attributes, the ar_data and ar_nbytes
470    are not needed.  Instead, the ar_ref_die points to
471    the other die, and its di_offset value is used as
472    the reference value.
473*/
474Dwarf_P_Attribute
475dwarf_add_AT_reference(Dwarf_P_Debug dbg,
476		       Dwarf_P_Die ownerdie,
477		       Dwarf_Half attr,
478		       Dwarf_P_Die otherdie, Dwarf_Error * error)
479{
480    Dwarf_P_Attribute new_attr;
481
482    if (dbg == NULL) {
483	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
484	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
485    }
486
487    if (ownerdie == NULL) {
488	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
489	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
490    }
491
492    if (otherdie == NULL) {
493	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
494	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
495    }
496
497    switch (attr) {
498    case DW_AT_specification:
499    case DW_AT_discr:
500    case DW_AT_common_reference:
501    case DW_AT_import:
502    case DW_AT_containing_type:
503    case DW_AT_default_value:
504    case DW_AT_abstract_origin:
505    case DW_AT_friend:
506    case DW_AT_priority:
507    case DW_AT_type:
508    case DW_AT_lower_bound:
509    case DW_AT_upper_bound:
510    case DW_AT_count:
511    case DW_AT_sibling:
512    case DW_AT_MIPS_stride:
513    case DW_AT_MIPS_stride_byte:
514    case DW_AT_MIPS_stride_elem:
515    case DW_AT_MIPS_clone_origin:
516    case DW_AT_MIPS_ptr_dopetype:
517    case DW_AT_MIPS_allocatable_dopetype:
518    case DW_AT_MIPS_assumed_shape_dopetype:
519	break;
520
521    default:{
522	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
523	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
524	}
525    }
526
527    new_attr = (Dwarf_P_Attribute)
528	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
529    if (new_attr == NULL) {
530	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
531	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
532    }
533
534    new_attr->ar_attribute = attr;
535    new_attr->ar_attribute_form = dbg->de_ar_ref_attr_form;
536    new_attr->ar_nbytes = dbg->de_offset_size;
537    new_attr->ar_reloc_len = dbg->de_offset_size;
538    new_attr->ar_ref_die = otherdie;
539    new_attr->ar_rel_type = R_MIPS_NONE;
540    new_attr->ar_next = 0;
541
542    /* add attribute to the die */
543    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
544    return new_attr;
545}
546
547
548/*
549    This function adds attributes of the flag class.
550*/
551Dwarf_P_Attribute
552dwarf_add_AT_flag(Dwarf_P_Debug dbg,
553		  Dwarf_P_Die ownerdie,
554		  Dwarf_Half attr,
555		  Dwarf_Small flag, Dwarf_Error * error)
556{
557    Dwarf_P_Attribute new_attr;
558
559    if (dbg == NULL) {
560	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
561	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
562    }
563
564    if (ownerdie == NULL) {
565	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
566	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
567    }
568
569    switch (attr) {
570    case DW_AT_is_optional:
571    case DW_AT_artificial:
572    case DW_AT_declaration:
573    case DW_AT_external:
574    case DW_AT_prototyped:
575    case DW_AT_variable_parameter:
576    case DW_AT_MIPS_has_inlines:
577    case DW_AT_MIPS_assumed_size:
578	break;
579
580    default:{
581	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
582	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
583	}
584    }
585
586    new_attr = (Dwarf_P_Attribute)
587	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
588    if (new_attr == NULL) {
589	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
590	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
591    }
592
593    new_attr->ar_attribute = attr;
594    new_attr->ar_attribute_form = DW_FORM_flag;
595    new_attr->ar_nbytes = 1;
596    new_attr->ar_reloc_len = 0;	/* not used */
597    new_attr->ar_rel_type = R_MIPS_NONE;
598    new_attr->ar_next = 0;
599
600    new_attr->ar_data = (char *)
601	_dwarf_p_get_alloc(dbg, 1);
602    if (new_attr->ar_data == NULL) {
603	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
604	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
605    }
606    memcpy(new_attr->ar_data, &flag, 1);
607
608    /* add attribute to the die */
609    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
610    return new_attr;
611}
612
613
614/*
615    This function adds values of attributes
616    belonging to the string class.
617*/
618Dwarf_P_Attribute
619dwarf_add_AT_string(Dwarf_P_Debug dbg,
620		    Dwarf_P_Die ownerdie,
621		    Dwarf_Half attr, char *string, Dwarf_Error * error)
622{
623    Dwarf_P_Attribute new_attr;
624
625    if (dbg == NULL) {
626	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
627	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
628    }
629
630    if (ownerdie == NULL) {
631	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
632	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
633    }
634
635    new_attr = (Dwarf_P_Attribute)
636	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
637    if (new_attr == NULL) {
638	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
639	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
640    }
641
642    switch (attr) {
643    case DW_AT_name:
644    case DW_AT_comp_dir:
645    case DW_AT_const_value:
646    case DW_AT_producer:
647    case DW_AT_MIPS_linkage_name:
648    case DW_AT_MIPS_abstract_name:
649	break;
650
651    default:{
652	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
653	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
654	}
655    }
656
657    new_attr->ar_attribute = attr;
658    new_attr->ar_attribute_form = DW_FORM_string;
659    new_attr->ar_nbytes = strlen(string) + 1;
660    new_attr->ar_next = 0;
661
662    new_attr->ar_data =
663	(char *) _dwarf_p_get_alloc(NULL, strlen(string) + 1);
664    if (new_attr->ar_data == NULL) {
665	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
666	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
667    }
668
669    strcpy(new_attr->ar_data, string);
670    new_attr->ar_rel_type = R_MIPS_NONE;
671    new_attr->ar_reloc_len = 0;	/* unused for R_MIPS_NONE */
672
673    /* add attribute to the die */
674    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
675    return new_attr;
676}
677
678
679Dwarf_P_Attribute
680dwarf_add_AT_const_value_string(Dwarf_P_Die ownerdie,
681				char *string_value, Dwarf_Error * error)
682{
683    Dwarf_P_Attribute new_attr;
684
685    if (ownerdie == NULL) {
686	_dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
687	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
688    }
689
690    new_attr = (Dwarf_P_Attribute)
691	_dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s));
692    if (new_attr == NULL) {
693	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
694	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
695    }
696
697    new_attr->ar_attribute = DW_AT_const_value;
698    new_attr->ar_attribute_form = DW_FORM_string;
699    new_attr->ar_nbytes = strlen(string_value) + 1;
700    new_attr->ar_next = 0;
701
702    new_attr->ar_data =
703	(char *) _dwarf_p_get_alloc(NULL, strlen(string_value) + 1);
704    if (new_attr->ar_data == NULL) {
705	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
706	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
707    }
708
709    strcpy(new_attr->ar_data, string_value);
710    new_attr->ar_rel_type = R_MIPS_NONE;
711    new_attr->ar_reloc_len = 0;	/* unused for R_MIPS_NONE */
712
713    /* add attribute to the die */
714    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
715    return new_attr;
716}
717
718
719Dwarf_P_Attribute
720dwarf_add_AT_producer(Dwarf_P_Die ownerdie,
721		      char *producer_string, Dwarf_Error * error)
722{
723    Dwarf_P_Attribute new_attr;
724
725    if (ownerdie == NULL) {
726	_dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
727	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
728    }
729
730    new_attr = (Dwarf_P_Attribute)
731	_dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s));
732    if (new_attr == NULL) {
733	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
734	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
735    }
736
737    new_attr->ar_attribute = DW_AT_producer;
738    new_attr->ar_attribute_form = DW_FORM_string;
739    new_attr->ar_nbytes = strlen(producer_string) + 1;
740    new_attr->ar_next = 0;
741
742    new_attr->ar_data =
743	(char *) _dwarf_p_get_alloc(NULL, strlen(producer_string) + 1);
744    if (new_attr->ar_data == NULL) {
745	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
746	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
747    }
748
749    strcpy(new_attr->ar_data, producer_string);
750    new_attr->ar_rel_type = R_MIPS_NONE;
751    new_attr->ar_reloc_len = 0;	/* unused for R_MIPS_NONE */
752
753    /* add attribute to the die */
754    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
755    return new_attr;
756}
757
758
759Dwarf_P_Attribute
760dwarf_add_AT_const_value_signedint(Dwarf_P_Die ownerdie,
761				   Dwarf_Signed signed_value,
762				   Dwarf_Error * error)
763{
764    Dwarf_P_Attribute new_attr;
765    int leb_size;
766    char encode_buffer[ENCODE_SPACE_NEEDED];
767    int res;
768
769    if (ownerdie == NULL) {
770	_dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
771	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
772    }
773
774    new_attr = (Dwarf_P_Attribute)
775	_dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s));
776    if (new_attr == NULL) {
777	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
778	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
779    }
780
781    new_attr->ar_attribute = DW_AT_const_value;
782    new_attr->ar_attribute_form = DW_FORM_sdata;
783    new_attr->ar_rel_type = R_MIPS_NONE;
784    new_attr->ar_reloc_len = 0;	/* unused for R_MIPS_NONE */
785    new_attr->ar_next = 0;
786
787    res = _dwarf_pro_encode_signed_leb128_nm(signed_value, &leb_size,
788					     encode_buffer,
789					     sizeof(encode_buffer));
790    if (res != DW_DLV_OK) {
791	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
792	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
793    }
794    new_attr->ar_data = (char *)
795	_dwarf_p_get_alloc(NULL, leb_size);
796    if (new_attr->ar_data == NULL) {
797	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
798	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
799    }
800    memcpy(new_attr->ar_data, encode_buffer, leb_size);
801    new_attr->ar_nbytes = leb_size;
802
803    /* add attribute to the die */
804    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
805    return new_attr;
806}
807
808
809Dwarf_P_Attribute
810dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die ownerdie,
811				     Dwarf_Unsigned unsigned_value,
812				     Dwarf_Error * error)
813{
814    Dwarf_P_Attribute new_attr;
815    int leb_size;
816    char encode_buffer[ENCODE_SPACE_NEEDED];
817    int res;
818
819    if (ownerdie == NULL) {
820	_dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
821	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
822    }
823
824    new_attr = (Dwarf_P_Attribute)
825	_dwarf_p_get_alloc(NULL, sizeof(struct Dwarf_P_Attribute_s));
826    if (new_attr == NULL) {
827	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
828	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
829    }
830
831    new_attr->ar_attribute = DW_AT_const_value;
832    new_attr->ar_attribute_form = DW_FORM_udata;
833    new_attr->ar_rel_type = R_MIPS_NONE;
834    new_attr->ar_reloc_len = 0;	/* unused for R_MIPS_NONE */
835    new_attr->ar_next = 0;
836
837    res = _dwarf_pro_encode_leb128_nm(unsigned_value, &leb_size,
838				      encode_buffer,
839				      sizeof(encode_buffer));
840    if (res != DW_DLV_OK) {
841	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
842	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
843    }
844    new_attr->ar_data = (char *)
845	_dwarf_p_get_alloc(NULL, leb_size);
846    if (new_attr->ar_data == NULL) {
847	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
848	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
849    }
850    memcpy(new_attr->ar_data, encode_buffer, leb_size);
851    new_attr->ar_nbytes = leb_size;
852
853    /* add attribute to the die */
854    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
855    return new_attr;
856}
857