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