1 /* $NetBSD: libdwarf_init.c,v 1.2 2014/03/09 16:58:04 christos Exp $ */
2
3 /*-
4 * Copyright (c) 2009,2011 Kai Wang
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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.
15 *
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
26 * SUCH DAMAGE.
27 */
28
29 #include "_libdwarf.h"
30
31 __RCSID("$NetBSD: libdwarf_init.c,v 1.2 2014/03/09 16:58:04 christos Exp $");
32 ELFTC_VCSID("Id: libdwarf_init.c 2948 2013-05-30 21:25:52Z kaiwang27 ");
33
34 static int
_dwarf_consumer_init(Dwarf_Debug dbg,Dwarf_Error * error)35 _dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error)
36 {
37 const Dwarf_Obj_Access_Methods *m;
38 Dwarf_Obj_Access_Section sec;
39 void *obj;
40 Dwarf_Unsigned cnt;
41 Dwarf_Half i;
42 int ret;
43
44 assert(dbg != NULL);
45 assert(dbg->dbg_iface != NULL);
46
47 m = dbg->dbg_iface->methods;
48 obj = dbg->dbg_iface->object;
49
50 assert(m != NULL);
51 assert(obj != NULL);
52
53 if (m->get_byte_order(obj) == DW_OBJECT_MSB) {
54 dbg->read = _dwarf_read_msb;
55 dbg->write = _dwarf_write_msb;
56 dbg->decode = _dwarf_decode_msb;
57 } else {
58 dbg->read = _dwarf_read_lsb;
59 dbg->write = _dwarf_write_lsb;
60 dbg->decode = _dwarf_decode_lsb;
61 }
62
63 dbg->dbg_pointer_size = m->get_pointer_size(obj);
64 dbg->dbg_offset_size = m->get_length_size(obj);
65
66 cnt = m->get_section_count(obj);
67
68 if (cnt == 0) {
69 DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_INFO_NULL);
70 return (DW_DLE_DEBUG_INFO_NULL);
71 }
72
73 dbg->dbg_seccnt = cnt;
74
75 if ((dbg->dbg_section = calloc(cnt, sizeof(Dwarf_Section))) == NULL) {
76 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
77 return (DW_DLE_MEMORY);
78 }
79
80 for (i = 0; i < cnt; i++) {
81 if (m->get_section_info(obj, i, &sec, &ret) != DW_DLV_OK) {
82 DWARF_SET_ERROR(dbg, error, ret);
83 return (ret);
84 }
85
86 dbg->dbg_section[i].ds_addr = sec.addr;
87 dbg->dbg_section[i].ds_size = sec.size;
88 dbg->dbg_section[i].ds_name = sec.name;
89
90 if (m->load_section(obj, i, &dbg->dbg_section[i].ds_data, &ret)
91 != DW_DLV_OK) {
92 DWARF_SET_ERROR(dbg, error, ret);
93 return (ret);
94 }
95 }
96
97 if (_dwarf_find_section(dbg, ".debug_abbrev") == NULL ||
98 ((dbg->dbg_info_sec = _dwarf_find_section(dbg, ".debug_info")) ==
99 NULL)) {
100 DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_INFO_NULL);
101 return (DW_DLE_DEBUG_INFO_NULL);
102 }
103
104 /* Initialise call frame API related parameters. */
105 _dwarf_frame_params_init(dbg);
106
107 return (DW_DLV_OK);
108 }
109
110 static int
_dwarf_producer_init(Dwarf_Debug dbg,Dwarf_Unsigned pf,Dwarf_Error * error)111 _dwarf_producer_init(Dwarf_Debug dbg, Dwarf_Unsigned pf, Dwarf_Error *error)
112 {
113
114 /* Producer only support DWARF2 which has fixed 32bit offset. */
115 dbg->dbg_offset_size = 4;
116
117 if (pf & DW_DLC_SIZE_32 && pf & DW_DLC_SIZE_64) {
118 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
119 return (DW_DLE_ARGUMENT);
120 }
121
122 if ((pf & DW_DLC_SIZE_32) == 0 && (pf & DW_DLC_SIZE_64) == 0)
123 pf |= DW_DLC_SIZE_32;
124
125 if (pf & DW_DLC_SIZE_64)
126 dbg->dbg_pointer_size = 8;
127 else
128 dbg->dbg_pointer_size = 4;
129
130 if (pf & DW_DLC_ISA_IA64 && pf & DW_DLC_ISA_MIPS) {
131 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
132 return (DW_DLE_ARGUMENT);
133 }
134
135 if (pf & DW_DLC_ISA_IA64)
136 dbg->dbgp_isa = DW_ISA_IA64;
137 else
138 dbg->dbgp_isa = DW_ISA_MIPS;
139
140 if (pf & DW_DLC_TARGET_BIGENDIAN && pf & DW_DLC_TARGET_LITTLEENDIAN) {
141 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
142 return (DW_DLE_ARGUMENT);
143 }
144
145 if ((pf & DW_DLC_TARGET_BIGENDIAN) == 0 &&
146 (pf & DW_DLC_TARGET_LITTLEENDIAN) == 0) {
147 #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_BIG_ENDIAN
148 pf |= DW_DLC_TARGET_BIGENDIAN;
149 #else
150 pf |= DW_DLC_TARGET_LITTLEENDIAN;
151 #endif
152 }
153
154 if (pf & DW_DLC_TARGET_BIGENDIAN) {
155 dbg->write = _dwarf_write_msb;
156 dbg->write_alloc = _dwarf_write_msb_alloc;
157 } else if (pf & DW_DLC_TARGET_LITTLEENDIAN) {
158 dbg->write = _dwarf_write_lsb;
159 dbg->write_alloc = _dwarf_write_lsb_alloc;
160 } else
161 assert(0);
162
163 if (pf & DW_DLC_STREAM_RELOCATIONS &&
164 pf & DW_DLC_SYMBOLIC_RELOCATIONS) {
165 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
166 return (DW_DLE_ARGUMENT);
167 }
168
169 if ((pf & DW_DLC_STREAM_RELOCATIONS) == 0 &&
170 (pf & DW_DLC_SYMBOLIC_RELOCATIONS) == 0)
171 pf |= DW_DLC_STREAM_RELOCATIONS;
172
173 dbg->dbgp_flags = pf;
174
175 STAILQ_INIT(&dbg->dbgp_dielist);
176 STAILQ_INIT(&dbg->dbgp_pelist);
177 STAILQ_INIT(&dbg->dbgp_seclist);
178 STAILQ_INIT(&dbg->dbgp_drslist);
179 STAILQ_INIT(&dbg->dbgp_cielist);
180 STAILQ_INIT(&dbg->dbgp_fdelist);
181
182 if ((dbg->dbgp_lineinfo = calloc(1, sizeof(struct _Dwarf_LineInfo))) ==
183 NULL) {
184 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
185 return (DW_DLE_MEMORY);
186 }
187 STAILQ_INIT(&dbg->dbgp_lineinfo->li_lflist);
188 STAILQ_INIT(&dbg->dbgp_lineinfo->li_lnlist);
189
190 if ((dbg->dbgp_as = calloc(1, sizeof(struct _Dwarf_ArangeSet))) ==
191 NULL) {
192 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
193 return (DW_DLE_MEMORY);
194 }
195 STAILQ_INIT(&dbg->dbgp_as->as_arlist);
196
197 return (DW_DLE_NONE);
198 }
199
200 int
_dwarf_init(Dwarf_Debug dbg,Dwarf_Unsigned pro_flags,Dwarf_Handler errhand,Dwarf_Ptr errarg,Dwarf_Error * error)201 _dwarf_init(Dwarf_Debug dbg, Dwarf_Unsigned pro_flags, Dwarf_Handler errhand,
202 Dwarf_Ptr errarg, Dwarf_Error *error)
203 {
204 int ret;
205
206 ret = DW_DLE_NONE;
207
208 /*
209 * Set the error handler fields early, so that the application
210 * is notified of initialization errors.
211 */
212 dbg->dbg_errhand = errhand;
213 dbg->dbg_errarg = errarg;
214
215 STAILQ_INIT(&dbg->dbg_cu);
216 STAILQ_INIT(&dbg->dbg_rllist);
217 STAILQ_INIT(&dbg->dbg_aslist);
218 STAILQ_INIT(&dbg->dbg_mslist);
219 TAILQ_INIT(&dbg->dbg_loclist);
220
221 if (dbg->dbg_mode == DW_DLC_READ || dbg->dbg_mode == DW_DLC_RDWR) {
222 ret = _dwarf_consumer_init(dbg, error);
223 if (ret != DW_DLE_NONE) {
224 _dwarf_deinit(dbg);
225 return (ret);
226 }
227 }
228
229 if (dbg->dbg_mode == DW_DLC_WRITE) {
230 ret = _dwarf_producer_init(dbg, pro_flags, error);
231 if (ret != DW_DLE_NONE) {
232 _dwarf_deinit(dbg);
233 return (ret);
234 }
235 }
236
237 /*
238 * Initialise internal string table.
239 */
240 if ((ret = _dwarf_strtab_init(dbg, error)) != DW_DLE_NONE)
241 return (ret);
242
243 return (DW_DLE_NONE);
244 }
245
246 static void
_dwarf_producer_deinit(Dwarf_P_Debug dbg)247 _dwarf_producer_deinit(Dwarf_P_Debug dbg)
248 {
249
250 assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE);
251
252 _dwarf_info_pro_cleanup(dbg);
253 _dwarf_die_pro_cleanup(dbg);
254 _dwarf_expr_cleanup(dbg);
255 _dwarf_lineno_pro_cleanup(dbg);
256 _dwarf_frame_pro_cleanup(dbg);
257 _dwarf_arange_pro_cleanup(dbg);
258 _dwarf_macinfo_pro_cleanup(dbg);
259 _dwarf_strtab_cleanup(dbg);
260 _dwarf_nametbl_pro_cleanup(&dbg->dbgp_pubs);
261 _dwarf_nametbl_pro_cleanup(&dbg->dbgp_weaks);
262 _dwarf_nametbl_pro_cleanup(&dbg->dbgp_funcs);
263 _dwarf_nametbl_pro_cleanup(&dbg->dbgp_types);
264 _dwarf_nametbl_pro_cleanup(&dbg->dbgp_vars);
265 _dwarf_section_cleanup(dbg);
266 _dwarf_reloc_cleanup(dbg);
267 }
268
269 static void
_dwarf_consumer_deinit(Dwarf_Debug dbg)270 _dwarf_consumer_deinit(Dwarf_Debug dbg)
271 {
272
273 assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ);
274
275 _dwarf_info_cleanup(dbg);
276 _dwarf_loclist_cleanup(dbg);
277 _dwarf_ranges_cleanup(dbg);
278 _dwarf_frame_cleanup(dbg);
279 _dwarf_arange_cleanup(dbg);
280 _dwarf_macinfo_cleanup(dbg);
281 _dwarf_strtab_cleanup(dbg);
282 _dwarf_nametbl_cleanup(&dbg->dbg_globals);
283 _dwarf_nametbl_cleanup(&dbg->dbg_pubtypes);
284 _dwarf_nametbl_cleanup(&dbg->dbg_weaks);
285 _dwarf_nametbl_cleanup(&dbg->dbg_funcs);
286 _dwarf_nametbl_cleanup(&dbg->dbg_vars);
287 _dwarf_nametbl_cleanup(&dbg->dbg_types);
288
289 free(dbg->dbg_section);
290 }
291
292 void
_dwarf_deinit(Dwarf_Debug dbg)293 _dwarf_deinit(Dwarf_Debug dbg)
294 {
295
296 assert(dbg != NULL);
297
298 if (dbg->dbg_mode == DW_DLC_READ)
299 _dwarf_consumer_deinit(dbg);
300 else if (dbg->dbg_mode == DW_DLC_WRITE)
301 _dwarf_producer_deinit(dbg);
302 }
303
304 int
_dwarf_alloc(Dwarf_Debug * ret_dbg,int mode,Dwarf_Error * error)305 _dwarf_alloc(Dwarf_Debug *ret_dbg, int mode, Dwarf_Error *error)
306 {
307 Dwarf_Debug dbg;
308
309 if ((dbg = calloc(sizeof(struct _Dwarf_Debug), 1)) == NULL) {
310 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
311 return (DW_DLE_MEMORY);
312 }
313
314 dbg->dbg_mode = mode;
315
316 *ret_dbg = dbg;
317
318 return (DW_DLE_NONE);
319 }
320