1 /* $NetBSD: dwarf_pro_expr.c,v 1.2 2014/03/09 16:58:04 christos Exp $ */
4 * Copyright (c) 2010 Kai Wang
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include "_libdwarf.h"
31 __RCSID("$NetBSD: dwarf_pro_expr.c,v 1.2 2014/03/09 16:58:04 christos Exp $");
32 ELFTC_VCSID("Id: dwarf_pro_expr.c 2074 2011-10-27 03:34:33Z jkoshy ");
34 static struct _Dwarf_P_Expr_Entry
*
35 _dwarf_add_expr(Dwarf_P_Expr expr
, Dwarf_Small opcode
, Dwarf_Unsigned val1
,
36 Dwarf_Unsigned val2
, Dwarf_Error
*error
)
38 struct _Dwarf_P_Expr_Entry
*ee
;
42 dbg
= expr
!= NULL
? expr
->pe_dbg
: NULL
;
44 if (_dwarf_loc_expr_add_atom(expr
->pe_dbg
, NULL
, NULL
, opcode
, val1
,
45 val2
, &len
, error
) != DW_DLE_NONE
)
49 if ((ee
= calloc(1, sizeof(*ee
))) == NULL
) {
50 DWARF_SET_ERROR(dbg
, error
, DW_DLE_MEMORY
);
54 STAILQ_INSERT_TAIL(&expr
->pe_eelist
, ee
, ee_next
);
56 ee
->ee_loc
.lr_atom
= opcode
;
57 ee
->ee_loc
.lr_number
= val1
;
58 ee
->ee_loc
.lr_number2
= val2
;
59 ee
->ee_loc
.lr_offset
= expr
->pe_length
;
60 expr
->pe_length
+= len
;
67 _dwarf_expr_into_block(Dwarf_P_Expr expr
, Dwarf_Error
*error
)
69 struct _Dwarf_P_Expr_Entry
*ee
;
73 dbg
= expr
!= NULL
? expr
->pe_dbg
: NULL
;
75 if (expr
->pe_block
!= NULL
) {
77 expr
->pe_block
= NULL
;
80 if (expr
->pe_length
<= 0) {
81 DWARF_SET_ERROR(dbg
, error
, DW_DLE_EXPR_LENGTH_BAD
);
82 return (DW_DLE_EXPR_LENGTH_BAD
);
86 if ((expr
->pe_block
= calloc((size_t) expr
->pe_length
, 1)) == NULL
) {
87 DWARF_SET_ERROR(dbg
, error
, DW_DLE_MEMORY
);
88 return (DW_DLE_MEMORY
);
92 STAILQ_FOREACH(ee
, &expr
->pe_eelist
, ee_next
) {
93 assert((Dwarf_Unsigned
) pos
< expr
->pe_length
);
94 ret
= _dwarf_loc_expr_add_atom(expr
->pe_dbg
,
95 &expr
->pe_block
[pos
], &expr
->pe_block
[expr
->pe_length
],
96 ee
->ee_loc
.lr_atom
, ee
->ee_loc
.lr_number
,
97 ee
->ee_loc
.lr_number2
, &len
, error
);
98 assert(ret
== DW_DLE_NONE
);
103 expr
->pe_invalid
= 0;
105 return (DW_DLE_NONE
);
109 _dwarf_expr_cleanup(Dwarf_P_Debug dbg
)
111 Dwarf_P_Expr pe
, tpe
;
112 struct _Dwarf_P_Expr_Entry
*ee
, *tee
;
114 assert(dbg
!= NULL
&& dbg
->dbg_mode
== DW_DLC_WRITE
);
116 STAILQ_FOREACH_SAFE(pe
, &dbg
->dbgp_pelist
, pe_next
, tpe
) {
117 STAILQ_REMOVE(&dbg
->dbgp_pelist
, pe
, _Dwarf_P_Expr
, pe_next
);
118 STAILQ_FOREACH_SAFE(ee
, &pe
->pe_eelist
, ee_next
, tee
) {
119 STAILQ_REMOVE(&pe
->pe_eelist
, ee
, _Dwarf_P_Expr_Entry
,
130 dwarf_new_expr(Dwarf_P_Debug dbg
, Dwarf_Error
*error
)
135 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARGUMENT
);
136 return (DW_DLV_BADADDR
);
139 if ((pe
= calloc(1, sizeof(struct _Dwarf_P_Expr
))) == NULL
) {
140 DWARF_SET_ERROR(dbg
, error
, DW_DLE_MEMORY
);
141 return (DW_DLV_BADADDR
);
143 STAILQ_INIT(&pe
->pe_eelist
);
145 STAILQ_INSERT_TAIL(&dbg
->dbgp_pelist
, pe
, pe_next
);
152 dwarf_add_expr_gen(Dwarf_P_Expr expr
, Dwarf_Small opcode
, Dwarf_Unsigned val1
,
153 Dwarf_Unsigned val2
, Dwarf_Error
*error
)
157 DWARF_SET_ERROR(NULL
, error
, DW_DLE_ARGUMENT
);
158 return (DW_DLV_NOCOUNT
);
161 if (_dwarf_add_expr(expr
, opcode
, val1
, val2
, error
) == NULL
)
162 return (DW_DLV_NOCOUNT
);
164 return (expr
->pe_length
);
168 dwarf_add_expr_addr(Dwarf_P_Expr expr
, Dwarf_Unsigned address
,
169 Dwarf_Signed sym_index
, Dwarf_Error
*error
)
172 return (dwarf_add_expr_addr_b(expr
, address
, sym_index
, error
));
176 dwarf_add_expr_addr_b(Dwarf_P_Expr expr
, Dwarf_Unsigned address
,
177 Dwarf_Unsigned sym_index
, Dwarf_Error
*error
)
179 struct _Dwarf_P_Expr_Entry
*ee
;
182 DWARF_SET_ERROR(NULL
, error
, DW_DLE_ARGUMENT
);
183 return (DW_DLV_NOCOUNT
);
186 if ((ee
= _dwarf_add_expr(expr
, DW_OP_addr
, address
, 0, error
)) == NULL
)
187 return (DW_DLV_NOCOUNT
);
189 ee
->ee_sym
= sym_index
;
191 return (expr
->pe_length
);
195 dwarf_expr_current_offset(Dwarf_P_Expr expr
, Dwarf_Error
*error
)
199 DWARF_SET_ERROR(NULL
, error
, DW_DLE_ARGUMENT
);
200 return (DW_DLV_NOCOUNT
);
203 return (expr
->pe_length
);
207 dwarf_expr_into_block(Dwarf_P_Expr expr
, Dwarf_Unsigned
*length
,
212 dbg
= expr
!= NULL
? expr
->pe_dbg
: NULL
;
214 if (expr
== NULL
|| length
== NULL
) {
215 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARGUMENT
);
216 return ((Dwarf_Addr
) (uintptr_t) DW_DLV_BADADDR
);
219 if (expr
->pe_block
== NULL
|| expr
->pe_invalid
)
220 if (_dwarf_expr_into_block(expr
, error
) != DW_DLE_NONE
)
221 return ((Dwarf_Addr
) (uintptr_t) DW_DLV_BADADDR
);
223 *length
= expr
->pe_length
;
225 return ((Dwarf_Addr
) (uintptr_t) expr
->pe_block
);