2 * Copyright (c) 2009,2011 Kai Wang
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 #include "_libdwarf.h"
29 ELFTC_VCSID("$Id: libdwarf_init.c 2948 2013-05-30 21:25:52Z kaiwang27 $");
32 _dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error)
34 const Dwarf_Obj_Access_Methods *m;
35 Dwarf_Obj_Access_Section sec;
42 assert(dbg->dbg_iface != NULL);
44 m = dbg->dbg_iface->methods;
45 obj = dbg->dbg_iface->object;
50 if (m->get_byte_order(obj) == DW_OBJECT_MSB) {
51 dbg->read = _dwarf_read_msb;
52 dbg->write = _dwarf_write_msb;
53 dbg->decode = _dwarf_decode_msb;
55 dbg->read = _dwarf_read_lsb;
56 dbg->write = _dwarf_write_lsb;
57 dbg->decode = _dwarf_decode_lsb;
60 dbg->dbg_pointer_size = m->get_pointer_size(obj);
61 dbg->dbg_offset_size = m->get_length_size(obj);
63 cnt = m->get_section_count(obj);
66 DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_INFO_NULL);
67 return (DW_DLE_DEBUG_INFO_NULL);
70 dbg->dbg_seccnt = cnt;
72 if ((dbg->dbg_section = calloc(cnt, sizeof(Dwarf_Section))) == NULL) {
73 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
74 return (DW_DLE_MEMORY);
77 for (i = 0; i < cnt; i++) {
78 if (m->get_section_info(obj, i, &sec, &ret) != DW_DLV_OK) {
79 DWARF_SET_ERROR(dbg, error, ret);
83 dbg->dbg_section[i].ds_addr = sec.addr;
84 dbg->dbg_section[i].ds_size = sec.size;
85 dbg->dbg_section[i].ds_name = sec.name;
87 if (m->load_section(obj, i, &dbg->dbg_section[i].ds_data, &ret)
89 DWARF_SET_ERROR(dbg, error, ret);
94 if (_dwarf_find_section(dbg, ".debug_abbrev") == NULL ||
95 ((dbg->dbg_info_sec = _dwarf_find_section(dbg, ".debug_info")) ==
97 DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_INFO_NULL);
98 return (DW_DLE_DEBUG_INFO_NULL);
101 /* Initialise call frame API related parameters. */
102 _dwarf_frame_params_init(dbg);
108 _dwarf_producer_init(Dwarf_Debug dbg, Dwarf_Unsigned pf, Dwarf_Error *error)
111 /* Producer only support DWARF2 which has fixed 32bit offset. */
112 dbg->dbg_offset_size = 4;
114 if (pf & DW_DLC_SIZE_32 && pf & DW_DLC_SIZE_64) {
115 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
116 return (DW_DLE_ARGUMENT);
119 if ((pf & DW_DLC_SIZE_32) == 0 && (pf & DW_DLC_SIZE_64) == 0)
120 pf |= DW_DLC_SIZE_32;
122 if (pf & DW_DLC_SIZE_64)
123 dbg->dbg_pointer_size = 8;
125 dbg->dbg_pointer_size = 4;
127 if (pf & DW_DLC_ISA_IA64 && pf & DW_DLC_ISA_MIPS) {
128 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
129 return (DW_DLE_ARGUMENT);
132 if (pf & DW_DLC_ISA_IA64)
133 dbg->dbgp_isa = DW_ISA_IA64;
135 dbg->dbgp_isa = DW_ISA_MIPS;
137 if (pf & DW_DLC_TARGET_BIGENDIAN && pf & DW_DLC_TARGET_LITTLEENDIAN) {
138 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
139 return (DW_DLE_ARGUMENT);
142 if ((pf & DW_DLC_TARGET_BIGENDIAN) == 0 &&
143 (pf & DW_DLC_TARGET_LITTLEENDIAN) == 0) {
144 #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_BIG_ENDIAN
145 pf |= DW_DLC_TARGET_BIGENDIAN;
147 pf |= DW_DLC_TARGET_LITTLEENDIAN;
151 if (pf & DW_DLC_TARGET_BIGENDIAN) {
152 dbg->write = _dwarf_write_msb;
153 dbg->write_alloc = _dwarf_write_msb_alloc;
154 } else if (pf & DW_DLC_TARGET_LITTLEENDIAN) {
155 dbg->write = _dwarf_write_lsb;
156 dbg->write_alloc = _dwarf_write_lsb_alloc;
160 if (pf & DW_DLC_STREAM_RELOCATIONS &&
161 pf & DW_DLC_SYMBOLIC_RELOCATIONS) {
162 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
163 return (DW_DLE_ARGUMENT);
166 if ((pf & DW_DLC_STREAM_RELOCATIONS) == 0 &&
167 (pf & DW_DLC_SYMBOLIC_RELOCATIONS) == 0)
168 pf |= DW_DLC_STREAM_RELOCATIONS;
170 dbg->dbgp_flags = pf;
172 STAILQ_INIT(&dbg->dbgp_dielist);
173 STAILQ_INIT(&dbg->dbgp_pelist);
174 STAILQ_INIT(&dbg->dbgp_seclist);
175 STAILQ_INIT(&dbg->dbgp_drslist);
176 STAILQ_INIT(&dbg->dbgp_cielist);
177 STAILQ_INIT(&dbg->dbgp_fdelist);
179 if ((dbg->dbgp_lineinfo = calloc(1, sizeof(struct _Dwarf_LineInfo))) ==
181 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
182 return (DW_DLE_MEMORY);
184 STAILQ_INIT(&dbg->dbgp_lineinfo->li_lflist);
185 STAILQ_INIT(&dbg->dbgp_lineinfo->li_lnlist);
187 if ((dbg->dbgp_as = calloc(1, sizeof(struct _Dwarf_ArangeSet))) ==
189 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
190 return (DW_DLE_MEMORY);
192 STAILQ_INIT(&dbg->dbgp_as->as_arlist);
194 return (DW_DLE_NONE);
198 _dwarf_init(Dwarf_Debug dbg, Dwarf_Unsigned pro_flags, Dwarf_Handler errhand,
199 Dwarf_Ptr errarg, Dwarf_Error *error)
206 * Set the error handler fields early, so that the application
207 * is notified of initialization errors.
209 dbg->dbg_errhand = errhand;
210 dbg->dbg_errarg = errarg;
212 STAILQ_INIT(&dbg->dbg_cu);
213 STAILQ_INIT(&dbg->dbg_rllist);
214 STAILQ_INIT(&dbg->dbg_aslist);
215 STAILQ_INIT(&dbg->dbg_mslist);
216 TAILQ_INIT(&dbg->dbg_loclist);
218 if (dbg->dbg_mode == DW_DLC_READ || dbg->dbg_mode == DW_DLC_RDWR) {
219 ret = _dwarf_consumer_init(dbg, error);
220 if (ret != DW_DLE_NONE) {
226 if (dbg->dbg_mode == DW_DLC_WRITE) {
227 ret = _dwarf_producer_init(dbg, pro_flags, error);
228 if (ret != DW_DLE_NONE) {
235 * Initialise internal string table.
237 if ((ret = _dwarf_strtab_init(dbg, error)) != DW_DLE_NONE)
240 return (DW_DLE_NONE);
244 _dwarf_producer_deinit(Dwarf_P_Debug dbg)
247 assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE);
249 _dwarf_info_pro_cleanup(dbg);
250 _dwarf_die_pro_cleanup(dbg);
251 _dwarf_expr_cleanup(dbg);
252 _dwarf_lineno_pro_cleanup(dbg);
253 _dwarf_frame_pro_cleanup(dbg);
254 _dwarf_arange_pro_cleanup(dbg);
255 _dwarf_macinfo_pro_cleanup(dbg);
256 _dwarf_strtab_cleanup(dbg);
257 _dwarf_nametbl_pro_cleanup(&dbg->dbgp_pubs);
258 _dwarf_nametbl_pro_cleanup(&dbg->dbgp_weaks);
259 _dwarf_nametbl_pro_cleanup(&dbg->dbgp_funcs);
260 _dwarf_nametbl_pro_cleanup(&dbg->dbgp_types);
261 _dwarf_nametbl_pro_cleanup(&dbg->dbgp_vars);
262 _dwarf_section_cleanup(dbg);
263 _dwarf_reloc_cleanup(dbg);
267 _dwarf_consumer_deinit(Dwarf_Debug dbg)
270 assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ);
272 _dwarf_info_cleanup(dbg);
273 _dwarf_loclist_cleanup(dbg);
274 _dwarf_ranges_cleanup(dbg);
275 _dwarf_frame_cleanup(dbg);
276 _dwarf_arange_cleanup(dbg);
277 _dwarf_macinfo_cleanup(dbg);
278 _dwarf_strtab_cleanup(dbg);
279 _dwarf_nametbl_cleanup(&dbg->dbg_globals);
280 _dwarf_nametbl_cleanup(&dbg->dbg_pubtypes);
281 _dwarf_nametbl_cleanup(&dbg->dbg_weaks);
282 _dwarf_nametbl_cleanup(&dbg->dbg_funcs);
283 _dwarf_nametbl_cleanup(&dbg->dbg_vars);
284 _dwarf_nametbl_cleanup(&dbg->dbg_types);
286 free(dbg->dbg_section);
290 _dwarf_deinit(Dwarf_Debug dbg)
295 if (dbg->dbg_mode == DW_DLC_READ)
296 _dwarf_consumer_deinit(dbg);
297 else if (dbg->dbg_mode == DW_DLC_WRITE)
298 _dwarf_producer_deinit(dbg);
302 _dwarf_alloc(Dwarf_Debug *ret_dbg, int mode, Dwarf_Error *error)
306 if ((dbg = calloc(sizeof(struct _Dwarf_Debug), 1)) == NULL) {
307 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
308 return (DW_DLE_MEMORY);
311 dbg->dbg_mode = mode;
315 return (DW_DLE_NONE);