1*2de3b87aSKai Wang /*- 2*2de3b87aSKai Wang * Copyright (c) 2009,2011 Kai Wang 3*2de3b87aSKai Wang * All rights reserved. 4*2de3b87aSKai Wang * 5*2de3b87aSKai Wang * Redistribution and use in source and binary forms, with or without 6*2de3b87aSKai Wang * modification, are permitted provided that the following conditions 7*2de3b87aSKai Wang * are met: 8*2de3b87aSKai Wang * 1. Redistributions of source code must retain the above copyright 9*2de3b87aSKai Wang * notice, this list of conditions and the following disclaimer. 10*2de3b87aSKai Wang * 2. Redistributions in binary form must reproduce the above copyright 11*2de3b87aSKai Wang * notice, this list of conditions and the following disclaimer in the 12*2de3b87aSKai Wang * documentation and/or other materials provided with the distribution. 13*2de3b87aSKai Wang * 14*2de3b87aSKai Wang * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*2de3b87aSKai Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*2de3b87aSKai Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*2de3b87aSKai Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*2de3b87aSKai Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*2de3b87aSKai Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*2de3b87aSKai Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*2de3b87aSKai Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*2de3b87aSKai Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*2de3b87aSKai Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*2de3b87aSKai Wang * SUCH DAMAGE. 25*2de3b87aSKai Wang */ 26*2de3b87aSKai Wang 27*2de3b87aSKai Wang #include "_libdwarf.h" 28*2de3b87aSKai Wang 29*2de3b87aSKai Wang ELFTC_VCSID("$Id: libdwarf_init.c 2948 2013-05-30 21:25:52Z kaiwang27 $"); 30*2de3b87aSKai Wang 31*2de3b87aSKai Wang static int 32*2de3b87aSKai Wang _dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error) 33*2de3b87aSKai Wang { 34*2de3b87aSKai Wang const Dwarf_Obj_Access_Methods *m; 35*2de3b87aSKai Wang Dwarf_Obj_Access_Section sec; 36*2de3b87aSKai Wang void *obj; 37*2de3b87aSKai Wang Dwarf_Unsigned cnt; 38*2de3b87aSKai Wang Dwarf_Half i; 39*2de3b87aSKai Wang int ret; 40*2de3b87aSKai Wang 41*2de3b87aSKai Wang assert(dbg != NULL); 42*2de3b87aSKai Wang assert(dbg->dbg_iface != NULL); 43*2de3b87aSKai Wang 44*2de3b87aSKai Wang m = dbg->dbg_iface->methods; 45*2de3b87aSKai Wang obj = dbg->dbg_iface->object; 46*2de3b87aSKai Wang 47*2de3b87aSKai Wang assert(m != NULL); 48*2de3b87aSKai Wang assert(obj != NULL); 49*2de3b87aSKai Wang 50*2de3b87aSKai Wang if (m->get_byte_order(obj) == DW_OBJECT_MSB) { 51*2de3b87aSKai Wang dbg->read = _dwarf_read_msb; 52*2de3b87aSKai Wang dbg->write = _dwarf_write_msb; 53*2de3b87aSKai Wang dbg->decode = _dwarf_decode_msb; 54*2de3b87aSKai Wang } else { 55*2de3b87aSKai Wang dbg->read = _dwarf_read_lsb; 56*2de3b87aSKai Wang dbg->write = _dwarf_write_lsb; 57*2de3b87aSKai Wang dbg->decode = _dwarf_decode_lsb; 58*2de3b87aSKai Wang } 59*2de3b87aSKai Wang 60*2de3b87aSKai Wang dbg->dbg_pointer_size = m->get_pointer_size(obj); 61*2de3b87aSKai Wang dbg->dbg_offset_size = m->get_length_size(obj); 62*2de3b87aSKai Wang 63*2de3b87aSKai Wang cnt = m->get_section_count(obj); 64*2de3b87aSKai Wang 65*2de3b87aSKai Wang if (cnt == 0) { 66*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_INFO_NULL); 67*2de3b87aSKai Wang return (DW_DLE_DEBUG_INFO_NULL); 68*2de3b87aSKai Wang } 69*2de3b87aSKai Wang 70*2de3b87aSKai Wang dbg->dbg_seccnt = cnt; 71*2de3b87aSKai Wang 72*2de3b87aSKai Wang if ((dbg->dbg_section = calloc(cnt, sizeof(Dwarf_Section))) == NULL) { 73*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 74*2de3b87aSKai Wang return (DW_DLE_MEMORY); 75*2de3b87aSKai Wang } 76*2de3b87aSKai Wang 77*2de3b87aSKai Wang for (i = 0; i < cnt; i++) { 78*2de3b87aSKai Wang if (m->get_section_info(obj, i, &sec, &ret) != DW_DLV_OK) { 79*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, ret); 80*2de3b87aSKai Wang return (ret); 81*2de3b87aSKai Wang } 82*2de3b87aSKai Wang 83*2de3b87aSKai Wang dbg->dbg_section[i].ds_addr = sec.addr; 84*2de3b87aSKai Wang dbg->dbg_section[i].ds_size = sec.size; 85*2de3b87aSKai Wang dbg->dbg_section[i].ds_name = sec.name; 86*2de3b87aSKai Wang 87*2de3b87aSKai Wang if (m->load_section(obj, i, &dbg->dbg_section[i].ds_data, &ret) 88*2de3b87aSKai Wang != DW_DLV_OK) { 89*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, ret); 90*2de3b87aSKai Wang return (ret); 91*2de3b87aSKai Wang } 92*2de3b87aSKai Wang } 93*2de3b87aSKai Wang 94*2de3b87aSKai Wang if (_dwarf_find_section(dbg, ".debug_abbrev") == NULL || 95*2de3b87aSKai Wang ((dbg->dbg_info_sec = _dwarf_find_section(dbg, ".debug_info")) == 96*2de3b87aSKai Wang NULL)) { 97*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_INFO_NULL); 98*2de3b87aSKai Wang return (DW_DLE_DEBUG_INFO_NULL); 99*2de3b87aSKai Wang } 100*2de3b87aSKai Wang 101*2de3b87aSKai Wang /* Initialise call frame API related parameters. */ 102*2de3b87aSKai Wang _dwarf_frame_params_init(dbg); 103*2de3b87aSKai Wang 104*2de3b87aSKai Wang return (DW_DLV_OK); 105*2de3b87aSKai Wang } 106*2de3b87aSKai Wang 107*2de3b87aSKai Wang static int 108*2de3b87aSKai Wang _dwarf_producer_init(Dwarf_Debug dbg, Dwarf_Unsigned pf, Dwarf_Error *error) 109*2de3b87aSKai Wang { 110*2de3b87aSKai Wang 111*2de3b87aSKai Wang /* Producer only support DWARF2 which has fixed 32bit offset. */ 112*2de3b87aSKai Wang dbg->dbg_offset_size = 4; 113*2de3b87aSKai Wang 114*2de3b87aSKai Wang if (pf & DW_DLC_SIZE_32 && pf & DW_DLC_SIZE_64) { 115*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 116*2de3b87aSKai Wang return (DW_DLE_ARGUMENT); 117*2de3b87aSKai Wang } 118*2de3b87aSKai Wang 119*2de3b87aSKai Wang if ((pf & DW_DLC_SIZE_32) == 0 && (pf & DW_DLC_SIZE_64) == 0) 120*2de3b87aSKai Wang pf |= DW_DLC_SIZE_32; 121*2de3b87aSKai Wang 122*2de3b87aSKai Wang if (pf & DW_DLC_SIZE_64) 123*2de3b87aSKai Wang dbg->dbg_pointer_size = 8; 124*2de3b87aSKai Wang else 125*2de3b87aSKai Wang dbg->dbg_pointer_size = 4; 126*2de3b87aSKai Wang 127*2de3b87aSKai Wang if (pf & DW_DLC_ISA_IA64 && pf & DW_DLC_ISA_MIPS) { 128*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 129*2de3b87aSKai Wang return (DW_DLE_ARGUMENT); 130*2de3b87aSKai Wang } 131*2de3b87aSKai Wang 132*2de3b87aSKai Wang if (pf & DW_DLC_ISA_IA64) 133*2de3b87aSKai Wang dbg->dbgp_isa = DW_ISA_IA64; 134*2de3b87aSKai Wang else 135*2de3b87aSKai Wang dbg->dbgp_isa = DW_ISA_MIPS; 136*2de3b87aSKai Wang 137*2de3b87aSKai Wang if (pf & DW_DLC_TARGET_BIGENDIAN && pf & DW_DLC_TARGET_LITTLEENDIAN) { 138*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 139*2de3b87aSKai Wang return (DW_DLE_ARGUMENT); 140*2de3b87aSKai Wang } 141*2de3b87aSKai Wang 142*2de3b87aSKai Wang if ((pf & DW_DLC_TARGET_BIGENDIAN) == 0 && 143*2de3b87aSKai Wang (pf & DW_DLC_TARGET_LITTLEENDIAN) == 0) { 144*2de3b87aSKai Wang #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_BIG_ENDIAN 145*2de3b87aSKai Wang pf |= DW_DLC_TARGET_BIGENDIAN; 146*2de3b87aSKai Wang #else 147*2de3b87aSKai Wang pf |= DW_DLC_TARGET_LITTLEENDIAN; 148*2de3b87aSKai Wang #endif 149*2de3b87aSKai Wang } 150*2de3b87aSKai Wang 151*2de3b87aSKai Wang if (pf & DW_DLC_TARGET_BIGENDIAN) { 152*2de3b87aSKai Wang dbg->write = _dwarf_write_msb; 153*2de3b87aSKai Wang dbg->write_alloc = _dwarf_write_msb_alloc; 154*2de3b87aSKai Wang } else if (pf & DW_DLC_TARGET_LITTLEENDIAN) { 155*2de3b87aSKai Wang dbg->write = _dwarf_write_lsb; 156*2de3b87aSKai Wang dbg->write_alloc = _dwarf_write_lsb_alloc; 157*2de3b87aSKai Wang } else 158*2de3b87aSKai Wang assert(0); 159*2de3b87aSKai Wang 160*2de3b87aSKai Wang if (pf & DW_DLC_STREAM_RELOCATIONS && 161*2de3b87aSKai Wang pf & DW_DLC_SYMBOLIC_RELOCATIONS) { 162*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 163*2de3b87aSKai Wang return (DW_DLE_ARGUMENT); 164*2de3b87aSKai Wang } 165*2de3b87aSKai Wang 166*2de3b87aSKai Wang if ((pf & DW_DLC_STREAM_RELOCATIONS) == 0 && 167*2de3b87aSKai Wang (pf & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) 168*2de3b87aSKai Wang pf |= DW_DLC_STREAM_RELOCATIONS; 169*2de3b87aSKai Wang 170*2de3b87aSKai Wang dbg->dbgp_flags = pf; 171*2de3b87aSKai Wang 172*2de3b87aSKai Wang STAILQ_INIT(&dbg->dbgp_dielist); 173*2de3b87aSKai Wang STAILQ_INIT(&dbg->dbgp_pelist); 174*2de3b87aSKai Wang STAILQ_INIT(&dbg->dbgp_seclist); 175*2de3b87aSKai Wang STAILQ_INIT(&dbg->dbgp_drslist); 176*2de3b87aSKai Wang STAILQ_INIT(&dbg->dbgp_cielist); 177*2de3b87aSKai Wang STAILQ_INIT(&dbg->dbgp_fdelist); 178*2de3b87aSKai Wang 179*2de3b87aSKai Wang if ((dbg->dbgp_lineinfo = calloc(1, sizeof(struct _Dwarf_LineInfo))) == 180*2de3b87aSKai Wang NULL) { 181*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 182*2de3b87aSKai Wang return (DW_DLE_MEMORY); 183*2de3b87aSKai Wang } 184*2de3b87aSKai Wang STAILQ_INIT(&dbg->dbgp_lineinfo->li_lflist); 185*2de3b87aSKai Wang STAILQ_INIT(&dbg->dbgp_lineinfo->li_lnlist); 186*2de3b87aSKai Wang 187*2de3b87aSKai Wang if ((dbg->dbgp_as = calloc(1, sizeof(struct _Dwarf_ArangeSet))) == 188*2de3b87aSKai Wang NULL) { 189*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 190*2de3b87aSKai Wang return (DW_DLE_MEMORY); 191*2de3b87aSKai Wang } 192*2de3b87aSKai Wang STAILQ_INIT(&dbg->dbgp_as->as_arlist); 193*2de3b87aSKai Wang 194*2de3b87aSKai Wang return (DW_DLE_NONE); 195*2de3b87aSKai Wang } 196*2de3b87aSKai Wang 197*2de3b87aSKai Wang int 198*2de3b87aSKai Wang _dwarf_init(Dwarf_Debug dbg, Dwarf_Unsigned pro_flags, Dwarf_Handler errhand, 199*2de3b87aSKai Wang Dwarf_Ptr errarg, Dwarf_Error *error) 200*2de3b87aSKai Wang { 201*2de3b87aSKai Wang int ret; 202*2de3b87aSKai Wang 203*2de3b87aSKai Wang ret = DW_DLE_NONE; 204*2de3b87aSKai Wang 205*2de3b87aSKai Wang /* 206*2de3b87aSKai Wang * Set the error handler fields early, so that the application 207*2de3b87aSKai Wang * is notified of initialization errors. 208*2de3b87aSKai Wang */ 209*2de3b87aSKai Wang dbg->dbg_errhand = errhand; 210*2de3b87aSKai Wang dbg->dbg_errarg = errarg; 211*2de3b87aSKai Wang 212*2de3b87aSKai Wang STAILQ_INIT(&dbg->dbg_cu); 213*2de3b87aSKai Wang STAILQ_INIT(&dbg->dbg_rllist); 214*2de3b87aSKai Wang STAILQ_INIT(&dbg->dbg_aslist); 215*2de3b87aSKai Wang STAILQ_INIT(&dbg->dbg_mslist); 216*2de3b87aSKai Wang TAILQ_INIT(&dbg->dbg_loclist); 217*2de3b87aSKai Wang 218*2de3b87aSKai Wang if (dbg->dbg_mode == DW_DLC_READ || dbg->dbg_mode == DW_DLC_RDWR) { 219*2de3b87aSKai Wang ret = _dwarf_consumer_init(dbg, error); 220*2de3b87aSKai Wang if (ret != DW_DLE_NONE) { 221*2de3b87aSKai Wang _dwarf_deinit(dbg); 222*2de3b87aSKai Wang return (ret); 223*2de3b87aSKai Wang } 224*2de3b87aSKai Wang } 225*2de3b87aSKai Wang 226*2de3b87aSKai Wang if (dbg->dbg_mode == DW_DLC_WRITE) { 227*2de3b87aSKai Wang ret = _dwarf_producer_init(dbg, pro_flags, error); 228*2de3b87aSKai Wang if (ret != DW_DLE_NONE) { 229*2de3b87aSKai Wang _dwarf_deinit(dbg); 230*2de3b87aSKai Wang return (ret); 231*2de3b87aSKai Wang } 232*2de3b87aSKai Wang } 233*2de3b87aSKai Wang 234*2de3b87aSKai Wang /* 235*2de3b87aSKai Wang * Initialise internal string table. 236*2de3b87aSKai Wang */ 237*2de3b87aSKai Wang if ((ret = _dwarf_strtab_init(dbg, error)) != DW_DLE_NONE) 238*2de3b87aSKai Wang return (ret); 239*2de3b87aSKai Wang 240*2de3b87aSKai Wang return (DW_DLE_NONE); 241*2de3b87aSKai Wang } 242*2de3b87aSKai Wang 243*2de3b87aSKai Wang static void 244*2de3b87aSKai Wang _dwarf_producer_deinit(Dwarf_P_Debug dbg) 245*2de3b87aSKai Wang { 246*2de3b87aSKai Wang 247*2de3b87aSKai Wang assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); 248*2de3b87aSKai Wang 249*2de3b87aSKai Wang _dwarf_info_pro_cleanup(dbg); 250*2de3b87aSKai Wang _dwarf_die_pro_cleanup(dbg); 251*2de3b87aSKai Wang _dwarf_expr_cleanup(dbg); 252*2de3b87aSKai Wang _dwarf_lineno_pro_cleanup(dbg); 253*2de3b87aSKai Wang _dwarf_frame_pro_cleanup(dbg); 254*2de3b87aSKai Wang _dwarf_arange_pro_cleanup(dbg); 255*2de3b87aSKai Wang _dwarf_macinfo_pro_cleanup(dbg); 256*2de3b87aSKai Wang _dwarf_strtab_cleanup(dbg); 257*2de3b87aSKai Wang _dwarf_nametbl_pro_cleanup(&dbg->dbgp_pubs); 258*2de3b87aSKai Wang _dwarf_nametbl_pro_cleanup(&dbg->dbgp_weaks); 259*2de3b87aSKai Wang _dwarf_nametbl_pro_cleanup(&dbg->dbgp_funcs); 260*2de3b87aSKai Wang _dwarf_nametbl_pro_cleanup(&dbg->dbgp_types); 261*2de3b87aSKai Wang _dwarf_nametbl_pro_cleanup(&dbg->dbgp_vars); 262*2de3b87aSKai Wang _dwarf_section_cleanup(dbg); 263*2de3b87aSKai Wang _dwarf_reloc_cleanup(dbg); 264*2de3b87aSKai Wang } 265*2de3b87aSKai Wang 266*2de3b87aSKai Wang static void 267*2de3b87aSKai Wang _dwarf_consumer_deinit(Dwarf_Debug dbg) 268*2de3b87aSKai Wang { 269*2de3b87aSKai Wang 270*2de3b87aSKai Wang assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); 271*2de3b87aSKai Wang 272*2de3b87aSKai Wang _dwarf_info_cleanup(dbg); 273*2de3b87aSKai Wang _dwarf_loclist_cleanup(dbg); 274*2de3b87aSKai Wang _dwarf_ranges_cleanup(dbg); 275*2de3b87aSKai Wang _dwarf_frame_cleanup(dbg); 276*2de3b87aSKai Wang _dwarf_arange_cleanup(dbg); 277*2de3b87aSKai Wang _dwarf_macinfo_cleanup(dbg); 278*2de3b87aSKai Wang _dwarf_strtab_cleanup(dbg); 279*2de3b87aSKai Wang _dwarf_nametbl_cleanup(&dbg->dbg_globals); 280*2de3b87aSKai Wang _dwarf_nametbl_cleanup(&dbg->dbg_pubtypes); 281*2de3b87aSKai Wang _dwarf_nametbl_cleanup(&dbg->dbg_weaks); 282*2de3b87aSKai Wang _dwarf_nametbl_cleanup(&dbg->dbg_funcs); 283*2de3b87aSKai Wang _dwarf_nametbl_cleanup(&dbg->dbg_vars); 284*2de3b87aSKai Wang _dwarf_nametbl_cleanup(&dbg->dbg_types); 285*2de3b87aSKai Wang 286*2de3b87aSKai Wang free(dbg->dbg_section); 287*2de3b87aSKai Wang } 288*2de3b87aSKai Wang 289*2de3b87aSKai Wang void 290*2de3b87aSKai Wang _dwarf_deinit(Dwarf_Debug dbg) 291*2de3b87aSKai Wang { 292*2de3b87aSKai Wang 293*2de3b87aSKai Wang assert(dbg != NULL); 294*2de3b87aSKai Wang 295*2de3b87aSKai Wang if (dbg->dbg_mode == DW_DLC_READ) 296*2de3b87aSKai Wang _dwarf_consumer_deinit(dbg); 297*2de3b87aSKai Wang else if (dbg->dbg_mode == DW_DLC_WRITE) 298*2de3b87aSKai Wang _dwarf_producer_deinit(dbg); 299*2de3b87aSKai Wang } 300*2de3b87aSKai Wang 301*2de3b87aSKai Wang int 302*2de3b87aSKai Wang _dwarf_alloc(Dwarf_Debug *ret_dbg, int mode, Dwarf_Error *error) 303*2de3b87aSKai Wang { 304*2de3b87aSKai Wang Dwarf_Debug dbg; 305*2de3b87aSKai Wang 306*2de3b87aSKai Wang if ((dbg = calloc(sizeof(struct _Dwarf_Debug), 1)) == NULL) { 307*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 308*2de3b87aSKai Wang return (DW_DLE_MEMORY); 309*2de3b87aSKai Wang } 310*2de3b87aSKai Wang 311*2de3b87aSKai Wang dbg->dbg_mode = mode; 312*2de3b87aSKai Wang 313*2de3b87aSKai Wang *ret_dbg = dbg; 314*2de3b87aSKai Wang 315*2de3b87aSKai Wang return (DW_DLE_NONE); 316*2de3b87aSKai Wang } 317