1 /* $NetBSD: libdwarf_init.c,v 1.3 2016/02/20 02:43:41 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.3 2016/02/20 02:43:41 christos Exp $"); 32 ELFTC_VCSID("Id: libdwarf_init.c 3136 2014-12-24 16:04:38Z kaiwang27 "); 33 34 static int 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 + 1, sizeof(Dwarf_Section))) == 76 NULL) { 77 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 78 return (DW_DLE_MEMORY); 79 } 80 81 for (i = 0; i < cnt; i++) { 82 if (m->get_section_info(obj, i, &sec, &ret) != DW_DLV_OK) { 83 DWARF_SET_ERROR(dbg, error, ret); 84 return (ret); 85 } 86 87 dbg->dbg_section[i].ds_addr = sec.addr; 88 dbg->dbg_section[i].ds_size = sec.size; 89 dbg->dbg_section[i].ds_name = sec.name; 90 91 if (m->load_section(obj, i, &dbg->dbg_section[i].ds_data, &ret) 92 != DW_DLV_OK) { 93 DWARF_SET_ERROR(dbg, error, ret); 94 return (ret); 95 } 96 } 97 dbg->dbg_section[cnt].ds_name = NULL; 98 99 dbg->dbg_info_sec = _dwarf_find_section(dbg, ".debug_info"); 100 101 /* Try to find the optional DWARF4 .debug_types section. */ 102 dbg->dbg_types_sec = _dwarf_find_next_types_section(dbg, NULL); 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 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 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_tu); 217 STAILQ_INIT(&dbg->dbg_rllist); 218 STAILQ_INIT(&dbg->dbg_aslist); 219 STAILQ_INIT(&dbg->dbg_mslist); 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 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 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_ranges_cleanup(dbg); 277 _dwarf_frame_cleanup(dbg); 278 _dwarf_arange_cleanup(dbg); 279 _dwarf_macinfo_cleanup(dbg); 280 _dwarf_strtab_cleanup(dbg); 281 _dwarf_nametbl_cleanup(&dbg->dbg_globals); 282 _dwarf_nametbl_cleanup(&dbg->dbg_pubtypes); 283 _dwarf_nametbl_cleanup(&dbg->dbg_weaks); 284 _dwarf_nametbl_cleanup(&dbg->dbg_funcs); 285 _dwarf_nametbl_cleanup(&dbg->dbg_vars); 286 _dwarf_nametbl_cleanup(&dbg->dbg_types); 287 288 free(dbg->dbg_section); 289 } 290 291 void 292 _dwarf_deinit(Dwarf_Debug dbg) 293 { 294 295 assert(dbg != NULL); 296 297 if (dbg->dbg_mode == DW_DLC_READ) 298 _dwarf_consumer_deinit(dbg); 299 else if (dbg->dbg_mode == DW_DLC_WRITE) 300 _dwarf_producer_deinit(dbg); 301 } 302 303 int 304 _dwarf_alloc(Dwarf_Debug *ret_dbg, int mode, Dwarf_Error *error) 305 { 306 Dwarf_Debug dbg; 307 308 if ((dbg = calloc(sizeof(struct _Dwarf_Debug), 1)) == NULL) { 309 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 310 return (DW_DLE_MEMORY); 311 } 312 313 dbg->dbg_mode = mode; 314 315 *ret_dbg = dbg; 316 317 return (DW_DLE_NONE); 318 } 319