xref: /titanic_52/usr/src/lib/libdwarf/common/pro_expr.c (revision 7fd791373689a6af05e27efec3b1ab556e02aa23)
1*7fd79137SRobert Mustacchi /*
2*7fd79137SRobert Mustacchi 
3*7fd79137SRobert Mustacchi   Copyright (C) 2000,2004,2006 Silicon Graphics, Inc.  All Rights Reserved.
4*7fd79137SRobert Mustacchi   Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
5*7fd79137SRobert Mustacchi 
6*7fd79137SRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
7*7fd79137SRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
8*7fd79137SRobert Mustacchi   as published by the Free Software Foundation.
9*7fd79137SRobert Mustacchi 
10*7fd79137SRobert Mustacchi   This program is distributed in the hope that it would be useful, but
11*7fd79137SRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
12*7fd79137SRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13*7fd79137SRobert Mustacchi 
14*7fd79137SRobert Mustacchi   Further, this software is distributed without any warranty that it is
15*7fd79137SRobert Mustacchi   free of the rightful claim of any third person regarding infringement
16*7fd79137SRobert Mustacchi   or the like.  Any license provided herein, whether implied or
17*7fd79137SRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
18*7fd79137SRobert Mustacchi   any, provided herein do not apply to combinations of this program with
19*7fd79137SRobert Mustacchi   other software, or any other product whatsoever.
20*7fd79137SRobert Mustacchi 
21*7fd79137SRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
22*7fd79137SRobert Mustacchi   License along with this program; if not, write the Free Software
23*7fd79137SRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24*7fd79137SRobert Mustacchi   USA.
25*7fd79137SRobert Mustacchi 
26*7fd79137SRobert Mustacchi   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
27*7fd79137SRobert Mustacchi   Mountain View, CA 94043, or:
28*7fd79137SRobert Mustacchi 
29*7fd79137SRobert Mustacchi   http://www.sgi.com
30*7fd79137SRobert Mustacchi 
31*7fd79137SRobert Mustacchi   For further information regarding this notice, see:
32*7fd79137SRobert Mustacchi 
33*7fd79137SRobert Mustacchi   http://oss.sgi.com/projects/GenInfo/NoticeExplan
34*7fd79137SRobert Mustacchi 
35*7fd79137SRobert Mustacchi */
36*7fd79137SRobert Mustacchi 
37*7fd79137SRobert Mustacchi 
38*7fd79137SRobert Mustacchi 
39*7fd79137SRobert Mustacchi #include "config.h"
40*7fd79137SRobert Mustacchi #include "libdwarfdefs.h"
41*7fd79137SRobert Mustacchi #include <stdio.h>
42*7fd79137SRobert Mustacchi #include <string.h>
43*7fd79137SRobert Mustacchi #include <sys/types.h>
44*7fd79137SRobert Mustacchi #include "pro_incl.h"
45*7fd79137SRobert Mustacchi #include "pro_expr.h"
46*7fd79137SRobert Mustacchi 
47*7fd79137SRobert Mustacchi /*
48*7fd79137SRobert Mustacchi     This function creates a new expression
49*7fd79137SRobert Mustacchi     struct that can be used to build up a
50*7fd79137SRobert Mustacchi     location expression.
51*7fd79137SRobert Mustacchi */
52*7fd79137SRobert Mustacchi Dwarf_P_Expr
53*7fd79137SRobert Mustacchi dwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error * error)
54*7fd79137SRobert Mustacchi {
55*7fd79137SRobert Mustacchi     Dwarf_P_Expr ret_expr;
56*7fd79137SRobert Mustacchi 
57*7fd79137SRobert Mustacchi     if (dbg == NULL) {
58*7fd79137SRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
59*7fd79137SRobert Mustacchi         return (NULL);
60*7fd79137SRobert Mustacchi     }
61*7fd79137SRobert Mustacchi 
62*7fd79137SRobert Mustacchi     ret_expr = (Dwarf_P_Expr)
63*7fd79137SRobert Mustacchi         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Expr_s));
64*7fd79137SRobert Mustacchi     if (ret_expr == NULL) {
65*7fd79137SRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
66*7fd79137SRobert Mustacchi         return (NULL);
67*7fd79137SRobert Mustacchi     }
68*7fd79137SRobert Mustacchi 
69*7fd79137SRobert Mustacchi     ret_expr->ex_dbg = dbg;
70*7fd79137SRobert Mustacchi 
71*7fd79137SRobert Mustacchi     return (ret_expr);
72*7fd79137SRobert Mustacchi }
73*7fd79137SRobert Mustacchi 
74*7fd79137SRobert Mustacchi 
75*7fd79137SRobert Mustacchi Dwarf_Unsigned
76*7fd79137SRobert Mustacchi dwarf_add_expr_gen(Dwarf_P_Expr expr,
77*7fd79137SRobert Mustacchi                    Dwarf_Small opcode,
78*7fd79137SRobert Mustacchi                    Dwarf_Unsigned val1,
79*7fd79137SRobert Mustacchi                    Dwarf_Unsigned val2, Dwarf_Error * error)
80*7fd79137SRobert Mustacchi {
81*7fd79137SRobert Mustacchi     char encode_buffer[2 * ENCODE_SPACE_NEEDED];        /* 2* since
82*7fd79137SRobert Mustacchi                                                            used to
83*7fd79137SRobert Mustacchi                                                            concatenate
84*7fd79137SRobert Mustacchi                                                            2 leb's
85*7fd79137SRobert Mustacchi                                                            below */
86*7fd79137SRobert Mustacchi     char encode_buffer2[ENCODE_SPACE_NEEDED];
87*7fd79137SRobert Mustacchi     int res;
88*7fd79137SRobert Mustacchi     Dwarf_P_Debug dbg = expr->ex_dbg;
89*7fd79137SRobert Mustacchi 
90*7fd79137SRobert Mustacchi     /*
91*7fd79137SRobert Mustacchi        Give the buffer where the operands are first going to be
92*7fd79137SRobert Mustacchi        assembled the largest alignment. */
93*7fd79137SRobert Mustacchi     Dwarf_Unsigned operand_buffer[10];
94*7fd79137SRobert Mustacchi 
95*7fd79137SRobert Mustacchi     /*
96*7fd79137SRobert Mustacchi        Size of the byte stream buffer that needs to be memcpy-ed. */
97*7fd79137SRobert Mustacchi     int operand_size;
98*7fd79137SRobert Mustacchi 
99*7fd79137SRobert Mustacchi     /*
100*7fd79137SRobert Mustacchi        Points to the byte stream for the first operand, and finally to
101*7fd79137SRobert Mustacchi        the buffer that is memcp-ed into the Dwarf_P_Expr_s struct. */
102*7fd79137SRobert Mustacchi     Dwarf_Small *operand;
103*7fd79137SRobert Mustacchi 
104*7fd79137SRobert Mustacchi     /* Size of the byte stream for second operand. */
105*7fd79137SRobert Mustacchi     int operand2_size;
106*7fd79137SRobert Mustacchi 
107*7fd79137SRobert Mustacchi     /* Points to next byte to be written in Dwarf_P_Expr_s struct. */
108*7fd79137SRobert Mustacchi     Dwarf_Small *next_byte_ptr;
109*7fd79137SRobert Mustacchi 
110*7fd79137SRobert Mustacchi     /* Offset past the last byte written into Dwarf_P_Expr_s. */
111*7fd79137SRobert Mustacchi     int next_byte_offset;
112*7fd79137SRobert Mustacchi 
113*7fd79137SRobert Mustacchi     /* ***** BEGIN CODE ***** */
114*7fd79137SRobert Mustacchi 
115*7fd79137SRobert Mustacchi     if (expr == NULL) {
116*7fd79137SRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
117*7fd79137SRobert Mustacchi         return (DW_DLV_NOCOUNT);
118*7fd79137SRobert Mustacchi     }
119*7fd79137SRobert Mustacchi 
120*7fd79137SRobert Mustacchi     if (expr->ex_dbg == NULL) {
121*7fd79137SRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
122*7fd79137SRobert Mustacchi         return (DW_DLV_NOCOUNT);
123*7fd79137SRobert Mustacchi     }
124*7fd79137SRobert Mustacchi 
125*7fd79137SRobert Mustacchi     operand = NULL;
126*7fd79137SRobert Mustacchi     operand_size = 0;
127*7fd79137SRobert Mustacchi 
128*7fd79137SRobert Mustacchi     switch (opcode) {
129*7fd79137SRobert Mustacchi     case DW_OP_reg0:
130*7fd79137SRobert Mustacchi     case DW_OP_reg1:
131*7fd79137SRobert Mustacchi     case DW_OP_reg2:
132*7fd79137SRobert Mustacchi     case DW_OP_reg3:
133*7fd79137SRobert Mustacchi     case DW_OP_reg4:
134*7fd79137SRobert Mustacchi     case DW_OP_reg5:
135*7fd79137SRobert Mustacchi     case DW_OP_reg6:
136*7fd79137SRobert Mustacchi     case DW_OP_reg7:
137*7fd79137SRobert Mustacchi     case DW_OP_reg8:
138*7fd79137SRobert Mustacchi     case DW_OP_reg9:
139*7fd79137SRobert Mustacchi     case DW_OP_reg10:
140*7fd79137SRobert Mustacchi     case DW_OP_reg11:
141*7fd79137SRobert Mustacchi     case DW_OP_reg12:
142*7fd79137SRobert Mustacchi     case DW_OP_reg13:
143*7fd79137SRobert Mustacchi     case DW_OP_reg14:
144*7fd79137SRobert Mustacchi     case DW_OP_reg15:
145*7fd79137SRobert Mustacchi     case DW_OP_reg16:
146*7fd79137SRobert Mustacchi     case DW_OP_reg17:
147*7fd79137SRobert Mustacchi     case DW_OP_reg18:
148*7fd79137SRobert Mustacchi     case DW_OP_reg19:
149*7fd79137SRobert Mustacchi     case DW_OP_reg20:
150*7fd79137SRobert Mustacchi     case DW_OP_reg21:
151*7fd79137SRobert Mustacchi     case DW_OP_reg22:
152*7fd79137SRobert Mustacchi     case DW_OP_reg23:
153*7fd79137SRobert Mustacchi     case DW_OP_reg24:
154*7fd79137SRobert Mustacchi     case DW_OP_reg25:
155*7fd79137SRobert Mustacchi     case DW_OP_reg26:
156*7fd79137SRobert Mustacchi     case DW_OP_reg27:
157*7fd79137SRobert Mustacchi     case DW_OP_reg28:
158*7fd79137SRobert Mustacchi     case DW_OP_reg29:
159*7fd79137SRobert Mustacchi     case DW_OP_reg30:
160*7fd79137SRobert Mustacchi     case DW_OP_reg31:
161*7fd79137SRobert Mustacchi         break;
162*7fd79137SRobert Mustacchi 
163*7fd79137SRobert Mustacchi     case DW_OP_breg0:
164*7fd79137SRobert Mustacchi     case DW_OP_breg1:
165*7fd79137SRobert Mustacchi     case DW_OP_breg2:
166*7fd79137SRobert Mustacchi     case DW_OP_breg3:
167*7fd79137SRobert Mustacchi     case DW_OP_breg4:
168*7fd79137SRobert Mustacchi     case DW_OP_breg5:
169*7fd79137SRobert Mustacchi     case DW_OP_breg6:
170*7fd79137SRobert Mustacchi     case DW_OP_breg7:
171*7fd79137SRobert Mustacchi     case DW_OP_breg8:
172*7fd79137SRobert Mustacchi     case DW_OP_breg9:
173*7fd79137SRobert Mustacchi     case DW_OP_breg10:
174*7fd79137SRobert Mustacchi     case DW_OP_breg11:
175*7fd79137SRobert Mustacchi     case DW_OP_breg12:
176*7fd79137SRobert Mustacchi     case DW_OP_breg13:
177*7fd79137SRobert Mustacchi     case DW_OP_breg14:
178*7fd79137SRobert Mustacchi     case DW_OP_breg15:
179*7fd79137SRobert Mustacchi     case DW_OP_breg16:
180*7fd79137SRobert Mustacchi     case DW_OP_breg17:
181*7fd79137SRobert Mustacchi     case DW_OP_breg18:
182*7fd79137SRobert Mustacchi     case DW_OP_breg19:
183*7fd79137SRobert Mustacchi     case DW_OP_breg20:
184*7fd79137SRobert Mustacchi     case DW_OP_breg21:
185*7fd79137SRobert Mustacchi     case DW_OP_breg22:
186*7fd79137SRobert Mustacchi     case DW_OP_breg23:
187*7fd79137SRobert Mustacchi     case DW_OP_breg24:
188*7fd79137SRobert Mustacchi     case DW_OP_breg25:
189*7fd79137SRobert Mustacchi     case DW_OP_breg26:
190*7fd79137SRobert Mustacchi     case DW_OP_breg27:
191*7fd79137SRobert Mustacchi     case DW_OP_breg28:
192*7fd79137SRobert Mustacchi     case DW_OP_breg29:
193*7fd79137SRobert Mustacchi     case DW_OP_breg30:
194*7fd79137SRobert Mustacchi     case DW_OP_breg31:
195*7fd79137SRobert Mustacchi         res = _dwarf_pro_encode_signed_leb128_nm(val1,
196*7fd79137SRobert Mustacchi                                                  &operand_size,
197*7fd79137SRobert Mustacchi                                                  encode_buffer,
198*7fd79137SRobert Mustacchi                                                  sizeof(encode_buffer));
199*7fd79137SRobert Mustacchi         if (res != DW_DLV_OK) {
200*7fd79137SRobert Mustacchi             _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
201*7fd79137SRobert Mustacchi             return (DW_DLV_NOCOUNT);
202*7fd79137SRobert Mustacchi         }
203*7fd79137SRobert Mustacchi         operand = (Dwarf_Small *) encode_buffer;
204*7fd79137SRobert Mustacchi         break;
205*7fd79137SRobert Mustacchi 
206*7fd79137SRobert Mustacchi     case DW_OP_regx:
207*7fd79137SRobert Mustacchi         res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
208*7fd79137SRobert Mustacchi                                           encode_buffer,
209*7fd79137SRobert Mustacchi                                           sizeof(encode_buffer));
210*7fd79137SRobert Mustacchi         if (res != DW_DLV_OK) {
211*7fd79137SRobert Mustacchi             _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
212*7fd79137SRobert Mustacchi             return (DW_DLV_NOCOUNT);
213*7fd79137SRobert Mustacchi         }
214*7fd79137SRobert Mustacchi         operand = (Dwarf_Small *) encode_buffer;
215*7fd79137SRobert Mustacchi         break;
216*7fd79137SRobert Mustacchi 
217*7fd79137SRobert Mustacchi     case DW_OP_lit0:
218*7fd79137SRobert Mustacchi     case DW_OP_lit1:
219*7fd79137SRobert Mustacchi     case DW_OP_lit2:
220*7fd79137SRobert Mustacchi     case DW_OP_lit3:
221*7fd79137SRobert Mustacchi     case DW_OP_lit4:
222*7fd79137SRobert Mustacchi     case DW_OP_lit5:
223*7fd79137SRobert Mustacchi     case DW_OP_lit6:
224*7fd79137SRobert Mustacchi     case DW_OP_lit7:
225*7fd79137SRobert Mustacchi     case DW_OP_lit8:
226*7fd79137SRobert Mustacchi     case DW_OP_lit9:
227*7fd79137SRobert Mustacchi     case DW_OP_lit10:
228*7fd79137SRobert Mustacchi     case DW_OP_lit11:
229*7fd79137SRobert Mustacchi     case DW_OP_lit12:
230*7fd79137SRobert Mustacchi     case DW_OP_lit13:
231*7fd79137SRobert Mustacchi     case DW_OP_lit14:
232*7fd79137SRobert Mustacchi     case DW_OP_lit15:
233*7fd79137SRobert Mustacchi     case DW_OP_lit16:
234*7fd79137SRobert Mustacchi     case DW_OP_lit17:
235*7fd79137SRobert Mustacchi     case DW_OP_lit18:
236*7fd79137SRobert Mustacchi     case DW_OP_lit19:
237*7fd79137SRobert Mustacchi     case DW_OP_lit20:
238*7fd79137SRobert Mustacchi     case DW_OP_lit21:
239*7fd79137SRobert Mustacchi     case DW_OP_lit22:
240*7fd79137SRobert Mustacchi     case DW_OP_lit23:
241*7fd79137SRobert Mustacchi     case DW_OP_lit24:
242*7fd79137SRobert Mustacchi     case DW_OP_lit25:
243*7fd79137SRobert Mustacchi     case DW_OP_lit26:
244*7fd79137SRobert Mustacchi     case DW_OP_lit27:
245*7fd79137SRobert Mustacchi     case DW_OP_lit28:
246*7fd79137SRobert Mustacchi     case DW_OP_lit29:
247*7fd79137SRobert Mustacchi     case DW_OP_lit30:
248*7fd79137SRobert Mustacchi     case DW_OP_lit31:
249*7fd79137SRobert Mustacchi         break;
250*7fd79137SRobert Mustacchi 
251*7fd79137SRobert Mustacchi     case DW_OP_addr:
252*7fd79137SRobert Mustacchi         _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
253*7fd79137SRobert Mustacchi         return (DW_DLV_NOCOUNT);
254*7fd79137SRobert Mustacchi 
255*7fd79137SRobert Mustacchi     case DW_OP_const1u:
256*7fd79137SRobert Mustacchi     case DW_OP_const1s:
257*7fd79137SRobert Mustacchi         operand = (Dwarf_Small *) & operand_buffer[0];
258*7fd79137SRobert Mustacchi         WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 1);
259*7fd79137SRobert Mustacchi         operand_size = 1;
260*7fd79137SRobert Mustacchi         break;
261*7fd79137SRobert Mustacchi 
262*7fd79137SRobert Mustacchi     case DW_OP_const2u:
263*7fd79137SRobert Mustacchi     case DW_OP_const2s:
264*7fd79137SRobert Mustacchi         operand = (Dwarf_Small *) & operand_buffer[0];
265*7fd79137SRobert Mustacchi         WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2);
266*7fd79137SRobert Mustacchi         operand_size = 2;
267*7fd79137SRobert Mustacchi         break;
268*7fd79137SRobert Mustacchi 
269*7fd79137SRobert Mustacchi     case DW_OP_const4u:
270*7fd79137SRobert Mustacchi     case DW_OP_const4s:
271*7fd79137SRobert Mustacchi         operand = (Dwarf_Small *) & operand_buffer[0];
272*7fd79137SRobert Mustacchi         WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 4);
273*7fd79137SRobert Mustacchi         operand_size = 4;
274*7fd79137SRobert Mustacchi         break;
275*7fd79137SRobert Mustacchi 
276*7fd79137SRobert Mustacchi     case DW_OP_const8u:
277*7fd79137SRobert Mustacchi     case DW_OP_const8s:
278*7fd79137SRobert Mustacchi         operand = (Dwarf_Small *) & operand_buffer[0];
279*7fd79137SRobert Mustacchi         WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 8);
280*7fd79137SRobert Mustacchi         operand_size = 8;
281*7fd79137SRobert Mustacchi         break;
282*7fd79137SRobert Mustacchi 
283*7fd79137SRobert Mustacchi     case DW_OP_constu:
284*7fd79137SRobert Mustacchi         res = _dwarf_pro_encode_leb128_nm(val1,
285*7fd79137SRobert Mustacchi                                           &operand_size,
286*7fd79137SRobert Mustacchi                                           encode_buffer,
287*7fd79137SRobert Mustacchi                                           sizeof(encode_buffer));
288*7fd79137SRobert Mustacchi         if (res != DW_DLV_OK) {
289*7fd79137SRobert Mustacchi             _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
290*7fd79137SRobert Mustacchi             return (DW_DLV_NOCOUNT);
291*7fd79137SRobert Mustacchi         }
292*7fd79137SRobert Mustacchi         operand = (Dwarf_Small *) encode_buffer;
293*7fd79137SRobert Mustacchi         break;
294*7fd79137SRobert Mustacchi 
295*7fd79137SRobert Mustacchi     case DW_OP_consts:
296*7fd79137SRobert Mustacchi         res = _dwarf_pro_encode_signed_leb128_nm(val1,
297*7fd79137SRobert Mustacchi                                                  &operand_size,
298*7fd79137SRobert Mustacchi                                                  encode_buffer,
299*7fd79137SRobert Mustacchi                                                  sizeof(encode_buffer));
300*7fd79137SRobert Mustacchi         if (res != DW_DLV_OK) {
301*7fd79137SRobert Mustacchi             _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
302*7fd79137SRobert Mustacchi             return (DW_DLV_NOCOUNT);
303*7fd79137SRobert Mustacchi         }
304*7fd79137SRobert Mustacchi         operand = (Dwarf_Small *) encode_buffer;
305*7fd79137SRobert Mustacchi         break;
306*7fd79137SRobert Mustacchi 
307*7fd79137SRobert Mustacchi     case DW_OP_fbreg:
308*7fd79137SRobert Mustacchi         res = _dwarf_pro_encode_signed_leb128_nm(val1,
309*7fd79137SRobert Mustacchi                                                  &operand_size,
310*7fd79137SRobert Mustacchi                                                  encode_buffer,
311*7fd79137SRobert Mustacchi                                                  sizeof(encode_buffer));
312*7fd79137SRobert Mustacchi         if (res != DW_DLV_OK) {
313*7fd79137SRobert Mustacchi             _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
314*7fd79137SRobert Mustacchi             return (DW_DLV_NOCOUNT);
315*7fd79137SRobert Mustacchi         }
316*7fd79137SRobert Mustacchi         operand = (Dwarf_Small *) encode_buffer;
317*7fd79137SRobert Mustacchi         break;
318*7fd79137SRobert Mustacchi 
319*7fd79137SRobert Mustacchi     case DW_OP_bregx:
320*7fd79137SRobert Mustacchi         res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
321*7fd79137SRobert Mustacchi                                           encode_buffer,
322*7fd79137SRobert Mustacchi                                           sizeof(encode_buffer));
323*7fd79137SRobert Mustacchi         if (res != DW_DLV_OK) {
324*7fd79137SRobert Mustacchi             _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
325*7fd79137SRobert Mustacchi             return (DW_DLV_NOCOUNT);
326*7fd79137SRobert Mustacchi         }
327*7fd79137SRobert Mustacchi         operand = (Dwarf_Small *) encode_buffer;
328*7fd79137SRobert Mustacchi         /* put this one directly into 'operand' at tail of prev value */
329*7fd79137SRobert Mustacchi         res = _dwarf_pro_encode_signed_leb128_nm(val2, &operand2_size,
330*7fd79137SRobert Mustacchi                                                  ((char *) operand) +
331*7fd79137SRobert Mustacchi                                                  operand_size,
332*7fd79137SRobert Mustacchi                                                  sizeof
333*7fd79137SRobert Mustacchi                                                  (encode_buffer2));
334*7fd79137SRobert Mustacchi         if (res != DW_DLV_OK) {
335*7fd79137SRobert Mustacchi             _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
336*7fd79137SRobert Mustacchi             return (DW_DLV_NOCOUNT);
337*7fd79137SRobert Mustacchi         }
338*7fd79137SRobert Mustacchi         operand_size += operand2_size;
339*7fd79137SRobert Mustacchi 
340*7fd79137SRobert Mustacchi     case DW_OP_dup:
341*7fd79137SRobert Mustacchi     case DW_OP_drop:
342*7fd79137SRobert Mustacchi         break;
343*7fd79137SRobert Mustacchi 
344*7fd79137SRobert Mustacchi     case DW_OP_pick:
345*7fd79137SRobert Mustacchi         operand = (Dwarf_Small *) & operand_buffer[0];
346*7fd79137SRobert Mustacchi         WRITE_UNALIGNED(dbg, operand, (const void *) &val1,
347*7fd79137SRobert Mustacchi                         sizeof(val1), 1);
348*7fd79137SRobert Mustacchi         operand_size = 1;
349*7fd79137SRobert Mustacchi         break;
350*7fd79137SRobert Mustacchi 
351*7fd79137SRobert Mustacchi     case DW_OP_over:
352*7fd79137SRobert Mustacchi     case DW_OP_swap:
353*7fd79137SRobert Mustacchi     case DW_OP_rot:
354*7fd79137SRobert Mustacchi     case DW_OP_deref:
355*7fd79137SRobert Mustacchi     case DW_OP_xderef:
356*7fd79137SRobert Mustacchi         break;
357*7fd79137SRobert Mustacchi 
358*7fd79137SRobert Mustacchi     case DW_OP_deref_size:
359*7fd79137SRobert Mustacchi     case DW_OP_xderef_size:
360*7fd79137SRobert Mustacchi         operand = (Dwarf_Small *) & operand_buffer[0];
361*7fd79137SRobert Mustacchi         WRITE_UNALIGNED(dbg, operand, (const void *) &val1,
362*7fd79137SRobert Mustacchi                         sizeof(val1), 1);
363*7fd79137SRobert Mustacchi         operand_size = 1;
364*7fd79137SRobert Mustacchi         break;
365*7fd79137SRobert Mustacchi 
366*7fd79137SRobert Mustacchi     case DW_OP_abs:
367*7fd79137SRobert Mustacchi     case DW_OP_and:
368*7fd79137SRobert Mustacchi     case DW_OP_div:
369*7fd79137SRobert Mustacchi     case DW_OP_minus:
370*7fd79137SRobert Mustacchi     case DW_OP_mod:
371*7fd79137SRobert Mustacchi     case DW_OP_mul:
372*7fd79137SRobert Mustacchi     case DW_OP_neg:
373*7fd79137SRobert Mustacchi     case DW_OP_not:
374*7fd79137SRobert Mustacchi     case DW_OP_or:
375*7fd79137SRobert Mustacchi     case DW_OP_plus:
376*7fd79137SRobert Mustacchi         break;
377*7fd79137SRobert Mustacchi 
378*7fd79137SRobert Mustacchi     case DW_OP_plus_uconst:
379*7fd79137SRobert Mustacchi         res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
380*7fd79137SRobert Mustacchi                                           encode_buffer,
381*7fd79137SRobert Mustacchi                                           sizeof(encode_buffer));
382*7fd79137SRobert Mustacchi         if (res != DW_DLV_OK) {
383*7fd79137SRobert Mustacchi             _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
384*7fd79137SRobert Mustacchi             return (DW_DLV_NOCOUNT);
385*7fd79137SRobert Mustacchi         }
386*7fd79137SRobert Mustacchi         operand = (Dwarf_Small *) encode_buffer;
387*7fd79137SRobert Mustacchi         break;
388*7fd79137SRobert Mustacchi 
389*7fd79137SRobert Mustacchi     case DW_OP_shl:
390*7fd79137SRobert Mustacchi     case DW_OP_shr:
391*7fd79137SRobert Mustacchi     case DW_OP_shra:
392*7fd79137SRobert Mustacchi     case DW_OP_xor:
393*7fd79137SRobert Mustacchi         break;
394*7fd79137SRobert Mustacchi 
395*7fd79137SRobert Mustacchi     case DW_OP_le:
396*7fd79137SRobert Mustacchi     case DW_OP_ge:
397*7fd79137SRobert Mustacchi     case DW_OP_eq:
398*7fd79137SRobert Mustacchi     case DW_OP_lt:
399*7fd79137SRobert Mustacchi     case DW_OP_gt:
400*7fd79137SRobert Mustacchi     case DW_OP_ne:
401*7fd79137SRobert Mustacchi         break;
402*7fd79137SRobert Mustacchi 
403*7fd79137SRobert Mustacchi     case DW_OP_skip:
404*7fd79137SRobert Mustacchi     case DW_OP_bra:
405*7fd79137SRobert Mustacchi         /* FIX: unhandled! OP_bra, OP_skip! */
406*7fd79137SRobert Mustacchi         _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
407*7fd79137SRobert Mustacchi         return (DW_DLV_NOCOUNT);
408*7fd79137SRobert Mustacchi 
409*7fd79137SRobert Mustacchi     case DW_OP_piece:
410*7fd79137SRobert Mustacchi         res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
411*7fd79137SRobert Mustacchi                                           encode_buffer,
412*7fd79137SRobert Mustacchi                                           sizeof(encode_buffer));
413*7fd79137SRobert Mustacchi         if (res != DW_DLV_OK) {
414*7fd79137SRobert Mustacchi             _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
415*7fd79137SRobert Mustacchi             return (DW_DLV_NOCOUNT);
416*7fd79137SRobert Mustacchi         }
417*7fd79137SRobert Mustacchi         operand = (Dwarf_Small *) encode_buffer;
418*7fd79137SRobert Mustacchi         break;
419*7fd79137SRobert Mustacchi 
420*7fd79137SRobert Mustacchi     case DW_OP_nop:
421*7fd79137SRobert Mustacchi         break;
422*7fd79137SRobert Mustacchi     case DW_OP_push_object_address:     /* DWARF3 */
423*7fd79137SRobert Mustacchi         break;
424*7fd79137SRobert Mustacchi     case DW_OP_call2:           /* DWARF3 */
425*7fd79137SRobert Mustacchi         operand = (Dwarf_Small *) & operand_buffer[0];
426*7fd79137SRobert Mustacchi         WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2);
427*7fd79137SRobert Mustacchi         operand_size = 2;
428*7fd79137SRobert Mustacchi         break;
429*7fd79137SRobert Mustacchi 
430*7fd79137SRobert Mustacchi     case DW_OP_call4:           /* DWARF3 */
431*7fd79137SRobert Mustacchi         operand = (Dwarf_Small *) & operand_buffer[0];
432*7fd79137SRobert Mustacchi         WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 4);
433*7fd79137SRobert Mustacchi         operand_size = 4;
434*7fd79137SRobert Mustacchi         break;
435*7fd79137SRobert Mustacchi 
436*7fd79137SRobert Mustacchi     case DW_OP_call_ref:        /* DWARF3 */
437*7fd79137SRobert Mustacchi         operand = (Dwarf_Small *) & operand_buffer[0];
438*7fd79137SRobert Mustacchi         WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1),
439*7fd79137SRobert Mustacchi                         dbg->de_offset_size);
440*7fd79137SRobert Mustacchi         operand_size = dbg->de_offset_size;
441*7fd79137SRobert Mustacchi         break;
442*7fd79137SRobert Mustacchi     case DW_OP_form_tls_address:        /* DWARF3f */
443*7fd79137SRobert Mustacchi         break;
444*7fd79137SRobert Mustacchi     case DW_OP_call_frame_cfa:  /* DWARF3f */
445*7fd79137SRobert Mustacchi         break;
446*7fd79137SRobert Mustacchi     case DW_OP_bit_piece:       /* DWARF3f */
447*7fd79137SRobert Mustacchi         res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
448*7fd79137SRobert Mustacchi                                           encode_buffer,
449*7fd79137SRobert Mustacchi                                           sizeof(encode_buffer));
450*7fd79137SRobert Mustacchi         if (res != DW_DLV_OK) {
451*7fd79137SRobert Mustacchi             _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
452*7fd79137SRobert Mustacchi             return (DW_DLV_NOCOUNT);
453*7fd79137SRobert Mustacchi         }
454*7fd79137SRobert Mustacchi         operand = (Dwarf_Small *) encode_buffer;
455*7fd79137SRobert Mustacchi         /* put this one directly into 'operand' at tail of prev value */
456*7fd79137SRobert Mustacchi         res = _dwarf_pro_encode_leb128_nm(val2, &operand2_size,
457*7fd79137SRobert Mustacchi                                           ((char *) operand) +
458*7fd79137SRobert Mustacchi                                           operand_size,
459*7fd79137SRobert Mustacchi                                           sizeof(encode_buffer2));
460*7fd79137SRobert Mustacchi         if (res != DW_DLV_OK) {
461*7fd79137SRobert Mustacchi             _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
462*7fd79137SRobert Mustacchi             return (DW_DLV_NOCOUNT);
463*7fd79137SRobert Mustacchi         }
464*7fd79137SRobert Mustacchi         operand_size += operand2_size;
465*7fd79137SRobert Mustacchi 
466*7fd79137SRobert Mustacchi 
467*7fd79137SRobert Mustacchi     default:
468*7fd79137SRobert Mustacchi         _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
469*7fd79137SRobert Mustacchi         return (DW_DLV_NOCOUNT);
470*7fd79137SRobert Mustacchi     }
471*7fd79137SRobert Mustacchi 
472*7fd79137SRobert Mustacchi     next_byte_offset = expr->ex_next_byte_offset + operand_size + 1;
473*7fd79137SRobert Mustacchi 
474*7fd79137SRobert Mustacchi     if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) {
475*7fd79137SRobert Mustacchi         _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
476*7fd79137SRobert Mustacchi         return (DW_DLV_NOCOUNT);
477*7fd79137SRobert Mustacchi     }
478*7fd79137SRobert Mustacchi 
479*7fd79137SRobert Mustacchi     next_byte_ptr =
480*7fd79137SRobert Mustacchi         &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset;
481*7fd79137SRobert Mustacchi 
482*7fd79137SRobert Mustacchi     *next_byte_ptr = opcode;
483*7fd79137SRobert Mustacchi     next_byte_ptr++;
484*7fd79137SRobert Mustacchi     memcpy(next_byte_ptr, operand, operand_size);
485*7fd79137SRobert Mustacchi 
486*7fd79137SRobert Mustacchi     expr->ex_next_byte_offset = next_byte_offset;
487*7fd79137SRobert Mustacchi     return (next_byte_offset);
488*7fd79137SRobert Mustacchi }
489*7fd79137SRobert Mustacchi 
490*7fd79137SRobert Mustacchi Dwarf_Unsigned
491*7fd79137SRobert Mustacchi dwarf_add_expr_addr_b(Dwarf_P_Expr expr,
492*7fd79137SRobert Mustacchi                       Dwarf_Unsigned addr,
493*7fd79137SRobert Mustacchi                       Dwarf_Unsigned sym_index, Dwarf_Error * error)
494*7fd79137SRobert Mustacchi {
495*7fd79137SRobert Mustacchi     Dwarf_P_Debug dbg;
496*7fd79137SRobert Mustacchi     Dwarf_Small *next_byte_ptr;
497*7fd79137SRobert Mustacchi     Dwarf_Unsigned next_byte_offset;
498*7fd79137SRobert Mustacchi     int upointer_size;
499*7fd79137SRobert Mustacchi 
500*7fd79137SRobert Mustacchi     if (expr == NULL) {
501*7fd79137SRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
502*7fd79137SRobert Mustacchi         return (DW_DLV_NOCOUNT);
503*7fd79137SRobert Mustacchi     }
504*7fd79137SRobert Mustacchi 
505*7fd79137SRobert Mustacchi     dbg = expr->ex_dbg;
506*7fd79137SRobert Mustacchi     if (dbg == NULL) {
507*7fd79137SRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
508*7fd79137SRobert Mustacchi         return (DW_DLV_NOCOUNT);
509*7fd79137SRobert Mustacchi     }
510*7fd79137SRobert Mustacchi 
511*7fd79137SRobert Mustacchi     upointer_size = dbg->de_pointer_size;
512*7fd79137SRobert Mustacchi     next_byte_offset = expr->ex_next_byte_offset + upointer_size + 1;
513*7fd79137SRobert Mustacchi     if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) {
514*7fd79137SRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD);
515*7fd79137SRobert Mustacchi         return (DW_DLV_NOCOUNT);
516*7fd79137SRobert Mustacchi     }
517*7fd79137SRobert Mustacchi 
518*7fd79137SRobert Mustacchi     next_byte_ptr =
519*7fd79137SRobert Mustacchi         &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset;
520*7fd79137SRobert Mustacchi 
521*7fd79137SRobert Mustacchi     *next_byte_ptr = DW_OP_addr;
522*7fd79137SRobert Mustacchi     next_byte_ptr++;
523*7fd79137SRobert Mustacchi     WRITE_UNALIGNED(dbg, next_byte_ptr, (const void *) &addr,
524*7fd79137SRobert Mustacchi                     sizeof(addr), upointer_size);
525*7fd79137SRobert Mustacchi 
526*7fd79137SRobert Mustacchi     if (expr->ex_reloc_offset != 0) {
527*7fd79137SRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_MULTIPLE_RELOC_IN_EXPR);
528*7fd79137SRobert Mustacchi         return (DW_DLV_NOCOUNT);
529*7fd79137SRobert Mustacchi     }
530*7fd79137SRobert Mustacchi 
531*7fd79137SRobert Mustacchi     expr->ex_reloc_sym_index = sym_index;
532*7fd79137SRobert Mustacchi     expr->ex_reloc_offset = expr->ex_next_byte_offset + 1;
533*7fd79137SRobert Mustacchi 
534*7fd79137SRobert Mustacchi     expr->ex_next_byte_offset = next_byte_offset;
535*7fd79137SRobert Mustacchi     return (next_byte_offset);
536*7fd79137SRobert Mustacchi }
537*7fd79137SRobert Mustacchi 
538*7fd79137SRobert Mustacchi Dwarf_Unsigned
539*7fd79137SRobert Mustacchi dwarf_add_expr_addr(Dwarf_P_Expr expr,
540*7fd79137SRobert Mustacchi                     Dwarf_Unsigned addr,
541*7fd79137SRobert Mustacchi                     Dwarf_Signed sym_index, Dwarf_Error * error)
542*7fd79137SRobert Mustacchi {
543*7fd79137SRobert Mustacchi     return
544*7fd79137SRobert Mustacchi         dwarf_add_expr_addr_b(expr, addr, (Dwarf_Unsigned) sym_index,
545*7fd79137SRobert Mustacchi                               error);
546*7fd79137SRobert Mustacchi }
547*7fd79137SRobert Mustacchi 
548*7fd79137SRobert Mustacchi 
549*7fd79137SRobert Mustacchi Dwarf_Unsigned
550*7fd79137SRobert Mustacchi dwarf_expr_current_offset(Dwarf_P_Expr expr, Dwarf_Error * error)
551*7fd79137SRobert Mustacchi {
552*7fd79137SRobert Mustacchi     if (expr == NULL) {
553*7fd79137SRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
554*7fd79137SRobert Mustacchi         return (DW_DLV_NOCOUNT);
555*7fd79137SRobert Mustacchi     }
556*7fd79137SRobert Mustacchi 
557*7fd79137SRobert Mustacchi     if (expr->ex_dbg == NULL) {
558*7fd79137SRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
559*7fd79137SRobert Mustacchi         return (DW_DLV_NOCOUNT);
560*7fd79137SRobert Mustacchi     }
561*7fd79137SRobert Mustacchi 
562*7fd79137SRobert Mustacchi     return (expr->ex_next_byte_offset);
563*7fd79137SRobert Mustacchi }
564*7fd79137SRobert Mustacchi 
565*7fd79137SRobert Mustacchi void
566*7fd79137SRobert Mustacchi dwarf_expr_reset(Dwarf_P_Expr expr, Dwarf_Error * error)
567*7fd79137SRobert Mustacchi {
568*7fd79137SRobert Mustacchi    if (expr == NULL) {
569*7fd79137SRobert Mustacchi       _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
570*7fd79137SRobert Mustacchi       return;
571*7fd79137SRobert Mustacchi    }
572*7fd79137SRobert Mustacchi    expr->ex_next_byte_offset=0;
573*7fd79137SRobert Mustacchi }
574*7fd79137SRobert Mustacchi 
575*7fd79137SRobert Mustacchi 
576*7fd79137SRobert Mustacchi Dwarf_Addr
577*7fd79137SRobert Mustacchi dwarf_expr_into_block(Dwarf_P_Expr expr,
578*7fd79137SRobert Mustacchi                       Dwarf_Unsigned * length, Dwarf_Error * error)
579*7fd79137SRobert Mustacchi {
580*7fd79137SRobert Mustacchi     if (expr == NULL) {
581*7fd79137SRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
582*7fd79137SRobert Mustacchi         return (DW_DLV_BADADDR);
583*7fd79137SRobert Mustacchi     }
584*7fd79137SRobert Mustacchi 
585*7fd79137SRobert Mustacchi     if (expr->ex_dbg == NULL) {
586*7fd79137SRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
587*7fd79137SRobert Mustacchi         return (DW_DLV_BADADDR);
588*7fd79137SRobert Mustacchi     }
589*7fd79137SRobert Mustacchi 
590*7fd79137SRobert Mustacchi     if (length != NULL)
591*7fd79137SRobert Mustacchi         *length = expr->ex_next_byte_offset;
592*7fd79137SRobert Mustacchi     /* The following cast from pointer to integer is ok as long as
593*7fd79137SRobert Mustacchi        Dwarf_Addr is at least as large as a pointer. Which is a
594*7fd79137SRobert Mustacchi        requirement of libdwarf so must be satisfied (some compilers
595*7fd79137SRobert Mustacchi        emit a warning about the following line). */
596*7fd79137SRobert Mustacchi     return ((Dwarf_Addr)(uintptr_t) &(expr->ex_byte_stream[0]));
597*7fd79137SRobert Mustacchi }
598