1/*
2  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
3  Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
4  Portions Copyright 2007-2010 David Anderson. 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 <limits.h>
44#include "pro_incl.h"
45#include "pro_expr.h"
46
47#ifndef R_MIPS_NONE
48#define R_MIPS_NONE 0
49#endif
50
51
52    /* Indicates no relocation needed. */
53#define NO_ELF_SYM_INDEX        0
54
55
56/* adds an attribute to a die */
57extern void _dwarf_pro_add_at_to_die(Dwarf_P_Die die,
58                                     Dwarf_P_Attribute attr);
59
60/*
61    This function adds an attribute whose value is
62    a target address to the given die.  The attribute
63    is given the name provided by attr.  The address
64    is given in pc_value.
65*/
66
67static Dwarf_P_Attribute
68local_add_AT_address(Dwarf_P_Debug dbg,
69                     Dwarf_P_Die ownerdie,
70                     Dwarf_Half attr,
71                     Dwarf_Signed form,
72                     Dwarf_Unsigned pc_value,
73                     Dwarf_Unsigned sym_index,
74                     Dwarf_Error * error);
75
76/* old interface */
77Dwarf_P_Attribute
78dwarf_add_AT_targ_address(Dwarf_P_Debug dbg,
79                          Dwarf_P_Die ownerdie,
80                          Dwarf_Half attr,
81                          Dwarf_Unsigned pc_value,
82                          Dwarf_Signed sym_index, Dwarf_Error * error)
83{
84    return
85        dwarf_add_AT_targ_address_b(dbg,
86                                    ownerdie,
87                                    attr,
88                                    pc_value,
89                                    (Dwarf_Unsigned) sym_index, error);
90}
91
92/* New interface, replacing dwarf_add_AT_targ_address.
93   Essentially just makes sym_index a Dwarf_Unsigned
94   so for symbolic relocations it can be a full address.
95*/
96Dwarf_P_Attribute
97dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg,
98                            Dwarf_P_Die ownerdie,
99                            Dwarf_Half attr,
100                            Dwarf_Unsigned pc_value,
101                            Dwarf_Unsigned sym_index,
102                            Dwarf_Error * error)
103{
104    switch (attr) {
105    case DW_AT_low_pc:
106    case DW_AT_high_pc:
107
108    /* added to support location lists */
109    /* no way to check that this is a loclist-style address though */
110    case DW_AT_location:
111    case DW_AT_string_length:
112    case DW_AT_return_addr:
113    case DW_AT_frame_base:
114    case DW_AT_segment:
115    case DW_AT_static_link:
116    case DW_AT_use_location:
117    case DW_AT_vtable_elem_location:
118    case DW_AT_const_value: /* Gcc can generate this as address. */
119    case DW_AT_entry_pc:
120        break;
121    default:
122        if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
123            _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
124            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
125        }
126        break;
127    }
128
129    return local_add_AT_address(dbg, ownerdie, attr, DW_FORM_addr,
130                                pc_value, sym_index, error);
131}
132
133Dwarf_P_Attribute
134dwarf_add_AT_ref_address(Dwarf_P_Debug dbg,
135                         Dwarf_P_Die ownerdie,
136                         Dwarf_Half attr,
137                         Dwarf_Unsigned pc_value,
138                         Dwarf_Unsigned sym_index,
139                         Dwarf_Error * error)
140{
141    switch (attr) {
142    case DW_AT_type:
143    case DW_AT_import:
144        break;
145
146    default:
147        if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
148            _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
149            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
150        }
151        break;
152    }
153
154    return local_add_AT_address(dbg, ownerdie, attr, DW_FORM_ref_addr,
155                                pc_value, sym_index, error);
156}
157
158
159/* Make sure attribute types are checked before entering here. */
160static Dwarf_P_Attribute
161local_add_AT_address(Dwarf_P_Debug dbg,
162                     Dwarf_P_Die ownerdie,
163                     Dwarf_Half attr,
164                     Dwarf_Signed form,
165                     Dwarf_Unsigned pc_value,
166                     Dwarf_Unsigned sym_index,
167                     Dwarf_Error * error)
168{
169    Dwarf_P_Attribute new_attr;
170    int upointer_size = dbg->de_pointer_size;
171
172    if (dbg == NULL) {
173        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
174        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
175    }
176
177    if (ownerdie == NULL) {
178        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
179        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
180    }
181
182    /* attribute types have already been checked */
183    /* switch (attr) { ... } */
184
185    new_attr = (Dwarf_P_Attribute)
186        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
187    if (new_attr == NULL) {
188        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
189        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
190    }
191
192    new_attr->ar_attribute = attr;
193    new_attr->ar_attribute_form = form;
194    new_attr->ar_nbytes = upointer_size;
195    new_attr->ar_rel_symidx = sym_index;
196    new_attr->ar_reloc_len = upointer_size;
197    new_attr->ar_next = 0;
198    if (sym_index != NO_ELF_SYM_INDEX)
199        new_attr->ar_rel_type = dbg->de_ptr_reloc;
200    else
201        new_attr->ar_rel_type = R_MIPS_NONE;
202
203    new_attr->ar_data = (char *)
204        _dwarf_p_get_alloc(dbg, upointer_size);
205    if (new_attr->ar_data == NULL) {
206        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
207        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
208    }
209    WRITE_UNALIGNED(dbg, new_attr->ar_data,
210                    (const void *) &pc_value,
211                    sizeof(pc_value), upointer_size);
212
213    /* add attribute to the die */
214    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
215    return new_attr;
216}
217
218/*
219 * Functions to compress and uncompress data from normal
220 * arrays of integral types into arrays of LEB128 numbers.
221 * Extend these functions as needed to handle wider input
222 * variety.  Return values should be freed with _dwarf_p_dealloc
223 * after they aren't needed any more.
224 */
225
226/* return value points to an array of LEB number */
227
228void *
229dwarf_compress_integer_block(
230    Dwarf_P_Debug    dbg,
231    Dwarf_Bool       unit_is_signed,
232    Dwarf_Small      unit_length_in_bits,
233    void*            input_block,
234    Dwarf_Unsigned   input_length_in_units,
235    Dwarf_Unsigned*  output_length_in_bytes_ptr,
236    Dwarf_Error*     error
237)
238{
239    Dwarf_Unsigned output_length_in_bytes = 0;
240    char * output_block = 0;
241    char encode_buffer[ENCODE_SPACE_NEEDED];
242    int i = 0;
243    char * ptr = 0;
244    int remain = 0;
245    int result = 0;
246
247    if (dbg == NULL) {
248        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
249        return((void *)DW_DLV_BADADDR);
250    }
251
252    if (unit_is_signed == false ||
253        unit_length_in_bits != 32 ||
254        input_block == NULL ||
255        input_length_in_units == 0 ||
256        output_length_in_bytes_ptr == NULL) {
257
258        _dwarf_p_error(NULL, error, DW_DLE_BADBITC);
259        return ((void *) DW_DLV_BADADDR);
260    }
261
262    /* At this point we assume the format is: signed 32 bit */
263
264    /* first compress everything to find the total size. */
265
266    output_length_in_bytes = 0;
267    for (i=0; i<input_length_in_units; i++) {
268        int unit_encoded_size;
269        Dwarf_sfixed unit; /* this is fixed at signed-32-bits */
270
271        unit = ((Dwarf_sfixed*)input_block)[i];
272
273        result = _dwarf_pro_encode_signed_leb128_nm(unit, &unit_encoded_size,
274                                             encode_buffer,sizeof(encode_buffer));
275        if (result !=  DW_DLV_OK) {
276            _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
277            return((Dwarf_P_Attribute)DW_DLV_BADADDR);
278        }
279        output_length_in_bytes += unit_encoded_size;
280    }
281
282
283    /* then alloc */
284
285    output_block = (void *)
286        _dwarf_p_get_alloc(dbg, output_length_in_bytes);
287    if (output_block == NULL) {
288        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
289        return((void*)DW_DLV_BADADDR);
290    }
291
292    /* then compress again and copy into new buffer */
293
294    ptr = output_block;
295    remain = output_length_in_bytes;
296    for (i=0; i<input_length_in_units; i++) {
297        int unit_encoded_size;
298        Dwarf_sfixed unit; /* this is fixed at signed-32-bits */
299
300        unit = ((Dwarf_sfixed*)input_block)[i];
301
302        result = _dwarf_pro_encode_signed_leb128_nm(unit, &unit_encoded_size,
303                                             ptr, remain);
304        if (result !=  DW_DLV_OK) {
305            _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
306            return((Dwarf_P_Attribute)DW_DLV_BADADDR);
307        }
308        remain -= unit_encoded_size;
309        ptr += unit_encoded_size;
310    }
311
312    if (remain != 0) {
313        _dwarf_p_dealloc(dbg, (unsigned char *)output_block);
314        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
315        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
316    }
317
318    *output_length_in_bytes_ptr = output_length_in_bytes;
319    return (void*) output_block;
320
321}
322
323void
324dwarf_dealloc_compressed_block(Dwarf_P_Debug dbg, void * space)
325{
326    _dwarf_p_dealloc(dbg, space);
327}
328
329/* This is very similar to targ_address but results in a different FORM */
330/* dbg->de_ar_data_attribute_form is data4 or data8
331   and dwarf4 changes the definition for such on DW_AT_high_pc.
332   DWARF 3: the FORM here has no defined meaning for dwarf3.
333   DWARF 4: the FORM here means that for DW_AT_high_pc the value
334            is not a high address but is instead an offset
335            from a (separate) DW_AT_low_pc.
336   The intent for DWARF4 is that this is not a relocated
337   address at all.  Instead a simple offset.
338   But this should NOT be called for a simple non-relocated offset.
339   So do not call this with an attr of DW_AT_high_pc.
340   Use dwarf_add_AT_unsigned_const() (for example) instead of
341   dwarf_add_AT_dataref when the value is a simple offset .
342*/
343Dwarf_P_Attribute
344dwarf_add_AT_dataref(
345    Dwarf_P_Debug dbg,
346    Dwarf_P_Die ownerdie,
347    Dwarf_Half attr,
348    Dwarf_Unsigned pc_value,
349    Dwarf_Unsigned sym_index,
350    Dwarf_Error * error)
351{
352    /* TODO: Add checking here */
353    return local_add_AT_address(dbg, ownerdie, attr,
354                                dbg->de_ar_data_attribute_form,
355                                pc_value,
356                                sym_index,
357                                error);
358}
359
360
361
362Dwarf_P_Attribute
363dwarf_add_AT_block(
364    Dwarf_P_Debug       dbg,
365    Dwarf_P_Die         ownerdie,
366    Dwarf_Half          attr,
367    Dwarf_Small         *block_data,
368    Dwarf_Unsigned      block_size,
369    Dwarf_Error         *error
370)
371{
372    Dwarf_P_Attribute   new_attr;
373    int result;
374    char encode_buffer[ENCODE_SPACE_NEEDED];
375    int len_size;
376    char * attrdata;
377
378    if (dbg == NULL) {
379        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
380        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
381    }
382
383    if (ownerdie == NULL) {
384        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
385        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
386    }
387
388    /* I don't mess with block1, block2, block4, not worth the effort */
389
390    /* So, encode the length into LEB128 */
391    result = _dwarf_pro_encode_leb128_nm(block_size, &len_size,
392                                         encode_buffer,sizeof(encode_buffer));
393    if (result !=  DW_DLV_OK) {
394        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
395        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
396    }
397
398    /* Allocate the new attribute */
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_error(dbg, error, DW_DLE_ALLOC_FAIL);
403        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
404    }
405
406    /* Fill in the attribute */
407    new_attr->ar_attribute = attr;
408    new_attr->ar_attribute_form = DW_FORM_block;
409    new_attr->ar_nbytes = len_size + block_size;
410    new_attr->ar_next = 0;
411
412    new_attr->ar_data = attrdata = (char *)
413        _dwarf_p_get_alloc(dbg, len_size + block_size);
414    if (new_attr->ar_data == NULL) {
415        /* free the block we got earlier */
416        _dwarf_p_dealloc(dbg, (unsigned char *) new_attr);
417        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
418        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
419    }
420
421    /* write length and data to attribute data buffer */
422    memcpy(attrdata, encode_buffer, len_size);
423    attrdata += len_size;
424    memcpy(attrdata, block_data, block_size);
425
426    /* add attribute to the die */
427    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
428
429    return new_attr;
430}
431
432
433/*
434    This function adds attributes whose value
435    is an unsigned constant.  It determines the
436    size of the value field from the value of
437    the constant.
438*/
439Dwarf_P_Attribute
440dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg,
441                            Dwarf_P_Die ownerdie,
442                            Dwarf_Half attr,
443                            Dwarf_Unsigned value, Dwarf_Error * error)
444{
445    Dwarf_P_Attribute new_attr;
446    Dwarf_Half attr_form;
447    Dwarf_Small size;
448
449    if (dbg == NULL) {
450        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
451        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
452    }
453
454    if (ownerdie == NULL) {
455        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
456        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
457    }
458
459    switch (attr) {
460    case DW_AT_ordering:
461    case DW_AT_byte_size:
462    case DW_AT_bit_offset:
463    case DW_AT_bit_size:
464    case DW_AT_inline:
465    case DW_AT_language:
466    case DW_AT_visibility:
467    case DW_AT_virtuality:
468    case DW_AT_accessibility:
469    case DW_AT_address_class:
470    case DW_AT_calling_convention:
471    case DW_AT_encoding:
472    case DW_AT_identifier_case:
473    case DW_AT_MIPS_loop_unroll_factor:
474    case DW_AT_MIPS_software_pipeline_depth:
475        break;
476
477    case DW_AT_decl_column:
478    case DW_AT_decl_file:
479    case DW_AT_decl_line:
480    case DW_AT_const_value:
481    case DW_AT_start_scope:
482    case DW_AT_stride_size:
483    case DW_AT_count:
484    case DW_AT_associated:
485    case DW_AT_allocated:
486    case DW_AT_upper_bound:
487    case DW_AT_lower_bound:
488    case DW_AT_call_file:
489    case DW_AT_call_line:
490        break;
491
492        default: {
493                 if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
494                     _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
495                     return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
496               }
497               break;
498            }
499        }
500
501    /*
502       Compute the number of bytes needed to hold constant. */
503    if (value <= UCHAR_MAX) {
504        attr_form = DW_FORM_data1;
505        size = 1;
506    } else if (value <= USHRT_MAX) {
507        attr_form = DW_FORM_data2;
508        size = 2;
509    } else if (value <= UINT_MAX) {
510        attr_form = DW_FORM_data4;
511        size = 4;
512    } else {
513        attr_form = DW_FORM_data8;
514        size = 8;
515    }
516
517    new_attr = (Dwarf_P_Attribute)
518        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
519    if (new_attr == NULL) {
520        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
521        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
522    }
523
524    new_attr->ar_attribute = attr;
525    new_attr->ar_attribute_form = attr_form;
526    new_attr->ar_rel_type = R_MIPS_NONE;
527    new_attr->ar_reloc_len = 0; /* irrelevant: unused with R_MIPS_NONE */
528    new_attr->ar_nbytes = size;
529    new_attr->ar_next = 0;
530
531    new_attr->ar_data = (char *)
532        _dwarf_p_get_alloc(dbg, size);
533    if (new_attr->ar_data == NULL) {
534        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
535        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
536    }
537    WRITE_UNALIGNED(dbg, new_attr->ar_data,
538                    (const void *) &value, sizeof(value), size);
539
540    /* add attribute to the die */
541    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
542    return new_attr;
543}
544
545
546/*
547    This function adds attributes whose value
548    is an signed constant.  It determines the
549    size of the value field from the value of
550    the constant.
551*/
552Dwarf_P_Attribute
553dwarf_add_AT_signed_const(Dwarf_P_Debug dbg,
554                          Dwarf_P_Die ownerdie,
555                          Dwarf_Half attr,
556                          Dwarf_Signed value, Dwarf_Error * error)
557{
558    Dwarf_P_Attribute new_attr;
559    Dwarf_Half attr_form;
560    Dwarf_Small size;
561
562    if (dbg == NULL) {
563        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
564        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
565    }
566
567    if (ownerdie == NULL) {
568        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
569        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
570    }
571
572    switch (attr) {
573    case DW_AT_lower_bound:
574    case DW_AT_upper_bound:
575    case DW_AT_const_value:
576    case DW_AT_bit_offset:
577    case DW_AT_bit_size:
578    case DW_AT_byte_size:
579    case DW_AT_count:
580    case DW_AT_byte_stride:
581    case DW_AT_bit_stride:
582    case DW_AT_allocated:
583    case DW_AT_associated:
584        break;
585
586    default:{
587                if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
588                     _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
589                     return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
590                }
591        }
592        break;
593    }
594
595    /*
596       Compute the number of bytes needed to hold constant. */
597    if (value >= SCHAR_MIN && value <= SCHAR_MAX) {
598        attr_form = DW_FORM_data1;
599        size = 1;
600    } else if (value >= SHRT_MIN && value <= SHRT_MAX) {
601        attr_form = DW_FORM_data2;
602        size = 2;
603    } else if (value >= INT_MIN && value <= INT_MAX) {
604        attr_form = DW_FORM_data4;
605        size = 4;
606    } else {
607        attr_form = DW_FORM_data8;
608        size = 8;
609    }
610
611    new_attr = (Dwarf_P_Attribute)
612        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
613    if (new_attr == NULL) {
614        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
615        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
616    }
617
618    new_attr->ar_attribute = attr;
619    new_attr->ar_attribute_form = attr_form;
620    new_attr->ar_rel_type = R_MIPS_NONE;
621    new_attr->ar_reloc_len = 0; /* irrelevant: unused with R_MIPS_NONE */
622    new_attr->ar_nbytes = size;
623    new_attr->ar_next = 0;
624
625    new_attr->ar_data = (char *)
626        _dwarf_p_get_alloc(dbg, size);
627    if (new_attr->ar_data == NULL) {
628        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
629        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
630    }
631    WRITE_UNALIGNED(dbg, new_attr->ar_data,
632                    (const void *) &value, sizeof(value), size);
633
634    /* add attribute to the die */
635    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
636    return new_attr;
637}
638
639
640/*
641    This function adds attributes whose value
642    is a location expression.
643*/
644Dwarf_P_Attribute
645dwarf_add_AT_location_expr(Dwarf_P_Debug dbg,
646                           Dwarf_P_Die ownerdie,
647                           Dwarf_Half attr,
648                           Dwarf_P_Expr loc_expr, Dwarf_Error * error)
649{
650    char encode_buffer[ENCODE_SPACE_NEEDED];
651    int res;
652    Dwarf_P_Attribute new_attr;
653    Dwarf_Half attr_form;
654    char *len_str = 0;
655    int len_size;
656    int block_size;
657    char *block_dest_ptr;
658    int do_len_as_int = 0;
659
660    if (dbg == NULL) {
661        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
662        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
663    }
664
665    if (ownerdie == NULL) {
666        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
667        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
668    }
669
670    if (loc_expr == NULL) {
671        _dwarf_p_error(dbg, error, DW_DLE_EXPR_NULL);
672        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
673    }
674
675    if (loc_expr->ex_dbg != dbg) {
676        _dwarf_p_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
677        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
678    }
679    block_size = loc_expr->ex_next_byte_offset;
680
681    switch (attr) {
682    case DW_AT_location:
683    case DW_AT_string_length:
684    case DW_AT_const_value:
685    case DW_AT_use_location:
686    case DW_AT_return_addr:
687    case DW_AT_data_member_location:
688    case DW_AT_frame_base:
689    case DW_AT_static_link:
690    case DW_AT_vtable_elem_location:
691    case DW_AT_lower_bound:
692    case DW_AT_upper_bound:
693    case DW_AT_count:
694    case DW_AT_associated:
695    case DW_AT_allocated:
696    case DW_AT_data_location:
697    case DW_AT_byte_stride:
698    case DW_AT_bit_stride:
699    case DW_AT_byte_size:
700    case DW_AT_bit_size:
701    break;
702
703    default:
704        if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
705            _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
706            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
707        }
708    break;
709    }
710
711    /*
712       Compute the number of bytes needed to hold constant. */
713    if (block_size <= UCHAR_MAX) {
714        attr_form = DW_FORM_block1;
715        len_size = 1;
716        do_len_as_int = 1;
717    } else if (block_size <= USHRT_MAX) {
718        attr_form = DW_FORM_block2;
719        len_size = 2;
720        do_len_as_int = 1;
721    } else if (block_size <= UINT_MAX) {
722        attr_form = DW_FORM_block4;
723        len_size = 4;
724        do_len_as_int = 1;
725    } else {
726        attr_form = DW_FORM_block;
727        res = _dwarf_pro_encode_leb128_nm(block_size, &len_size,
728                                          encode_buffer,
729                                          sizeof(encode_buffer));
730        if (res != DW_DLV_OK) {
731            _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
732            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
733        }
734        len_str = (char *) encode_buffer;
735    }
736
737    new_attr = (Dwarf_P_Attribute)
738        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
739    if (new_attr == NULL) {
740        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
741        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
742    }
743
744    new_attr->ar_attribute = attr;
745    new_attr->ar_attribute_form = attr_form;
746    new_attr->ar_reloc_len = dbg->de_pointer_size;
747    if (loc_expr->ex_reloc_sym_index != NO_ELF_SYM_INDEX) {
748        new_attr->ar_rel_type = dbg->de_ptr_reloc;
749    } else {
750        new_attr->ar_rel_type = R_MIPS_NONE;
751    }
752    new_attr->ar_rel_symidx = loc_expr->ex_reloc_sym_index;
753    new_attr->ar_rel_offset =
754        (Dwarf_Word) loc_expr->ex_reloc_offset + len_size;
755
756    new_attr->ar_nbytes = block_size + len_size;
757
758    new_attr->ar_next = 0;
759    new_attr->ar_data = block_dest_ptr =
760        (char *) _dwarf_p_get_alloc(dbg, block_size + len_size);
761    if (new_attr->ar_data == NULL) {
762        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
763        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
764    }
765
766    if (do_len_as_int) {
767        WRITE_UNALIGNED(dbg, block_dest_ptr, (const void *) &block_size,
768                        sizeof(block_size), len_size);
769    } else {
770        /* Is uleb number form, DW_FORM_block. See above. */
771        memcpy(block_dest_ptr, len_str, len_size);
772    }
773    block_dest_ptr += len_size;
774    memcpy(block_dest_ptr, &(loc_expr->ex_byte_stream[0]), block_size);
775
776    /* add attribute to the die */
777    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
778    return new_attr;
779}
780
781
782/*
783    This function adds attributes of reference class.
784    The references here are local CU references,
785    not DW_FORM_ref_addr.
786    The offset field is 4 bytes for 32-bit objects,
787    and 8-bytes for 64-bit objects.  Otherdie is the
788    that is referenced by ownerdie.
789
790    For reference attributes, the ar_data and ar_nbytes
791    are not needed.  Instead, the ar_ref_die points to
792    the other die, and its di_offset value is used as
793    the reference value.
794*/
795Dwarf_P_Attribute
796dwarf_add_AT_reference(Dwarf_P_Debug dbg,
797                       Dwarf_P_Die ownerdie,
798                       Dwarf_Half attr,
799                       Dwarf_P_Die otherdie, Dwarf_Error * error)
800{
801    Dwarf_P_Attribute new_attr;
802
803    if (dbg == NULL) {
804        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
805        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
806    }
807
808    if (ownerdie == NULL) {
809        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
810        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
811    }
812
813    if (otherdie == NULL) {
814        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
815        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
816    }
817
818    switch (attr) {
819    case DW_AT_specification:
820    case DW_AT_discr:
821    case DW_AT_common_reference:
822    case DW_AT_import:
823    case DW_AT_containing_type:
824    case DW_AT_default_value:
825    case DW_AT_abstract_origin:
826    case DW_AT_friend:
827    case DW_AT_priority:
828    case DW_AT_type:
829    case DW_AT_lower_bound:
830    case DW_AT_upper_bound:
831    case DW_AT_count:
832    case DW_AT_associated:
833    case DW_AT_allocated:
834    case DW_AT_bit_offset:
835    case DW_AT_bit_size:
836    case DW_AT_byte_size:
837    case DW_AT_sibling:
838    case DW_AT_bit_stride:
839    case DW_AT_byte_stride:
840    case DW_AT_namelist_item:
841        break;
842
843    default:
844        if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
845            _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
846            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
847        }
848        break;
849    }
850
851    new_attr = (Dwarf_P_Attribute)
852        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
853    if (new_attr == NULL) {
854        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
855        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
856    }
857
858    new_attr->ar_attribute = attr;
859    new_attr->ar_attribute_form = dbg->de_ar_ref_attr_form;
860    new_attr->ar_nbytes = dbg->de_offset_size;
861    new_attr->ar_reloc_len = dbg->de_offset_size;
862    new_attr->ar_ref_die = otherdie;
863    new_attr->ar_rel_type = R_MIPS_NONE;
864    new_attr->ar_next = 0;
865
866    /* add attribute to the die */
867    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
868    return new_attr;
869}
870
871
872/*
873    This function adds attributes of the flag class.
874*/
875Dwarf_P_Attribute
876dwarf_add_AT_flag(Dwarf_P_Debug dbg,
877                  Dwarf_P_Die ownerdie,
878                  Dwarf_Half attr,
879                  Dwarf_Small flag, Dwarf_Error * error)
880{
881    Dwarf_P_Attribute new_attr;
882
883    if (dbg == NULL) {
884        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
885        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
886    }
887
888    if (ownerdie == NULL) {
889        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
890        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
891    }
892
893#if 0
894    switch (attr) {
895    case DW_AT_is_optional:
896    case DW_AT_artificial:
897    case DW_AT_declaration:
898    case DW_AT_external:
899    case DW_AT_prototyped:
900    case DW_AT_variable_parameter:
901        break;
902
903        default:
904            if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
905            _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
906            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
907        }
908            break;
909    }
910#endif
911
912    new_attr = (Dwarf_P_Attribute)
913        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
914    if (new_attr == NULL) {
915        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
916        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
917    }
918
919    new_attr->ar_attribute = attr;
920    new_attr->ar_attribute_form = DW_FORM_flag;
921    new_attr->ar_nbytes = 1;
922    new_attr->ar_reloc_len = 0; /* not used */
923    new_attr->ar_rel_type = R_MIPS_NONE;
924    new_attr->ar_next = 0;
925
926    new_attr->ar_data = (char *)
927        _dwarf_p_get_alloc(dbg, 1);
928    if (new_attr->ar_data == NULL) {
929        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
930        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
931    }
932    memcpy(new_attr->ar_data, &flag, 1);
933
934    /* add attribute to the die */
935    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
936    return new_attr;
937}
938
939
940/*
941    This function adds values of attributes
942    belonging to the string class.
943*/
944Dwarf_P_Attribute
945dwarf_add_AT_string(Dwarf_P_Debug dbg,
946                    Dwarf_P_Die ownerdie,
947                    Dwarf_Half attr, char *string, Dwarf_Error * error)
948{
949    Dwarf_P_Attribute new_attr;
950
951    if (dbg == NULL) {
952        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
953        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
954    }
955
956    if (ownerdie == NULL) {
957        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
958        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
959    }
960
961    new_attr = (Dwarf_P_Attribute)
962        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
963    if (new_attr == NULL) {
964        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
965        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
966    }
967
968    switch (attr) {
969    case DW_AT_name:
970    case DW_AT_comp_dir:
971    case DW_AT_const_value:
972    case DW_AT_producer:
973        break;
974
975        default:
976            if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
977            _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
978            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
979        }
980            break;
981    }
982
983    new_attr->ar_attribute = attr;
984    new_attr->ar_attribute_form = DW_FORM_string;
985    new_attr->ar_nbytes = strlen(string) + 1;
986    new_attr->ar_next = 0;
987
988    new_attr->ar_data =
989        (char *) _dwarf_p_get_alloc(dbg, strlen(string)+1);
990    if (new_attr->ar_data == NULL) {
991        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
992        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
993    }
994
995    strcpy(new_attr->ar_data, string);
996    new_attr->ar_rel_type = R_MIPS_NONE;
997    new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
998
999    /* add attribute to the die */
1000    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1001    return new_attr;
1002}
1003
1004
1005Dwarf_P_Attribute
1006dwarf_add_AT_const_value_string(Dwarf_P_Die ownerdie,
1007                                char *string_value, Dwarf_Error * error)
1008{
1009    Dwarf_P_Attribute new_attr;
1010
1011    if (ownerdie == NULL) {
1012        _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
1013        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1014    }
1015
1016    new_attr = (Dwarf_P_Attribute)
1017        _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
1018    if (new_attr == NULL) {
1019        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1020        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1021    }
1022
1023    new_attr->ar_attribute = DW_AT_const_value;
1024    new_attr->ar_attribute_form = DW_FORM_string;
1025    new_attr->ar_nbytes = strlen(string_value) + 1;
1026    new_attr->ar_next = 0;
1027
1028    new_attr->ar_data =
1029        (char *) _dwarf_p_get_alloc(ownerdie->di_dbg, strlen(string_value)+1);
1030    if (new_attr->ar_data == NULL) {
1031        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1032        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1033    }
1034
1035    strcpy(new_attr->ar_data, string_value);
1036    new_attr->ar_rel_type = R_MIPS_NONE;
1037    new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
1038
1039    /* add attribute to the die */
1040    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1041    return new_attr;
1042}
1043
1044
1045Dwarf_P_Attribute
1046dwarf_add_AT_producer(Dwarf_P_Die ownerdie,
1047                      char *producer_string, Dwarf_Error * error)
1048{
1049    Dwarf_P_Attribute new_attr;
1050
1051    if (ownerdie == NULL) {
1052        _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
1053        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1054    }
1055
1056    new_attr = (Dwarf_P_Attribute)
1057        _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
1058    if (new_attr == NULL) {
1059        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1060        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1061    }
1062
1063    new_attr->ar_attribute = DW_AT_producer;
1064    new_attr->ar_attribute_form = DW_FORM_string;
1065    new_attr->ar_nbytes = strlen(producer_string) + 1;
1066    new_attr->ar_next = 0;
1067
1068    new_attr->ar_data =
1069        (char *) _dwarf_p_get_alloc(ownerdie->di_dbg, strlen(producer_string)+1);
1070    if (new_attr->ar_data == NULL) {
1071        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1072        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1073    }
1074
1075    strcpy(new_attr->ar_data, producer_string);
1076    new_attr->ar_rel_type = R_MIPS_NONE;
1077    new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
1078
1079    /* add attribute to the die */
1080    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1081    return new_attr;
1082}
1083
1084
1085Dwarf_P_Attribute
1086dwarf_add_AT_const_value_signedint(Dwarf_P_Die ownerdie,
1087                                   Dwarf_Signed signed_value,
1088                                   Dwarf_Error * error)
1089{
1090    Dwarf_P_Attribute new_attr;
1091    int leb_size;
1092    char encode_buffer[ENCODE_SPACE_NEEDED];
1093    int res;
1094
1095    if (ownerdie == NULL) {
1096        _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
1097        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1098    }
1099
1100    new_attr = (Dwarf_P_Attribute)
1101        _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
1102    if (new_attr == NULL) {
1103        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1104        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1105    }
1106
1107    new_attr->ar_attribute = DW_AT_const_value;
1108    new_attr->ar_attribute_form = DW_FORM_sdata;
1109    new_attr->ar_rel_type = R_MIPS_NONE;
1110    new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
1111    new_attr->ar_next = 0;
1112
1113    res = _dwarf_pro_encode_signed_leb128_nm(signed_value, &leb_size,
1114                                             encode_buffer,
1115                                             sizeof(encode_buffer));
1116    if (res != DW_DLV_OK) {
1117        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1118        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1119    }
1120    new_attr->ar_data = (char *)
1121        _dwarf_p_get_alloc(ownerdie->di_dbg, leb_size);
1122    if (new_attr->ar_data == NULL) {
1123        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1124        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1125    }
1126    memcpy(new_attr->ar_data, encode_buffer, leb_size);
1127    new_attr->ar_nbytes = leb_size;
1128
1129    /* add attribute to the die */
1130    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1131    return new_attr;
1132}
1133
1134
1135Dwarf_P_Attribute
1136dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die ownerdie,
1137                                     Dwarf_Unsigned unsigned_value,
1138                                     Dwarf_Error * error)
1139{
1140    Dwarf_P_Attribute new_attr;
1141    int leb_size;
1142    char encode_buffer[ENCODE_SPACE_NEEDED];
1143    int res;
1144
1145    if (ownerdie == NULL) {
1146        _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
1147        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1148    }
1149
1150    new_attr = (Dwarf_P_Attribute)
1151        _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
1152    if (new_attr == NULL) {
1153        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1154        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1155    }
1156
1157    new_attr->ar_attribute = DW_AT_const_value;
1158    new_attr->ar_attribute_form = DW_FORM_udata;
1159    new_attr->ar_rel_type = R_MIPS_NONE;
1160    new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
1161    new_attr->ar_next = 0;
1162
1163    res = _dwarf_pro_encode_leb128_nm(unsigned_value, &leb_size,
1164                                      encode_buffer,
1165                                      sizeof(encode_buffer));
1166    if (res != DW_DLV_OK) {
1167        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1168        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1169    }
1170    new_attr->ar_data = (char *)
1171        _dwarf_p_get_alloc(ownerdie->di_dbg, leb_size);
1172    if (new_attr->ar_data == NULL) {
1173        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1174        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1175    }
1176    memcpy(new_attr->ar_data, encode_buffer, leb_size);
1177    new_attr->ar_nbytes = leb_size;
1178
1179    /* add attribute to the die */
1180    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1181    return new_attr;
1182}
1183