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