149d3bc91SRichard Lowe /*
249d3bc91SRichard Lowe
3*07dc1947SRichard Lowe Copyright (C) 2000,2004,2006 Silicon Graphics, Inc. All Rights Reserved.
4*07dc1947SRichard Lowe Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
549d3bc91SRichard Lowe
649d3bc91SRichard Lowe This program is free software; you can redistribute it and/or modify it
749d3bc91SRichard Lowe under the terms of version 2.1 of the GNU Lesser General Public License
849d3bc91SRichard Lowe as published by the Free Software Foundation.
949d3bc91SRichard Lowe
1049d3bc91SRichard Lowe This program is distributed in the hope that it would be useful, but
1149d3bc91SRichard Lowe WITHOUT ANY WARRANTY; without even the implied warranty of
1249d3bc91SRichard Lowe MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1349d3bc91SRichard Lowe
1449d3bc91SRichard Lowe Further, this software is distributed without any warranty that it is
1549d3bc91SRichard Lowe free of the rightful claim of any third person regarding infringement
1649d3bc91SRichard Lowe or the like. Any license provided herein, whether implied or
1749d3bc91SRichard Lowe otherwise, applies only to this software file. Patent licenses, if
1849d3bc91SRichard Lowe any, provided herein do not apply to combinations of this program with
1949d3bc91SRichard Lowe other software, or any other product whatsoever.
2049d3bc91SRichard Lowe
2149d3bc91SRichard Lowe You should have received a copy of the GNU Lesser General Public
2249d3bc91SRichard Lowe License along with this program; if not, write the Free Software
23*07dc1947SRichard Lowe Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2449d3bc91SRichard Lowe USA.
2549d3bc91SRichard Lowe
26*07dc1947SRichard Lowe Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
2749d3bc91SRichard Lowe Mountain View, CA 94043, or:
2849d3bc91SRichard Lowe
2949d3bc91SRichard Lowe http://www.sgi.com
3049d3bc91SRichard Lowe
3149d3bc91SRichard Lowe For further information regarding this notice, see:
3249d3bc91SRichard Lowe
3349d3bc91SRichard Lowe http://oss.sgi.com/projects/GenInfo/NoticeExplan
3449d3bc91SRichard Lowe
3549d3bc91SRichard Lowe */
3649d3bc91SRichard Lowe
3749d3bc91SRichard Lowe
3849d3bc91SRichard Lowe
3949d3bc91SRichard Lowe #include "config.h"
4049d3bc91SRichard Lowe #include "libdwarfdefs.h"
4149d3bc91SRichard Lowe #include <stdio.h>
4249d3bc91SRichard Lowe #include <string.h>
4349d3bc91SRichard Lowe #include <sys/types.h>
4449d3bc91SRichard Lowe #include "pro_incl.h"
4549d3bc91SRichard Lowe #include "pro_expr.h"
4649d3bc91SRichard Lowe
4749d3bc91SRichard Lowe /*
4849d3bc91SRichard Lowe This function creates a new expression
4949d3bc91SRichard Lowe struct that can be used to build up a
5049d3bc91SRichard Lowe location expression.
5149d3bc91SRichard Lowe */
5249d3bc91SRichard Lowe Dwarf_P_Expr
dwarf_new_expr(Dwarf_P_Debug dbg,Dwarf_Error * error)5349d3bc91SRichard Lowe dwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error * error)
5449d3bc91SRichard Lowe {
5549d3bc91SRichard Lowe Dwarf_P_Expr ret_expr;
5649d3bc91SRichard Lowe
5749d3bc91SRichard Lowe if (dbg == NULL) {
5849d3bc91SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
5949d3bc91SRichard Lowe return (NULL);
6049d3bc91SRichard Lowe }
6149d3bc91SRichard Lowe
6249d3bc91SRichard Lowe ret_expr = (Dwarf_P_Expr)
6349d3bc91SRichard Lowe _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Expr_s));
6449d3bc91SRichard Lowe if (ret_expr == NULL) {
6549d3bc91SRichard Lowe _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
6649d3bc91SRichard Lowe return (NULL);
6749d3bc91SRichard Lowe }
6849d3bc91SRichard Lowe
6949d3bc91SRichard Lowe ret_expr->ex_dbg = dbg;
7049d3bc91SRichard Lowe
7149d3bc91SRichard Lowe return (ret_expr);
7249d3bc91SRichard Lowe }
7349d3bc91SRichard Lowe
7449d3bc91SRichard Lowe
7549d3bc91SRichard Lowe Dwarf_Unsigned
dwarf_add_expr_gen(Dwarf_P_Expr expr,Dwarf_Small opcode,Dwarf_Unsigned val1,Dwarf_Unsigned val2,Dwarf_Error * error)7649d3bc91SRichard Lowe dwarf_add_expr_gen(Dwarf_P_Expr expr,
7749d3bc91SRichard Lowe Dwarf_Small opcode,
7849d3bc91SRichard Lowe Dwarf_Unsigned val1,
7949d3bc91SRichard Lowe Dwarf_Unsigned val2, Dwarf_Error * error)
8049d3bc91SRichard Lowe {
8149d3bc91SRichard Lowe char encode_buffer[2 * ENCODE_SPACE_NEEDED]; /* 2* since
8249d3bc91SRichard Lowe used to
8349d3bc91SRichard Lowe concatenate
8449d3bc91SRichard Lowe 2 leb's
8549d3bc91SRichard Lowe below */
8649d3bc91SRichard Lowe char encode_buffer2[ENCODE_SPACE_NEEDED];
8749d3bc91SRichard Lowe int res;
8849d3bc91SRichard Lowe Dwarf_P_Debug dbg = expr->ex_dbg;
8949d3bc91SRichard Lowe
9049d3bc91SRichard Lowe /*
9149d3bc91SRichard Lowe Give the buffer where the operands are first going to be
9249d3bc91SRichard Lowe assembled the largest alignment. */
9349d3bc91SRichard Lowe Dwarf_Unsigned operand_buffer[10];
9449d3bc91SRichard Lowe
9549d3bc91SRichard Lowe /*
9649d3bc91SRichard Lowe Size of the byte stream buffer that needs to be memcpy-ed. */
9749d3bc91SRichard Lowe int operand_size;
9849d3bc91SRichard Lowe
9949d3bc91SRichard Lowe /*
10049d3bc91SRichard Lowe Points to the byte stream for the first operand, and finally to
10149d3bc91SRichard Lowe the buffer that is memcp-ed into the Dwarf_P_Expr_s struct. */
10249d3bc91SRichard Lowe Dwarf_Small *operand;
10349d3bc91SRichard Lowe
10449d3bc91SRichard Lowe /* Size of the byte stream for second operand. */
10549d3bc91SRichard Lowe int operand2_size;
10649d3bc91SRichard Lowe
10749d3bc91SRichard Lowe /* Points to next byte to be written in Dwarf_P_Expr_s struct. */
10849d3bc91SRichard Lowe Dwarf_Small *next_byte_ptr;
10949d3bc91SRichard Lowe
11049d3bc91SRichard Lowe /* Offset past the last byte written into Dwarf_P_Expr_s. */
11149d3bc91SRichard Lowe int next_byte_offset;
11249d3bc91SRichard Lowe
11349d3bc91SRichard Lowe /* ***** BEGIN CODE ***** */
11449d3bc91SRichard Lowe
11549d3bc91SRichard Lowe if (expr == NULL) {
11649d3bc91SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
11749d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
11849d3bc91SRichard Lowe }
11949d3bc91SRichard Lowe
12049d3bc91SRichard Lowe if (expr->ex_dbg == NULL) {
12149d3bc91SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
12249d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
12349d3bc91SRichard Lowe }
12449d3bc91SRichard Lowe
12549d3bc91SRichard Lowe operand = NULL;
12649d3bc91SRichard Lowe operand_size = 0;
12749d3bc91SRichard Lowe
12849d3bc91SRichard Lowe switch (opcode) {
12949d3bc91SRichard Lowe case DW_OP_reg0:
13049d3bc91SRichard Lowe case DW_OP_reg1:
13149d3bc91SRichard Lowe case DW_OP_reg2:
13249d3bc91SRichard Lowe case DW_OP_reg3:
13349d3bc91SRichard Lowe case DW_OP_reg4:
13449d3bc91SRichard Lowe case DW_OP_reg5:
13549d3bc91SRichard Lowe case DW_OP_reg6:
13649d3bc91SRichard Lowe case DW_OP_reg7:
13749d3bc91SRichard Lowe case DW_OP_reg8:
13849d3bc91SRichard Lowe case DW_OP_reg9:
13949d3bc91SRichard Lowe case DW_OP_reg10:
14049d3bc91SRichard Lowe case DW_OP_reg11:
14149d3bc91SRichard Lowe case DW_OP_reg12:
14249d3bc91SRichard Lowe case DW_OP_reg13:
14349d3bc91SRichard Lowe case DW_OP_reg14:
14449d3bc91SRichard Lowe case DW_OP_reg15:
14549d3bc91SRichard Lowe case DW_OP_reg16:
14649d3bc91SRichard Lowe case DW_OP_reg17:
14749d3bc91SRichard Lowe case DW_OP_reg18:
14849d3bc91SRichard Lowe case DW_OP_reg19:
14949d3bc91SRichard Lowe case DW_OP_reg20:
15049d3bc91SRichard Lowe case DW_OP_reg21:
15149d3bc91SRichard Lowe case DW_OP_reg22:
15249d3bc91SRichard Lowe case DW_OP_reg23:
15349d3bc91SRichard Lowe case DW_OP_reg24:
15449d3bc91SRichard Lowe case DW_OP_reg25:
15549d3bc91SRichard Lowe case DW_OP_reg26:
15649d3bc91SRichard Lowe case DW_OP_reg27:
15749d3bc91SRichard Lowe case DW_OP_reg28:
15849d3bc91SRichard Lowe case DW_OP_reg29:
15949d3bc91SRichard Lowe case DW_OP_reg30:
16049d3bc91SRichard Lowe case DW_OP_reg31:
16149d3bc91SRichard Lowe break;
16249d3bc91SRichard Lowe
16349d3bc91SRichard Lowe case DW_OP_breg0:
16449d3bc91SRichard Lowe case DW_OP_breg1:
16549d3bc91SRichard Lowe case DW_OP_breg2:
16649d3bc91SRichard Lowe case DW_OP_breg3:
16749d3bc91SRichard Lowe case DW_OP_breg4:
16849d3bc91SRichard Lowe case DW_OP_breg5:
16949d3bc91SRichard Lowe case DW_OP_breg6:
17049d3bc91SRichard Lowe case DW_OP_breg7:
17149d3bc91SRichard Lowe case DW_OP_breg8:
17249d3bc91SRichard Lowe case DW_OP_breg9:
17349d3bc91SRichard Lowe case DW_OP_breg10:
17449d3bc91SRichard Lowe case DW_OP_breg11:
17549d3bc91SRichard Lowe case DW_OP_breg12:
17649d3bc91SRichard Lowe case DW_OP_breg13:
17749d3bc91SRichard Lowe case DW_OP_breg14:
17849d3bc91SRichard Lowe case DW_OP_breg15:
17949d3bc91SRichard Lowe case DW_OP_breg16:
18049d3bc91SRichard Lowe case DW_OP_breg17:
18149d3bc91SRichard Lowe case DW_OP_breg18:
18249d3bc91SRichard Lowe case DW_OP_breg19:
18349d3bc91SRichard Lowe case DW_OP_breg20:
18449d3bc91SRichard Lowe case DW_OP_breg21:
18549d3bc91SRichard Lowe case DW_OP_breg22:
18649d3bc91SRichard Lowe case DW_OP_breg23:
18749d3bc91SRichard Lowe case DW_OP_breg24:
18849d3bc91SRichard Lowe case DW_OP_breg25:
18949d3bc91SRichard Lowe case DW_OP_breg26:
19049d3bc91SRichard Lowe case DW_OP_breg27:
19149d3bc91SRichard Lowe case DW_OP_breg28:
19249d3bc91SRichard Lowe case DW_OP_breg29:
19349d3bc91SRichard Lowe case DW_OP_breg30:
19449d3bc91SRichard Lowe case DW_OP_breg31:
19549d3bc91SRichard Lowe res = _dwarf_pro_encode_signed_leb128_nm(val1,
19649d3bc91SRichard Lowe &operand_size,
19749d3bc91SRichard Lowe encode_buffer,
19849d3bc91SRichard Lowe sizeof(encode_buffer));
19949d3bc91SRichard Lowe if (res != DW_DLV_OK) {
20049d3bc91SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
20149d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
20249d3bc91SRichard Lowe }
20349d3bc91SRichard Lowe operand = (Dwarf_Small *) encode_buffer;
20449d3bc91SRichard Lowe break;
20549d3bc91SRichard Lowe
20649d3bc91SRichard Lowe case DW_OP_regx:
20749d3bc91SRichard Lowe res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
20849d3bc91SRichard Lowe encode_buffer,
20949d3bc91SRichard Lowe sizeof(encode_buffer));
21049d3bc91SRichard Lowe if (res != DW_DLV_OK) {
21149d3bc91SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
21249d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
21349d3bc91SRichard Lowe }
21449d3bc91SRichard Lowe operand = (Dwarf_Small *) encode_buffer;
21549d3bc91SRichard Lowe break;
21649d3bc91SRichard Lowe
21749d3bc91SRichard Lowe case DW_OP_lit0:
21849d3bc91SRichard Lowe case DW_OP_lit1:
21949d3bc91SRichard Lowe case DW_OP_lit2:
22049d3bc91SRichard Lowe case DW_OP_lit3:
22149d3bc91SRichard Lowe case DW_OP_lit4:
22249d3bc91SRichard Lowe case DW_OP_lit5:
22349d3bc91SRichard Lowe case DW_OP_lit6:
22449d3bc91SRichard Lowe case DW_OP_lit7:
22549d3bc91SRichard Lowe case DW_OP_lit8:
22649d3bc91SRichard Lowe case DW_OP_lit9:
22749d3bc91SRichard Lowe case DW_OP_lit10:
22849d3bc91SRichard Lowe case DW_OP_lit11:
22949d3bc91SRichard Lowe case DW_OP_lit12:
23049d3bc91SRichard Lowe case DW_OP_lit13:
23149d3bc91SRichard Lowe case DW_OP_lit14:
23249d3bc91SRichard Lowe case DW_OP_lit15:
23349d3bc91SRichard Lowe case DW_OP_lit16:
23449d3bc91SRichard Lowe case DW_OP_lit17:
23549d3bc91SRichard Lowe case DW_OP_lit18:
23649d3bc91SRichard Lowe case DW_OP_lit19:
23749d3bc91SRichard Lowe case DW_OP_lit20:
23849d3bc91SRichard Lowe case DW_OP_lit21:
23949d3bc91SRichard Lowe case DW_OP_lit22:
24049d3bc91SRichard Lowe case DW_OP_lit23:
24149d3bc91SRichard Lowe case DW_OP_lit24:
24249d3bc91SRichard Lowe case DW_OP_lit25:
24349d3bc91SRichard Lowe case DW_OP_lit26:
24449d3bc91SRichard Lowe case DW_OP_lit27:
24549d3bc91SRichard Lowe case DW_OP_lit28:
24649d3bc91SRichard Lowe case DW_OP_lit29:
24749d3bc91SRichard Lowe case DW_OP_lit30:
24849d3bc91SRichard Lowe case DW_OP_lit31:
24949d3bc91SRichard Lowe break;
25049d3bc91SRichard Lowe
25149d3bc91SRichard Lowe case DW_OP_addr:
25249d3bc91SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
25349d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
25449d3bc91SRichard Lowe
25549d3bc91SRichard Lowe case DW_OP_const1u:
25649d3bc91SRichard Lowe case DW_OP_const1s:
25749d3bc91SRichard Lowe operand = (Dwarf_Small *) & operand_buffer[0];
25849d3bc91SRichard Lowe WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 1);
25949d3bc91SRichard Lowe operand_size = 1;
26049d3bc91SRichard Lowe break;
26149d3bc91SRichard Lowe
26249d3bc91SRichard Lowe case DW_OP_const2u:
26349d3bc91SRichard Lowe case DW_OP_const2s:
26449d3bc91SRichard Lowe operand = (Dwarf_Small *) & operand_buffer[0];
26549d3bc91SRichard Lowe WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2);
26649d3bc91SRichard Lowe operand_size = 2;
26749d3bc91SRichard Lowe break;
26849d3bc91SRichard Lowe
26949d3bc91SRichard Lowe case DW_OP_const4u:
27049d3bc91SRichard Lowe case DW_OP_const4s:
27149d3bc91SRichard Lowe operand = (Dwarf_Small *) & operand_buffer[0];
27249d3bc91SRichard Lowe WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 4);
27349d3bc91SRichard Lowe operand_size = 4;
27449d3bc91SRichard Lowe break;
27549d3bc91SRichard Lowe
27649d3bc91SRichard Lowe case DW_OP_const8u:
27749d3bc91SRichard Lowe case DW_OP_const8s:
27849d3bc91SRichard Lowe operand = (Dwarf_Small *) & operand_buffer[0];
27949d3bc91SRichard Lowe WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 8);
28049d3bc91SRichard Lowe operand_size = 8;
28149d3bc91SRichard Lowe break;
28249d3bc91SRichard Lowe
28349d3bc91SRichard Lowe case DW_OP_constu:
28449d3bc91SRichard Lowe res = _dwarf_pro_encode_leb128_nm(val1,
28549d3bc91SRichard Lowe &operand_size,
28649d3bc91SRichard Lowe encode_buffer,
28749d3bc91SRichard Lowe sizeof(encode_buffer));
28849d3bc91SRichard Lowe if (res != DW_DLV_OK) {
28949d3bc91SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
29049d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
29149d3bc91SRichard Lowe }
29249d3bc91SRichard Lowe operand = (Dwarf_Small *) encode_buffer;
29349d3bc91SRichard Lowe break;
29449d3bc91SRichard Lowe
29549d3bc91SRichard Lowe case DW_OP_consts:
29649d3bc91SRichard Lowe res = _dwarf_pro_encode_signed_leb128_nm(val1,
29749d3bc91SRichard Lowe &operand_size,
29849d3bc91SRichard Lowe encode_buffer,
29949d3bc91SRichard Lowe sizeof(encode_buffer));
30049d3bc91SRichard Lowe if (res != DW_DLV_OK) {
30149d3bc91SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
30249d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
30349d3bc91SRichard Lowe }
30449d3bc91SRichard Lowe operand = (Dwarf_Small *) encode_buffer;
30549d3bc91SRichard Lowe break;
30649d3bc91SRichard Lowe
30749d3bc91SRichard Lowe case DW_OP_fbreg:
30849d3bc91SRichard Lowe res = _dwarf_pro_encode_signed_leb128_nm(val1,
30949d3bc91SRichard Lowe &operand_size,
31049d3bc91SRichard Lowe encode_buffer,
31149d3bc91SRichard Lowe sizeof(encode_buffer));
31249d3bc91SRichard Lowe if (res != DW_DLV_OK) {
31349d3bc91SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
31449d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
31549d3bc91SRichard Lowe }
31649d3bc91SRichard Lowe operand = (Dwarf_Small *) encode_buffer;
31749d3bc91SRichard Lowe break;
31849d3bc91SRichard Lowe
31949d3bc91SRichard Lowe case DW_OP_bregx:
32049d3bc91SRichard Lowe res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
32149d3bc91SRichard Lowe encode_buffer,
32249d3bc91SRichard Lowe sizeof(encode_buffer));
32349d3bc91SRichard Lowe if (res != DW_DLV_OK) {
32449d3bc91SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
32549d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
32649d3bc91SRichard Lowe }
32749d3bc91SRichard Lowe operand = (Dwarf_Small *) encode_buffer;
32849d3bc91SRichard Lowe /* put this one directly into 'operand' at tail of prev value */
32949d3bc91SRichard Lowe res = _dwarf_pro_encode_signed_leb128_nm(val2, &operand2_size,
33049d3bc91SRichard Lowe ((char *) operand) +
33149d3bc91SRichard Lowe operand_size,
33249d3bc91SRichard Lowe sizeof
33349d3bc91SRichard Lowe (encode_buffer2));
33449d3bc91SRichard Lowe if (res != DW_DLV_OK) {
33549d3bc91SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
33649d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
33749d3bc91SRichard Lowe }
33849d3bc91SRichard Lowe operand_size += operand2_size;
33949d3bc91SRichard Lowe
34049d3bc91SRichard Lowe case DW_OP_dup:
34149d3bc91SRichard Lowe case DW_OP_drop:
34249d3bc91SRichard Lowe break;
34349d3bc91SRichard Lowe
34449d3bc91SRichard Lowe case DW_OP_pick:
34549d3bc91SRichard Lowe operand = (Dwarf_Small *) & operand_buffer[0];
346*07dc1947SRichard Lowe WRITE_UNALIGNED(dbg, operand, (const void *) &val1,
34749d3bc91SRichard Lowe sizeof(val1), 1);
34849d3bc91SRichard Lowe operand_size = 1;
34949d3bc91SRichard Lowe break;
35049d3bc91SRichard Lowe
35149d3bc91SRichard Lowe case DW_OP_over:
35249d3bc91SRichard Lowe case DW_OP_swap:
35349d3bc91SRichard Lowe case DW_OP_rot:
35449d3bc91SRichard Lowe case DW_OP_deref:
35549d3bc91SRichard Lowe case DW_OP_xderef:
35649d3bc91SRichard Lowe break;
35749d3bc91SRichard Lowe
35849d3bc91SRichard Lowe case DW_OP_deref_size:
35949d3bc91SRichard Lowe case DW_OP_xderef_size:
36049d3bc91SRichard Lowe operand = (Dwarf_Small *) & operand_buffer[0];
361*07dc1947SRichard Lowe WRITE_UNALIGNED(dbg, operand, (const void *) &val1,
36249d3bc91SRichard Lowe sizeof(val1), 1);
36349d3bc91SRichard Lowe operand_size = 1;
36449d3bc91SRichard Lowe break;
36549d3bc91SRichard Lowe
36649d3bc91SRichard Lowe case DW_OP_abs:
36749d3bc91SRichard Lowe case DW_OP_and:
36849d3bc91SRichard Lowe case DW_OP_div:
36949d3bc91SRichard Lowe case DW_OP_minus:
37049d3bc91SRichard Lowe case DW_OP_mod:
37149d3bc91SRichard Lowe case DW_OP_mul:
37249d3bc91SRichard Lowe case DW_OP_neg:
37349d3bc91SRichard Lowe case DW_OP_not:
37449d3bc91SRichard Lowe case DW_OP_or:
37549d3bc91SRichard Lowe case DW_OP_plus:
37649d3bc91SRichard Lowe break;
37749d3bc91SRichard Lowe
37849d3bc91SRichard Lowe case DW_OP_plus_uconst:
37949d3bc91SRichard Lowe res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
38049d3bc91SRichard Lowe encode_buffer,
38149d3bc91SRichard Lowe sizeof(encode_buffer));
38249d3bc91SRichard Lowe if (res != DW_DLV_OK) {
38349d3bc91SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
38449d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
38549d3bc91SRichard Lowe }
38649d3bc91SRichard Lowe operand = (Dwarf_Small *) encode_buffer;
38749d3bc91SRichard Lowe break;
38849d3bc91SRichard Lowe
38949d3bc91SRichard Lowe case DW_OP_shl:
39049d3bc91SRichard Lowe case DW_OP_shr:
39149d3bc91SRichard Lowe case DW_OP_shra:
39249d3bc91SRichard Lowe case DW_OP_xor:
39349d3bc91SRichard Lowe break;
39449d3bc91SRichard Lowe
39549d3bc91SRichard Lowe case DW_OP_le:
39649d3bc91SRichard Lowe case DW_OP_ge:
39749d3bc91SRichard Lowe case DW_OP_eq:
39849d3bc91SRichard Lowe case DW_OP_lt:
39949d3bc91SRichard Lowe case DW_OP_gt:
40049d3bc91SRichard Lowe case DW_OP_ne:
40149d3bc91SRichard Lowe break;
40249d3bc91SRichard Lowe
40349d3bc91SRichard Lowe case DW_OP_skip:
40449d3bc91SRichard Lowe case DW_OP_bra:
40549d3bc91SRichard Lowe /* FIX: unhandled! OP_bra, OP_skip! */
40649d3bc91SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
40749d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
40849d3bc91SRichard Lowe
40949d3bc91SRichard Lowe case DW_OP_piece:
41049d3bc91SRichard Lowe res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
41149d3bc91SRichard Lowe encode_buffer,
41249d3bc91SRichard Lowe sizeof(encode_buffer));
41349d3bc91SRichard Lowe if (res != DW_DLV_OK) {
41449d3bc91SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
41549d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
41649d3bc91SRichard Lowe }
41749d3bc91SRichard Lowe operand = (Dwarf_Small *) encode_buffer;
41849d3bc91SRichard Lowe break;
41949d3bc91SRichard Lowe
42049d3bc91SRichard Lowe case DW_OP_nop:
42149d3bc91SRichard Lowe break;
422*07dc1947SRichard Lowe case DW_OP_push_object_address: /* DWARF3 */
423*07dc1947SRichard Lowe break;
424*07dc1947SRichard Lowe case DW_OP_call2: /* DWARF3 */
425*07dc1947SRichard Lowe operand = (Dwarf_Small *) & operand_buffer[0];
426*07dc1947SRichard Lowe WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2);
427*07dc1947SRichard Lowe operand_size = 2;
428*07dc1947SRichard Lowe break;
429*07dc1947SRichard Lowe
430*07dc1947SRichard Lowe case DW_OP_call4: /* DWARF3 */
431*07dc1947SRichard Lowe operand = (Dwarf_Small *) & operand_buffer[0];
432*07dc1947SRichard Lowe WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 4);
433*07dc1947SRichard Lowe operand_size = 4;
434*07dc1947SRichard Lowe break;
435*07dc1947SRichard Lowe
436*07dc1947SRichard Lowe case DW_OP_call_ref: /* DWARF3 */
437*07dc1947SRichard Lowe operand = (Dwarf_Small *) & operand_buffer[0];
438*07dc1947SRichard Lowe WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1),
439*07dc1947SRichard Lowe dbg->de_offset_size);
440*07dc1947SRichard Lowe operand_size = dbg->de_offset_size;
441*07dc1947SRichard Lowe break;
442*07dc1947SRichard Lowe case DW_OP_form_tls_address: /* DWARF3f */
443*07dc1947SRichard Lowe break;
444*07dc1947SRichard Lowe case DW_OP_call_frame_cfa: /* DWARF3f */
445*07dc1947SRichard Lowe break;
446*07dc1947SRichard Lowe case DW_OP_bit_piece: /* DWARF3f */
447*07dc1947SRichard Lowe res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
448*07dc1947SRichard Lowe encode_buffer,
449*07dc1947SRichard Lowe sizeof(encode_buffer));
450*07dc1947SRichard Lowe if (res != DW_DLV_OK) {
451*07dc1947SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
452*07dc1947SRichard Lowe return (DW_DLV_NOCOUNT);
453*07dc1947SRichard Lowe }
454*07dc1947SRichard Lowe operand = (Dwarf_Small *) encode_buffer;
455*07dc1947SRichard Lowe /* put this one directly into 'operand' at tail of prev value */
456*07dc1947SRichard Lowe res = _dwarf_pro_encode_leb128_nm(val2, &operand2_size,
457*07dc1947SRichard Lowe ((char *) operand) +
458*07dc1947SRichard Lowe operand_size,
459*07dc1947SRichard Lowe sizeof(encode_buffer2));
460*07dc1947SRichard Lowe if (res != DW_DLV_OK) {
461*07dc1947SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
462*07dc1947SRichard Lowe return (DW_DLV_NOCOUNT);
463*07dc1947SRichard Lowe }
464*07dc1947SRichard Lowe operand_size += operand2_size;
465*07dc1947SRichard Lowe
46649d3bc91SRichard Lowe
46749d3bc91SRichard Lowe default:
46849d3bc91SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
46949d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
47049d3bc91SRichard Lowe }
47149d3bc91SRichard Lowe
47249d3bc91SRichard Lowe next_byte_offset = expr->ex_next_byte_offset + operand_size + 1;
47349d3bc91SRichard Lowe
47449d3bc91SRichard Lowe if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) {
47549d3bc91SRichard Lowe _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
47649d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
47749d3bc91SRichard Lowe }
47849d3bc91SRichard Lowe
47949d3bc91SRichard Lowe next_byte_ptr =
48049d3bc91SRichard Lowe &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset;
48149d3bc91SRichard Lowe
48249d3bc91SRichard Lowe *next_byte_ptr = opcode;
48349d3bc91SRichard Lowe next_byte_ptr++;
48449d3bc91SRichard Lowe memcpy(next_byte_ptr, operand, operand_size);
48549d3bc91SRichard Lowe
48649d3bc91SRichard Lowe expr->ex_next_byte_offset = next_byte_offset;
48749d3bc91SRichard Lowe return (next_byte_offset);
48849d3bc91SRichard Lowe }
48949d3bc91SRichard Lowe
49049d3bc91SRichard Lowe Dwarf_Unsigned
dwarf_add_expr_addr_b(Dwarf_P_Expr expr,Dwarf_Unsigned addr,Dwarf_Unsigned sym_index,Dwarf_Error * error)49149d3bc91SRichard Lowe dwarf_add_expr_addr_b(Dwarf_P_Expr expr,
49249d3bc91SRichard Lowe Dwarf_Unsigned addr,
49349d3bc91SRichard Lowe Dwarf_Unsigned sym_index, Dwarf_Error * error)
49449d3bc91SRichard Lowe {
49549d3bc91SRichard Lowe Dwarf_P_Debug dbg;
49649d3bc91SRichard Lowe Dwarf_Small *next_byte_ptr;
49749d3bc91SRichard Lowe Dwarf_Unsigned next_byte_offset;
49849d3bc91SRichard Lowe int upointer_size;
49949d3bc91SRichard Lowe
50049d3bc91SRichard Lowe if (expr == NULL) {
50149d3bc91SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
50249d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
50349d3bc91SRichard Lowe }
50449d3bc91SRichard Lowe
50549d3bc91SRichard Lowe dbg = expr->ex_dbg;
50649d3bc91SRichard Lowe if (dbg == NULL) {
50749d3bc91SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
50849d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
50949d3bc91SRichard Lowe }
51049d3bc91SRichard Lowe
51149d3bc91SRichard Lowe upointer_size = dbg->de_pointer_size;
51249d3bc91SRichard Lowe next_byte_offset = expr->ex_next_byte_offset + upointer_size + 1;
51349d3bc91SRichard Lowe if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) {
51449d3bc91SRichard Lowe _dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD);
51549d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
51649d3bc91SRichard Lowe }
51749d3bc91SRichard Lowe
51849d3bc91SRichard Lowe next_byte_ptr =
51949d3bc91SRichard Lowe &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset;
52049d3bc91SRichard Lowe
52149d3bc91SRichard Lowe *next_byte_ptr = DW_OP_addr;
52249d3bc91SRichard Lowe next_byte_ptr++;
52349d3bc91SRichard Lowe WRITE_UNALIGNED(dbg, next_byte_ptr, (const void *) &addr,
52449d3bc91SRichard Lowe sizeof(addr), upointer_size);
52549d3bc91SRichard Lowe
52649d3bc91SRichard Lowe if (expr->ex_reloc_offset != 0) {
52749d3bc91SRichard Lowe _dwarf_p_error(dbg, error, DW_DLE_MULTIPLE_RELOC_IN_EXPR);
52849d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
52949d3bc91SRichard Lowe }
53049d3bc91SRichard Lowe
53149d3bc91SRichard Lowe expr->ex_reloc_sym_index = sym_index;
53249d3bc91SRichard Lowe expr->ex_reloc_offset = expr->ex_next_byte_offset + 1;
53349d3bc91SRichard Lowe
53449d3bc91SRichard Lowe expr->ex_next_byte_offset = next_byte_offset;
53549d3bc91SRichard Lowe return (next_byte_offset);
53649d3bc91SRichard Lowe }
53749d3bc91SRichard Lowe
53849d3bc91SRichard Lowe Dwarf_Unsigned
dwarf_add_expr_addr(Dwarf_P_Expr expr,Dwarf_Unsigned addr,Dwarf_Signed sym_index,Dwarf_Error * error)53949d3bc91SRichard Lowe dwarf_add_expr_addr(Dwarf_P_Expr expr,
54049d3bc91SRichard Lowe Dwarf_Unsigned addr,
54149d3bc91SRichard Lowe Dwarf_Signed sym_index, Dwarf_Error * error)
54249d3bc91SRichard Lowe {
54349d3bc91SRichard Lowe return
54449d3bc91SRichard Lowe dwarf_add_expr_addr_b(expr, addr, (Dwarf_Unsigned) sym_index,
54549d3bc91SRichard Lowe error);
54649d3bc91SRichard Lowe }
54749d3bc91SRichard Lowe
54849d3bc91SRichard Lowe
54949d3bc91SRichard Lowe Dwarf_Unsigned
dwarf_expr_current_offset(Dwarf_P_Expr expr,Dwarf_Error * error)55049d3bc91SRichard Lowe dwarf_expr_current_offset(Dwarf_P_Expr expr, Dwarf_Error * error)
55149d3bc91SRichard Lowe {
55249d3bc91SRichard Lowe if (expr == NULL) {
55349d3bc91SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
55449d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
55549d3bc91SRichard Lowe }
55649d3bc91SRichard Lowe
55749d3bc91SRichard Lowe if (expr->ex_dbg == NULL) {
55849d3bc91SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
55949d3bc91SRichard Lowe return (DW_DLV_NOCOUNT);
56049d3bc91SRichard Lowe }
56149d3bc91SRichard Lowe
56249d3bc91SRichard Lowe return (expr->ex_next_byte_offset);
56349d3bc91SRichard Lowe }
56449d3bc91SRichard Lowe
565*07dc1947SRichard Lowe void
dwarf_expr_reset(Dwarf_P_Expr expr,Dwarf_Error * error)566*07dc1947SRichard Lowe dwarf_expr_reset(Dwarf_P_Expr expr, Dwarf_Error * error)
567*07dc1947SRichard Lowe {
568*07dc1947SRichard Lowe if (expr == NULL) {
569*07dc1947SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
570*07dc1947SRichard Lowe return;
571*07dc1947SRichard Lowe }
572*07dc1947SRichard Lowe expr->ex_next_byte_offset=0;
573*07dc1947SRichard Lowe }
574*07dc1947SRichard Lowe
57549d3bc91SRichard Lowe
57649d3bc91SRichard Lowe Dwarf_Addr
dwarf_expr_into_block(Dwarf_P_Expr expr,Dwarf_Unsigned * length,Dwarf_Error * error)57749d3bc91SRichard Lowe dwarf_expr_into_block(Dwarf_P_Expr expr,
57849d3bc91SRichard Lowe Dwarf_Unsigned * length, Dwarf_Error * error)
57949d3bc91SRichard Lowe {
58049d3bc91SRichard Lowe if (expr == NULL) {
58149d3bc91SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
58249d3bc91SRichard Lowe return (DW_DLV_BADADDR);
58349d3bc91SRichard Lowe }
58449d3bc91SRichard Lowe
58549d3bc91SRichard Lowe if (expr->ex_dbg == NULL) {
58649d3bc91SRichard Lowe _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
58749d3bc91SRichard Lowe return (DW_DLV_BADADDR);
58849d3bc91SRichard Lowe }
58949d3bc91SRichard Lowe
59049d3bc91SRichard Lowe if (length != NULL)
59149d3bc91SRichard Lowe *length = expr->ex_next_byte_offset;
59249d3bc91SRichard Lowe /* The following cast from pointer to integer is ok as long as
59349d3bc91SRichard Lowe Dwarf_Addr is at least as large as a pointer. Which is a
59449d3bc91SRichard Lowe requirement of libdwarf so must be satisfied (some compilers
59549d3bc91SRichard Lowe emit a warning about the following line). */
59649d3bc91SRichard Lowe return ((Dwarf_Addr)(uintptr_t) &(expr->ex_byte_stream[0]));
59749d3bc91SRichard Lowe }
598