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_macinfo.c 2974 2013-12-23 06:46:22Z kaiwang27 $"); 30*2de3b87aSKai Wang 31*2de3b87aSKai Wang #define _FILEINDEX_STACK_SIZE 16384 32*2de3b87aSKai Wang 33*2de3b87aSKai Wang static int 34*2de3b87aSKai Wang _dwarf_macinfo_parse(Dwarf_Debug dbg, Dwarf_Section *ds, uint64_t *off, 35*2de3b87aSKai Wang Dwarf_Macro_Details *dmd, Dwarf_Unsigned *cnt, Dwarf_Error *error) 36*2de3b87aSKai Wang { 37*2de3b87aSKai Wang Dwarf_Unsigned lineno; 38*2de3b87aSKai Wang Dwarf_Signed fileindex[_FILEINDEX_STACK_SIZE]; 39*2de3b87aSKai Wang char *p; 40*2de3b87aSKai Wang int i, type, sp; 41*2de3b87aSKai Wang 42*2de3b87aSKai Wang i = 0; 43*2de3b87aSKai Wang sp = 0; 44*2de3b87aSKai Wang fileindex[sp] = -1; 45*2de3b87aSKai Wang while (*off < ds->ds_size) { 46*2de3b87aSKai Wang 47*2de3b87aSKai Wang if (dmd != NULL) 48*2de3b87aSKai Wang dmd[i].dmd_offset = *off; 49*2de3b87aSKai Wang 50*2de3b87aSKai Wang type = dbg->read(ds->ds_data, off, 1); 51*2de3b87aSKai Wang 52*2de3b87aSKai Wang if (dmd != NULL) { 53*2de3b87aSKai Wang dmd[i].dmd_type = type; 54*2de3b87aSKai Wang dmd[i].dmd_fileindex = fileindex[sp]; 55*2de3b87aSKai Wang } 56*2de3b87aSKai Wang 57*2de3b87aSKai Wang switch (type) { 58*2de3b87aSKai Wang case 0: 59*2de3b87aSKai Wang break; 60*2de3b87aSKai Wang case DW_MACINFO_define: 61*2de3b87aSKai Wang case DW_MACINFO_undef: 62*2de3b87aSKai Wang case DW_MACINFO_vendor_ext: 63*2de3b87aSKai Wang lineno = _dwarf_read_uleb128(ds->ds_data, off); 64*2de3b87aSKai Wang p = (char *) ds->ds_data; 65*2de3b87aSKai Wang if (dmd != NULL) { 66*2de3b87aSKai Wang dmd[i].dmd_lineno = lineno; 67*2de3b87aSKai Wang dmd[i].dmd_macro = p + *off; 68*2de3b87aSKai Wang 69*2de3b87aSKai Wang } 70*2de3b87aSKai Wang while (p[(*off)++] != '\0') 71*2de3b87aSKai Wang ; 72*2de3b87aSKai Wang break; 73*2de3b87aSKai Wang case DW_MACINFO_start_file: 74*2de3b87aSKai Wang lineno = _dwarf_read_uleb128(ds->ds_data, off); 75*2de3b87aSKai Wang if (sp >= _FILEINDEX_STACK_SIZE - 1) { 76*2de3b87aSKai Wang assert(0); 77*2de3b87aSKai Wang } 78*2de3b87aSKai Wang fileindex[++sp] = _dwarf_read_uleb128(ds->ds_data, off); 79*2de3b87aSKai Wang if (dmd != NULL) { 80*2de3b87aSKai Wang dmd[i].dmd_lineno = lineno; 81*2de3b87aSKai Wang dmd[i].dmd_fileindex = fileindex[sp]; 82*2de3b87aSKai Wang } 83*2de3b87aSKai Wang break; 84*2de3b87aSKai Wang case DW_MACINFO_end_file: 85*2de3b87aSKai Wang if (sp > 0) { 86*2de3b87aSKai Wang sp--; 87*2de3b87aSKai Wang break; 88*2de3b87aSKai Wang } 89*2de3b87aSKai Wang /* FALLTHROUGH */ 90*2de3b87aSKai Wang default: 91*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, 92*2de3b87aSKai Wang DW_DLE_DEBUG_MACRO_INCONSISTENT); 93*2de3b87aSKai Wang return (DW_DLE_DEBUG_MACRO_INCONSISTENT); 94*2de3b87aSKai Wang } 95*2de3b87aSKai Wang 96*2de3b87aSKai Wang i++; 97*2de3b87aSKai Wang 98*2de3b87aSKai Wang if (type == 0) 99*2de3b87aSKai Wang break; 100*2de3b87aSKai Wang } 101*2de3b87aSKai Wang 102*2de3b87aSKai Wang if (cnt != NULL) 103*2de3b87aSKai Wang *cnt = i; 104*2de3b87aSKai Wang 105*2de3b87aSKai Wang return (DW_DLE_NONE); 106*2de3b87aSKai Wang } 107*2de3b87aSKai Wang 108*2de3b87aSKai Wang void 109*2de3b87aSKai Wang _dwarf_macinfo_cleanup(Dwarf_Debug dbg) 110*2de3b87aSKai Wang { 111*2de3b87aSKai Wang Dwarf_MacroSet ms, tms; 112*2de3b87aSKai Wang 113*2de3b87aSKai Wang if (STAILQ_EMPTY(&dbg->dbg_mslist)) 114*2de3b87aSKai Wang return; 115*2de3b87aSKai Wang 116*2de3b87aSKai Wang STAILQ_FOREACH_SAFE(ms, &dbg->dbg_mslist, ms_next, tms) { 117*2de3b87aSKai Wang STAILQ_REMOVE(&dbg->dbg_mslist, ms, _Dwarf_MacroSet, ms_next); 118*2de3b87aSKai Wang if (ms->ms_mdlist) 119*2de3b87aSKai Wang free(ms->ms_mdlist); 120*2de3b87aSKai Wang free(ms); 121*2de3b87aSKai Wang } 122*2de3b87aSKai Wang } 123*2de3b87aSKai Wang 124*2de3b87aSKai Wang int 125*2de3b87aSKai Wang _dwarf_macinfo_init(Dwarf_Debug dbg, Dwarf_Error *error) 126*2de3b87aSKai Wang { 127*2de3b87aSKai Wang Dwarf_MacroSet ms; 128*2de3b87aSKai Wang Dwarf_Unsigned cnt; 129*2de3b87aSKai Wang Dwarf_Section *ds; 130*2de3b87aSKai Wang uint64_t offset, entry_off; 131*2de3b87aSKai Wang int ret; 132*2de3b87aSKai Wang 133*2de3b87aSKai Wang if ((ds = _dwarf_find_section(dbg, ".debug_macinfo")) == NULL) 134*2de3b87aSKai Wang return (DW_DLE_NONE); 135*2de3b87aSKai Wang 136*2de3b87aSKai Wang offset = 0; 137*2de3b87aSKai Wang while (offset < ds->ds_size) { 138*2de3b87aSKai Wang 139*2de3b87aSKai Wang entry_off = offset; 140*2de3b87aSKai Wang 141*2de3b87aSKai Wang ret = _dwarf_macinfo_parse(dbg, ds, &offset, NULL, &cnt, error); 142*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 143*2de3b87aSKai Wang return (ret); 144*2de3b87aSKai Wang 145*2de3b87aSKai Wang if (cnt == 0) 146*2de3b87aSKai Wang break; 147*2de3b87aSKai Wang 148*2de3b87aSKai Wang if ((ms = calloc(1, sizeof(struct _Dwarf_MacroSet))) == NULL) { 149*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 150*2de3b87aSKai Wang ret = DW_DLE_MEMORY; 151*2de3b87aSKai Wang goto fail_cleanup; 152*2de3b87aSKai Wang } 153*2de3b87aSKai Wang STAILQ_INSERT_TAIL(&dbg->dbg_mslist, ms, ms_next); 154*2de3b87aSKai Wang 155*2de3b87aSKai Wang if ((ms->ms_mdlist = calloc(cnt, sizeof(Dwarf_Macro_Details))) 156*2de3b87aSKai Wang == NULL) { 157*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 158*2de3b87aSKai Wang ret = DW_DLE_MEMORY; 159*2de3b87aSKai Wang goto fail_cleanup; 160*2de3b87aSKai Wang } 161*2de3b87aSKai Wang 162*2de3b87aSKai Wang ms->ms_cnt = cnt; 163*2de3b87aSKai Wang 164*2de3b87aSKai Wang offset = entry_off; 165*2de3b87aSKai Wang 166*2de3b87aSKai Wang ret = _dwarf_macinfo_parse(dbg, ds, &offset, ms->ms_mdlist, 167*2de3b87aSKai Wang NULL, error); 168*2de3b87aSKai Wang 169*2de3b87aSKai Wang if (ret != DW_DLE_NONE) { 170*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 171*2de3b87aSKai Wang ret = DW_DLE_MEMORY; 172*2de3b87aSKai Wang goto fail_cleanup; 173*2de3b87aSKai Wang } 174*2de3b87aSKai Wang } 175*2de3b87aSKai Wang 176*2de3b87aSKai Wang return (DW_DLE_NONE); 177*2de3b87aSKai Wang 178*2de3b87aSKai Wang fail_cleanup: 179*2de3b87aSKai Wang 180*2de3b87aSKai Wang _dwarf_macinfo_cleanup(dbg); 181*2de3b87aSKai Wang 182*2de3b87aSKai Wang return (ret); 183*2de3b87aSKai Wang } 184*2de3b87aSKai Wang 185*2de3b87aSKai Wang int 186*2de3b87aSKai Wang _dwarf_macinfo_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) 187*2de3b87aSKai Wang { 188*2de3b87aSKai Wang Dwarf_P_Section ds; 189*2de3b87aSKai Wang Dwarf_Macro_Details *md; 190*2de3b87aSKai Wang int i, ret; 191*2de3b87aSKai Wang 192*2de3b87aSKai Wang if (dbg->dbgp_mdcnt == 0) 193*2de3b87aSKai Wang return (DW_DLE_NONE); 194*2de3b87aSKai Wang 195*2de3b87aSKai Wang /* Create .debug_frame section. */ 196*2de3b87aSKai Wang RCHECK(_dwarf_section_init(dbg, &ds, ".debug_macinfo", 0, error)); 197*2de3b87aSKai Wang 198*2de3b87aSKai Wang /* Write the list of Dwarf_Macro_Details. */ 199*2de3b87aSKai Wang for (i = 0; (Dwarf_Unsigned) i < dbg->dbgp_mdcnt; i++) { 200*2de3b87aSKai Wang md = &dbg->dbgp_mdlist[i]; 201*2de3b87aSKai Wang md->dmd_offset = ds->ds_size; 202*2de3b87aSKai Wang RCHECK(WRITE_VALUE(md->dmd_type, 1)); 203*2de3b87aSKai Wang switch (md->dmd_type) { 204*2de3b87aSKai Wang case DW_MACINFO_define: 205*2de3b87aSKai Wang case DW_MACINFO_undef: 206*2de3b87aSKai Wang case DW_MACINFO_vendor_ext: 207*2de3b87aSKai Wang RCHECK(WRITE_ULEB128(md->dmd_lineno)); 208*2de3b87aSKai Wang assert(md->dmd_macro != NULL); 209*2de3b87aSKai Wang RCHECK(WRITE_STRING(md->dmd_macro)); 210*2de3b87aSKai Wang break; 211*2de3b87aSKai Wang case DW_MACINFO_start_file: 212*2de3b87aSKai Wang RCHECK(WRITE_ULEB128(md->dmd_lineno)); 213*2de3b87aSKai Wang RCHECK(WRITE_ULEB128(md->dmd_fileindex)); 214*2de3b87aSKai Wang break; 215*2de3b87aSKai Wang case DW_MACINFO_end_file: 216*2de3b87aSKai Wang break; 217*2de3b87aSKai Wang default: 218*2de3b87aSKai Wang assert(0); 219*2de3b87aSKai Wang break; 220*2de3b87aSKai Wang } 221*2de3b87aSKai Wang } 222*2de3b87aSKai Wang RCHECK(WRITE_VALUE(0, 1)); 223*2de3b87aSKai Wang 224*2de3b87aSKai Wang /* Inform application the creation of .debug_macinfo ELF section. */ 225*2de3b87aSKai Wang RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); 226*2de3b87aSKai Wang 227*2de3b87aSKai Wang return (DW_DLE_NONE); 228*2de3b87aSKai Wang 229*2de3b87aSKai Wang gen_fail: 230*2de3b87aSKai Wang _dwarf_section_free(dbg, &ds); 231*2de3b87aSKai Wang 232*2de3b87aSKai Wang return (ret); 233*2de3b87aSKai Wang } 234*2de3b87aSKai Wang 235*2de3b87aSKai Wang void 236*2de3b87aSKai Wang _dwarf_macinfo_pro_cleanup(Dwarf_P_Debug dbg) 237*2de3b87aSKai Wang { 238*2de3b87aSKai Wang Dwarf_Macro_Details *md; 239*2de3b87aSKai Wang int i; 240*2de3b87aSKai Wang 241*2de3b87aSKai Wang assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); 242*2de3b87aSKai Wang if (dbg->dbgp_mdlist == NULL) 243*2de3b87aSKai Wang return; 244*2de3b87aSKai Wang 245*2de3b87aSKai Wang assert(dbg->dbgp_mdcnt > 0); 246*2de3b87aSKai Wang for (i = 0; (Dwarf_Unsigned) i < dbg->dbgp_mdcnt; i++) { 247*2de3b87aSKai Wang md = &dbg->dbgp_mdlist[i]; 248*2de3b87aSKai Wang if (md->dmd_macro) 249*2de3b87aSKai Wang free(md->dmd_macro); 250*2de3b87aSKai Wang } 251*2de3b87aSKai Wang free(dbg->dbgp_mdlist); 252*2de3b87aSKai Wang dbg->dbgp_mdlist = NULL; 253*2de3b87aSKai Wang dbg->dbgp_mdcnt = 0; 254*2de3b87aSKai Wang } 255