1260684Skaiw/*- 2260684Skaiw * Copyright (c) 2010 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 29276371SemasteELFTC_VCSID("$Id: libdwarf_sections.c 3041 2014-05-18 15:11:03Z kaiwang27 $"); 30260684Skaiw 31260684Skaiw#define _SECTION_INIT_SIZE 128 32260684Skaiw 33260684Skaiwint 34260684Skaiw_dwarf_section_init(Dwarf_P_Debug dbg, Dwarf_P_Section *dsp, const char *name, 35260684Skaiw int pseudo, Dwarf_Error *error) 36260684Skaiw{ 37260684Skaiw Dwarf_P_Section ds; 38260684Skaiw 39260684Skaiw assert(dbg != NULL && dsp != NULL && name != NULL); 40260684Skaiw 41260684Skaiw if ((ds = calloc(1, sizeof(struct _Dwarf_P_Section))) == NULL) { 42260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 43260684Skaiw return (DW_DLE_MEMORY); 44260684Skaiw } 45260684Skaiw 46260684Skaiw if ((ds->ds_name = strdup(name)) == NULL) { 47260684Skaiw free(ds); 48260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 49260684Skaiw return (DW_DLE_MEMORY); 50260684Skaiw } 51260684Skaiw 52260684Skaiw if (!pseudo) { 53260684Skaiw ds->ds_cap = _SECTION_INIT_SIZE; 54260684Skaiw if ((ds->ds_data = malloc((size_t) ds->ds_cap)) == NULL) { 55260684Skaiw free(ds->ds_name); 56260684Skaiw free(ds); 57260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 58260684Skaiw return (DW_DLE_MEMORY); 59260684Skaiw } 60260684Skaiw STAILQ_INSERT_TAIL(&dbg->dbgp_seclist, ds, ds_next); 61260684Skaiw dbg->dbgp_seccnt++; 62260684Skaiw } 63260684Skaiw 64260684Skaiw *dsp = ds; 65260684Skaiw 66260684Skaiw return (DW_DLE_NONE); 67260684Skaiw} 68260684Skaiw 69260684Skaiwvoid 70260684Skaiw_dwarf_section_free(Dwarf_P_Debug dbg, Dwarf_P_Section *dsp) 71260684Skaiw{ 72260684Skaiw Dwarf_P_Section ds, tds; 73260684Skaiw 74260684Skaiw assert(dbg != NULL && dsp != NULL); 75260684Skaiw 76260684Skaiw if (*dsp == NULL) 77260684Skaiw return; 78260684Skaiw 79260684Skaiw STAILQ_FOREACH_SAFE(ds, &dbg->dbgp_seclist, ds_next, tds) { 80260684Skaiw if (ds == *dsp) { 81260684Skaiw STAILQ_REMOVE(&dbg->dbgp_seclist, ds, _Dwarf_P_Section, 82260684Skaiw ds_next); 83260684Skaiw dbg->dbgp_seccnt--; 84260684Skaiw break; 85260684Skaiw } 86260684Skaiw } 87260684Skaiw ds = *dsp; 88260684Skaiw if (ds->ds_name) 89260684Skaiw free(ds->ds_name); 90260684Skaiw if (ds->ds_data) 91260684Skaiw free(ds->ds_data); 92260684Skaiw free(ds); 93260684Skaiw *dsp = NULL; 94260684Skaiw} 95260684Skaiw 96260684Skaiwint 97260684Skaiw_dwarf_pro_callback(Dwarf_P_Debug dbg, char *name, int size, 98260684Skaiw Dwarf_Unsigned type, Dwarf_Unsigned flags, Dwarf_Unsigned link, 99260684Skaiw Dwarf_Unsigned info, Dwarf_Unsigned *symndx, int *error) 100260684Skaiw{ 101260684Skaiw int e, ret, isymndx; 102260684Skaiw 103260684Skaiw assert(dbg != NULL && name != NULL && symndx != NULL); 104260684Skaiw 105260684Skaiw if (dbg->dbgp_func_b) 106260684Skaiw ret = dbg->dbgp_func_b(name, size, type, flags, link, info, 107260684Skaiw symndx, &e); 108260684Skaiw else { 109260684Skaiw ret = dbg->dbgp_func(name, size, type, flags, link, info, 110260684Skaiw &isymndx, &e); 111260684Skaiw *symndx = isymndx; 112260684Skaiw } 113260684Skaiw if (ret < 0) { 114260684Skaiw if (error) 115260684Skaiw *error = e; 116260684Skaiw } 117260684Skaiw 118260684Skaiw return (ret); 119260684Skaiw} 120260684Skaiw 121260684Skaiwint 122260684Skaiw_dwarf_section_callback(Dwarf_P_Debug dbg, Dwarf_P_Section ds, 123260684Skaiw Dwarf_Unsigned type, Dwarf_Unsigned flags, Dwarf_Unsigned link, 124260684Skaiw Dwarf_Unsigned info, Dwarf_Error *error) 125260684Skaiw{ 126260684Skaiw int ret, ndx; 127260684Skaiw 128260684Skaiw ndx = _dwarf_pro_callback(dbg, ds->ds_name, (int) ds->ds_size, 129260684Skaiw type, flags, link, info, &ds->ds_symndx, NULL); 130260684Skaiw if (ndx < 0) { 131260684Skaiw ret = DW_DLE_ELF_SECT_ERR; 132260684Skaiw DWARF_SET_ERROR(dbg, error, ret); 133260684Skaiw return (ret); 134260684Skaiw } 135260684Skaiw ds->ds_ndx = ndx; 136260684Skaiw 137260684Skaiw return (DW_DLE_NONE); 138260684Skaiw} 139260684Skaiw 140260684Skaiwint 141260684Skaiw_dwarf_generate_sections(Dwarf_P_Debug dbg, Dwarf_Error *error) 142260684Skaiw{ 143260684Skaiw int ret; 144260684Skaiw 145260684Skaiw /* Produce .debug_info section. */ 146260684Skaiw if ((ret = _dwarf_info_gen(dbg, error)) != DW_DLE_NONE) 147260684Skaiw return (ret); 148260684Skaiw 149260684Skaiw /* Produce .debug_abbrev section. */ 150260684Skaiw if ((ret = _dwarf_abbrev_gen(dbg, error)) != DW_DLE_NONE) 151260684Skaiw return (ret); 152260684Skaiw 153260684Skaiw /* Produce .debug_line section. */ 154260684Skaiw if ((ret = _dwarf_lineno_gen(dbg, error)) != DW_DLE_NONE) 155260684Skaiw return (ret); 156260684Skaiw 157260684Skaiw /* Produce .debug_frame section. */ 158260684Skaiw if ((ret = _dwarf_frame_gen(dbg, error)) != DW_DLE_NONE) 159260684Skaiw return (ret); 160260684Skaiw 161260684Skaiw /* Produce .debug_aranges section. */ 162260684Skaiw if ((ret = _dwarf_arange_gen(dbg, error)) != DW_DLE_NONE) 163260684Skaiw return (ret); 164260684Skaiw 165260684Skaiw /* Produce .debug_macinfo section. */ 166260684Skaiw if ((ret = _dwarf_macinfo_gen(dbg, error)) != DW_DLE_NONE) 167260684Skaiw return (ret); 168260684Skaiw 169260684Skaiw /* Produce .debug_pubnames section. */ 170260684Skaiw if ((ret = _dwarf_nametbl_gen(dbg, ".debug_pubnames", dbg->dbgp_pubs, 171260684Skaiw error)) != DW_DLE_NONE) 172260684Skaiw return (ret); 173260684Skaiw 174260684Skaiw /* Produce .debug_weaknames section. */ 175260684Skaiw if ((ret = _dwarf_nametbl_gen(dbg, ".debug_weaknames", dbg->dbgp_weaks, 176260684Skaiw error)) != DW_DLE_NONE) 177260684Skaiw return (ret); 178260684Skaiw 179260684Skaiw /* Produce .debug_funcnames section. */ 180260684Skaiw if ((ret = _dwarf_nametbl_gen(dbg, ".debug_funcnames", dbg->dbgp_funcs, 181260684Skaiw error)) != DW_DLE_NONE) 182260684Skaiw return (ret); 183260684Skaiw 184260684Skaiw /* Produce .debug_typenames section. */ 185260684Skaiw if ((ret = _dwarf_nametbl_gen(dbg, ".debug_typenames", dbg->dbgp_types, 186260684Skaiw error)) != DW_DLE_NONE) 187260684Skaiw return (ret); 188260684Skaiw 189260684Skaiw /* Produce .debug_varnames section. */ 190260684Skaiw if ((ret = _dwarf_nametbl_gen(dbg, ".debug_varnames", dbg->dbgp_vars, 191260684Skaiw error)) != DW_DLE_NONE) 192260684Skaiw return (ret); 193260684Skaiw 194260684Skaiw /* Produce .debug_str section. */ 195260684Skaiw if ((ret = _dwarf_strtab_gen(dbg, error)) != DW_DLE_NONE) 196260684Skaiw return (ret); 197260684Skaiw 198260684Skaiw /* Finally, update and generate all relocation sections. */ 199260684Skaiw if ((ret = _dwarf_reloc_gen(dbg, error)) != DW_DLE_NONE) 200260684Skaiw return (ret); 201260684Skaiw 202260684Skaiw /* Set section/relocation iterator to the first element. */ 203260684Skaiw dbg->dbgp_secpos = STAILQ_FIRST(&dbg->dbgp_seclist); 204260684Skaiw dbg->dbgp_drspos = STAILQ_FIRST(&dbg->dbgp_drslist); 205260684Skaiw 206260684Skaiw return (DW_DLE_NONE); 207260684Skaiw} 208260684Skaiw 209260684SkaiwDwarf_Section * 210260684Skaiw_dwarf_find_section(Dwarf_Debug dbg, const char *name) 211260684Skaiw{ 212260684Skaiw Dwarf_Section *ds; 213260684Skaiw Dwarf_Half i; 214260684Skaiw 215276371Semaste assert(dbg != NULL && name != NULL); 216260684Skaiw 217260684Skaiw for (i = 0; i < dbg->dbg_seccnt; i++) { 218260684Skaiw ds = &dbg->dbg_section[i]; 219260684Skaiw if (ds->ds_name != NULL && !strcmp(ds->ds_name, name)) 220260684Skaiw return (ds); 221260684Skaiw } 222260684Skaiw 223260684Skaiw return (NULL); 224260684Skaiw} 225260684Skaiw 226276371SemasteDwarf_Section * 227276371Semaste_dwarf_find_next_types_section(Dwarf_Debug dbg, Dwarf_Section *ds) 228276371Semaste{ 229276371Semaste 230276371Semaste assert(dbg != NULL); 231276371Semaste 232276371Semaste if (ds == NULL) 233276371Semaste return (_dwarf_find_section(dbg, ".debug_types")); 234276371Semaste 235276371Semaste assert(ds->ds_name != NULL); 236276371Semaste 237276371Semaste do { 238276371Semaste ds++; 239276371Semaste if (ds->ds_name != NULL && 240276371Semaste !strcmp(ds->ds_name, ".debug_types")) 241276371Semaste return (ds); 242276371Semaste } while (ds->ds_name != NULL); 243276371Semaste 244276371Semaste return (NULL); 245276371Semaste} 246276371Semaste 247260684SkaiwDwarf_P_Section 248260684Skaiw_dwarf_pro_find_section(Dwarf_P_Debug dbg, const char *name) 249260684Skaiw{ 250260684Skaiw Dwarf_P_Section ds; 251260684Skaiw 252260684Skaiw assert(dbg != NULL && name != NULL); 253260684Skaiw 254260684Skaiw STAILQ_FOREACH(ds, &dbg->dbgp_seclist, ds_next) { 255260684Skaiw if (ds->ds_name != NULL && !strcmp(ds->ds_name ,name)) 256260684Skaiw return (ds); 257260684Skaiw } 258260684Skaiw 259260684Skaiw return (NULL); 260260684Skaiw} 261260684Skaiw 262260684Skaiwvoid 263260684Skaiw_dwarf_section_cleanup(Dwarf_P_Debug dbg) 264260684Skaiw{ 265260684Skaiw Dwarf_P_Section ds, tds; 266260684Skaiw 267260684Skaiw assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); 268260684Skaiw 269260684Skaiw STAILQ_FOREACH_SAFE(ds, &dbg->dbgp_seclist, ds_next, tds) { 270260684Skaiw STAILQ_REMOVE(&dbg->dbgp_seclist, ds, _Dwarf_P_Section, 271260684Skaiw ds_next); 272260684Skaiw if (ds->ds_name) 273260684Skaiw free(ds->ds_name); 274260684Skaiw if (ds->ds_data) 275260684Skaiw free(ds->ds_data); 276260684Skaiw free(ds); 277260684Skaiw } 278260684Skaiw dbg->dbgp_seccnt = 0; 279260684Skaiw dbg->dbgp_secpos = 0; 280260684Skaiw} 281