1 /*- 2 * Copyright (c) 2009,2011 Kai Wang 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 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. 13 * 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 24 * SUCH DAMAGE. 25 */ 26 27 #include "_libdwarf.h" 28 29 ELFTC_VCSID("$Id: libdwarf_init.c 3136 2014-12-24 16:04:38Z kaiwang27 $"); 30 31 static int 32 _dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error) 33 { 34 const Dwarf_Obj_Access_Methods *m; 35 Dwarf_Obj_Access_Section sec; 36 void *obj; 37 Dwarf_Unsigned cnt; 38 Dwarf_Half i; 39 int ret; 40 41 assert(dbg != NULL); 42 assert(dbg->dbg_iface != NULL); 43 44 m = dbg->dbg_iface->methods; 45 obj = dbg->dbg_iface->object; 46 47 assert(m != NULL); 48 assert(obj != NULL); 49 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; 54 } else { 55 dbg->read = _dwarf_read_lsb; 56 dbg->write = _dwarf_write_lsb; 57 dbg->decode = _dwarf_decode_lsb; 58 } 59 60 dbg->dbg_pointer_size = m->get_pointer_size(obj); 61 dbg->dbg_offset_size = m->get_length_size(obj); 62 63 cnt = m->get_section_count(obj); 64 65 if (cnt == 0) { 66 DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_INFO_NULL); 67 return (DW_DLE_DEBUG_INFO_NULL); 68 } 69 70 dbg->dbg_seccnt = cnt; 71 72 if ((dbg->dbg_section = calloc(cnt + 1, sizeof(Dwarf_Section))) == 73 NULL) { 74 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 75 return (DW_DLE_MEMORY); 76 } 77 78 for (i = 0; i < cnt; i++) { 79 if (m->get_section_info(obj, i, &sec, &ret) != DW_DLV_OK) { 80 DWARF_SET_ERROR(dbg, error, ret); 81 return (ret); 82 } 83 84 dbg->dbg_section[i].ds_addr = sec.addr; 85 dbg->dbg_section[i].ds_size = sec.size; 86 dbg->dbg_section[i].ds_name = sec.name; 87 88 if (m->load_section(obj, i, &dbg->dbg_section[i].ds_data, &ret) 89 != DW_DLV_OK) { 90 DWARF_SET_ERROR(dbg, error, ret); 91 return (ret); 92 } 93 } 94 dbg->dbg_section[cnt].ds_name = NULL; 95 96 dbg->dbg_info_sec = _dwarf_find_section(dbg, ".debug_info"); 97 98 /* Try to find the optional DWARF4 .debug_types section. */ 99 dbg->dbg_types_sec = _dwarf_find_next_types_section(dbg, NULL); 100 101 /* Initialise call frame API related parameters. */ 102 _dwarf_frame_params_init(dbg); 103 104 return (DW_DLV_OK); 105 } 106 107 static int 108 _dwarf_producer_init(Dwarf_Debug dbg, Dwarf_Unsigned pf, Dwarf_Error *error) 109 { 110 111 /* Producer only support DWARF2 which has fixed 32bit offset. */ 112 dbg->dbg_offset_size = 4; 113 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); 117 } 118 119 if ((pf & DW_DLC_SIZE_32) == 0 && (pf & DW_DLC_SIZE_64) == 0) 120 pf |= DW_DLC_SIZE_32; 121 122 if (pf & DW_DLC_SIZE_64) 123 dbg->dbg_pointer_size = 8; 124 else 125 dbg->dbg_pointer_size = 4; 126 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); 130 } 131 132 if (pf & DW_DLC_ISA_IA64) 133 dbg->dbgp_isa = DW_ISA_IA64; 134 else 135 dbg->dbgp_isa = DW_ISA_MIPS; 136 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); 140 } 141 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; 146 #else 147 pf |= DW_DLC_TARGET_LITTLEENDIAN; 148 #endif 149 } 150 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; 157 } else 158 assert(0); 159 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); 164 } 165 166 if ((pf & DW_DLC_STREAM_RELOCATIONS) == 0 && 167 (pf & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) 168 pf |= DW_DLC_STREAM_RELOCATIONS; 169 170 dbg->dbgp_flags = pf; 171 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); 178 179 if ((dbg->dbgp_lineinfo = calloc(1, sizeof(struct _Dwarf_LineInfo))) == 180 NULL) { 181 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 182 return (DW_DLE_MEMORY); 183 } 184 STAILQ_INIT(&dbg->dbgp_lineinfo->li_lflist); 185 STAILQ_INIT(&dbg->dbgp_lineinfo->li_lnlist); 186 187 if ((dbg->dbgp_as = calloc(1, sizeof(struct _Dwarf_ArangeSet))) == 188 NULL) { 189 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 190 return (DW_DLE_MEMORY); 191 } 192 STAILQ_INIT(&dbg->dbgp_as->as_arlist); 193 194 return (DW_DLE_NONE); 195 } 196 197 int 198 _dwarf_init(Dwarf_Debug dbg, Dwarf_Unsigned pro_flags, Dwarf_Handler errhand, 199 Dwarf_Ptr errarg, Dwarf_Error *error) 200 { 201 int ret; 202 203 ret = DW_DLE_NONE; 204 205 /* 206 * Set the error handler fields early, so that the application 207 * is notified of initialization errors. 208 */ 209 dbg->dbg_errhand = errhand; 210 dbg->dbg_errarg = errarg; 211 212 STAILQ_INIT(&dbg->dbg_cu); 213 STAILQ_INIT(&dbg->dbg_tu); 214 STAILQ_INIT(&dbg->dbg_rllist); 215 STAILQ_INIT(&dbg->dbg_aslist); 216 STAILQ_INIT(&dbg->dbg_mslist); 217 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) { 221 _dwarf_deinit(dbg); 222 return (ret); 223 } 224 } 225 226 if (dbg->dbg_mode == DW_DLC_WRITE) { 227 ret = _dwarf_producer_init(dbg, pro_flags, error); 228 if (ret != DW_DLE_NONE) { 229 _dwarf_deinit(dbg); 230 return (ret); 231 } 232 } 233 234 /* 235 * Initialise internal string table. 236 */ 237 if ((ret = _dwarf_strtab_init(dbg, error)) != DW_DLE_NONE) 238 return (ret); 239 240 return (DW_DLE_NONE); 241 } 242 243 static void 244 _dwarf_producer_deinit(Dwarf_P_Debug dbg) 245 { 246 247 assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); 248 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); 264 } 265 266 static void 267 _dwarf_consumer_deinit(Dwarf_Debug dbg) 268 { 269 270 assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); 271 272 _dwarf_info_cleanup(dbg); 273 _dwarf_ranges_cleanup(dbg); 274 _dwarf_frame_cleanup(dbg); 275 _dwarf_arange_cleanup(dbg); 276 _dwarf_macinfo_cleanup(dbg); 277 _dwarf_strtab_cleanup(dbg); 278 _dwarf_nametbl_cleanup(&dbg->dbg_globals); 279 _dwarf_nametbl_cleanup(&dbg->dbg_pubtypes); 280 _dwarf_nametbl_cleanup(&dbg->dbg_weaks); 281 _dwarf_nametbl_cleanup(&dbg->dbg_funcs); 282 _dwarf_nametbl_cleanup(&dbg->dbg_vars); 283 _dwarf_nametbl_cleanup(&dbg->dbg_types); 284 285 free(dbg->dbg_section); 286 } 287 288 void 289 _dwarf_deinit(Dwarf_Debug dbg) 290 { 291 292 assert(dbg != NULL); 293 294 if (dbg->dbg_mode == DW_DLC_READ) 295 _dwarf_consumer_deinit(dbg); 296 else if (dbg->dbg_mode == DW_DLC_WRITE) 297 _dwarf_producer_deinit(dbg); 298 } 299 300 int 301 _dwarf_alloc(Dwarf_Debug *ret_dbg, int mode, Dwarf_Error *error) 302 { 303 Dwarf_Debug dbg; 304 305 if ((dbg = calloc(sizeof(struct _Dwarf_Debug), 1)) == NULL) { 306 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 307 return (DW_DLE_MEMORY); 308 } 309 310 dbg->dbg_mode = mode; 311 312 *ret_dbg = dbg; 313 314 return (DW_DLE_NONE); 315 } 316