149d3bc9Richard Lowe/*
207dc194Richard Lowe  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
307dc194Richard Lowe  Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
407dc194Richard Lowe  Portions Copyright 2007-2010 David Anderson. All rights reserved.
549d3bc9Richard Lowe
649d3bc9Richard Lowe  This program is free software; you can redistribute it and/or modify it
749d3bc9Richard Lowe  under the terms of version 2.1 of the GNU Lesser General Public License
849d3bc9Richard Lowe  as published by the Free Software Foundation.
949d3bc9Richard Lowe
1049d3bc9Richard Lowe  This program is distributed in the hope that it would be useful, but
1149d3bc9Richard Lowe  WITHOUT ANY WARRANTY; without even the implied warranty of
1249d3bc9Richard Lowe  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1349d3bc9Richard Lowe
1449d3bc9Richard Lowe  Further, this software is distributed without any warranty that it is
1549d3bc9Richard Lowe  free of the rightful claim of any third person regarding infringement
1649d3bc9Richard Lowe  or the like.  Any license provided herein, whether implied or
1749d3bc9Richard Lowe  otherwise, applies only to this software file.  Patent licenses, if
1849d3bc9Richard Lowe  any, provided herein do not apply to combinations of this program with
1949d3bc9Richard Lowe  other software, or any other product whatsoever.
2049d3bc9Richard Lowe
2149d3bc9Richard Lowe  You should have received a copy of the GNU Lesser General Public
2249d3bc9Richard Lowe  License along with this program; if not, write the Free Software
2307dc194Richard Lowe  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2449d3bc9Richard Lowe  USA.
2549d3bc9Richard Lowe
2607dc194Richard Lowe  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
2749d3bc9Richard Lowe  Mountain View, CA 94043, or:
2849d3bc9Richard Lowe
2949d3bc9Richard Lowe  http://www.sgi.com
3049d3bc9Richard Lowe
3149d3bc9Richard Lowe  For further information regarding this notice, see:
3249d3bc9Richard Lowe
3349d3bc9Richard Lowe  http://oss.sgi.com/projects/GenInfo/NoticeExplan
3449d3bc9Richard Lowe
3549d3bc9Richard Lowe*/
3649d3bc9Richard Lowe
3749d3bc9Richard Lowe
3849d3bc9Richard Lowe
3949d3bc9Richard Lowe#include "config.h"
4049d3bc9Richard Lowe#include "libdwarfdefs.h"
4149d3bc9Richard Lowe#include <stdio.h>
4249d3bc9Richard Lowe#include <string.h>
4349d3bc9Richard Lowe#include <limits.h>
4449d3bc9Richard Lowe#include "pro_incl.h"
4549d3bc9Richard Lowe#include "pro_expr.h"
4649d3bc9Richard Lowe
4749d3bc9Richard Lowe#ifndef R_MIPS_NONE
4849d3bc9Richard Lowe#define R_MIPS_NONE 0
4949d3bc9Richard Lowe#endif
5049d3bc9Richard Lowe
5149d3bc9Richard Lowe
5249d3bc9Richard Lowe    /* Indicates no relocation needed. */
5307dc194Richard Lowe#define NO_ELF_SYM_INDEX        0
5449d3bc9Richard Lowe
5549d3bc9Richard Lowe
5649d3bc9Richard Lowe/* adds an attribute to a die */
5749d3bc9Richard Loweextern void _dwarf_pro_add_at_to_die(Dwarf_P_Die die,
5807dc194Richard Lowe                                     Dwarf_P_Attribute attr);
5949d3bc9Richard Lowe
6049d3bc9Richard Lowe/*
6149d3bc9Richard Lowe    This function adds an attribute whose value is
6249d3bc9Richard Lowe    a target address to the given die.  The attribute
6349d3bc9Richard Lowe    is given the name provided by attr.  The address
6449d3bc9Richard Lowe    is given in pc_value.
6549d3bc9Richard Lowe*/
6607dc194Richard Lowe
6707dc194Richard Lowestatic Dwarf_P_Attribute
6807dc194Richard Lowelocal_add_AT_address(Dwarf_P_Debug dbg,
6907dc194Richard Lowe                     Dwarf_P_Die ownerdie,
7007dc194Richard Lowe                     Dwarf_Half attr,
7107dc194Richard Lowe                     Dwarf_Signed form,
7207dc194Richard Lowe                     Dwarf_Unsigned pc_value,
7307dc194Richard Lowe                     Dwarf_Unsigned sym_index,
7407dc194Richard Lowe                     Dwarf_Error * error);
7507dc194Richard Lowe
7649d3bc9Richard Lowe/* old interface */
7749d3bc9Richard LoweDwarf_P_Attribute
7849d3bc9Richard Lowedwarf_add_AT_targ_address(Dwarf_P_Debug dbg,
7907dc194Richard Lowe                          Dwarf_P_Die ownerdie,
8007dc194Richard Lowe                          Dwarf_Half attr,
8107dc194Richard Lowe                          Dwarf_Unsigned pc_value,
8207dc194Richard Lowe                          Dwarf_Signed sym_index, Dwarf_Error * error)
8349d3bc9Richard Lowe{
8407dc194Richard Lowe    return
8507dc194Richard Lowe        dwarf_add_AT_targ_address_b(dbg,
8607dc194Richard Lowe                                    ownerdie,
8707dc194Richard Lowe                                    attr,
8807dc194Richard Lowe                                    pc_value,
8907dc194Richard Lowe                                    (Dwarf_Unsigned) sym_index, error);
9049d3bc9Richard Lowe}
9149d3bc9Richard Lowe
9207dc194Richard Lowe/* New interface, replacing dwarf_add_AT_targ_address.
9307dc194Richard Lowe   Essentially just makes sym_index a Dwarf_Unsigned
9407dc194Richard Lowe   so for symbolic relocations it can be a full address.
9507dc194Richard Lowe*/
9649d3bc9Richard LoweDwarf_P_Attribute
9749d3bc9Richard Lowedwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg,
9807dc194Richard Lowe                            Dwarf_P_Die ownerdie,
9907dc194Richard Lowe                            Dwarf_Half attr,
10007dc194Richard Lowe                            Dwarf_Unsigned pc_value,
10107dc194Richard Lowe                            Dwarf_Unsigned sym_index,
10207dc194Richard Lowe                            Dwarf_Error * error)
10307dc194Richard Lowe{
10407dc194Richard Lowe    switch (attr) {
10507dc194Richard Lowe    case DW_AT_low_pc:
10607dc194Richard Lowe    case DW_AT_high_pc:
10707dc194Richard Lowe
10807dc194Richard Lowe    /* added to support location lists */
10907dc194Richard Lowe    /* no way to check that this is a loclist-style address though */
11007dc194Richard Lowe    case DW_AT_location:
11107dc194Richard Lowe    case DW_AT_string_length:
11207dc194Richard Lowe    case DW_AT_return_addr:
11307dc194Richard Lowe    case DW_AT_frame_base:
11407dc194Richard Lowe    case DW_AT_segment:
11507dc194Richard Lowe    case DW_AT_static_link:
11607dc194Richard Lowe    case DW_AT_use_location:
11707dc194Richard Lowe    case DW_AT_vtable_elem_location:
11807dc194Richard Lowe    case DW_AT_const_value: /* Gcc can generate this as address. */
11907dc194Richard Lowe    case DW_AT_entry_pc:
12007dc194Richard Lowe        break;
12107dc194Richard Lowe    default:
12207dc194Richard Lowe        if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
12307dc194Richard Lowe            _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
12407dc194Richard Lowe            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
12507dc194Richard Lowe        }
12607dc194Richard Lowe        break;
12707dc194Richard Lowe    }
12807dc194Richard Lowe
12907dc194Richard Lowe    return local_add_AT_address(dbg, ownerdie, attr, DW_FORM_addr,
13007dc194Richard Lowe                                pc_value, sym_index, error);
13107dc194Richard Lowe}
13207dc194Richard Lowe
13307dc194Richard LoweDwarf_P_Attribute
13407dc194Richard Lowedwarf_add_AT_ref_address(Dwarf_P_Debug dbg,
13507dc194Richard Lowe                         Dwarf_P_Die ownerdie,
13607dc194Richard Lowe                         Dwarf_Half attr,
13707dc194Richard Lowe                         Dwarf_Unsigned pc_value,
13807dc194Richard Lowe                         Dwarf_Unsigned sym_index,
13907dc194Richard Lowe                         Dwarf_Error * error)
14007dc194Richard Lowe{
14107dc194Richard Lowe    switch (attr) {
14207dc194Richard Lowe    case DW_AT_type:
14307dc194Richard Lowe    case DW_AT_import:
14407dc194Richard Lowe        break;
14507dc194Richard Lowe
14607dc194Richard Lowe    default:
14707dc194Richard Lowe        if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
14807dc194Richard Lowe            _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
14907dc194Richard Lowe            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
15007dc194Richard Lowe        }
15107dc194Richard Lowe        break;
15207dc194Richard Lowe    }
15307dc194Richard Lowe
15407dc194Richard Lowe    return local_add_AT_address(dbg, ownerdie, attr, DW_FORM_ref_addr,
15507dc194Richard Lowe                                pc_value, sym_index, error);
15607dc194Richard Lowe}
15707dc194Richard Lowe
15807dc194Richard Lowe
15907dc194Richard Lowe/* Make sure attribute types are checked before entering here. */
16007dc194Richard Lowestatic Dwarf_P_Attribute
16107dc194Richard Lowelocal_add_AT_address(Dwarf_P_Debug dbg,
16207dc194Richard Lowe                     Dwarf_P_Die ownerdie,
16307dc194Richard Lowe                     Dwarf_Half attr,
16407dc194Richard Lowe                     Dwarf_Signed form,
16507dc194Richard Lowe                     Dwarf_Unsigned pc_value,
16607dc194Richard Lowe                     Dwarf_Unsigned sym_index,
16707dc194Richard Lowe                     Dwarf_Error * error)
16849d3bc9Richard Lowe{
16949d3bc9Richard Lowe    Dwarf_P_Attribute new_attr;
17049d3bc9Richard Lowe    int upointer_size = dbg->de_pointer_size;
17149d3bc9Richard Lowe
17249d3bc9Richard Lowe    if (dbg == NULL) {
17307dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
17407dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
17549d3bc9Richard Lowe    }
17649d3bc9Richard Lowe
17749d3bc9Richard Lowe    if (ownerdie == NULL) {
17807dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
17907dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
18049d3bc9Richard Lowe    }
18149d3bc9Richard Lowe
18207dc194Richard Lowe    /* attribute types have already been checked */
18307dc194Richard Lowe    /* switch (attr) { ... } */
18449d3bc9Richard Lowe
18549d3bc9Richard Lowe    new_attr = (Dwarf_P_Attribute)
18607dc194Richard Lowe        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
18749d3bc9Richard Lowe    if (new_attr == NULL) {
18807dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
18907dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
19049d3bc9Richard Lowe    }
19149d3bc9Richard Lowe
19249d3bc9Richard Lowe    new_attr->ar_attribute = attr;
19307dc194Richard Lowe    new_attr->ar_attribute_form = form;
19449d3bc9Richard Lowe    new_attr->ar_nbytes = upointer_size;
19549d3bc9Richard Lowe    new_attr->ar_rel_symidx = sym_index;
19649d3bc9Richard Lowe    new_attr->ar_reloc_len = upointer_size;
19749d3bc9Richard Lowe    new_attr->ar_next = 0;
19849d3bc9Richard Lowe    if (sym_index != NO_ELF_SYM_INDEX)
19907dc194Richard Lowe        new_attr->ar_rel_type = dbg->de_ptr_reloc;
20049d3bc9Richard Lowe    else
20107dc194Richard Lowe        new_attr->ar_rel_type = R_MIPS_NONE;
20249d3bc9Richard Lowe
20349d3bc9Richard Lowe    new_attr->ar_data = (char *)
20407dc194Richard Lowe        _dwarf_p_get_alloc(dbg, upointer_size);
20549d3bc9Richard Lowe    if (new_attr->ar_data == NULL) {
20607dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
20707dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
20849d3bc9Richard Lowe    }
20949d3bc9Richard Lowe    WRITE_UNALIGNED(dbg, new_attr->ar_data,
21007dc194Richard Lowe                    (const void *) &pc_value,
21107dc194Richard Lowe                    sizeof(pc_value), upointer_size);
21207dc194Richard Lowe
21307dc194Richard Lowe    /* add attribute to the die */
21407dc194Richard Lowe    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
21507dc194Richard Lowe    return new_attr;
21607dc194Richard Lowe}
21707dc194Richard Lowe
21807dc194Richard Lowe/*
21907dc194Richard Lowe * Functions to compress and uncompress data from normal
22007dc194Richard Lowe * arrays of integral types into arrays of LEB128 numbers.
22107dc194Richard Lowe * Extend these functions as needed to handle wider input
22207dc194Richard Lowe * variety.  Return values should be freed with _dwarf_p_dealloc
22307dc194Richard Lowe * after they aren't needed any more.
22407dc194Richard Lowe */
22507dc194Richard Lowe
22607dc194Richard Lowe/* return value points to an array of LEB number */
22707dc194Richard Lowe
22807dc194Richard Lowevoid *
22907dc194Richard Lowedwarf_compress_integer_block(
23007dc194Richard Lowe    Dwarf_P_Debug    dbg,
23107dc194Richard Lowe    Dwarf_Bool       unit_is_signed,
23207dc194Richard Lowe    Dwarf_Small      unit_length_in_bits,
23307dc194Richard Lowe    void*            input_block,
23407dc194Richard Lowe    Dwarf_Unsigned   input_length_in_units,
23507dc194Richard Lowe    Dwarf_Unsigned*  output_length_in_bytes_ptr,
23607dc194Richard Lowe    Dwarf_Error*     error
23707dc194Richard Lowe)
23807dc194Richard Lowe{
23907dc194Richard Lowe    Dwarf_Unsigned output_length_in_bytes = 0;
24007dc194Richard Lowe    char * output_block = 0;
24107dc194Richard Lowe    char encode_buffer[ENCODE_SPACE_NEEDED];
24207dc194Richard Lowe    int i = 0;
24307dc194Richard Lowe    char * ptr = 0;
24407dc194Richard Lowe    int remain = 0;
24507dc194Richard Lowe    int result = 0;
24607dc194Richard Lowe
24707dc194Richard Lowe    if (dbg == NULL) {
24807dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
24907dc194Richard Lowe        return((void *)DW_DLV_BADADDR);
25007dc194Richard Lowe    }
25107dc194Richard Lowe
25207dc194Richard Lowe    if (unit_is_signed == false ||
25307dc194Richard Lowe        unit_length_in_bits != 32 ||
25407dc194Richard Lowe        input_block == NULL ||
25507dc194Richard Lowe        input_length_in_units == 0 ||
25607dc194Richard Lowe        output_length_in_bytes_ptr == NULL) {
25707dc194Richard Lowe
25807dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_BADBITC);
25907dc194Richard Lowe        return ((void *) DW_DLV_BADADDR);
26007dc194Richard Lowe    }
26107dc194Richard Lowe
26207dc194Richard Lowe    /* At this point we assume the format is: signed 32 bit */
26307dc194Richard Lowe
26407dc194Richard Lowe    /* first compress everything to find the total size. */
26507dc194Richard Lowe
26607dc194Richard Lowe    output_length_in_bytes = 0;
26707dc194Richard Lowe    for (i=0; i<input_length_in_units; i++) {
26807dc194Richard Lowe        int unit_encoded_size;
26907dc194Richard Lowe        Dwarf_sfixed unit; /* this is fixed at signed-32-bits */
27007dc194Richard Lowe
27107dc194Richard Lowe        unit = ((Dwarf_sfixed*)input_block)[i];
27207dc194Richard Lowe
27307dc194Richard Lowe        result = _dwarf_pro_encode_signed_leb128_nm(unit, &unit_encoded_size,
27407dc194Richard Lowe                                             encode_buffer,sizeof(encode_buffer));
27507dc194Richard Lowe        if (result !=  DW_DLV_OK) {
27607dc194Richard Lowe            _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
27707dc194Richard Lowe            return((Dwarf_P_Attribute)DW_DLV_BADADDR);
27807dc194Richard Lowe        }
27907dc194Richard Lowe        output_length_in_bytes += unit_encoded_size;
28007dc194Richard Lowe    }
28107dc194Richard Lowe
28207dc194Richard Lowe
28307dc194Richard Lowe    /* then alloc */
28407dc194Richard Lowe
28507dc194Richard Lowe    output_block = (void *)
28607dc194Richard Lowe        _dwarf_p_get_alloc(dbg, output_length_in_bytes);
28707dc194Richard Lowe    if (output_block == NULL) {
28807dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
28907dc194Richard Lowe        return((void*)DW_DLV_BADADDR);
29007dc194Richard Lowe    }
29107dc194Richard Lowe
29207dc194Richard Lowe    /* then compress again and copy into new buffer */
29307dc194Richard Lowe
29407dc194Richard Lowe    ptr = output_block;
29507dc194Richard Lowe    remain = output_length_in_bytes;
29607dc194Richard Lowe    for (i=0; i<input_length_in_units; i++) {
29707dc194Richard Lowe        int unit_encoded_size;
29807dc194Richard Lowe        Dwarf_sfixed unit; /* this is fixed at signed-32-bits */
29907dc194Richard Lowe
30007dc194Richard Lowe        unit = ((Dwarf_sfixed*)input_block)[i];
30107dc194Richard Lowe
30207dc194Richard Lowe        result = _dwarf_pro_encode_signed_leb128_nm(unit, &unit_encoded_size,
30307dc194Richard Lowe                                             ptr, remain);
30407dc194Richard Lowe        if (result !=  DW_DLV_OK) {
30507dc194Richard Lowe            _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
30607dc194Richard Lowe            return((Dwarf_P_Attribute)DW_DLV_BADADDR);
30707dc194Richard Lowe        }
30807dc194Richard Lowe        remain -= unit_encoded_size;
30907dc194Richard Lowe        ptr += unit_encoded_size;
31007dc194Richard Lowe    }
31107dc194Richard Lowe
31207dc194Richard Lowe    if (remain != 0) {
31307dc194Richard Lowe        _dwarf_p_dealloc(dbg, (unsigned char *)output_block);
31407dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
31507dc194Richard Lowe        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
31607dc194Richard Lowe    }
31707dc194Richard Lowe
31807dc194Richard Lowe    *output_length_in_bytes_ptr = output_length_in_bytes;
31907dc194Richard Lowe    return (void*) output_block;
32007dc194Richard Lowe
32107dc194Richard Lowe}
32207dc194Richard Lowe
32307dc194Richard Lowevoid
32407dc194Richard Lowedwarf_dealloc_compressed_block(Dwarf_P_Debug dbg, void * space)
32507dc194Richard Lowe{
32607dc194Richard Lowe    _dwarf_p_dealloc(dbg, space);
32707dc194Richard Lowe}
32807dc194Richard Lowe
32907dc194Richard Lowe/* This is very similar to targ_address but results in a different FORM */
33007dc194Richard Lowe/* dbg->de_ar_data_attribute_form is data4 or data8
33107dc194Richard Lowe   and dwarf4 changes the definition for such on DW_AT_high_pc.
33207dc194Richard Lowe   DWARF 3: the FORM here has no defined meaning for dwarf3.
33307dc194Richard Lowe   DWARF 4: the FORM here means that for DW_AT_high_pc the value
33407dc194Richard Lowe            is not a high address but is instead an offset
33507dc194Richard Lowe            from a (separate) DW_AT_low_pc.
33607dc194Richard Lowe   The intent for DWARF4 is that this is not a relocated
33707dc194Richard Lowe   address at all.  Instead a simple offset.
33807dc194Richard Lowe   But this should NOT be called for a simple non-relocated offset.
33907dc194Richard Lowe   So do not call this with an attr of DW_AT_high_pc.
34007dc194Richard Lowe   Use dwarf_add_AT_unsigned_const() (for example) instead of
34107dc194Richard Lowe   dwarf_add_AT_dataref when the value is a simple offset .
34207dc194Richard Lowe*/
34307dc194Richard LoweDwarf_P_Attribute
34407dc194Richard Lowedwarf_add_AT_dataref(
34507dc194Richard Lowe    Dwarf_P_Debug dbg,
34607dc194Richard Lowe    Dwarf_P_Die ownerdie,
34707dc194Richard Lowe    Dwarf_Half attr,
34807dc194Richard Lowe    Dwarf_Unsigned pc_value,
34907dc194Richard Lowe    Dwarf_Unsigned sym_index,
35007dc194Richard Lowe    Dwarf_Error * error)
35107dc194Richard Lowe{
35207dc194Richard Lowe    /* TODO: Add checking here */
35307dc194Richard Lowe    return local_add_AT_address(dbg, ownerdie, attr,
35407dc194Richard Lowe                                dbg->de_ar_data_attribute_form,
35507dc194Richard Lowe                                pc_value,
35607dc194Richard Lowe                                sym_index,
35707dc194Richard Lowe                                error);
35807dc194Richard Lowe}
35907dc194Richard Lowe
36007dc194Richard Lowe
36107dc194Richard Lowe
36207dc194Richard LoweDwarf_P_Attribute
36307dc194Richard Lowedwarf_add_AT_block(
36407dc194Richard Lowe    Dwarf_P_Debug       dbg,
36507dc194Richard Lowe    Dwarf_P_Die         ownerdie,
36607dc194Richard Lowe    Dwarf_Half          attr,
36707dc194Richard Lowe    Dwarf_Small         *block_data,
36807dc194Richard Lowe    Dwarf_Unsigned      block_size,
36907dc194Richard Lowe    Dwarf_Error         *error
37007dc194Richard Lowe)
37107dc194Richard Lowe{
37207dc194Richard Lowe    Dwarf_P_Attribute   new_attr;
37307dc194Richard Lowe    int result;
37407dc194Richard Lowe    char encode_buffer[ENCODE_SPACE_NEEDED];
37507dc194Richard Lowe    int len_size;
37607dc194Richard Lowe    char * attrdata;
37707dc194Richard Lowe
37807dc194Richard Lowe    if (dbg == NULL) {
37907dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
38007dc194Richard Lowe        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
38107dc194Richard Lowe    }
38207dc194Richard Lowe
38307dc194Richard Lowe    if (ownerdie == NULL) {
38407dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
38507dc194Richard Lowe        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
38607dc194Richard Lowe    }
38707dc194Richard Lowe
38807dc194Richard Lowe    /* I don't mess with block1, block2, block4, not worth the effort */
38907dc194Richard Lowe
39007dc194Richard Lowe    /* So, encode the length into LEB128 */
39107dc194Richard Lowe    result = _dwarf_pro_encode_leb128_nm(block_size, &len_size,
39207dc194Richard Lowe                                         encode_buffer,sizeof(encode_buffer));
39307dc194Richard Lowe    if (result !=  DW_DLV_OK) {
39407dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
39507dc194Richard Lowe        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
39607dc194Richard Lowe    }
39707dc194Richard Lowe
39807dc194Richard Lowe    /* Allocate the new attribute */
39907dc194Richard Lowe    new_attr = (Dwarf_P_Attribute)
40007dc194Richard Lowe        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
40107dc194Richard Lowe    if (new_attr == NULL) {
40207dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
40307dc194Richard Lowe        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
40407dc194Richard Lowe    }
40507dc194Richard Lowe
40607dc194Richard Lowe    /* Fill in the attribute */
40707dc194Richard Lowe    new_attr->ar_attribute = attr;
40807dc194Richard Lowe    new_attr->ar_attribute_form = DW_FORM_block;
40907dc194Richard Lowe    new_attr->ar_nbytes = len_size + block_size;
41007dc194Richard Lowe    new_attr->ar_next = 0;
41107dc194Richard Lowe
41207dc194Richard Lowe    new_attr->ar_data = attrdata = (char *)
41307dc194Richard Lowe        _dwarf_p_get_alloc(dbg, len_size + block_size);
41407dc194Richard Lowe    if (new_attr->ar_data == NULL) {
41507dc194Richard Lowe        /* free the block we got earlier */
41607dc194Richard Lowe        _dwarf_p_dealloc(dbg, (unsigned char *) new_attr);
41707dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
41807dc194Richard Lowe        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
41907dc194Richard Lowe    }
42049d3bc9Richard Lowe
42107dc194Richard Lowe    /* write length and data to attribute data buffer */
42207dc194Richard Lowe    memcpy(attrdata, encode_buffer, len_size);
42307dc194Richard Lowe    attrdata += len_size;
42407dc194Richard Lowe    memcpy(attrdata, block_data, block_size);
42507dc194Richard Lowe
42649d3bc9Richard Lowe    /* add attribute to the die */
42749d3bc9Richard Lowe    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
42807dc194Richard Lowe
42949d3bc9Richard Lowe    return new_attr;
43049d3bc9Richard Lowe}
43149d3bc9Richard Lowe
43249d3bc9Richard Lowe
43349d3bc9Richard Lowe/*
43449d3bc9Richard Lowe    This function adds attributes whose value
43549d3bc9Richard Lowe    is an unsigned constant.  It determines the
43649d3bc9Richard Lowe    size of the value field from the value of
43749d3bc9Richard Lowe    the constant.
43849d3bc9Richard Lowe*/
43949d3bc9Richard LoweDwarf_P_Attribute
44049d3bc9Richard Lowedwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg,
44107dc194Richard Lowe                            Dwarf_P_Die ownerdie,
44207dc194Richard Lowe                            Dwarf_Half attr,
44307dc194Richard Lowe                            Dwarf_Unsigned value, Dwarf_Error * error)
44449d3bc9Richard Lowe{
44549d3bc9Richard Lowe    Dwarf_P_Attribute new_attr;
44649d3bc9Richard Lowe    Dwarf_Half attr_form;
44749d3bc9Richard Lowe    Dwarf_Small size;
44849d3bc9Richard Lowe
44949d3bc9Richard Lowe    if (dbg == NULL) {
45007dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
45107dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
45249d3bc9Richard Lowe    }
45349d3bc9Richard Lowe
45449d3bc9Richard Lowe    if (ownerdie == NULL) {
45507dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
45607dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
45749d3bc9Richard Lowe    }
45849d3bc9Richard Lowe
45949d3bc9Richard Lowe    switch (attr) {
46049d3bc9Richard Lowe    case DW_AT_ordering:
46149d3bc9Richard Lowe    case DW_AT_byte_size:
46249d3bc9Richard Lowe    case DW_AT_bit_offset:
46349d3bc9Richard Lowe    case DW_AT_bit_size:
46449d3bc9Richard Lowe    case DW_AT_inline:
46549d3bc9Richard Lowe    case DW_AT_language:
46649d3bc9Richard Lowe    case DW_AT_visibility:
46749d3bc9Richard Lowe    case DW_AT_virtuality:
46849d3bc9Richard Lowe    case DW_AT_accessibility:
46949d3bc9Richard Lowe    case DW_AT_address_class:
47049d3bc9Richard Lowe    case DW_AT_calling_convention:
47149d3bc9Richard Lowe    case DW_AT_encoding:
47249d3bc9Richard Lowe    case DW_AT_identifier_case:
47349d3bc9Richard Lowe    case DW_AT_MIPS_loop_unroll_factor:
47449d3bc9Richard Lowe    case DW_AT_MIPS_software_pipeline_depth:
47507dc194Richard Lowe        break;
47649d3bc9Richard Lowe
47749d3bc9Richard Lowe    case DW_AT_decl_column:
47849d3bc9Richard Lowe    case DW_AT_decl_file:
47949d3bc9Richard Lowe    case DW_AT_decl_line:
48049d3bc9Richard Lowe    case DW_AT_const_value:
48149d3bc9Richard Lowe    case DW_AT_start_scope:
48249d3bc9Richard Lowe    case DW_AT_stride_size:
48349d3bc9Richard Lowe    case DW_AT_count:
48407dc194Richard Lowe    case DW_AT_associated:
48507dc194Richard Lowe    case DW_AT_allocated:
48607dc194Richard Lowe    case DW_AT_upper_bound:
48707dc194Richard Lowe    case DW_AT_lower_bound:
48807dc194Richard Lowe    case DW_AT_call_file:
48907dc194Richard Lowe    case DW_AT_call_line:
49007dc194Richard Lowe        break;
49107dc194Richard Lowe
49207dc194Richard Lowe        default: {
49307dc194Richard Lowe                 if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
49407dc194Richard Lowe                     _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
49507dc194Richard Lowe                     return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
49607dc194Richard Lowe               }
49707dc194Richard Lowe               break;
49807dc194Richard Lowe            }
49907dc194Richard Lowe        }
50049d3bc9Richard Lowe
50149d3bc9Richard Lowe    /*
50249d3bc9Richard Lowe       Compute the number of bytes needed to hold constant. */
50349d3bc9Richard Lowe    if (value <= UCHAR_MAX) {
50407dc194Richard Lowe        attr_form = DW_FORM_data1;
50507dc194Richard Lowe        size = 1;
50649d3bc9Richard Lowe    } else if (value <= USHRT_MAX) {
50707dc194Richard Lowe        attr_form = DW_FORM_data2;
50807dc194Richard Lowe        size = 2;
50949d3bc9Richard Lowe    } else if (value <= UINT_MAX) {
51007dc194Richard Lowe        attr_form = DW_FORM_data4;
51107dc194Richard Lowe        size = 4;
51249d3bc9Richard Lowe    } else {
51307dc194Richard Lowe        attr_form = DW_FORM_data8;
51407dc194Richard Lowe        size = 8;
51549d3bc9Richard Lowe    }
51649d3bc9Richard Lowe
51749d3bc9Richard Lowe    new_attr = (Dwarf_P_Attribute)
51807dc194Richard Lowe        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
51949d3bc9Richard Lowe    if (new_attr == NULL) {
52007dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
52107dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
52249d3bc9Richard Lowe    }
52349d3bc9Richard Lowe
52449d3bc9Richard Lowe    new_attr->ar_attribute = attr;
52549d3bc9Richard Lowe    new_attr->ar_attribute_form = attr_form;
52649d3bc9Richard Lowe    new_attr->ar_rel_type = R_MIPS_NONE;
52707dc194Richard Lowe    new_attr->ar_reloc_len = 0; /* irrelevant: unused with R_MIPS_NONE */
52849d3bc9Richard Lowe    new_attr->ar_nbytes = size;
52949d3bc9Richard Lowe    new_attr->ar_next = 0;
53049d3bc9Richard Lowe
53149d3bc9Richard Lowe    new_attr->ar_data = (char *)
53207dc194Richard Lowe        _dwarf_p_get_alloc(dbg, size);
53349d3bc9Richard Lowe    if (new_attr->ar_data == NULL) {
53407dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
53507dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
53649d3bc9Richard Lowe    }
53749d3bc9Richard Lowe    WRITE_UNALIGNED(dbg, new_attr->ar_data,
53807dc194Richard Lowe                    (const void *) &value, sizeof(value), size);
53949d3bc9Richard Lowe
54049d3bc9Richard Lowe    /* add attribute to the die */
54149d3bc9Richard Lowe    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
54249d3bc9Richard Lowe    return new_attr;
54349d3bc9Richard Lowe}
54449d3bc9Richard Lowe
54549d3bc9Richard Lowe
54649d3bc9Richard Lowe/*
54749d3bc9Richard Lowe    This function adds attributes whose value
54849d3bc9Richard Lowe    is an signed constant.  It determines the
54949d3bc9Richard Lowe    size of the value field from the value of
55049d3bc9Richard Lowe    the constant.
55149d3bc9Richard Lowe*/
55249d3bc9Richard LoweDwarf_P_Attribute
55349d3bc9Richard Lowedwarf_add_AT_signed_const(Dwarf_P_Debug dbg,
55407dc194Richard Lowe                          Dwarf_P_Die ownerdie,
55507dc194Richard Lowe                          Dwarf_Half attr,
55607dc194Richard Lowe                          Dwarf_Signed value, Dwarf_Error * error)
55749d3bc9Richard Lowe{
55849d3bc9Richard Lowe    Dwarf_P_Attribute new_attr;
55949d3bc9Richard Lowe    Dwarf_Half attr_form;
56049d3bc9Richard Lowe    Dwarf_Small size;
56149d3bc9Richard Lowe
56249d3bc9Richard Lowe    if (dbg == NULL) {
56307dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
56407dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
56549d3bc9Richard Lowe    }
56649d3bc9Richard Lowe
56749d3bc9Richard Lowe    if (ownerdie == NULL) {
56807dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
56907dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
57049d3bc9Richard Lowe    }
57149d3bc9Richard Lowe
57249d3bc9Richard Lowe    switch (attr) {
57349d3bc9Richard Lowe    case DW_AT_lower_bound:
57407dc194Richard Lowe    case DW_AT_upper_bound:
57507dc194Richard Lowe    case DW_AT_const_value:
57607dc194Richard Lowe    case DW_AT_bit_offset:
57707dc194Richard Lowe    case DW_AT_bit_size:
57807dc194Richard Lowe    case DW_AT_byte_size:
57907dc194Richard Lowe    case DW_AT_count:
58007dc194Richard Lowe    case DW_AT_byte_stride:
58107dc194Richard Lowe    case DW_AT_bit_stride:
58207dc194Richard Lowe    case DW_AT_allocated:
58307dc194Richard Lowe    case DW_AT_associated:
58407dc194Richard Lowe        break;
58507dc194Richard Lowe
58607dc194Richard Lowe    default:{
58707dc194Richard Lowe                if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
58807dc194Richard Lowe                     _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
58907dc194Richard Lowe                     return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
59007dc194Richard Lowe                }
59107dc194Richard Lowe        }
59207dc194Richard Lowe        break;
59349d3bc9Richard Lowe    }
59449d3bc9Richard Lowe
59549d3bc9Richard Lowe    /*
59649d3bc9Richard Lowe       Compute the number of bytes needed to hold constant. */
59749d3bc9Richard Lowe    if (value >= SCHAR_MIN && value <= SCHAR_MAX) {
59807dc194Richard Lowe        attr_form = DW_FORM_data1;
59907dc194Richard Lowe        size = 1;
60049d3bc9Richard Lowe    } else if (value >= SHRT_MIN && value <= SHRT_MAX) {
60107dc194Richard Lowe        attr_form = DW_FORM_data2;
60207dc194Richard Lowe        size = 2;
60349d3bc9Richard Lowe    } else if (value >= INT_MIN && value <= INT_MAX) {
60407dc194Richard Lowe        attr_form = DW_FORM_data4;
60507dc194Richard Lowe        size = 4;
60649d3bc9Richard Lowe    } else {
60707dc194Richard Lowe        attr_form = DW_FORM_data8;
60807dc194Richard Lowe        size = 8;
60949d3bc9Richard Lowe    }
61049d3bc9Richard Lowe
61149d3bc9Richard Lowe    new_attr = (Dwarf_P_Attribute)
61207dc194Richard Lowe        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
61349d3bc9Richard Lowe    if (new_attr == NULL) {
61407dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
61507dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
61649d3bc9Richard Lowe    }
61749d3bc9Richard Lowe
61849d3bc9Richard Lowe    new_attr->ar_attribute = attr;
61949d3bc9Richard Lowe    new_attr->ar_attribute_form = attr_form;
62049d3bc9Richard Lowe    new_attr->ar_rel_type = R_MIPS_NONE;
62107dc194Richard Lowe    new_attr->ar_reloc_len = 0; /* irrelevant: unused with R_MIPS_NONE */
62249d3bc9Richard Lowe    new_attr->ar_nbytes = size;
62349d3bc9Richard Lowe    new_attr->ar_next = 0;
62449d3bc9Richard Lowe
62549d3bc9Richard Lowe    new_attr->ar_data = (char *)
62607dc194Richard Lowe        _dwarf_p_get_alloc(dbg, size);
62749d3bc9Richard Lowe    if (new_attr->ar_data == NULL) {
62807dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
62907dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
63049d3bc9Richard Lowe    }
63149d3bc9Richard Lowe    WRITE_UNALIGNED(dbg, new_attr->ar_data,
63207dc194Richard Lowe                    (const void *) &value, sizeof(value), size);
63349d3bc9Richard Lowe
63449d3bc9Richard Lowe    /* add attribute to the die */
63549d3bc9Richard Lowe    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
63649d3bc9Richard Lowe    return new_attr;
63749d3bc9Richard Lowe}
63849d3bc9Richard Lowe
63949d3bc9Richard Lowe
64049d3bc9Richard Lowe/*
64149d3bc9Richard Lowe    This function adds attributes whose value
64249d3bc9Richard Lowe    is a location expression.
64349d3bc9Richard Lowe*/
64449d3bc9Richard LoweDwarf_P_Attribute
64549d3bc9Richard Lowedwarf_add_AT_location_expr(Dwarf_P_Debug dbg,
64607dc194Richard Lowe                           Dwarf_P_Die ownerdie,
64707dc194Richard Lowe                           Dwarf_Half attr,
64807dc194Richard Lowe                           Dwarf_P_Expr loc_expr, Dwarf_Error * error)
64949d3bc9Richard Lowe{
65049d3bc9Richard Lowe    char encode_buffer[ENCODE_SPACE_NEEDED];
65149d3bc9Richard Lowe    int res;
65249d3bc9Richard Lowe    Dwarf_P_Attribute new_attr;
65349d3bc9Richard Lowe    Dwarf_Half attr_form;
65407dc194Richard Lowe    char *len_str = 0;
65549d3bc9Richard Lowe    int len_size;
65649d3bc9Richard Lowe    int block_size;
65749d3bc9Richard Lowe    char *block_dest_ptr;
65849d3bc9Richard Lowe    int do_len_as_int = 0;
65949d3bc9Richard Lowe
66049d3bc9Richard Lowe    if (dbg == NULL) {
66107dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
66207dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
66349d3bc9Richard Lowe    }
66449d3bc9Richard Lowe
66549d3bc9Richard Lowe    if (ownerdie == NULL) {
66607dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
66707dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
66849d3bc9Richard Lowe    }
66949d3bc9Richard Lowe
67049d3bc9Richard Lowe    if (loc_expr == NULL) {
67107dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_EXPR_NULL);
67207dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
67349d3bc9Richard Lowe    }
67449d3bc9Richard Lowe
67549d3bc9Richard Lowe    if (loc_expr->ex_dbg != dbg) {
67607dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
67707dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
67849d3bc9Richard Lowe    }
67949d3bc9Richard Lowe    block_size = loc_expr->ex_next_byte_offset;
68049d3bc9Richard Lowe
68149d3bc9Richard Lowe    switch (attr) {
68249d3bc9Richard Lowe    case DW_AT_location:
68349d3bc9Richard Lowe    case DW_AT_string_length:
68449d3bc9Richard Lowe    case DW_AT_const_value:
68549d3bc9Richard Lowe    case DW_AT_use_location:
68649d3bc9Richard Lowe    case DW_AT_return_addr:
68749d3bc9Richard Lowe    case DW_AT_data_member_location:
68849d3bc9Richard Lowe    case DW_AT_frame_base:
68949d3bc9Richard Lowe    case DW_AT_static_link:
69049d3bc9Richard Lowe    case DW_AT_vtable_elem_location:
69107dc194Richard Lowe    case DW_AT_lower_bound:
69207dc194Richard Lowe    case DW_AT_upper_bound:
69307dc194Richard Lowe    case DW_AT_count:
69407dc194Richard Lowe    case DW_AT_associated:
69507dc194Richard Lowe    case DW_AT_allocated:
69607dc194Richard Lowe    case DW_AT_data_location:
69707dc194Richard Lowe    case DW_AT_byte_stride:
69807dc194Richard Lowe    case DW_AT_bit_stride:
69907dc194Richard Lowe    case DW_AT_byte_size:
70007dc194Richard Lowe    case DW_AT_bit_size:
70107dc194Richard Lowe    break;
70207dc194Richard Lowe
70307dc194Richard Lowe    default:
70407dc194Richard Lowe        if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
70507dc194Richard Lowe            _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
70607dc194Richard Lowe            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
70707dc194Richard Lowe        }
70807dc194Richard Lowe    break;
70949d3bc9Richard Lowe    }
71049d3bc9Richard Lowe
71149d3bc9Richard Lowe    /*
71249d3bc9Richard Lowe       Compute the number of bytes needed to hold constant. */
71349d3bc9Richard Lowe    if (block_size <= UCHAR_MAX) {
71407dc194Richard Lowe        attr_form = DW_FORM_block1;
71507dc194Richard Lowe        len_size = 1;
71607dc194Richard Lowe        do_len_as_int = 1;
71749d3bc9Richard Lowe    } else if (block_size <= USHRT_MAX) {
71807dc194Richard Lowe        attr_form = DW_FORM_block2;
71907dc194Richard Lowe        len_size = 2;
72007dc194Richard Lowe        do_len_as_int = 1;
72149d3bc9Richard Lowe    } else if (block_size <= UINT_MAX) {
72207dc194Richard Lowe        attr_form = DW_FORM_block4;
72307dc194Richard Lowe        len_size = 4;
72407dc194Richard Lowe        do_len_as_int = 1;
72549d3bc9Richard Lowe    } else {
72607dc194Richard Lowe        attr_form = DW_FORM_block;
72707dc194Richard Lowe        res = _dwarf_pro_encode_leb128_nm(block_size, &len_size,
72807dc194Richard Lowe                                          encode_buffer,
72907dc194Richard Lowe                                          sizeof(encode_buffer));
73007dc194Richard Lowe        if (res != DW_DLV_OK) {
73107dc194Richard Lowe            _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
73207dc194Richard Lowe            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
73307dc194Richard Lowe        }
73407dc194Richard Lowe        len_str = (char *) encode_buffer;
73549d3bc9Richard Lowe    }
73649d3bc9Richard Lowe
73749d3bc9Richard Lowe    new_attr = (Dwarf_P_Attribute)
73807dc194Richard Lowe        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
73949d3bc9Richard Lowe    if (new_attr == NULL) {
74007dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
74107dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
74249d3bc9Richard Lowe    }
74349d3bc9Richard Lowe
74449d3bc9Richard Lowe    new_attr->ar_attribute = attr;
74549d3bc9Richard Lowe    new_attr->ar_attribute_form = attr_form;
74649d3bc9Richard Lowe    new_attr->ar_reloc_len = dbg->de_pointer_size;
74749d3bc9Richard Lowe    if (loc_expr->ex_reloc_sym_index != NO_ELF_SYM_INDEX) {
74807dc194Richard Lowe        new_attr->ar_rel_type = dbg->de_ptr_reloc;
74949d3bc9Richard Lowe    } else {
75007dc194Richard Lowe        new_attr->ar_rel_type = R_MIPS_NONE;
75149d3bc9Richard Lowe    }
75249d3bc9Richard Lowe    new_attr->ar_rel_symidx = loc_expr->ex_reloc_sym_index;
75349d3bc9Richard Lowe    new_attr->ar_rel_offset =
75407dc194Richard Lowe        (Dwarf_Word) loc_expr->ex_reloc_offset + len_size;
75549d3bc9Richard Lowe
75649d3bc9Richard Lowe    new_attr->ar_nbytes = block_size + len_size;
75749d3bc9Richard Lowe
75849d3bc9Richard Lowe    new_attr->ar_next = 0;
75949d3bc9Richard Lowe    new_attr->ar_data = block_dest_ptr =
76007dc194Richard Lowe        (char *) _dwarf_p_get_alloc(dbg, block_size + len_size);
76149d3bc9Richard Lowe    if (new_attr->ar_data == NULL) {
76207dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
76307dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
76449d3bc9Richard Lowe    }
76549d3bc9Richard Lowe
76649d3bc9Richard Lowe    if (do_len_as_int) {
76707dc194Richard Lowe        WRITE_UNALIGNED(dbg, block_dest_ptr, (const void *) &block_size,
76807dc194Richard Lowe                        sizeof(block_size), len_size);
76949d3bc9Richard Lowe    } else {
77007dc194Richard Lowe        /* Is uleb number form, DW_FORM_block. See above. */
77107dc194Richard Lowe        memcpy(block_dest_ptr, len_str, len_size);
77249d3bc9Richard Lowe    }
77349d3bc9Richard Lowe    block_dest_ptr += len_size;
77449d3bc9Richard Lowe    memcpy(block_dest_ptr, &(loc_expr->ex_byte_stream[0]), block_size);
77549d3bc9Richard Lowe
77649d3bc9Richard Lowe    /* add attribute to the die */
77749d3bc9Richard Lowe    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
77849d3bc9Richard Lowe    return new_attr;
77949d3bc9Richard Lowe}
78049d3bc9Richard Lowe
78149d3bc9Richard Lowe
78249d3bc9Richard Lowe/*
78349d3bc9Richard Lowe    This function adds attributes of reference class.
78449d3bc9Richard Lowe    The references here are local CU references,
78549d3bc9Richard Lowe    not DW_FORM_ref_addr.
78649d3bc9Richard Lowe    The offset field is 4 bytes for 32-bit objects,
78749d3bc9Richard Lowe    and 8-bytes for 64-bit objects.  Otherdie is the
78849d3bc9Richard Lowe    that is referenced by ownerdie.
78949d3bc9Richard Lowe
79049d3bc9Richard Lowe    For reference attributes, the ar_data and ar_nbytes
79149d3bc9Richard Lowe    are not needed.  Instead, the ar_ref_die points to
79249d3bc9Richard Lowe    the other die, and its di_offset value is used as
79349d3bc9Richard Lowe    the reference value.
79449d3bc9Richard Lowe*/
79549d3bc9Richard LoweDwarf_P_Attribute
79649d3bc9Richard Lowedwarf_add_AT_reference(Dwarf_P_Debug dbg,
79707dc194Richard Lowe                       Dwarf_P_Die ownerdie,
79807dc194Richard Lowe                       Dwarf_Half attr,
79907dc194Richard Lowe                       Dwarf_P_Die otherdie, Dwarf_Error * error)
80049d3bc9Richard Lowe{
80149d3bc9Richard Lowe    Dwarf_P_Attribute new_attr;
80249d3bc9Richard Lowe
80349d3bc9Richard Lowe    if (dbg == NULL) {
80407dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
80507dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
80649d3bc9Richard Lowe    }
80749d3bc9Richard Lowe
80849d3bc9Richard Lowe    if (ownerdie == NULL) {
80907dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
81007dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
81149d3bc9Richard Lowe    }
81249d3bc9Richard Lowe
81349d3bc9Richard Lowe    if (otherdie == NULL) {
81407dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
81507dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
81649d3bc9Richard Lowe    }
81749d3bc9Richard Lowe
81849d3bc9Richard Lowe    switch (attr) {
81949d3bc9Richard Lowe    case DW_AT_specification:
82049d3bc9Richard Lowe    case DW_AT_discr:
82149d3bc9Richard Lowe    case DW_AT_common_reference:
82249d3bc9Richard Lowe    case DW_AT_import:
82349d3bc9Richard Lowe    case DW_AT_containing_type:
82449d3bc9Richard Lowe    case DW_AT_default_value:
82549d3bc9Richard Lowe    case DW_AT_abstract_origin:
82649d3bc9Richard Lowe    case DW_AT_friend:
82749d3bc9Richard Lowe    case DW_AT_priority:
82849d3bc9Richard Lowe    case DW_AT_type:
82949d3bc9Richard Lowe    case DW_AT_lower_bound:
83049d3bc9Richard Lowe    case DW_AT_upper_bound:
83149d3bc9Richard Lowe    case DW_AT_count:
83207dc194Richard Lowe    case DW_AT_associated:
83307dc194Richard Lowe    case DW_AT_allocated:
83407dc194Richard Lowe    case DW_AT_bit_offset:
83507dc194Richard Lowe    case DW_AT_bit_size:
83607dc194Richard Lowe    case DW_AT_byte_size:
83749d3bc9Richard Lowe    case DW_AT_sibling:
83807dc194Richard Lowe    case DW_AT_bit_stride:
83907dc194Richard Lowe    case DW_AT_byte_stride:
84007dc194Richard Lowe    case DW_AT_namelist_item:
84107dc194Richard Lowe        break;
84207dc194Richard Lowe
84307dc194Richard Lowe    default:
84407dc194Richard Lowe        if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
84507dc194Richard Lowe            _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
84607dc194Richard Lowe            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
84707dc194Richard Lowe        }
84807dc194Richard Lowe        break;
84949d3bc9Richard Lowe    }
85049d3bc9Richard Lowe
85149d3bc9Richard Lowe    new_attr = (Dwarf_P_Attribute)
85207dc194Richard Lowe        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
85349d3bc9Richard Lowe    if (new_attr == NULL) {
85407dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
85507dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
85649d3bc9Richard Lowe    }
85749d3bc9Richard Lowe
85849d3bc9Richard Lowe    new_attr->ar_attribute = attr;
85949d3bc9Richard Lowe    new_attr->ar_attribute_form = dbg->de_ar_ref_attr_form;
86049d3bc9Richard Lowe    new_attr->ar_nbytes = dbg->de_offset_size;
86149d3bc9Richard Lowe    new_attr->ar_reloc_len = dbg->de_offset_size;
86249d3bc9Richard Lowe    new_attr->ar_ref_die = otherdie;
86349d3bc9Richard Lowe    new_attr->ar_rel_type = R_MIPS_NONE;
86449d3bc9Richard Lowe    new_attr->ar_next = 0;
86549d3bc9Richard Lowe
86649d3bc9Richard Lowe    /* add attribute to the die */
86749d3bc9Richard Lowe    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
86849d3bc9Richard Lowe    return new_attr;
86949d3bc9Richard Lowe}
87049d3bc9Richard Lowe
87149d3bc9Richard Lowe
87249d3bc9Richard Lowe/*
87349d3bc9Richard Lowe    This function adds attributes of the flag class.
87449d3bc9Richard Lowe*/
87549d3bc9Richard LoweDwarf_P_Attribute
87649d3bc9Richard Lowedwarf_add_AT_flag(Dwarf_P_Debug dbg,
87707dc194Richard Lowe                  Dwarf_P_Die ownerdie,
87807dc194Richard Lowe                  Dwarf_Half attr,
87907dc194Richard Lowe                  Dwarf_Small flag, Dwarf_Error * error)
88049d3bc9Richard Lowe{
88149d3bc9Richard Lowe    Dwarf_P_Attribute new_attr;
88249d3bc9Richard Lowe
88349d3bc9Richard Lowe    if (dbg == NULL) {
88407dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
88507dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
88649d3bc9Richard Lowe    }
88749d3bc9Richard Lowe
88849d3bc9Richard Lowe    if (ownerdie == NULL) {
88907dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
89007dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
89149d3bc9Richard Lowe    }
89249d3bc9Richard Lowe
89307dc194Richard Lowe#if 0
89449d3bc9Richard Lowe    switch (attr) {
89549d3bc9Richard Lowe    case DW_AT_is_optional:
89649d3bc9Richard Lowe    case DW_AT_artificial:
89749d3bc9Richard Lowe    case DW_AT_declaration:
89849d3bc9Richard Lowe    case DW_AT_external:
89949d3bc9Richard Lowe    case DW_AT_prototyped:
90049d3bc9Richard Lowe    case DW_AT_variable_parameter:
90107dc194Richard Lowe        break;
90207dc194Richard Lowe
90307dc194Richard Lowe        default:
90407dc194Richard Lowe            if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
90507dc194Richard Lowe            _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
90607dc194Richard Lowe            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
90707dc194Richard Lowe        }
90807dc194Richard Lowe            break;
90949d3bc9Richard Lowe    }
91007dc194Richard Lowe#endif
91149d3bc9Richard Lowe
91249d3bc9Richard Lowe    new_attr = (Dwarf_P_Attribute)
91307dc194Richard Lowe        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
91449d3bc9Richard Lowe    if (new_attr == NULL) {
91507dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
91607dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
91749d3bc9Richard Lowe    }
91849d3bc9Richard Lowe
91949d3bc9Richard Lowe    new_attr->ar_attribute = attr;
92049d3bc9Richard Lowe    new_attr->ar_attribute_form = DW_FORM_flag;
92149d3bc9Richard Lowe    new_attr->ar_nbytes = 1;
92207dc194Richard Lowe    new_attr->ar_reloc_len = 0; /* not used */
92349d3bc9Richard Lowe    new_attr->ar_rel_type = R_MIPS_NONE;
92449d3bc9Richard Lowe    new_attr->ar_next = 0;
92549d3bc9Richard Lowe
92649d3bc9Richard Lowe    new_attr->ar_data = (char *)
92707dc194Richard Lowe        _dwarf_p_get_alloc(dbg, 1);
92849d3bc9Richard Lowe    if (new_attr->ar_data == NULL) {
92907dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
93007dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
93149d3bc9Richard Lowe    }
93249d3bc9Richard Lowe    memcpy(new_attr->ar_data, &flag, 1);
93349d3bc9Richard Lowe
93449d3bc9Richard Lowe    /* add attribute to the die */
93549d3bc9Richard Lowe    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
93649d3bc9Richard Lowe    return new_attr;
93749d3bc9Richard Lowe}
93849d3bc9Richard Lowe
93949d3bc9Richard Lowe
94049d3bc9Richard Lowe/*
94149d3bc9Richard Lowe    This function adds values of attributes
94249d3bc9Richard Lowe    belonging to the string class.
94349d3bc9Richard Lowe*/
94449d3bc9Richard LoweDwarf_P_Attribute
94549d3bc9Richard Lowedwarf_add_AT_string(Dwarf_P_Debug dbg,
94607dc194Richard Lowe                    Dwarf_P_Die ownerdie,
94707dc194Richard Lowe                    Dwarf_Half attr, char *string, Dwarf_Error * error)
94849d3bc9Richard Lowe{
94949d3bc9Richard Lowe    Dwarf_P_Attribute new_attr;
95049d3bc9Richard Lowe
95149d3bc9Richard Lowe    if (dbg == NULL) {
95207dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
95307dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
95449d3bc9Richard Lowe    }
95549d3bc9Richard Lowe
95649d3bc9Richard Lowe    if (ownerdie == NULL) {
95707dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
95807dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
95949d3bc9Richard Lowe    }
96049d3bc9Richard Lowe
96149d3bc9Richard Lowe    new_attr = (Dwarf_P_Attribute)
96207dc194Richard Lowe        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
96349d3bc9Richard Lowe    if (new_attr == NULL) {
96407dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
96507dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
96649d3bc9Richard Lowe    }
96749d3bc9Richard Lowe
96849d3bc9Richard Lowe    switch (attr) {
96949d3bc9Richard Lowe    case DW_AT_name:
97049d3bc9Richard Lowe    case DW_AT_comp_dir:
97149d3bc9Richard Lowe    case DW_AT_const_value:
97249d3bc9Richard Lowe    case DW_AT_producer:
97307dc194Richard Lowe        break;
97407dc194Richard Lowe
97507dc194Richard Lowe        default:
97607dc194Richard Lowe            if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
97707dc194Richard Lowe            _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
97807dc194Richard Lowe            return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
97907dc194Richard Lowe        }
98007dc194Richard Lowe            break;
98149d3bc9Richard Lowe    }
98249d3bc9Richard Lowe
98349d3bc9Richard Lowe    new_attr->ar_attribute = attr;
98449d3bc9Richard Lowe    new_attr->ar_attribute_form = DW_FORM_string;
98549d3bc9Richard Lowe    new_attr->ar_nbytes = strlen(string) + 1;
98649d3bc9Richard Lowe    new_attr->ar_next = 0;
98749d3bc9Richard Lowe
98849d3bc9Richard Lowe    new_attr->ar_data =
98907dc194Richard Lowe        (char *) _dwarf_p_get_alloc(dbg, strlen(string)+1);
99049d3bc9Richard Lowe    if (new_attr->ar_data == NULL) {
99107dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
99207dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
99349d3bc9Richard Lowe    }
99449d3bc9Richard Lowe
99549d3bc9Richard Lowe    strcpy(new_attr->ar_data, string);
99649d3bc9Richard Lowe    new_attr->ar_rel_type = R_MIPS_NONE;
99707dc194Richard Lowe    new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
99849d3bc9Richard Lowe
99949d3bc9Richard Lowe    /* add attribute to the die */
100049d3bc9Richard Lowe    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
100149d3bc9Richard Lowe    return new_attr;
100249d3bc9Richard Lowe}
100349d3bc9Richard Lowe
100449d3bc9Richard Lowe
100549d3bc9Richard LoweDwarf_P_Attribute
100649d3bc9Richard Lowedwarf_add_AT_const_value_string(Dwarf_P_Die ownerdie,
100707dc194Richard Lowe                                char *string_value, Dwarf_Error * error)
100849d3bc9Richard Lowe{
100949d3bc9Richard Lowe    Dwarf_P_Attribute new_attr;
101049d3bc9Richard Lowe
101149d3bc9Richard Lowe    if (ownerdie == NULL) {
101207dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
101307dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
101449d3bc9Richard Lowe    }
101549d3bc9Richard Lowe
101649d3bc9Richard Lowe    new_attr = (Dwarf_P_Attribute)
101707dc194Richard Lowe        _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
101849d3bc9Richard Lowe    if (new_attr == NULL) {
101907dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
102007dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
102149d3bc9Richard Lowe    }
102249d3bc9Richard Lowe
102349d3bc9Richard Lowe    new_attr->ar_attribute = DW_AT_const_value;
102449d3bc9Richard Lowe    new_attr->ar_attribute_form = DW_FORM_string;
102549d3bc9Richard Lowe    new_attr->ar_nbytes = strlen(string_value) + 1;
102649d3bc9Richard Lowe    new_attr->ar_next = 0;
102749d3bc9Richard Lowe
102849d3bc9Richard Lowe    new_attr->ar_data =
102907dc194Richard Lowe        (char *) _dwarf_p_get_alloc(ownerdie->di_dbg, strlen(string_value)+1);
103049d3bc9Richard Lowe    if (new_attr->ar_data == NULL) {
103107dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
103207dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
103349d3bc9Richard Lowe    }
103449d3bc9Richard Lowe
103549d3bc9Richard Lowe    strcpy(new_attr->ar_data, string_value);
103649d3bc9Richard Lowe    new_attr->ar_rel_type = R_MIPS_NONE;
103707dc194Richard Lowe    new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
103849d3bc9Richard Lowe
103949d3bc9Richard Lowe    /* add attribute to the die */
104049d3bc9Richard Lowe    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
104149d3bc9Richard Lowe    return new_attr;
104249d3bc9Richard Lowe}
104349d3bc9Richard Lowe
104449d3bc9Richard Lowe
104549d3bc9Richard LoweDwarf_P_Attribute
104649d3bc9Richard Lowedwarf_add_AT_producer(Dwarf_P_Die ownerdie,
104707dc194Richard Lowe                      char *producer_string, Dwarf_Error * error)
104849d3bc9Richard Lowe{
104949d3bc9Richard Lowe    Dwarf_P_Attribute new_attr;
105049d3bc9Richard Lowe
105149d3bc9Richard Lowe    if (ownerdie == NULL) {
105207dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
105307dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
105449d3bc9Richard Lowe    }
105549d3bc9Richard Lowe
105649d3bc9Richard Lowe    new_attr = (Dwarf_P_Attribute)
105707dc194Richard Lowe        _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
105849d3bc9Richard Lowe    if (new_attr == NULL) {
105907dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
106007dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
106149d3bc9Richard Lowe    }
106249d3bc9Richard Lowe
106349d3bc9Richard Lowe    new_attr->ar_attribute = DW_AT_producer;
106449d3bc9Richard Lowe    new_attr->ar_attribute_form = DW_FORM_string;
106549d3bc9Richard Lowe    new_attr->ar_nbytes = strlen(producer_string) + 1;
106649d3bc9Richard Lowe    new_attr->ar_next = 0;
106749d3bc9Richard Lowe
106849d3bc9Richard Lowe    new_attr->ar_data =
106907dc194Richard Lowe        (char *) _dwarf_p_get_alloc(ownerdie->di_dbg, strlen(producer_string)+1);
107049d3bc9Richard Lowe    if (new_attr->ar_data == NULL) {
107107dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
107207dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
107349d3bc9Richard Lowe    }
107449d3bc9Richard Lowe
107549d3bc9Richard Lowe    strcpy(new_attr->ar_data, producer_string);
107649d3bc9Richard Lowe    new_attr->ar_rel_type = R_MIPS_NONE;
107707dc194Richard Lowe    new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
107849d3bc9Richard Lowe
107949d3bc9Richard Lowe    /* add attribute to the die */
108049d3bc9Richard Lowe    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
108149d3bc9Richard Lowe    return new_attr;
108249d3bc9Richard Lowe}
108349d3bc9Richard Lowe
108449d3bc9Richard Lowe
108549d3bc9Richard LoweDwarf_P_Attribute
108649d3bc9Richard Lowedwarf_add_AT_const_value_signedint(Dwarf_P_Die ownerdie,
108707dc194Richard Lowe                                   Dwarf_Signed signed_value,
108807dc194Richard Lowe                                   Dwarf_Error * error)
108949d3bc9Richard Lowe{
109049d3bc9Richard Lowe    Dwarf_P_Attribute new_attr;
109149d3bc9Richard Lowe    int leb_size;
109249d3bc9Richard Lowe    char encode_buffer[ENCODE_SPACE_NEEDED];
109349d3bc9Richard Lowe    int res;
109449d3bc9Richard Lowe
109549d3bc9Richard Lowe    if (ownerdie == NULL) {
109607dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
109707dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
109849d3bc9Richard Lowe    }
109949d3bc9Richard Lowe
110049d3bc9Richard Lowe    new_attr = (Dwarf_P_Attribute)
110107dc194Richard Lowe        _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
110249d3bc9Richard Lowe    if (new_attr == NULL) {
110307dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
110407dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
110549d3bc9Richard Lowe    }
110649d3bc9Richard Lowe
110749d3bc9Richard Lowe    new_attr->ar_attribute = DW_AT_const_value;
110849d3bc9Richard Lowe    new_attr->ar_attribute_form = DW_FORM_sdata;
110949d3bc9Richard Lowe    new_attr->ar_rel_type = R_MIPS_NONE;
111007dc194Richard Lowe    new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
111149d3bc9Richard Lowe    new_attr->ar_next = 0;
111249d3bc9Richard Lowe
111349d3bc9Richard Lowe    res = _dwarf_pro_encode_signed_leb128_nm(signed_value, &leb_size,
111407dc194Richard Lowe                                             encode_buffer,
111507dc194Richard Lowe                                             sizeof(encode_buffer));
111649d3bc9Richard Lowe    if (res != DW_DLV_OK) {
111707dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
111807dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
111949d3bc9Richard Lowe    }
112049d3bc9Richard Lowe    new_attr->ar_data = (char *)
112107dc194Richard Lowe        _dwarf_p_get_alloc(ownerdie->di_dbg, leb_size);
112249d3bc9Richard Lowe    if (new_attr->ar_data == NULL) {
112307dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
112407dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
112549d3bc9Richard Lowe    }
112649d3bc9Richard Lowe    memcpy(new_attr->ar_data, encode_buffer, leb_size);
112749d3bc9Richard Lowe    new_attr->ar_nbytes = leb_size;
112849d3bc9Richard Lowe
112949d3bc9Richard Lowe    /* add attribute to the die */
113049d3bc9Richard Lowe    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
113149d3bc9Richard Lowe    return new_attr;
113249d3bc9Richard Lowe}
113349d3bc9Richard Lowe
113449d3bc9Richard Lowe
113549d3bc9Richard LoweDwarf_P_Attribute
113649d3bc9Richard Lowedwarf_add_AT_const_value_unsignedint(Dwarf_P_Die ownerdie,
113707dc194Richard Lowe                                     Dwarf_Unsigned unsigned_value,
113807dc194Richard Lowe                                     Dwarf_Error * error)
113949d3bc9Richard Lowe{
114049d3bc9Richard Lowe    Dwarf_P_Attribute new_attr;
114149d3bc9Richard Lowe    int leb_size;
114249d3bc9Richard Lowe    char encode_buffer[ENCODE_SPACE_NEEDED];
114349d3bc9Richard Lowe    int res;
114449d3bc9Richard Lowe
114549d3bc9Richard Lowe    if (ownerdie == NULL) {
114607dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
114707dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
114849d3bc9Richard Lowe    }
114949d3bc9Richard Lowe
115049d3bc9Richard Lowe    new_attr = (Dwarf_P_Attribute)
115107dc194Richard Lowe        _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
115249d3bc9Richard Lowe    if (new_attr == NULL) {
115307dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
115407dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
115549d3bc9Richard Lowe    }
115649d3bc9Richard Lowe
115749d3bc9Richard Lowe    new_attr->ar_attribute = DW_AT_const_value;
115849d3bc9Richard Lowe    new_attr->ar_attribute_form = DW_FORM_udata;
115949d3bc9Richard Lowe    new_attr->ar_rel_type = R_MIPS_NONE;
116007dc194Richard Lowe    new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
116149d3bc9Richard Lowe    new_attr->ar_next = 0;
116249d3bc9Richard Lowe
116349d3bc9Richard Lowe    res = _dwarf_pro_encode_leb128_nm(unsigned_value, &leb_size,
116407dc194Richard Lowe                                      encode_buffer,
116507dc194Richard Lowe                                      sizeof(encode_buffer));
116649d3bc9Richard Lowe    if (res != DW_DLV_OK) {
116707dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
116807dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
116949d3bc9Richard Lowe    }
117049d3bc9Richard Lowe    new_attr->ar_data = (char *)
117107dc194Richard Lowe        _dwarf_p_get_alloc(ownerdie->di_dbg, leb_size);
117249d3bc9Richard Lowe    if (new_attr->ar_data == NULL) {
117307dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
117407dc194Richard Lowe        return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
117549d3bc9Richard Lowe    }
117649d3bc9Richard Lowe    memcpy(new_attr->ar_data, encode_buffer, leb_size);
117749d3bc9Richard Lowe    new_attr->ar_nbytes = leb_size;
117849d3bc9Richard Lowe
117949d3bc9Richard Lowe    /* add attribute to the die */
118049d3bc9Richard Lowe    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
118149d3bc9Richard Lowe    return new_attr;
118249d3bc9Richard Lowe}
1183