3 Copyright (C) 2000,2004,2006 Silicon Graphics, Inc. All Rights Reserved.
4 Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of version 2.1 of the GNU Lesser General Public License
8 as published by the Free Software Foundation.
10 This program is distributed in the hope that it would be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 Further, this software is distributed without any warranty that it is
15 free of the rightful claim of any third person regarding infringement
16 or the like. Any license provided herein, whether implied or
17 otherwise, applies only to this software file. Patent licenses, if
18 any, provided herein do not apply to combinations of this program with
19 other software, or any other product whatsoever.
21 You should have received a copy of the GNU Lesser General Public
22 License along with this program; if not, write the Free Software
23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
26 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
27 Mountain View, CA 94043, or:
31 For further information regarding this notice, see:
33 http://oss.sgi.com/projects/GenInfo/NoticeExplan
40 #include "libdwarfdefs.h"
43 #include <sys/types.h>
48 This function creates a new expression
49 struct that can be used to build up a
53 dwarf_new_expr(Dwarf_P_Debug dbg
, Dwarf_Error
* error
)
55 Dwarf_P_Expr ret_expr
;
58 _dwarf_p_error(NULL
, error
, DW_DLE_DBG_NULL
);
62 ret_expr
= (Dwarf_P_Expr
)
63 _dwarf_p_get_alloc(dbg
, sizeof(struct Dwarf_P_Expr_s
));
64 if (ret_expr
== NULL
) {
65 _dwarf_p_error(dbg
, error
, DW_DLE_ALLOC_FAIL
);
69 ret_expr
->ex_dbg
= dbg
;
76 dwarf_add_expr_gen(Dwarf_P_Expr expr
,
79 Dwarf_Unsigned val2
, Dwarf_Error
* error
)
81 char encode_buffer
[2 * ENCODE_SPACE_NEEDED
]; /* 2* since
86 char encode_buffer2
[ENCODE_SPACE_NEEDED
];
88 Dwarf_P_Debug dbg
= expr
->ex_dbg
;
91 Give the buffer where the operands are first going to be
92 assembled the largest alignment. */
93 Dwarf_Unsigned operand_buffer
[10];
96 Size of the byte stream buffer that needs to be memcpy-ed. */
100 Points to the byte stream for the first operand, and finally to
101 the buffer that is memcp-ed into the Dwarf_P_Expr_s struct. */
102 Dwarf_Small
*operand
;
104 /* Size of the byte stream for second operand. */
107 /* Points to next byte to be written in Dwarf_P_Expr_s struct. */
108 Dwarf_Small
*next_byte_ptr
;
110 /* Offset past the last byte written into Dwarf_P_Expr_s. */
111 int next_byte_offset
;
113 /* ***** BEGIN CODE ***** */
116 _dwarf_p_error(NULL
, error
, DW_DLE_EXPR_NULL
);
117 return (DW_DLV_NOCOUNT
);
120 if (expr
->ex_dbg
== NULL
) {
121 _dwarf_p_error(NULL
, error
, DW_DLE_DBG_NULL
);
122 return (DW_DLV_NOCOUNT
);
195 res
= _dwarf_pro_encode_signed_leb128_nm(val1
,
198 sizeof(encode_buffer
));
199 if (res
!= DW_DLV_OK
) {
200 _dwarf_p_error(expr
->ex_dbg
, error
, DW_DLE_EXPR_LENGTH_BAD
);
201 return (DW_DLV_NOCOUNT
);
203 operand
= (Dwarf_Small
*) encode_buffer
;
207 res
= _dwarf_pro_encode_leb128_nm(val1
, &operand_size
,
209 sizeof(encode_buffer
));
210 if (res
!= DW_DLV_OK
) {
211 _dwarf_p_error(expr
->ex_dbg
, error
, DW_DLE_EXPR_LENGTH_BAD
);
212 return (DW_DLV_NOCOUNT
);
214 operand
= (Dwarf_Small
*) encode_buffer
;
252 _dwarf_p_error(expr
->ex_dbg
, error
, DW_DLE_BAD_EXPR_OPCODE
);
253 return (DW_DLV_NOCOUNT
);
257 operand
= (Dwarf_Small
*) & operand_buffer
[0];
258 WRITE_UNALIGNED(dbg
, operand
, &val1
, sizeof(val1
), 1);
264 operand
= (Dwarf_Small
*) & operand_buffer
[0];
265 WRITE_UNALIGNED(dbg
, operand
, &val1
, sizeof(val1
), 2);
271 operand
= (Dwarf_Small
*) & operand_buffer
[0];
272 WRITE_UNALIGNED(dbg
, operand
, &val1
, sizeof(val1
), 4);
278 operand
= (Dwarf_Small
*) & operand_buffer
[0];
279 WRITE_UNALIGNED(dbg
, operand
, &val1
, sizeof(val1
), 8);
284 res
= _dwarf_pro_encode_leb128_nm(val1
,
287 sizeof(encode_buffer
));
288 if (res
!= DW_DLV_OK
) {
289 _dwarf_p_error(expr
->ex_dbg
, error
, DW_DLE_EXPR_LENGTH_BAD
);
290 return (DW_DLV_NOCOUNT
);
292 operand
= (Dwarf_Small
*) encode_buffer
;
296 res
= _dwarf_pro_encode_signed_leb128_nm(val1
,
299 sizeof(encode_buffer
));
300 if (res
!= DW_DLV_OK
) {
301 _dwarf_p_error(expr
->ex_dbg
, error
, DW_DLE_EXPR_LENGTH_BAD
);
302 return (DW_DLV_NOCOUNT
);
304 operand
= (Dwarf_Small
*) encode_buffer
;
308 res
= _dwarf_pro_encode_signed_leb128_nm(val1
,
311 sizeof(encode_buffer
));
312 if (res
!= DW_DLV_OK
) {
313 _dwarf_p_error(expr
->ex_dbg
, error
, DW_DLE_EXPR_LENGTH_BAD
);
314 return (DW_DLV_NOCOUNT
);
316 operand
= (Dwarf_Small
*) encode_buffer
;
320 res
= _dwarf_pro_encode_leb128_nm(val1
, &operand_size
,
322 sizeof(encode_buffer
));
323 if (res
!= DW_DLV_OK
) {
324 _dwarf_p_error(expr
->ex_dbg
, error
, DW_DLE_EXPR_LENGTH_BAD
);
325 return (DW_DLV_NOCOUNT
);
327 operand
= (Dwarf_Small
*) encode_buffer
;
328 /* put this one directly into 'operand' at tail of prev value */
329 res
= _dwarf_pro_encode_signed_leb128_nm(val2
, &operand2_size
,
334 if (res
!= DW_DLV_OK
) {
335 _dwarf_p_error(expr
->ex_dbg
, error
, DW_DLE_EXPR_LENGTH_BAD
);
336 return (DW_DLV_NOCOUNT
);
338 operand_size
+= operand2_size
;
345 operand
= (Dwarf_Small
*) & operand_buffer
[0];
346 WRITE_UNALIGNED(dbg
, operand
, (const void *) &val1
,
358 case DW_OP_deref_size
:
359 case DW_OP_xderef_size
:
360 operand
= (Dwarf_Small
*) & operand_buffer
[0];
361 WRITE_UNALIGNED(dbg
, operand
, (const void *) &val1
,
378 case DW_OP_plus_uconst
:
379 res
= _dwarf_pro_encode_leb128_nm(val1
, &operand_size
,
381 sizeof(encode_buffer
));
382 if (res
!= DW_DLV_OK
) {
383 _dwarf_p_error(expr
->ex_dbg
, error
, DW_DLE_EXPR_LENGTH_BAD
);
384 return (DW_DLV_NOCOUNT
);
386 operand
= (Dwarf_Small
*) encode_buffer
;
405 /* FIX: unhandled! OP_bra, OP_skip! */
406 _dwarf_p_error(expr
->ex_dbg
, error
, DW_DLE_BAD_EXPR_OPCODE
);
407 return (DW_DLV_NOCOUNT
);
410 res
= _dwarf_pro_encode_leb128_nm(val1
, &operand_size
,
412 sizeof(encode_buffer
));
413 if (res
!= DW_DLV_OK
) {
414 _dwarf_p_error(expr
->ex_dbg
, error
, DW_DLE_EXPR_LENGTH_BAD
);
415 return (DW_DLV_NOCOUNT
);
417 operand
= (Dwarf_Small
*) encode_buffer
;
422 case DW_OP_push_object_address
: /* DWARF3 */
424 case DW_OP_call2
: /* DWARF3 */
425 operand
= (Dwarf_Small
*) & operand_buffer
[0];
426 WRITE_UNALIGNED(dbg
, operand
, &val1
, sizeof(val1
), 2);
430 case DW_OP_call4
: /* DWARF3 */
431 operand
= (Dwarf_Small
*) & operand_buffer
[0];
432 WRITE_UNALIGNED(dbg
, operand
, &val1
, sizeof(val1
), 4);
436 case DW_OP_call_ref
: /* DWARF3 */
437 operand
= (Dwarf_Small
*) & operand_buffer
[0];
438 WRITE_UNALIGNED(dbg
, operand
, &val1
, sizeof(val1
),
439 dbg
->de_offset_size
);
440 operand_size
= dbg
->de_offset_size
;
442 case DW_OP_form_tls_address
: /* DWARF3f */
444 case DW_OP_call_frame_cfa
: /* DWARF3f */
446 case DW_OP_bit_piece
: /* DWARF3f */
447 res
= _dwarf_pro_encode_leb128_nm(val1
, &operand_size
,
449 sizeof(encode_buffer
));
450 if (res
!= DW_DLV_OK
) {
451 _dwarf_p_error(expr
->ex_dbg
, error
, DW_DLE_EXPR_LENGTH_BAD
);
452 return (DW_DLV_NOCOUNT
);
454 operand
= (Dwarf_Small
*) encode_buffer
;
455 /* put this one directly into 'operand' at tail of prev value */
456 res
= _dwarf_pro_encode_leb128_nm(val2
, &operand2_size
,
459 sizeof(encode_buffer2
));
460 if (res
!= DW_DLV_OK
) {
461 _dwarf_p_error(expr
->ex_dbg
, error
, DW_DLE_EXPR_LENGTH_BAD
);
462 return (DW_DLV_NOCOUNT
);
464 operand_size
+= operand2_size
;
468 _dwarf_p_error(expr
->ex_dbg
, error
, DW_DLE_BAD_EXPR_OPCODE
);
469 return (DW_DLV_NOCOUNT
);
472 next_byte_offset
= expr
->ex_next_byte_offset
+ operand_size
+ 1;
474 if (next_byte_offset
> MAXIMUM_LOC_EXPR_LENGTH
) {
475 _dwarf_p_error(expr
->ex_dbg
, error
, DW_DLE_EXPR_LENGTH_BAD
);
476 return (DW_DLV_NOCOUNT
);
480 &(expr
->ex_byte_stream
[0]) + expr
->ex_next_byte_offset
;
482 *next_byte_ptr
= opcode
;
484 memcpy(next_byte_ptr
, operand
, operand_size
);
486 expr
->ex_next_byte_offset
= next_byte_offset
;
487 return (next_byte_offset
);
491 dwarf_add_expr_addr_b(Dwarf_P_Expr expr
,
493 Dwarf_Unsigned sym_index
, Dwarf_Error
* error
)
496 Dwarf_Small
*next_byte_ptr
;
497 Dwarf_Unsigned next_byte_offset
;
501 _dwarf_p_error(NULL
, error
, DW_DLE_EXPR_NULL
);
502 return (DW_DLV_NOCOUNT
);
507 _dwarf_p_error(NULL
, error
, DW_DLE_DBG_NULL
);
508 return (DW_DLV_NOCOUNT
);
511 upointer_size
= dbg
->de_pointer_size
;
512 next_byte_offset
= expr
->ex_next_byte_offset
+ upointer_size
+ 1;
513 if (next_byte_offset
> MAXIMUM_LOC_EXPR_LENGTH
) {
514 _dwarf_p_error(dbg
, error
, DW_DLE_EXPR_LENGTH_BAD
);
515 return (DW_DLV_NOCOUNT
);
519 &(expr
->ex_byte_stream
[0]) + expr
->ex_next_byte_offset
;
521 *next_byte_ptr
= DW_OP_addr
;
523 WRITE_UNALIGNED(dbg
, next_byte_ptr
, (const void *) &addr
,
524 sizeof(addr
), upointer_size
);
526 if (expr
->ex_reloc_offset
!= 0) {
527 _dwarf_p_error(dbg
, error
, DW_DLE_MULTIPLE_RELOC_IN_EXPR
);
528 return (DW_DLV_NOCOUNT
);
531 expr
->ex_reloc_sym_index
= sym_index
;
532 expr
->ex_reloc_offset
= expr
->ex_next_byte_offset
+ 1;
534 expr
->ex_next_byte_offset
= next_byte_offset
;
535 return (next_byte_offset
);
539 dwarf_add_expr_addr(Dwarf_P_Expr expr
,
541 Dwarf_Signed sym_index
, Dwarf_Error
* error
)
544 dwarf_add_expr_addr_b(expr
, addr
, (Dwarf_Unsigned
) sym_index
,
550 dwarf_expr_current_offset(Dwarf_P_Expr expr
, Dwarf_Error
* error
)
553 _dwarf_p_error(NULL
, error
, DW_DLE_EXPR_NULL
);
554 return (DW_DLV_NOCOUNT
);
557 if (expr
->ex_dbg
== NULL
) {
558 _dwarf_p_error(NULL
, error
, DW_DLE_DBG_NULL
);
559 return (DW_DLV_NOCOUNT
);
562 return (expr
->ex_next_byte_offset
);
566 dwarf_expr_reset(Dwarf_P_Expr expr
, Dwarf_Error
* error
)
569 _dwarf_p_error(NULL
, error
, DW_DLE_EXPR_NULL
);
572 expr
->ex_next_byte_offset
=0;
577 dwarf_expr_into_block(Dwarf_P_Expr expr
,
578 Dwarf_Unsigned
* length
, Dwarf_Error
* error
)
581 _dwarf_p_error(NULL
, error
, DW_DLE_EXPR_NULL
);
582 return (DW_DLV_BADADDR
);
585 if (expr
->ex_dbg
== NULL
) {
586 _dwarf_p_error(NULL
, error
, DW_DLE_DBG_NULL
);
587 return (DW_DLV_BADADDR
);
591 *length
= expr
->ex_next_byte_offset
;
592 /* The following cast from pointer to integer is ok as long as
593 Dwarf_Addr is at least as large as a pointer. Which is a
594 requirement of libdwarf so must be satisfied (some compilers
595 emit a warning about the following line). */
596 return ((Dwarf_Addr
)(uintptr_t) &(expr
->ex_byte_stream
[0]));