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 3061 2014-06-02 00:42:41Z 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 if (_dwarf_find_section(dbg, ".debug_abbrev") == NULL || 97 ((dbg->dbg_info_sec = _dwarf_find_section(dbg, ".debug_info")) == 98 NULL)) { 99 DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_INFO_NULL); 100 return (DW_DLE_DEBUG_INFO_NULL); 101 } 102 103 /* Try to find the optional DWARF4 .debug_types section. */ 104 dbg->dbg_types_sec = _dwarf_find_next_types_section(dbg, NULL); 105 106 /* Initialise call frame API related parameters. */ 107 _dwarf_frame_params_init(dbg); 108 109 return (DW_DLV_OK); 110 } 111 112 static int 113 _dwarf_producer_init(Dwarf_Debug dbg, Dwarf_Unsigned pf, Dwarf_Error *error) 114 { 115 116 /* Producer only support DWARF2 which has fixed 32bit offset. */ 117 dbg->dbg_offset_size = 4; 118 119 if (pf & DW_DLC_SIZE_32 && pf & DW_DLC_SIZE_64) { 120 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 121 return (DW_DLE_ARGUMENT); 122 } 123 124 if ((pf & DW_DLC_SIZE_32) == 0 && (pf & DW_DLC_SIZE_64) == 0) 125 pf |= DW_DLC_SIZE_32; 126 127 if (pf & DW_DLC_SIZE_64) 128 dbg->dbg_pointer_size = 8; 129 else 130 dbg->dbg_pointer_size = 4; 131 132 if (pf & DW_DLC_ISA_IA64 && pf & DW_DLC_ISA_MIPS) { 133 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 134 return (DW_DLE_ARGUMENT); 135 } 136 137 if (pf & DW_DLC_ISA_IA64) 138 dbg->dbgp_isa = DW_ISA_IA64; 139 else 140 dbg->dbgp_isa = DW_ISA_MIPS; 141 142 if (pf & DW_DLC_TARGET_BIGENDIAN && pf & DW_DLC_TARGET_LITTLEENDIAN) { 143 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 144 return (DW_DLE_ARGUMENT); 145 } 146 147 if ((pf & DW_DLC_TARGET_BIGENDIAN) == 0 && 148 (pf & DW_DLC_TARGET_LITTLEENDIAN) == 0) { 149 #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_BIG_ENDIAN 150 pf |= DW_DLC_TARGET_BIGENDIAN; 151 #else 152 pf |= DW_DLC_TARGET_LITTLEENDIAN; 153 #endif 154 } 155 156 if (pf & DW_DLC_TARGET_BIGENDIAN) { 157 dbg->write = _dwarf_write_msb; 158 dbg->write_alloc = _dwarf_write_msb_alloc; 159 } else if (pf & DW_DLC_TARGET_LITTLEENDIAN) { 160 dbg->write = _dwarf_write_lsb; 161 dbg->write_alloc = _dwarf_write_lsb_alloc; 162 } else 163 assert(0); 164 165 if (pf & DW_DLC_STREAM_RELOCATIONS && 166 pf & DW_DLC_SYMBOLIC_RELOCATIONS) { 167 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 168 return (DW_DLE_ARGUMENT); 169 } 170 171 if ((pf & DW_DLC_STREAM_RELOCATIONS) == 0 && 172 (pf & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) 173 pf |= DW_DLC_STREAM_RELOCATIONS; 174 175 dbg->dbgp_flags = pf; 176 177 STAILQ_INIT(&dbg->dbgp_dielist); 178 STAILQ_INIT(&dbg->dbgp_pelist); 179 STAILQ_INIT(&dbg->dbgp_seclist); 180 STAILQ_INIT(&dbg->dbgp_drslist); 181 STAILQ_INIT(&dbg->dbgp_cielist); 182 STAILQ_INIT(&dbg->dbgp_fdelist); 183 184 if ((dbg->dbgp_lineinfo = calloc(1, sizeof(struct _Dwarf_LineInfo))) == 185 NULL) { 186 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 187 return (DW_DLE_MEMORY); 188 } 189 STAILQ_INIT(&dbg->dbgp_lineinfo->li_lflist); 190 STAILQ_INIT(&dbg->dbgp_lineinfo->li_lnlist); 191 192 if ((dbg->dbgp_as = calloc(1, sizeof(struct _Dwarf_ArangeSet))) == 193 NULL) { 194 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 195 return (DW_DLE_MEMORY); 196 } 197 STAILQ_INIT(&dbg->dbgp_as->as_arlist); 198 199 return (DW_DLE_NONE); 200 } 201 202 int 203 _dwarf_init(Dwarf_Debug dbg, Dwarf_Unsigned pro_flags, Dwarf_Handler errhand, 204 Dwarf_Ptr errarg, Dwarf_Error *error) 205 { 206 int ret; 207 208 ret = DW_DLE_NONE; 209 210 /* 211 * Set the error handler fields early, so that the application 212 * is notified of initialization errors. 213 */ 214 dbg->dbg_errhand = errhand; 215 dbg->dbg_errarg = errarg; 216 217 STAILQ_INIT(&dbg->dbg_cu); 218 STAILQ_INIT(&dbg->dbg_tu); 219 STAILQ_INIT(&dbg->dbg_rllist); 220 STAILQ_INIT(&dbg->dbg_aslist); 221 STAILQ_INIT(&dbg->dbg_mslist); 222 223 if (dbg->dbg_mode == DW_DLC_READ || dbg->dbg_mode == DW_DLC_RDWR) { 224 ret = _dwarf_consumer_init(dbg, error); 225 if (ret != DW_DLE_NONE) { 226 _dwarf_deinit(dbg); 227 return (ret); 228 } 229 } 230 231 if (dbg->dbg_mode == DW_DLC_WRITE) { 232 ret = _dwarf_producer_init(dbg, pro_flags, error); 233 if (ret != DW_DLE_NONE) { 234 _dwarf_deinit(dbg); 235 return (ret); 236 } 237 } 238 239 /* 240 * Initialise internal string table. 241 */ 242 if ((ret = _dwarf_strtab_init(dbg, error)) != DW_DLE_NONE) 243 return (ret); 244 245 return (DW_DLE_NONE); 246 } 247 248 static void 249 _dwarf_producer_deinit(Dwarf_P_Debug dbg) 250 { 251 252 assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); 253 254 _dwarf_info_pro_cleanup(dbg); 255 _dwarf_die_pro_cleanup(dbg); 256 _dwarf_expr_cleanup(dbg); 257 _dwarf_lineno_pro_cleanup(dbg); 258 _dwarf_frame_pro_cleanup(dbg); 259 _dwarf_arange_pro_cleanup(dbg); 260 _dwarf_macinfo_pro_cleanup(dbg); 261 _dwarf_strtab_cleanup(dbg); 262 _dwarf_nametbl_pro_cleanup(&dbg->dbgp_pubs); 263 _dwarf_nametbl_pro_cleanup(&dbg->dbgp_weaks); 264 _dwarf_nametbl_pro_cleanup(&dbg->dbgp_funcs); 265 _dwarf_nametbl_pro_cleanup(&dbg->dbgp_types); 266 _dwarf_nametbl_pro_cleanup(&dbg->dbgp_vars); 267 _dwarf_section_cleanup(dbg); 268 _dwarf_reloc_cleanup(dbg); 269 } 270 271 static void 272 _dwarf_consumer_deinit(Dwarf_Debug dbg) 273 { 274 275 assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); 276 277 _dwarf_info_cleanup(dbg); 278 _dwarf_ranges_cleanup(dbg); 279 _dwarf_frame_cleanup(dbg); 280 _dwarf_arange_cleanup(dbg); 281 _dwarf_macinfo_cleanup(dbg); 282 _dwarf_strtab_cleanup(dbg); 283 _dwarf_nametbl_cleanup(&dbg->dbg_globals); 284 _dwarf_nametbl_cleanup(&dbg->dbg_pubtypes); 285 _dwarf_nametbl_cleanup(&dbg->dbg_weaks); 286 _dwarf_nametbl_cleanup(&dbg->dbg_funcs); 287 _dwarf_nametbl_cleanup(&dbg->dbg_vars); 288 _dwarf_nametbl_cleanup(&dbg->dbg_types); 289 290 free(dbg->dbg_section); 291 } 292 293 void 294 _dwarf_deinit(Dwarf_Debug dbg) 295 { 296 297 assert(dbg != NULL); 298 299 if (dbg->dbg_mode == DW_DLC_READ) 300 _dwarf_consumer_deinit(dbg); 301 else if (dbg->dbg_mode == DW_DLC_WRITE) 302 _dwarf_producer_deinit(dbg); 303 } 304 305 int 306 _dwarf_alloc(Dwarf_Debug *ret_dbg, int mode, Dwarf_Error *error) 307 { 308 Dwarf_Debug dbg; 309 310 if ((dbg = calloc(sizeof(struct _Dwarf_Debug), 1)) == NULL) { 311 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 312 return (DW_DLE_MEMORY); 313 } 314 315 dbg->dbg_mode = mode; 316 317 *ret_dbg = dbg; 318 319 return (DW_DLE_NONE); 320 } 321