149d3bc9Richard Lowe/*
207dc194Richard Lowe  Copyright (C) 2000,2004,2006 Silicon Graphics, Inc.  All Rights Reserved.
307dc194Richard Lowe  Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
44d9fdb4Robert Mustacchi  Portions Copyright 2011-2019 David Anderson. All rights reserved.
54d9fdb4Robert Mustacchi
64d9fdb4Robert Mustacchi  This program is free software; you can redistribute it
74d9fdb4Robert Mustacchi  and/or modify it under the terms of version 2.1 of the
84d9fdb4Robert Mustacchi  GNU Lesser General Public License as published by the Free
94d9fdb4Robert Mustacchi  Software Foundation.
104d9fdb4Robert Mustacchi
114d9fdb4Robert Mustacchi  This program is distributed in the hope that it would be
124d9fdb4Robert Mustacchi  useful, but WITHOUT ANY WARRANTY; without even the implied
134d9fdb4Robert Mustacchi  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
144d9fdb4Robert Mustacchi  PURPOSE.
154d9fdb4Robert Mustacchi
164d9fdb4Robert Mustacchi  Further, this software is distributed without any warranty
174d9fdb4Robert Mustacchi  that it is free of the rightful claim of any third person
184d9fdb4Robert Mustacchi  regarding infringement or the like.  Any license provided
194d9fdb4Robert Mustacchi  herein, whether implied or otherwise, applies only to this
204d9fdb4Robert Mustacchi  software file.  Patent licenses, if any, provided herein
214d9fdb4Robert Mustacchi  do not apply to combinations of this program with other
224d9fdb4Robert Mustacchi  software, or any other product whatsoever.
234d9fdb4Robert Mustacchi
244d9fdb4Robert Mustacchi  You should have received a copy of the GNU Lesser General
254d9fdb4Robert Mustacchi  Public License along with this program; if not, write the
264d9fdb4Robert Mustacchi  Free Software Foundation, Inc., 51 Franklin Street - Fifth
274d9fdb4Robert Mustacchi  Floor, Boston MA 02110-1301, USA.
2849d3bc9Richard Lowe
2949d3bc9Richard Lowe*/
3049d3bc9Richard Lowe
3149d3bc9Richard Lowe#include "config.h"
3249d3bc9Richard Lowe#include "libdwarfdefs.h"
3349d3bc9Richard Lowe#include <stdio.h>
3449d3bc9Richard Lowe#include <string.h>
354d9fdb4Robert Mustacchi#include <stddef.h>
364d9fdb4Robert Mustacchi#ifdef HAVE_STDINT_H
374d9fdb4Robert Mustacchi#include <stdint.h> /* For uintptr_t */
384d9fdb4Robert Mustacchi#endif /* HAVE_STDINT_H */
3949d3bc9Richard Lowe#include "pro_incl.h"
404d9fdb4Robert Mustacchi#include "dwarf.h"
414d9fdb4Robert Mustacchi#include "libdwarf.h"
424d9fdb4Robert Mustacchi#include "pro_opaque.h"
434d9fdb4Robert Mustacchi#include "pro_error.h"
444d9fdb4Robert Mustacchi#include "pro_encode_nm.h"
454d9fdb4Robert Mustacchi#include "pro_alloc.h"
4649d3bc9Richard Lowe#include "pro_expr.h"
4749d3bc9Richard Lowe
484d9fdb4Robert Mustacchi#define SIZEOFT16 2
494d9fdb4Robert Mustacchi#define SIZEOFT32 4
504d9fdb4Robert Mustacchi#define SIZEOFT64 8
514d9fdb4Robert Mustacchi
5249d3bc9Richard Lowe/*
534d9fdb4Robert Mustacchi    This function creates a new expression
5449d3bc9Richard Lowe    struct that can be used to build up a
5549d3bc9Richard Lowe    location expression.
5649d3bc9Richard Lowe*/
5749d3bc9Richard LoweDwarf_P_Expr
5849d3bc9Richard Lowedwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error * error)
5949d3bc9Richard Lowe{
6049d3bc9Richard Lowe    Dwarf_P_Expr ret_expr;
6149d3bc9Richard Lowe
6249d3bc9Richard Lowe    if (dbg == NULL) {
6307dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
6407dc194Richard Lowe        return (NULL);
6549d3bc9Richard Lowe    }
6649d3bc9Richard Lowe
6749d3bc9Richard Lowe    ret_expr = (Dwarf_P_Expr)
6807dc194Richard Lowe        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Expr_s));
6949d3bc9Richard Lowe    if (ret_expr == NULL) {
7007dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
7107dc194Richard Lowe        return (NULL);
7249d3bc9Richard Lowe    }
7349d3bc9Richard Lowe
7449d3bc9Richard Lowe    ret_expr->ex_dbg = dbg;
7549d3bc9Richard Lowe
7649d3bc9Richard Lowe    return (ret_expr);
7749d3bc9Richard Lowe}
7849d3bc9Richard Lowe
7949d3bc9Richard LoweDwarf_Unsigned
8049d3bc9Richard Lowedwarf_add_expr_gen(Dwarf_P_Expr expr,
814d9fdb4Robert Mustacchi    Dwarf_Small opcode,
824d9fdb4Robert Mustacchi    Dwarf_Unsigned val1,
834d9fdb4Robert Mustacchi    Dwarf_Unsigned val2, Dwarf_Error * error)
844d9fdb4Robert Mustacchi{
854d9fdb4Robert Mustacchi    Dwarf_Unsigned len = 0;
864d9fdb4Robert Mustacchi    int res = 0;
874d9fdb4Robert Mustacchi
884d9fdb4Robert Mustacchi    res = dwarf_add_expr_gen_a(expr,opcode,
894d9fdb4Robert Mustacchi        val1,val2,&len,error);
904d9fdb4Robert Mustacchi    if (res != DW_DLV_OK) {
914d9fdb4Robert Mustacchi        return DW_DLV_NOCOUNT;
924d9fdb4Robert Mustacchi    }
934d9fdb4Robert Mustacchi    return len;
944d9fdb4Robert Mustacchi
954d9fdb4Robert Mustacchi}
964d9fdb4Robert Mustacchi
974d9fdb4Robert Mustacchiint
984d9fdb4Robert Mustacchidwarf_add_expr_gen_a(Dwarf_P_Expr expr,
994d9fdb4Robert Mustacchi    Dwarf_Small opcode,
1004d9fdb4Robert Mustacchi    Dwarf_Unsigned val1,
1014d9fdb4Robert Mustacchi    Dwarf_Unsigned val2,
1024d9fdb4Robert Mustacchi    Dwarf_Unsigned *stream_length_out,
1034d9fdb4Robert Mustacchi    Dwarf_Error * error)
10449d3bc9Richard Lowe{
1054d9fdb4Robert Mustacchi    /* 2* since used to concatenate 2 leb's below */
1064d9fdb4Robert Mustacchi    char encode_buffer[2 * ENCODE_SPACE_NEEDED];
1074d9fdb4Robert Mustacchi
10849d3bc9Richard Lowe    char encode_buffer2[ENCODE_SPACE_NEEDED];
1094d9fdb4Robert Mustacchi    int res = 0;
1104d9fdb4Robert Mustacchi    Dwarf_P_Debug dbg = 0;
11149d3bc9Richard Lowe
1124d9fdb4Robert Mustacchi    /*  Give the buffer where the operands are first going to be
1134d9fdb4Robert Mustacchi        assembled the largest alignment. */
11449d3bc9Richard Lowe    Dwarf_Unsigned operand_buffer[10];
11549d3bc9Richard Lowe
1164d9fdb4Robert Mustacchi    /* Size of the byte stream buffer that needs to be memcpy-ed. */
1174d9fdb4Robert Mustacchi    int operand_size = 0;
11849d3bc9Richard Lowe
1194d9fdb4Robert Mustacchi    /*  Points to the byte stream for the first operand, and finally to
1204d9fdb4Robert Mustacchi        the buffer that is memcp-ed into the Dwarf_P_Expr_s struct. */
1214d9fdb4Robert Mustacchi    Dwarf_Small *operand = 0;
12249d3bc9Richard Lowe
1234d9fdb4Robert Mustacchi    /*  Size of the byte stream for second operand. */
1244d9fdb4Robert Mustacchi    int operand2_size = 0;
12549d3bc9Richard Lowe
1264d9fdb4Robert Mustacchi    /*  Points to next byte to be written in Dwarf_P_Expr_s struct. */
1274d9fdb4Robert Mustacchi    Dwarf_Small *next_byte_ptr = 0;
12849d3bc9Richard Lowe
1294d9fdb4Robert Mustacchi    /*  Offset past the last byte written into Dwarf_P_Expr_s. */
1304d9fdb4Robert Mustacchi    int next_byte_offset = 0;
13149d3bc9Richard Lowe
13249d3bc9Richard Lowe    /* ***** BEGIN CODE ***** */
13349d3bc9Richard Lowe
13449d3bc9Richard Lowe    if (expr == NULL) {
13507dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
1364d9fdb4Robert Mustacchi        return DW_DLV_ERROR;
13749d3bc9Richard Lowe    }
1384d9fdb4Robert Mustacchi    dbg = expr->ex_dbg;
13949d3bc9Richard Lowe
14049d3bc9Richard Lowe    if (expr->ex_dbg == NULL) {
14107dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
1424d9fdb4Robert Mustacchi        return DW_DLV_ERROR;
14349d3bc9Richard Lowe    }
14449d3bc9Richard Lowe
14549d3bc9Richard Lowe    operand = NULL;
14649d3bc9Richard Lowe    operand_size = 0;
14749d3bc9Richard Lowe
14849d3bc9Richard Lowe    switch (opcode) {
14949d3bc9Richard Lowe    case DW_OP_reg0:
15049d3bc9Richard Lowe    case DW_OP_reg1:
15149d3bc9Richard Lowe    case DW_OP_reg2:
15249d3bc9Richard Lowe    case DW_OP_reg3:
15349d3bc9Richard Lowe    case DW_OP_reg4:
15449d3bc9Richard Lowe    case DW_OP_reg5:
15549d3bc9Richard Lowe    case DW_OP_reg6:
15649d3bc9Richard Lowe    case DW_OP_reg7:
15749d3bc9Richard Lowe    case DW_OP_reg8:
15849d3bc9Richard Lowe    case DW_OP_reg9:
15949d3bc9Richard Lowe    case DW_OP_reg10:
16049d3bc9Richard Lowe    case DW_OP_reg11:
16149d3bc9Richard Lowe    case DW_OP_reg12:
16249d3bc9Richard Lowe    case DW_OP_reg13:
16349d3bc9Richard Lowe    case DW_OP_reg14:
16449d3bc9Richard Lowe    case DW_OP_reg15:
16549d3bc9Richard Lowe    case DW_OP_reg16:
16649d3bc9Richard Lowe    case DW_OP_reg17:
16749d3bc9Richard Lowe    case DW_OP_reg18:
16849d3bc9Richard Lowe    case DW_OP_reg19:
16949d3bc9Richard Lowe    case DW_OP_reg20:
17049d3bc9Richard Lowe    case DW_OP_reg21:
17149d3bc9Richard Lowe    case DW_OP_reg22:
17249d3bc9Richard Lowe    case DW_OP_reg23:
17349d3bc9Richard Lowe    case DW_OP_reg24:
17449d3bc9Richard Lowe    case DW_OP_reg25:
17549d3bc9Richard Lowe    case DW_OP_reg26:
17649d3bc9Richard Lowe    case DW_OP_reg27:
17749d3bc9Richard Lowe    case DW_OP_reg28:
17849d3bc9Richard Lowe    case DW_OP_reg29:
17949d3bc9Richard Lowe    case DW_OP_reg30:
18049d3bc9Richard Lowe    case DW_OP_reg31:
18107dc194Richard Lowe        break;
18249d3bc9Richard Lowe
18349d3bc9Richard Lowe    case DW_OP_breg0:
18449d3bc9Richard Lowe    case DW_OP_breg1:
18549d3bc9Richard Lowe    case DW_OP_breg2:
18649d3bc9Richard Lowe    case DW_OP_breg3:
18749d3bc9Richard Lowe    case DW_OP_breg4:
18849d3bc9Richard Lowe    case DW_OP_breg5:
18949d3bc9Richard Lowe    case DW_OP_breg6:
19049d3bc9Richard Lowe    case DW_OP_breg7:
19149d3bc9Richard Lowe    case DW_OP_breg8:
19249d3bc9Richard Lowe    case DW_OP_breg9:
19349d3bc9Richard Lowe    case DW_OP_breg10:
19449d3bc9Richard Lowe    case DW_OP_breg11:
19549d3bc9Richard Lowe    case DW_OP_breg12:
19649d3bc9Richard Lowe    case DW_OP_breg13:
19749d3bc9Richard Lowe    case DW_OP_breg14:
19849d3bc9Richard Lowe    case DW_OP_breg15:
19949d3bc9Richard Lowe    case DW_OP_breg16:
20049d3bc9Richard Lowe    case DW_OP_breg17:
20149d3bc9Richard Lowe    case DW_OP_breg18:
20249d3bc9Richard Lowe    case DW_OP_breg19:
20349d3bc9Richard Lowe    case DW_OP_breg20:
20449d3bc9Richard Lowe    case DW_OP_breg21:
20549d3bc9Richard Lowe    case DW_OP_breg22:
20649d3bc9Richard Lowe    case DW_OP_breg23:
20749d3bc9Richard Lowe    case DW_OP_breg24:
20849d3bc9Richard Lowe    case DW_OP_breg25:
20949d3bc9Richard Lowe    case DW_OP_breg26:
21049d3bc9Richard Lowe    case DW_OP_breg27:
21149d3bc9Richard Lowe    case DW_OP_breg28:
21249d3bc9Richard Lowe    case DW_OP_breg29:
21349d3bc9Richard Lowe    case DW_OP_breg30:
21449d3bc9Richard Lowe    case DW_OP_breg31:
21507dc194Richard Lowe        res = _dwarf_pro_encode_signed_leb128_nm(val1,
2164d9fdb4Robert Mustacchi            &operand_size, encode_buffer, sizeof(encode_buffer));
21707dc194Richard Lowe        if (res != DW_DLV_OK) {
21807dc194Richard Lowe            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
2194d9fdb4Robert Mustacchi            return DW_DLV_ERROR;
22007dc194Richard Lowe        }
22107dc194Richard Lowe        operand = (Dwarf_Small *) encode_buffer;
22207dc194Richard Lowe        break;
22349d3bc9Richard Lowe
22449d3bc9Richard Lowe    case DW_OP_regx:
22507dc194Richard Lowe        res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
2264d9fdb4Robert Mustacchi            encode_buffer, sizeof(encode_buffer));
22707dc194Richard Lowe        if (res != DW_DLV_OK) {
22807dc194Richard Lowe            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
2294d9fdb4Robert Mustacchi            return DW_DLV_ERROR;
23007dc194Richard Lowe        }
23107dc194Richard Lowe        operand = (Dwarf_Small *) encode_buffer;
23207dc194Richard Lowe        break;
23349d3bc9Richard Lowe
23449d3bc9Richard Lowe    case DW_OP_lit0:
23549d3bc9Richard Lowe    case DW_OP_lit1:
23649d3bc9Richard Lowe    case DW_OP_lit2:
23749d3bc9Richard Lowe    case DW_OP_lit3:
23849d3bc9Richard Lowe    case DW_OP_lit4:
23949d3bc9Richard Lowe    case DW_OP_lit5:
24049d3bc9Richard Lowe    case DW_OP_lit6:
24149d3bc9Richard Lowe    case DW_OP_lit7:
24249d3bc9Richard Lowe    case DW_OP_lit8:
24349d3bc9Richard Lowe    case DW_OP_lit9:
24449d3bc9Richard Lowe    case DW_OP_lit10:
24549d3bc9Richard Lowe    case DW_OP_lit11:
24649d3bc9Richard Lowe    case DW_OP_lit12:
24749d3bc9Richard Lowe    case DW_OP_lit13:
24849d3bc9Richard Lowe    case DW_OP_lit14:
24949d3bc9Richard Lowe    case DW_OP_lit15:
25049d3bc9Richard Lowe    case DW_OP_lit16:
25149d3bc9Richard Lowe    case DW_OP_lit17:
25249d3bc9Richard Lowe    case DW_OP_lit18:
25349d3bc9Richard Lowe    case DW_OP_lit19:
25449d3bc9Richard Lowe    case DW_OP_lit20:
25549d3bc9Richard Lowe    case DW_OP_lit21:
25649d3bc9Richard Lowe    case DW_OP_lit22:
25749d3bc9Richard Lowe    case DW_OP_lit23:
25849d3bc9Richard Lowe    case DW_OP_lit24:
25949d3bc9Richard Lowe    case DW_OP_lit25:
26049d3bc9Richard Lowe    case DW_OP_lit26:
26149d3bc9Richard Lowe    case DW_OP_lit27:
26249d3bc9Richard Lowe    case DW_OP_lit28:
26349d3bc9Richard Lowe    case DW_OP_lit29:
26449d3bc9Richard Lowe    case DW_OP_lit30:
26549d3bc9Richard Lowe    case DW_OP_lit31:
26607dc194Richard Lowe        break;
26749d3bc9Richard Lowe
26849d3bc9Richard Lowe    case DW_OP_addr:
26907dc194Richard Lowe        _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
2704d9fdb4Robert Mustacchi        return DW_DLV_ERROR;
27149d3bc9Richard Lowe
27249d3bc9Richard Lowe    case DW_OP_const1u:
27349d3bc9Richard Lowe    case DW_OP_const1s:
27407dc194Richard Lowe        operand = (Dwarf_Small *) & operand_buffer[0];
27507dc194Richard Lowe        WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 1);
27607dc194Richard Lowe        operand_size = 1;
27707dc194Richard Lowe        break;
27849d3bc9Richard Lowe
27949d3bc9Richard Lowe    case DW_OP_const2u:
28049d3bc9Richard Lowe    case DW_OP_const2s:
28107dc194Richard Lowe        operand = (Dwarf_Small *) & operand_buffer[0];
28207dc194Richard Lowe        WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2);
28307dc194Richard Lowe        operand_size = 2;
28407dc194Richard Lowe        break;
28549d3bc9Richard Lowe
28649d3bc9Richard Lowe    case DW_OP_const4u:
28749d3bc9Richard Lowe    case DW_OP_const4s:
28807dc194Richard Lowe        operand = (Dwarf_Small *) & operand_buffer[0];
2894d9fdb4Robert Mustacchi        WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1),
2904d9fdb4Robert Mustacchi            SIZEOFT32);
2914d9fdb4Robert Mustacchi        operand_size = SIZEOFT32;
29207dc194Richard Lowe        break;
29349d3bc9Richard Lowe
29449d3bc9Richard Lowe    case DW_OP_const8u:
29549d3bc9Richard Lowe    case DW_OP_const8s:
29607dc194Richard Lowe        operand = (Dwarf_Small *) & operand_buffer[0];
29707dc194Richard Lowe        WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 8);
29807dc194Richard Lowe        operand_size = 8;
29907dc194Richard Lowe        break;
30049d3bc9Richard Lowe
30149d3bc9Richard Lowe    case DW_OP_constu:
30207dc194Richard Lowe        res = _dwarf_pro_encode_leb128_nm(val1,
3034d9fdb4Robert Mustacchi            &operand_size, encode_buffer, sizeof(encode_buffer));
30407dc194Richard Lowe        if (res != DW_DLV_OK) {
30507dc194Richard Lowe            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
3064d9fdb4Robert Mustacchi            return DW_DLV_ERROR;
30707dc194Richard Lowe        }
30807dc194Richard Lowe        operand = (Dwarf_Small *) encode_buffer;
30907dc194Richard Lowe        break;
31049d3bc9Richard Lowe
31149d3bc9Richard Lowe    case DW_OP_consts:
31207dc194Richard Lowe        res = _dwarf_pro_encode_signed_leb128_nm(val1,
3134d9fdb4Robert Mustacchi            &operand_size,
3144d9fdb4Robert Mustacchi            encode_buffer,
3154d9fdb4Robert Mustacchi            sizeof(encode_buffer));
31607dc194Richard Lowe        if (res != DW_DLV_OK) {
31707dc194Richard Lowe            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
3184d9fdb4Robert Mustacchi            return DW_DLV_ERROR;
31907dc194Richard Lowe        }
32007dc194Richard Lowe        operand = (Dwarf_Small *) encode_buffer;
32107dc194Richard Lowe        break;
32249d3bc9Richard Lowe
32349d3bc9Richard Lowe    case DW_OP_fbreg:
32407dc194Richard Lowe        res = _dwarf_pro_encode_signed_leb128_nm(val1,
3254d9fdb4Robert Mustacchi            &operand_size,
3264d9fdb4Robert Mustacchi            encode_buffer,
3274d9fdb4Robert Mustacchi            sizeof(encode_buffer));
32807dc194Richard Lowe        if (res != DW_DLV_OK) {
32907dc194Richard Lowe            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
3304d9fdb4Robert Mustacchi            return DW_DLV_ERROR;
33107dc194Richard Lowe        }
33207dc194Richard Lowe        operand = (Dwarf_Small *) encode_buffer;
33307dc194Richard Lowe        break;
33449d3bc9Richard Lowe
33549d3bc9Richard Lowe    case DW_OP_bregx:
33607dc194Richard Lowe        res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
3374d9fdb4Robert Mustacchi            encode_buffer,
3384d9fdb4Robert Mustacchi            sizeof(encode_buffer));
33907dc194Richard Lowe        if (res != DW_DLV_OK) {
34007dc194Richard Lowe            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
3414d9fdb4Robert Mustacchi            return DW_DLV_ERROR;
34207dc194Richard Lowe        }
34307dc194Richard Lowe        operand = (Dwarf_Small *) encode_buffer;
34407dc194Richard Lowe        /* put this one directly into 'operand' at tail of prev value */
34507dc194Richard Lowe        res = _dwarf_pro_encode_signed_leb128_nm(val2, &operand2_size,
3464d9fdb4Robert Mustacchi            ((char *) operand) +
3474d9fdb4Robert Mustacchi            operand_size,
3484d9fdb4Robert Mustacchi            sizeof(encode_buffer2));
34907dc194Richard Lowe        if (res != DW_DLV_OK) {
35007dc194Richard Lowe            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
3514d9fdb4Robert Mustacchi            return DW_DLV_ERROR;
35207dc194Richard Lowe        }
35307dc194Richard Lowe        operand_size += operand2_size;
35449d3bc9Richard Lowe
35549d3bc9Richard Lowe    case DW_OP_dup:
35649d3bc9Richard Lowe    case DW_OP_drop:
35707dc194Richard Lowe        break;
35849d3bc9Richard Lowe
35949d3bc9Richard Lowe    case DW_OP_pick:
36007dc194Richard Lowe        operand = (Dwarf_Small *) & operand_buffer[0];
36107dc194Richard Lowe        WRITE_UNALIGNED(dbg, operand, (const void *) &val1,
3624d9fdb4Robert Mustacchi            sizeof(val1), 1);
36307dc194Richard Lowe        operand_size = 1;
36407dc194Richard Lowe        break;
36549d3bc9Richard Lowe
36649d3bc9Richard Lowe    case DW_OP_over:
36749d3bc9Richard Lowe    case DW_OP_swap:
36849d3bc9Richard Lowe    case DW_OP_rot:
36949d3bc9Richard Lowe    case DW_OP_deref:
37049d3bc9Richard Lowe    case DW_OP_xderef:
37107dc194Richard Lowe        break;
37249d3bc9Richard Lowe
37349d3bc9Richard Lowe    case DW_OP_deref_size:
37449d3bc9Richard Lowe    case DW_OP_xderef_size:
37507dc194Richard Lowe        operand = (Dwarf_Small *) & operand_buffer[0];
37607dc194Richard Lowe        WRITE_UNALIGNED(dbg, operand, (const void *) &val1,
3774d9fdb4Robert Mustacchi            sizeof(val1), 1);
37807dc194Richard Lowe        operand_size = 1;
37907dc194Richard Lowe        break;
38049d3bc9Richard Lowe
38149d3bc9Richard Lowe    case DW_OP_abs:
38249d3bc9Richard Lowe    case DW_OP_and:
38349d3bc9Richard Lowe    case DW_OP_div:
38449d3bc9Richard Lowe    case DW_OP_minus:
38549d3bc9Richard Lowe    case DW_OP_mod:
38649d3bc9Richard Lowe    case DW_OP_mul:
38749d3bc9Richard Lowe    case DW_OP_neg:
38849d3bc9Richard Lowe    case DW_OP_not:
38949d3bc9Richard Lowe    case DW_OP_or:
39049d3bc9Richard Lowe    case DW_OP_plus:
39107dc194Richard Lowe        break;
39249d3bc9Richard Lowe
39349d3bc9Richard Lowe    case DW_OP_plus_uconst:
39407dc194Richard Lowe        res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
3954d9fdb4Robert Mustacchi            encode_buffer,
3964d9fdb4Robert Mustacchi            sizeof(encode_buffer));
39707dc194Richard Lowe        if (res != DW_DLV_OK) {
39807dc194Richard Lowe            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
3994d9fdb4Robert Mustacchi            return DW_DLV_ERROR;
40007dc194Richard Lowe        }
40107dc194Richard Lowe        operand = (Dwarf_Small *) encode_buffer;
40207dc194Richard Lowe        break;
40349d3bc9Richard Lowe
40449d3bc9Richard Lowe    case DW_OP_shl:
40549d3bc9Richard Lowe    case DW_OP_shr:
40649d3bc9Richard Lowe    case DW_OP_shra:
40749d3bc9Richard Lowe    case DW_OP_xor:
40807dc194Richard Lowe        break;
40949d3bc9Richard Lowe
41049d3bc9Richard Lowe    case DW_OP_le:
41149d3bc9Richard Lowe    case DW_OP_ge:
41249d3bc9Richard Lowe    case DW_OP_eq:
41349d3bc9Richard Lowe    case DW_OP_lt:
41449d3bc9Richard Lowe    case DW_OP_gt:
41549d3bc9Richard Lowe    case DW_OP_ne:
41607dc194Richard Lowe        break;
41749d3bc9Richard Lowe
41849d3bc9Richard Lowe    case DW_OP_skip:
41949d3bc9Richard Lowe    case DW_OP_bra:
42007dc194Richard Lowe        /* FIX: unhandled! OP_bra, OP_skip! */
42107dc194Richard Lowe        _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
4224d9fdb4Robert Mustacchi        return DW_DLV_ERROR;
42349d3bc9Richard Lowe
42449d3bc9Richard Lowe    case DW_OP_piece:
42507dc194Richard Lowe        res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
4264d9fdb4Robert Mustacchi            encode_buffer,
4274d9fdb4Robert Mustacchi            sizeof(encode_buffer));
42807dc194Richard Lowe        if (res != DW_DLV_OK) {
42907dc194Richard Lowe            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
4304d9fdb4Robert Mustacchi            return DW_DLV_ERROR;
43107dc194Richard Lowe        }
43207dc194Richard Lowe        operand = (Dwarf_Small *) encode_buffer;
43307dc194Richard Lowe        break;
43449d3bc9Richard Lowe
43549d3bc9Richard Lowe    case DW_OP_nop:
43607dc194Richard Lowe        break;
43707dc194Richard Lowe    case DW_OP_push_object_address:     /* DWARF3 */
43807dc194Richard Lowe        break;
43907dc194Richard Lowe    case DW_OP_call2:           /* DWARF3 */
44007dc194Richard Lowe        operand = (Dwarf_Small *) & operand_buffer[0];
4414d9fdb4Robert Mustacchi        WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), SIZEOFT16);
4424d9fdb4Robert Mustacchi        operand_size = SIZEOFT16;
44307dc194Richard Lowe        break;
44407dc194Richard Lowe
44507dc194Richard Lowe    case DW_OP_call4:           /* DWARF3 */
44607dc194Richard Lowe        operand = (Dwarf_Small *) & operand_buffer[0];
4474d9fdb4Robert Mustacchi        WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), SIZEOFT32);
4484d9fdb4Robert Mustacchi        operand_size = SIZEOFT32;
44907dc194Richard Lowe        break;
45007dc194Richard Lowe
45107dc194Richard Lowe    case DW_OP_call_ref:        /* DWARF3 */
45207dc194Richard Lowe        operand = (Dwarf_Small *) & operand_buffer[0];
45307dc194Richard Lowe        WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1),
4544d9fdb4Robert Mustacchi            dbg->de_dwarf_offset_size);
4554d9fdb4Robert Mustacchi        operand_size = dbg->de_dwarf_offset_size;
45607dc194Richard Lowe        break;
45707dc194Richard Lowe    case DW_OP_form_tls_address:        /* DWARF3f */
45807dc194Richard Lowe        break;
45907dc194Richard Lowe    case DW_OP_call_frame_cfa:  /* DWARF3f */
46007dc194Richard Lowe        break;
46107dc194Richard Lowe    case DW_OP_bit_piece:       /* DWARF3f */
46207dc194Richard Lowe        res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
4634d9fdb4Robert Mustacchi            encode_buffer,
4644d9fdb4Robert Mustacchi            sizeof(encode_buffer));
46507dc194Richard Lowe        if (res != DW_DLV_OK) {
46607dc194Richard Lowe            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
4674d9fdb4Robert Mustacchi            return DW_DLV_ERROR;
46807dc194Richard Lowe        }
46907dc194Richard Lowe        operand = (Dwarf_Small *) encode_buffer;
47007dc194Richard Lowe        /* put this one directly into 'operand' at tail of prev value */
47107dc194Richard Lowe        res = _dwarf_pro_encode_leb128_nm(val2, &operand2_size,
4724d9fdb4Robert Mustacchi            ((char *) operand) +
4734d9fdb4Robert Mustacchi            operand_size,
4744d9fdb4Robert Mustacchi            sizeof(encode_buffer2));
47507dc194Richard Lowe        if (res != DW_DLV_OK) {
47607dc194Richard Lowe            _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
4774d9fdb4Robert Mustacchi            return DW_DLV_ERROR;
47807dc194Richard Lowe        }
47907dc194Richard Lowe        operand_size += operand2_size;
4804d9fdb4Robert Mustacchi        break;
48149d3bc9Richard Lowe    default:
48207dc194Richard Lowe        _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
4834d9fdb4Robert Mustacchi        return DW_DLV_ERROR;
48449d3bc9Richard Lowe    }
48549d3bc9Richard Lowe
48649d3bc9Richard Lowe    next_byte_offset = expr->ex_next_byte_offset + operand_size + 1;
48749d3bc9Richard Lowe
48849d3bc9Richard Lowe    if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) {
48907dc194Richard Lowe        _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
4904d9fdb4Robert Mustacchi        return DW_DLV_ERROR;
49149d3bc9Richard Lowe    }
49249d3bc9Richard Lowe
49349d3bc9Richard Lowe    next_byte_ptr =
49407dc194Richard Lowe        &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset;
49549d3bc9Richard Lowe
49649d3bc9Richard Lowe    *next_byte_ptr = opcode;
49749d3bc9Richard Lowe    next_byte_ptr++;
4984d9fdb4Robert Mustacchi    if (operand) {
4994d9fdb4Robert Mustacchi        memcpy(next_byte_ptr, operand, operand_size);
5004d9fdb4Robert Mustacchi    }
50149d3bc9Richard Lowe
50249d3bc9Richard Lowe    expr->ex_next_byte_offset = next_byte_offset;
5034d9fdb4Robert Mustacchi    *stream_length_out = next_byte_offset;
5044d9fdb4Robert Mustacchi    return DW_DLV_OK;
50549d3bc9Richard Lowe}
50649d3bc9Richard Lowe
50749d3bc9Richard LoweDwarf_Unsigned
50849d3bc9Richard Lowedwarf_add_expr_addr_b(Dwarf_P_Expr expr,
5094d9fdb4Robert Mustacchi    Dwarf_Unsigned addr,
5104d9fdb4Robert Mustacchi    Dwarf_Unsigned sym_index,
5114d9fdb4Robert Mustacchi    Dwarf_Error * error)
5124d9fdb4Robert Mustacchi{
5134d9fdb4Robert Mustacchi    Dwarf_Unsigned length = 0;
5144d9fdb4Robert Mustacchi    int res = 0;
5154d9fdb4Robert Mustacchi
5164d9fdb4Robert Mustacchi    res = dwarf_add_expr_addr_c(expr,addr,sym_index,
5174d9fdb4Robert Mustacchi        &length,error);
5184d9fdb4Robert Mustacchi    if (res != DW_DLV_OK) {
5194d9fdb4Robert Mustacchi        return DW_DLV_NOCOUNT;
5204d9fdb4Robert Mustacchi    }
5214d9fdb4Robert Mustacchi    return length;
5224d9fdb4Robert Mustacchi
5234d9fdb4Robert Mustacchi}
5244d9fdb4Robert Mustacchiint
5254d9fdb4Robert Mustacchidwarf_add_expr_addr_c(Dwarf_P_Expr expr,
5264d9fdb4Robert Mustacchi    Dwarf_Unsigned addr,
5274d9fdb4Robert Mustacchi    Dwarf_Unsigned sym_index,
5284d9fdb4Robert Mustacchi    Dwarf_Unsigned *stream_length_out,
5294d9fdb4Robert Mustacchi    Dwarf_Error * error)
53049d3bc9Richard Lowe{
53149d3bc9Richard Lowe    Dwarf_P_Debug dbg;
53249d3bc9Richard Lowe    Dwarf_Small *next_byte_ptr;
53349d3bc9Richard Lowe    Dwarf_Unsigned next_byte_offset;
53449d3bc9Richard Lowe    int upointer_size;
53549d3bc9Richard Lowe
53649d3bc9Richard Lowe    if (expr == NULL) {
53707dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
5384d9fdb4Robert Mustacchi        return (DW_DLV_ERROR);
53949d3bc9Richard Lowe    }
54049d3bc9Richard Lowe
54149d3bc9Richard Lowe    dbg = expr->ex_dbg;
54249d3bc9Richard Lowe    if (dbg == NULL) {
54307dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
5444d9fdb4Robert Mustacchi        return (DW_DLV_ERROR);
54549d3bc9Richard Lowe    }
54649d3bc9Richard Lowe
54749d3bc9Richard Lowe    upointer_size = dbg->de_pointer_size;
54849d3bc9Richard Lowe    next_byte_offset = expr->ex_next_byte_offset + upointer_size + 1;
54949d3bc9Richard Lowe    if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) {
55007dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD);
5514d9fdb4Robert Mustacchi        return (DW_DLV_ERROR);
55249d3bc9Richard Lowe    }
55349d3bc9Richard Lowe
55449d3bc9Richard Lowe    next_byte_ptr =
55507dc194Richard Lowe        &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset;
55649d3bc9Richard Lowe
55749d3bc9Richard Lowe    *next_byte_ptr = DW_OP_addr;
55849d3bc9Richard Lowe    next_byte_ptr++;
55949d3bc9Richard Lowe    WRITE_UNALIGNED(dbg, next_byte_ptr, (const void *) &addr,
5604d9fdb4Robert Mustacchi        sizeof(addr), upointer_size);
56149d3bc9Richard Lowe
56249d3bc9Richard Lowe    if (expr->ex_reloc_offset != 0) {
56307dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_MULTIPLE_RELOC_IN_EXPR);
5644d9fdb4Robert Mustacchi        return (DW_DLV_ERROR);
56549d3bc9Richard Lowe    }
56649d3bc9Richard Lowe
56749d3bc9Richard Lowe    expr->ex_reloc_sym_index = sym_index;
56849d3bc9Richard Lowe    expr->ex_reloc_offset = expr->ex_next_byte_offset + 1;
56949d3bc9Richard Lowe
57049d3bc9Richard Lowe    expr->ex_next_byte_offset = next_byte_offset;
5714d9fdb4Robert Mustacchi    *stream_length_out = next_byte_offset;
5724d9fdb4Robert Mustacchi    return DW_DLV_OK;
57349d3bc9Richard Lowe}
57449d3bc9Richard Lowe
57549d3bc9Richard LoweDwarf_Unsigned
57649d3bc9Richard Lowedwarf_add_expr_addr(Dwarf_P_Expr expr,
5774d9fdb4Robert Mustacchi    Dwarf_Unsigned addr,
5784d9fdb4Robert Mustacchi    Dwarf_Signed sym_index,
5794d9fdb4Robert Mustacchi    Dwarf_Error * error)
58049d3bc9Richard Lowe{
5814d9fdb4Robert Mustacchi    Dwarf_Unsigned length = 0;
5824d9fdb4Robert Mustacchi    int res = 0;
5834d9fdb4Robert Mustacchi    Dwarf_P_Debug dbg = 0;
5844d9fdb4Robert Mustacchi
5854d9fdb4Robert Mustacchi    if (sym_index < 0) {
5864d9fdb4Robert Mustacchi        _dwarf_p_error(dbg, error,
5874d9fdb4Robert Mustacchi            DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD);
5884d9fdb4Robert Mustacchi        return DW_DLV_NOCOUNT;
5894d9fdb4Robert Mustacchi    }
5904d9fdb4Robert Mustacchi    res = dwarf_add_expr_addr_c(expr,
5914d9fdb4Robert Mustacchi        (Dwarf_Unsigned)addr,
5924d9fdb4Robert Mustacchi        (Dwarf_Unsigned)sym_index,
5934d9fdb4Robert Mustacchi        &length,error);
5944d9fdb4Robert Mustacchi    if (res != DW_DLV_OK) {
5954d9fdb4Robert Mustacchi        return (Dwarf_Unsigned)DW_DLV_NOCOUNT;
5964d9fdb4Robert Mustacchi    }
5974d9fdb4Robert Mustacchi    return length;
59849d3bc9Richard Lowe}
59949d3bc9Richard Lowe
60049d3bc9Richard LoweDwarf_Unsigned
60149d3bc9Richard Lowedwarf_expr_current_offset(Dwarf_P_Expr expr, Dwarf_Error * error)
60249d3bc9Richard Lowe{
6034d9fdb4Robert Mustacchi    Dwarf_Unsigned l = 0;
6044d9fdb4Robert Mustacchi    int res = 0;
6054d9fdb4Robert Mustacchi
6064d9fdb4Robert Mustacchi    res = dwarf_expr_current_offset_a(expr,&l,error);
6074d9fdb4Robert Mustacchi    if (res != DW_DLV_OK) {
6084d9fdb4Robert Mustacchi        return (DW_DLV_NOCOUNT);
6094d9fdb4Robert Mustacchi    }
6104d9fdb4Robert Mustacchi    return l;
6114d9fdb4Robert Mustacchi}
6124d9fdb4Robert Mustacchi
6134d9fdb4Robert Mustacchiint
6144d9fdb4Robert Mustacchidwarf_expr_current_offset_a(Dwarf_P_Expr expr,
6154d9fdb4Robert Mustacchi    Dwarf_Unsigned * stream_length_out,
6164d9fdb4Robert Mustacchi    Dwarf_Error * error)
6174d9fdb4Robert Mustacchi{
61849d3bc9Richard Lowe    if (expr == NULL) {
61907dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
6204d9fdb4Robert Mustacchi        return DW_DLV_ERROR;
62149d3bc9Richard Lowe    }
62249d3bc9Richard Lowe
62349d3bc9Richard Lowe    if (expr->ex_dbg == NULL) {
62407dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
6254d9fdb4Robert Mustacchi        return DW_DLV_ERROR;
62649d3bc9Richard Lowe    }
6274d9fdb4Robert Mustacchi    *stream_length_out = expr->ex_next_byte_offset;
6284d9fdb4Robert Mustacchi    return DW_DLV_OK;
62949d3bc9Richard Lowe}
63049d3bc9Richard Lowe
63107dc194Richard Lowevoid
63207dc194Richard Lowedwarf_expr_reset(Dwarf_P_Expr expr, Dwarf_Error * error)
63307dc194Richard Lowe{
6344d9fdb4Robert Mustacchi    if (expr == NULL) {
6354d9fdb4Robert Mustacchi        _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
6364d9fdb4Robert Mustacchi        return;
6374d9fdb4Robert Mustacchi    }
6384d9fdb4Robert Mustacchi    expr->ex_next_byte_offset=0;
63907dc194Richard Lowe}
64007dc194Richard Lowe
64149d3bc9Richard LoweDwarf_Addr
64249d3bc9Richard Lowedwarf_expr_into_block(Dwarf_P_Expr expr,
6434d9fdb4Robert Mustacchi    Dwarf_Unsigned * length,
6444d9fdb4Robert Mustacchi    Dwarf_Error * error)
6454d9fdb4Robert Mustacchi{
6464d9fdb4Robert Mustacchi    Dwarf_Small *addr = 0;
6474d9fdb4Robert Mustacchi    int res = 0;
6484d9fdb4Robert Mustacchi
6494d9fdb4Robert Mustacchi    res = dwarf_expr_into_block_a(expr,length,&addr,error);
6504d9fdb4Robert Mustacchi    if (res != DW_DLV_OK) {
6514d9fdb4Robert Mustacchi        return (DW_DLV_BADADDR);
6524d9fdb4Robert Mustacchi    }
6534d9fdb4Robert Mustacchi    return (Dwarf_Addr)(uintptr_t)addr;
6544d9fdb4Robert Mustacchi}
6554d9fdb4Robert Mustacchi
6564d9fdb4Robert Mustacchi
6574d9fdb4Robert Mustacchiint
6584d9fdb4Robert Mustacchidwarf_expr_into_block_a(Dwarf_P_Expr expr,
6594d9fdb4Robert Mustacchi    Dwarf_Unsigned * length,
6604d9fdb4Robert Mustacchi    Dwarf_Small    ** address,
6614d9fdb4Robert Mustacchi    Dwarf_Error * error)
66249d3bc9Richard Lowe{
66349d3bc9Richard Lowe    if (expr == NULL) {
66407dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
6654d9fdb4Robert Mustacchi        return DW_DLV_ERROR;
66649d3bc9Richard Lowe    }
66749d3bc9Richard Lowe
66849d3bc9Richard Lowe    if (expr->ex_dbg == NULL) {
66907dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
6704d9fdb4Robert Mustacchi        return DW_DLV_ERROR;
67149d3bc9Richard Lowe    }
67249d3bc9Richard Lowe
67349d3bc9Richard Lowe    if (length != NULL)
67407dc194Richard Lowe        *length = expr->ex_next_byte_offset;
6754d9fdb4Robert Mustacchi    *address = &(expr->ex_byte_stream[0]);
6764d9fdb4Robert Mustacchi    return DW_DLV_OK;
67749d3bc9Richard Lowe}