libdwarf_init.c revision 276398
154095Ssemenu/*- 247060Ssemenu * Copyright (c) 2009,2011 Kai Wang 343552Ssemenu * All rights reserved. 443552Ssemenu * 543552Ssemenu * Redistribution and use in source and binary forms, with or without 643552Ssemenu * modification, are permitted provided that the following conditions 743552Ssemenu * are met: 843552Ssemenu * 1. Redistributions of source code must retain the above copyright 943552Ssemenu * notice, this list of conditions and the following disclaimer. 1043552Ssemenu * 2. Redistributions in binary form must reproduce the above copyright 1143552Ssemenu * notice, this list of conditions and the following disclaimer in the 1243552Ssemenu * documentation and/or other materials provided with the distribution. 1343552Ssemenu * 1443552Ssemenu * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1543552Ssemenu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1643552Ssemenu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1743552Ssemenu * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1843552Ssemenu * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1943552Ssemenu * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2043552Ssemenu * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2143552Ssemenu * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2243552Ssemenu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2343552Ssemenu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2443552Ssemenu * SUCH DAMAGE. 2543552Ssemenu */ 2643552Ssemenu 2743552Ssemenu#include "_libdwarf.h" 2850477Speter 2943552SsemenuELFTC_VCSID("$Id: libdwarf_init.c 3136 2014-12-24 16:04:38Z kaiwang27 $"); 3043552Ssemenu 3143552Ssemenustatic int 3247060Ssemenu_dwarf_consumer_init(Dwarf_Debug dbg, Dwarf_Error *error) 3343552Ssemenu{ 3443552Ssemenu const Dwarf_Obj_Access_Methods *m; 3543552Ssemenu Dwarf_Obj_Access_Section sec; 3643552Ssemenu void *obj; 3743552Ssemenu Dwarf_Unsigned cnt; 3843552Ssemenu Dwarf_Half i; 3943552Ssemenu int ret; 4047060Ssemenu 4147060Ssemenu assert(dbg != NULL); 4243552Ssemenu assert(dbg->dbg_iface != NULL); 4343552Ssemenu 4443552Ssemenu m = dbg->dbg_iface->methods; 4543552Ssemenu obj = dbg->dbg_iface->object; 4643552Ssemenu 4743552Ssemenu assert(m != NULL); 4843552Ssemenu assert(obj != NULL); 4943552Ssemenu 5043552Ssemenu if (m->get_byte_order(obj) == DW_OBJECT_MSB) { 5143552Ssemenu dbg->read = _dwarf_read_msb; 5243552Ssemenu dbg->write = _dwarf_write_msb; 5343552Ssemenu dbg->decode = _dwarf_decode_msb; 5443552Ssemenu } else { 5547060Ssemenu dbg->read = _dwarf_read_lsb; 5643552Ssemenu dbg->write = _dwarf_write_lsb; 5743552Ssemenu dbg->decode = _dwarf_decode_lsb; 5843552Ssemenu } 5943552Ssemenu 6054095Ssemenu dbg->dbg_pointer_size = m->get_pointer_size(obj); 6154095Ssemenu dbg->dbg_offset_size = m->get_length_size(obj); 6254095Ssemenu 6360938Sjake cnt = m->get_section_count(obj); 6443552Ssemenu 6543552Ssemenu if (cnt == 0) { 6645879Ssemenu DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_INFO_NULL); 6744142Ssemenu return (DW_DLE_DEBUG_INFO_NULL); 6843552Ssemenu } 6954095Ssemenu 7054095Ssemenu dbg->dbg_seccnt = cnt; 7154095Ssemenu 7254095Ssemenu if ((dbg->dbg_section = calloc(cnt + 1, sizeof(Dwarf_Section))) == 7344142Ssemenu NULL) { 7454095Ssemenu DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 7560938Sjake return (DW_DLE_MEMORY); 7660938Sjake } 7744142Ssemenu 7843552Ssemenu for (i = 0; i < cnt; i++) { 7943552Ssemenu if (m->get_section_info(obj, i, &sec, &ret) != DW_DLV_OK) { 8043552Ssemenu DWARF_SET_ERROR(dbg, error, ret); 8144142Ssemenu return (ret); 8243552Ssemenu } 8344142Ssemenu 8445879Ssemenu dbg->dbg_section[i].ds_addr = sec.addr; 8544142Ssemenu dbg->dbg_section[i].ds_size = sec.size; 8644142Ssemenu dbg->dbg_section[i].ds_name = sec.name; 8754095Ssemenu 8854095Ssemenu if (m->load_section(obj, i, &dbg->dbg_section[i].ds_data, &ret) 8954095Ssemenu != DW_DLV_OK) { 9044142Ssemenu DWARF_SET_ERROR(dbg, error, ret); 9160938Sjake return (ret); 9244142Ssemenu } 9354095Ssemenu } 9444142Ssemenu dbg->dbg_section[cnt].ds_name = NULL; 9543552Ssemenu 9644142Ssemenu dbg->dbg_info_sec = _dwarf_find_section(dbg, ".debug_info"); 9744142Ssemenu 9844142Ssemenu /* Try to find the optional DWARF4 .debug_types section. */ 9944142Ssemenu dbg->dbg_types_sec = _dwarf_find_next_types_section(dbg, NULL); 10044142Ssemenu 10144142Ssemenu /* Initialise call frame API related parameters. */ 10244142Ssemenu _dwarf_frame_params_init(dbg); 10344142Ssemenu 10444142Ssemenu return (DW_DLV_OK); 10544142Ssemenu} 10644142Ssemenu 10744142Ssemenustatic int 10844142Ssemenu_dwarf_producer_init(Dwarf_Debug dbg, Dwarf_Unsigned pf, Dwarf_Error *error) 10944142Ssemenu{ 11044142Ssemenu 11144142Ssemenu /* Producer only support DWARF2 which has fixed 32bit offset. */ 11243552Ssemenu dbg->dbg_offset_size = 4; 11354095Ssemenu 11454095Ssemenu if (pf & DW_DLC_SIZE_32 && pf & DW_DLC_SIZE_64) { 11554095Ssemenu DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 11654095Ssemenu return (DW_DLE_ARGUMENT); 11754095Ssemenu } 11854095Ssemenu 11954095Ssemenu if ((pf & DW_DLC_SIZE_32) == 0 && (pf & DW_DLC_SIZE_64) == 0) 12054095Ssemenu 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 197int 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 243static 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 266static 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 288void 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 300int 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