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 2948 2013-05-30 21:25:52Z 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, sizeof(Dwarf_Section))) == NULL) { 73 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 74 return (DW_DLE_MEMORY); 75 } 76 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); 80 return (ret); 81 } 82 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; 86 87 if (m->load_section(obj, i, &dbg->dbg_section[i].ds_data, &ret) 88 != DW_DLV_OK) { 89 DWARF_SET_ERROR(dbg, error, ret); 90 return (ret); 91 } 92 } 93 94 if (_dwarf_find_section(dbg, ".debug_abbrev") == NULL || 95 ((dbg->dbg_info_sec = _dwarf_find_section(dbg, ".debug_info")) == 96 NULL)) { 97 DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_INFO_NULL); 98 return (DW_DLE_DEBUG_INFO_NULL); 99 } 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_rllist); 214 STAILQ_INIT(&dbg->dbg_aslist); 215 STAILQ_INIT(&dbg->dbg_mslist); 216 TAILQ_INIT(&dbg->dbg_loclist); 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_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); 285 286 free(dbg->dbg_section); 287 } 288 289 void 290 _dwarf_deinit(Dwarf_Debug dbg) 291 { 292 293 assert(dbg != NULL); 294 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); 299 } 300 301 int 302 _dwarf_alloc(Dwarf_Debug *ret_dbg, int mode, Dwarf_Error *error) 303 { 304 Dwarf_Debug dbg; 305 306 if ((dbg = calloc(sizeof(struct _Dwarf_Debug), 1)) == NULL) { 307 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 308 return (DW_DLE_MEMORY); 309 } 310 311 dbg->dbg_mode = mode; 312 313 *ret_dbg = dbg; 314 315 return (DW_DLE_NONE); 316 } 317