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