xref: /titanic_44/usr/src/tools/ctf/dwarf/common/pro_expr.c (revision 07dc1947c362e187fb955d283b692f8769dd5def)
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