1260684Skaiw/*- 2260684Skaiw * Copyright (c) 2009,2011 Kai Wang 3260684Skaiw * All rights reserved. 4260684Skaiw * 5260684Skaiw * Redistribution and use in source and binary forms, with or without 6260684Skaiw * modification, are permitted provided that the following conditions 7260684Skaiw * are met: 8260684Skaiw * 1. Redistributions of source code must retain the above copyright 9260684Skaiw * notice, this list of conditions and the following disclaimer. 10260684Skaiw * 2. Redistributions in binary form must reproduce the above copyright 11260684Skaiw * notice, this list of conditions and the following disclaimer in the 12260684Skaiw * documentation and/or other materials provided with the distribution. 13260684Skaiw * 14260684Skaiw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15260684Skaiw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16260684Skaiw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17260684Skaiw * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18260684Skaiw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19260684Skaiw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20260684Skaiw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21260684Skaiw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22260684Skaiw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23260684Skaiw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24260684Skaiw * SUCH DAMAGE. 25260684Skaiw */ 26260684Skaiw 27260684Skaiw#include "_libdwarf.h" 28260684Skaiw 29276398SemasteELFTC_VCSID("$Id: libdwarf_init.c 3136 2014-12-24 16:04:38Z kaiwang27 $"); 30260684Skaiw 31260684Skaiwstatic int 32260684Skaiw_dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error) 33260684Skaiw{ 34260684Skaiw const Dwarf_Obj_Access_Methods *m; 35260684Skaiw Dwarf_Obj_Access_Section sec; 36260684Skaiw void *obj; 37260684Skaiw Dwarf_Unsigned cnt; 38260684Skaiw Dwarf_Half i; 39260684Skaiw int ret; 40260684Skaiw 41260684Skaiw assert(dbg != NULL); 42260684Skaiw assert(dbg->dbg_iface != NULL); 43260684Skaiw 44260684Skaiw m = dbg->dbg_iface->methods; 45260684Skaiw obj = dbg->dbg_iface->object; 46260684Skaiw 47260684Skaiw assert(m != NULL); 48260684Skaiw assert(obj != NULL); 49260684Skaiw 50260684Skaiw if (m->get_byte_order(obj) == DW_OBJECT_MSB) { 51260684Skaiw dbg->read = _dwarf_read_msb; 52260684Skaiw dbg->write = _dwarf_write_msb; 53260684Skaiw dbg->decode = _dwarf_decode_msb; 54260684Skaiw } else { 55260684Skaiw dbg->read = _dwarf_read_lsb; 56260684Skaiw dbg->write = _dwarf_write_lsb; 57260684Skaiw dbg->decode = _dwarf_decode_lsb; 58260684Skaiw } 59260684Skaiw 60260684Skaiw dbg->dbg_pointer_size = m->get_pointer_size(obj); 61260684Skaiw dbg->dbg_offset_size = m->get_length_size(obj); 62260684Skaiw 63260684Skaiw cnt = m->get_section_count(obj); 64260684Skaiw 65260684Skaiw if (cnt == 0) { 66260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_INFO_NULL); 67260684Skaiw return (DW_DLE_DEBUG_INFO_NULL); 68260684Skaiw } 69260684Skaiw 70260684Skaiw dbg->dbg_seccnt = cnt; 71260684Skaiw 72276371Semaste if ((dbg->dbg_section = calloc(cnt + 1, sizeof(Dwarf_Section))) == 73276371Semaste NULL) { 74260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 75260684Skaiw return (DW_DLE_MEMORY); 76260684Skaiw } 77260684Skaiw 78260684Skaiw for (i = 0; i < cnt; i++) { 79260684Skaiw if (m->get_section_info(obj, i, &sec, &ret) != DW_DLV_OK) { 80260684Skaiw DWARF_SET_ERROR(dbg, error, ret); 81260684Skaiw return (ret); 82260684Skaiw } 83260684Skaiw 84260684Skaiw dbg->dbg_section[i].ds_addr = sec.addr; 85260684Skaiw dbg->dbg_section[i].ds_size = sec.size; 86260684Skaiw dbg->dbg_section[i].ds_name = sec.name; 87260684Skaiw 88260684Skaiw if (m->load_section(obj, i, &dbg->dbg_section[i].ds_data, &ret) 89260684Skaiw != DW_DLV_OK) { 90260684Skaiw DWARF_SET_ERROR(dbg, error, ret); 91260684Skaiw return (ret); 92260684Skaiw } 93260684Skaiw } 94276371Semaste dbg->dbg_section[cnt].ds_name = NULL; 95260684Skaiw 96276398Semaste dbg->dbg_info_sec = _dwarf_find_section(dbg, ".debug_info"); 97260684Skaiw 98276371Semaste /* Try to find the optional DWARF4 .debug_types section. */ 99276371Semaste dbg->dbg_types_sec = _dwarf_find_next_types_section(dbg, NULL); 100276371Semaste 101260684Skaiw /* Initialise call frame API related parameters. */ 102260684Skaiw _dwarf_frame_params_init(dbg); 103260684Skaiw 104260684Skaiw return (DW_DLV_OK); 105260684Skaiw} 106260684Skaiw 107260684Skaiwstatic int 108260684Skaiw_dwarf_producer_init(Dwarf_Debug dbg, Dwarf_Unsigned pf, Dwarf_Error *error) 109260684Skaiw{ 110260684Skaiw 111260684Skaiw /* Producer only support DWARF2 which has fixed 32bit offset. */ 112260684Skaiw dbg->dbg_offset_size = 4; 113260684Skaiw 114260684Skaiw if (pf & DW_DLC_SIZE_32 && pf & DW_DLC_SIZE_64) { 115260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 116260684Skaiw return (DW_DLE_ARGUMENT); 117260684Skaiw } 118260684Skaiw 119260684Skaiw if ((pf & DW_DLC_SIZE_32) == 0 && (pf & DW_DLC_SIZE_64) == 0) 120260684Skaiw pf |= DW_DLC_SIZE_32; 121260684Skaiw 122260684Skaiw if (pf & DW_DLC_SIZE_64) 123260684Skaiw dbg->dbg_pointer_size = 8; 124260684Skaiw else 125260684Skaiw dbg->dbg_pointer_size = 4; 126260684Skaiw 127260684Skaiw if (pf & DW_DLC_ISA_IA64 && pf & DW_DLC_ISA_MIPS) { 128260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 129260684Skaiw return (DW_DLE_ARGUMENT); 130260684Skaiw } 131260684Skaiw 132260684Skaiw if (pf & DW_DLC_ISA_IA64) 133260684Skaiw dbg->dbgp_isa = DW_ISA_IA64; 134260684Skaiw else 135260684Skaiw dbg->dbgp_isa = DW_ISA_MIPS; 136260684Skaiw 137260684Skaiw if (pf & DW_DLC_TARGET_BIGENDIAN && pf & DW_DLC_TARGET_LITTLEENDIAN) { 138260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 139260684Skaiw return (DW_DLE_ARGUMENT); 140260684Skaiw } 141260684Skaiw 142260684Skaiw if ((pf & DW_DLC_TARGET_BIGENDIAN) == 0 && 143260684Skaiw (pf & DW_DLC_TARGET_LITTLEENDIAN) == 0) { 144260684Skaiw#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_BIG_ENDIAN 145260684Skaiw pf |= DW_DLC_TARGET_BIGENDIAN; 146260684Skaiw#else 147260684Skaiw pf |= DW_DLC_TARGET_LITTLEENDIAN; 148260684Skaiw#endif 149260684Skaiw } 150260684Skaiw 151260684Skaiw if (pf & DW_DLC_TARGET_BIGENDIAN) { 152260684Skaiw dbg->write = _dwarf_write_msb; 153260684Skaiw dbg->write_alloc = _dwarf_write_msb_alloc; 154260684Skaiw } else if (pf & DW_DLC_TARGET_LITTLEENDIAN) { 155260684Skaiw dbg->write = _dwarf_write_lsb; 156260684Skaiw dbg->write_alloc = _dwarf_write_lsb_alloc; 157260684Skaiw } else 158260684Skaiw assert(0); 159260684Skaiw 160260684Skaiw if (pf & DW_DLC_STREAM_RELOCATIONS && 161260684Skaiw pf & DW_DLC_SYMBOLIC_RELOCATIONS) { 162260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 163260684Skaiw return (DW_DLE_ARGUMENT); 164260684Skaiw } 165260684Skaiw 166260684Skaiw if ((pf & DW_DLC_STREAM_RELOCATIONS) == 0 && 167260684Skaiw (pf & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) 168260684Skaiw pf |= DW_DLC_STREAM_RELOCATIONS; 169260684Skaiw 170260684Skaiw dbg->dbgp_flags = pf; 171260684Skaiw 172260684Skaiw STAILQ_INIT(&dbg->dbgp_dielist); 173260684Skaiw STAILQ_INIT(&dbg->dbgp_pelist); 174260684Skaiw STAILQ_INIT(&dbg->dbgp_seclist); 175260684Skaiw STAILQ_INIT(&dbg->dbgp_drslist); 176260684Skaiw STAILQ_INIT(&dbg->dbgp_cielist); 177260684Skaiw STAILQ_INIT(&dbg->dbgp_fdelist); 178260684Skaiw 179260684Skaiw if ((dbg->dbgp_lineinfo = calloc(1, sizeof(struct _Dwarf_LineInfo))) == 180260684Skaiw NULL) { 181260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 182260684Skaiw return (DW_DLE_MEMORY); 183260684Skaiw } 184260684Skaiw STAILQ_INIT(&dbg->dbgp_lineinfo->li_lflist); 185260684Skaiw STAILQ_INIT(&dbg->dbgp_lineinfo->li_lnlist); 186260684Skaiw 187260684Skaiw if ((dbg->dbgp_as = calloc(1, sizeof(struct _Dwarf_ArangeSet))) == 188260684Skaiw NULL) { 189260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 190260684Skaiw return (DW_DLE_MEMORY); 191260684Skaiw } 192260684Skaiw STAILQ_INIT(&dbg->dbgp_as->as_arlist); 193260684Skaiw 194260684Skaiw return (DW_DLE_NONE); 195260684Skaiw} 196260684Skaiw 197260684Skaiwint 198260684Skaiw_dwarf_init(Dwarf_Debug dbg, Dwarf_Unsigned pro_flags, Dwarf_Handler errhand, 199260684Skaiw Dwarf_Ptr errarg, Dwarf_Error *error) 200260684Skaiw{ 201260684Skaiw int ret; 202260684Skaiw 203260684Skaiw ret = DW_DLE_NONE; 204260684Skaiw 205260684Skaiw /* 206260684Skaiw * Set the error handler fields early, so that the application 207260684Skaiw * is notified of initialization errors. 208260684Skaiw */ 209260684Skaiw dbg->dbg_errhand = errhand; 210260684Skaiw dbg->dbg_errarg = errarg; 211260684Skaiw 212260684Skaiw STAILQ_INIT(&dbg->dbg_cu); 213276371Semaste STAILQ_INIT(&dbg->dbg_tu); 214260684Skaiw STAILQ_INIT(&dbg->dbg_rllist); 215260684Skaiw STAILQ_INIT(&dbg->dbg_aslist); 216260684Skaiw STAILQ_INIT(&dbg->dbg_mslist); 217260684Skaiw 218260684Skaiw if (dbg->dbg_mode == DW_DLC_READ || dbg->dbg_mode == DW_DLC_RDWR) { 219260684Skaiw ret = _dwarf_consumer_init(dbg, error); 220260684Skaiw if (ret != DW_DLE_NONE) { 221260684Skaiw _dwarf_deinit(dbg); 222260684Skaiw return (ret); 223260684Skaiw } 224260684Skaiw } 225260684Skaiw 226260684Skaiw if (dbg->dbg_mode == DW_DLC_WRITE) { 227260684Skaiw ret = _dwarf_producer_init(dbg, pro_flags, error); 228260684Skaiw if (ret != DW_DLE_NONE) { 229260684Skaiw _dwarf_deinit(dbg); 230260684Skaiw return (ret); 231260684Skaiw } 232260684Skaiw } 233260684Skaiw 234260684Skaiw /* 235260684Skaiw * Initialise internal string table. 236260684Skaiw */ 237260684Skaiw if ((ret = _dwarf_strtab_init(dbg, error)) != DW_DLE_NONE) 238260684Skaiw return (ret); 239260684Skaiw 240260684Skaiw return (DW_DLE_NONE); 241260684Skaiw} 242260684Skaiw 243260684Skaiwstatic void 244260684Skaiw_dwarf_producer_deinit(Dwarf_P_Debug dbg) 245260684Skaiw{ 246260684Skaiw 247260684Skaiw assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); 248260684Skaiw 249260684Skaiw _dwarf_info_pro_cleanup(dbg); 250260684Skaiw _dwarf_die_pro_cleanup(dbg); 251260684Skaiw _dwarf_expr_cleanup(dbg); 252260684Skaiw _dwarf_lineno_pro_cleanup(dbg); 253260684Skaiw _dwarf_frame_pro_cleanup(dbg); 254260684Skaiw _dwarf_arange_pro_cleanup(dbg); 255260684Skaiw _dwarf_macinfo_pro_cleanup(dbg); 256260684Skaiw _dwarf_strtab_cleanup(dbg); 257260684Skaiw _dwarf_nametbl_pro_cleanup(&dbg->dbgp_pubs); 258260684Skaiw _dwarf_nametbl_pro_cleanup(&dbg->dbgp_weaks); 259260684Skaiw _dwarf_nametbl_pro_cleanup(&dbg->dbgp_funcs); 260260684Skaiw _dwarf_nametbl_pro_cleanup(&dbg->dbgp_types); 261260684Skaiw _dwarf_nametbl_pro_cleanup(&dbg->dbgp_vars); 262260684Skaiw _dwarf_section_cleanup(dbg); 263260684Skaiw _dwarf_reloc_cleanup(dbg); 264260684Skaiw} 265260684Skaiw 266260684Skaiwstatic void 267260684Skaiw_dwarf_consumer_deinit(Dwarf_Debug dbg) 268260684Skaiw{ 269260684Skaiw 270260684Skaiw assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); 271260684Skaiw 272260684Skaiw _dwarf_info_cleanup(dbg); 273260684Skaiw _dwarf_ranges_cleanup(dbg); 274260684Skaiw _dwarf_frame_cleanup(dbg); 275260684Skaiw _dwarf_arange_cleanup(dbg); 276260684Skaiw _dwarf_macinfo_cleanup(dbg); 277260684Skaiw _dwarf_strtab_cleanup(dbg); 278260684Skaiw _dwarf_nametbl_cleanup(&dbg->dbg_globals); 279260684Skaiw _dwarf_nametbl_cleanup(&dbg->dbg_pubtypes); 280260684Skaiw _dwarf_nametbl_cleanup(&dbg->dbg_weaks); 281260684Skaiw _dwarf_nametbl_cleanup(&dbg->dbg_funcs); 282260684Skaiw _dwarf_nametbl_cleanup(&dbg->dbg_vars); 283260684Skaiw _dwarf_nametbl_cleanup(&dbg->dbg_types); 284260684Skaiw 285260684Skaiw free(dbg->dbg_section); 286260684Skaiw} 287260684Skaiw 288260684Skaiwvoid 289260684Skaiw_dwarf_deinit(Dwarf_Debug dbg) 290260684Skaiw{ 291260684Skaiw 292260684Skaiw assert(dbg != NULL); 293260684Skaiw 294260684Skaiw if (dbg->dbg_mode == DW_DLC_READ) 295260684Skaiw _dwarf_consumer_deinit(dbg); 296260684Skaiw else if (dbg->dbg_mode == DW_DLC_WRITE) 297260684Skaiw _dwarf_producer_deinit(dbg); 298260684Skaiw} 299260684Skaiw 300260684Skaiwint 301260684Skaiw_dwarf_alloc(Dwarf_Debug *ret_dbg, int mode, Dwarf_Error *error) 302260684Skaiw{ 303260684Skaiw Dwarf_Debug dbg; 304260684Skaiw 305260684Skaiw if ((dbg = calloc(sizeof(struct _Dwarf_Debug), 1)) == NULL) { 306260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 307260684Skaiw return (DW_DLE_MEMORY); 308260684Skaiw } 309260684Skaiw 310260684Skaiw dbg->dbg_mode = mode; 311260684Skaiw 312260684Skaiw *ret_dbg = dbg; 313260684Skaiw 314260684Skaiw return (DW_DLE_NONE); 315260684Skaiw} 316