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: dwarf_lineno.c 2074 2011-10-27 03:34:33Z jkoshy $"); 30*2de3b87aSKai Wang 31*2de3b87aSKai Wang int 32*2de3b87aSKai Wang dwarf_srclines(Dwarf_Die die, Dwarf_Line **linebuf, Dwarf_Signed *linecount, 33*2de3b87aSKai Wang Dwarf_Error *error) 34*2de3b87aSKai Wang { 35*2de3b87aSKai Wang Dwarf_LineInfo li; 36*2de3b87aSKai Wang Dwarf_Debug dbg; 37*2de3b87aSKai Wang Dwarf_Line ln; 38*2de3b87aSKai Wang Dwarf_CU cu; 39*2de3b87aSKai Wang Dwarf_Attribute at; 40*2de3b87aSKai Wang int i; 41*2de3b87aSKai Wang 42*2de3b87aSKai Wang dbg = die != NULL ? die->die_dbg : NULL; 43*2de3b87aSKai Wang 44*2de3b87aSKai Wang if (die == NULL || linebuf == NULL || linecount == NULL) { 45*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 46*2de3b87aSKai Wang return (DW_DLV_ERROR); 47*2de3b87aSKai Wang } 48*2de3b87aSKai Wang 49*2de3b87aSKai Wang if ((at = _dwarf_attr_find(die, DW_AT_stmt_list)) == NULL) { 50*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 51*2de3b87aSKai Wang return (DW_DLV_NO_ENTRY); 52*2de3b87aSKai Wang } 53*2de3b87aSKai Wang 54*2de3b87aSKai Wang cu = die->die_cu; 55*2de3b87aSKai Wang if (cu->cu_lineinfo == NULL) { 56*2de3b87aSKai Wang if (_dwarf_lineno_init(die, at->u[0].u64, error) != 57*2de3b87aSKai Wang DW_DLE_NONE) 58*2de3b87aSKai Wang return (DW_DLV_ERROR); 59*2de3b87aSKai Wang } 60*2de3b87aSKai Wang if (cu->cu_lineinfo == NULL) { 61*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 62*2de3b87aSKai Wang return (DW_DLV_NO_ENTRY); 63*2de3b87aSKai Wang } 64*2de3b87aSKai Wang 65*2de3b87aSKai Wang li = cu->cu_lineinfo; 66*2de3b87aSKai Wang *linecount = (Dwarf_Signed) li->li_lnlen; 67*2de3b87aSKai Wang 68*2de3b87aSKai Wang if (*linecount == 0) { 69*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 70*2de3b87aSKai Wang return (DW_DLV_NO_ENTRY); 71*2de3b87aSKai Wang } 72*2de3b87aSKai Wang 73*2de3b87aSKai Wang if (li->li_lnarray != NULL) { 74*2de3b87aSKai Wang *linebuf = li->li_lnarray; 75*2de3b87aSKai Wang return (DW_DLV_OK); 76*2de3b87aSKai Wang } 77*2de3b87aSKai Wang 78*2de3b87aSKai Wang if ((li->li_lnarray = malloc(*linecount * 79*2de3b87aSKai Wang sizeof(struct _Dwarf_Line))) == NULL) { 80*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 81*2de3b87aSKai Wang return (DW_DLV_ERROR); 82*2de3b87aSKai Wang } 83*2de3b87aSKai Wang 84*2de3b87aSKai Wang for (i = 0, ln = STAILQ_FIRST(&li->li_lnlist); 85*2de3b87aSKai Wang i < *linecount && ln != NULL; i++, ln = STAILQ_NEXT(ln, ln_next)) 86*2de3b87aSKai Wang li->li_lnarray[i] = ln; 87*2de3b87aSKai Wang 88*2de3b87aSKai Wang *linebuf = li->li_lnarray; 89*2de3b87aSKai Wang 90*2de3b87aSKai Wang return (DW_DLV_OK); 91*2de3b87aSKai Wang } 92*2de3b87aSKai Wang 93*2de3b87aSKai Wang int 94*2de3b87aSKai Wang dwarf_srcfiles(Dwarf_Die die, char ***srcfiles, Dwarf_Signed *srccount, 95*2de3b87aSKai Wang Dwarf_Error *error) 96*2de3b87aSKai Wang { 97*2de3b87aSKai Wang Dwarf_LineInfo li; 98*2de3b87aSKai Wang Dwarf_LineFile lf; 99*2de3b87aSKai Wang Dwarf_Debug dbg; 100*2de3b87aSKai Wang Dwarf_CU cu; 101*2de3b87aSKai Wang Dwarf_Attribute at; 102*2de3b87aSKai Wang int i; 103*2de3b87aSKai Wang 104*2de3b87aSKai Wang dbg = die != NULL ? die->die_dbg : NULL; 105*2de3b87aSKai Wang 106*2de3b87aSKai Wang if (die == NULL || srcfiles == NULL || srccount == NULL) { 107*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 108*2de3b87aSKai Wang return (DW_DLV_ERROR); 109*2de3b87aSKai Wang } 110*2de3b87aSKai Wang 111*2de3b87aSKai Wang if ((at = _dwarf_attr_find(die, DW_AT_stmt_list)) == NULL) { 112*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 113*2de3b87aSKai Wang return (DW_DLV_NO_ENTRY); 114*2de3b87aSKai Wang } 115*2de3b87aSKai Wang 116*2de3b87aSKai Wang cu = die->die_cu; 117*2de3b87aSKai Wang if (cu->cu_lineinfo == NULL) { 118*2de3b87aSKai Wang if (_dwarf_lineno_init(die, at->u[0].u64, error) != 119*2de3b87aSKai Wang DW_DLE_NONE) 120*2de3b87aSKai Wang return (DW_DLV_ERROR); 121*2de3b87aSKai Wang } 122*2de3b87aSKai Wang if (cu->cu_lineinfo == NULL) { 123*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 124*2de3b87aSKai Wang return (DW_DLV_NO_ENTRY); 125*2de3b87aSKai Wang } 126*2de3b87aSKai Wang 127*2de3b87aSKai Wang li = cu->cu_lineinfo; 128*2de3b87aSKai Wang *srccount = (Dwarf_Signed) li->li_lflen; 129*2de3b87aSKai Wang 130*2de3b87aSKai Wang if (*srccount == 0) { 131*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 132*2de3b87aSKai Wang return (DW_DLV_NO_ENTRY); 133*2de3b87aSKai Wang } 134*2de3b87aSKai Wang 135*2de3b87aSKai Wang if (li->li_lfnarray != NULL) { 136*2de3b87aSKai Wang *srcfiles = li->li_lfnarray; 137*2de3b87aSKai Wang return (DW_DLV_OK); 138*2de3b87aSKai Wang } 139*2de3b87aSKai Wang 140*2de3b87aSKai Wang if ((li->li_lfnarray = malloc(*srccount * sizeof(char *))) == NULL) { 141*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 142*2de3b87aSKai Wang return (DW_DLV_ERROR); 143*2de3b87aSKai Wang } 144*2de3b87aSKai Wang 145*2de3b87aSKai Wang for (i = 0, lf = STAILQ_FIRST(&li->li_lflist); 146*2de3b87aSKai Wang i < *srccount && lf != NULL; i++, lf = STAILQ_NEXT(lf, lf_next)) { 147*2de3b87aSKai Wang if (lf->lf_fullpath) 148*2de3b87aSKai Wang li->li_lfnarray[i] = lf->lf_fullpath; 149*2de3b87aSKai Wang else 150*2de3b87aSKai Wang li->li_lfnarray[i] = lf->lf_fname; 151*2de3b87aSKai Wang } 152*2de3b87aSKai Wang 153*2de3b87aSKai Wang *srcfiles = li->li_lfnarray; 154*2de3b87aSKai Wang 155*2de3b87aSKai Wang return (DW_DLV_OK); 156*2de3b87aSKai Wang } 157*2de3b87aSKai Wang 158*2de3b87aSKai Wang int 159*2de3b87aSKai Wang dwarf_linebeginstatement(Dwarf_Line ln, Dwarf_Bool *ret_bool, 160*2de3b87aSKai Wang Dwarf_Error *error) 161*2de3b87aSKai Wang { 162*2de3b87aSKai Wang 163*2de3b87aSKai Wang if (ln == NULL || ret_bool == NULL) { 164*2de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 165*2de3b87aSKai Wang return (DW_DLV_ERROR); 166*2de3b87aSKai Wang } 167*2de3b87aSKai Wang 168*2de3b87aSKai Wang *ret_bool = ln->ln_stmt; 169*2de3b87aSKai Wang 170*2de3b87aSKai Wang return (DW_DLV_OK); 171*2de3b87aSKai Wang } 172*2de3b87aSKai Wang 173*2de3b87aSKai Wang int 174*2de3b87aSKai Wang dwarf_lineendsequence(Dwarf_Line ln, Dwarf_Bool *ret_bool, Dwarf_Error *error) 175*2de3b87aSKai Wang { 176*2de3b87aSKai Wang 177*2de3b87aSKai Wang if (ln == NULL || ret_bool == NULL) { 178*2de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 179*2de3b87aSKai Wang return (DW_DLV_ERROR); 180*2de3b87aSKai Wang } 181*2de3b87aSKai Wang 182*2de3b87aSKai Wang *ret_bool = ln->ln_endseq; 183*2de3b87aSKai Wang 184*2de3b87aSKai Wang return (DW_DLV_OK); 185*2de3b87aSKai Wang } 186*2de3b87aSKai Wang 187*2de3b87aSKai Wang int 188*2de3b87aSKai Wang dwarf_lineno(Dwarf_Line ln, Dwarf_Unsigned *ret_lineno, Dwarf_Error *error) 189*2de3b87aSKai Wang { 190*2de3b87aSKai Wang 191*2de3b87aSKai Wang if (ln == NULL || ret_lineno == NULL) { 192*2de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 193*2de3b87aSKai Wang return (DW_DLV_ERROR); 194*2de3b87aSKai Wang } 195*2de3b87aSKai Wang 196*2de3b87aSKai Wang *ret_lineno = ln->ln_lineno; 197*2de3b87aSKai Wang 198*2de3b87aSKai Wang return (DW_DLV_OK); 199*2de3b87aSKai Wang } 200*2de3b87aSKai Wang 201*2de3b87aSKai Wang int 202*2de3b87aSKai Wang dwarf_line_srcfileno(Dwarf_Line ln, Dwarf_Unsigned *ret_fileno, 203*2de3b87aSKai Wang Dwarf_Error *error) 204*2de3b87aSKai Wang { 205*2de3b87aSKai Wang 206*2de3b87aSKai Wang if (ln == NULL || ret_fileno == NULL) { 207*2de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 208*2de3b87aSKai Wang return (DW_DLV_ERROR); 209*2de3b87aSKai Wang } 210*2de3b87aSKai Wang 211*2de3b87aSKai Wang *ret_fileno = ln->ln_fileno; 212*2de3b87aSKai Wang 213*2de3b87aSKai Wang return (DW_DLV_OK); 214*2de3b87aSKai Wang } 215*2de3b87aSKai Wang 216*2de3b87aSKai Wang int 217*2de3b87aSKai Wang dwarf_lineaddr(Dwarf_Line ln, Dwarf_Addr *ret_lineaddr, Dwarf_Error *error) 218*2de3b87aSKai Wang { 219*2de3b87aSKai Wang 220*2de3b87aSKai Wang if (ln == NULL || ret_lineaddr == NULL) { 221*2de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 222*2de3b87aSKai Wang return (DW_DLV_ERROR); 223*2de3b87aSKai Wang } 224*2de3b87aSKai Wang 225*2de3b87aSKai Wang *ret_lineaddr = ln->ln_addr; 226*2de3b87aSKai Wang 227*2de3b87aSKai Wang return (DW_DLV_OK); 228*2de3b87aSKai Wang } 229*2de3b87aSKai Wang 230*2de3b87aSKai Wang int 231*2de3b87aSKai Wang dwarf_lineoff(Dwarf_Line ln, Dwarf_Signed *ret_lineoff, Dwarf_Error *error) 232*2de3b87aSKai Wang { 233*2de3b87aSKai Wang 234*2de3b87aSKai Wang if (ln == NULL || ret_lineoff == NULL) { 235*2de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 236*2de3b87aSKai Wang return (DW_DLV_ERROR); 237*2de3b87aSKai Wang } 238*2de3b87aSKai Wang 239*2de3b87aSKai Wang if (ln->ln_column == 0) 240*2de3b87aSKai Wang *ret_lineoff = -1; 241*2de3b87aSKai Wang else 242*2de3b87aSKai Wang *ret_lineoff = (Dwarf_Signed) ln->ln_column; 243*2de3b87aSKai Wang 244*2de3b87aSKai Wang return (DW_DLV_OK); 245*2de3b87aSKai Wang } 246*2de3b87aSKai Wang 247*2de3b87aSKai Wang int 248*2de3b87aSKai Wang dwarf_linesrc(Dwarf_Line ln, char **ret_linesrc, Dwarf_Error *error) 249*2de3b87aSKai Wang { 250*2de3b87aSKai Wang Dwarf_LineInfo li; 251*2de3b87aSKai Wang Dwarf_LineFile lf; 252*2de3b87aSKai Wang int i; 253*2de3b87aSKai Wang 254*2de3b87aSKai Wang if (ln == NULL || ret_linesrc == NULL) { 255*2de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 256*2de3b87aSKai Wang return (DW_DLV_ERROR); 257*2de3b87aSKai Wang } 258*2de3b87aSKai Wang 259*2de3b87aSKai Wang li = ln->ln_li; 260*2de3b87aSKai Wang assert(li != NULL); 261*2de3b87aSKai Wang 262*2de3b87aSKai Wang for (i = 1, lf = STAILQ_FIRST(&li->li_lflist); 263*2de3b87aSKai Wang (Dwarf_Unsigned) i < ln->ln_fileno && lf != NULL; 264*2de3b87aSKai Wang i++, lf = STAILQ_NEXT(lf, lf_next)) 265*2de3b87aSKai Wang ; 266*2de3b87aSKai Wang 267*2de3b87aSKai Wang if (lf == NULL) { 268*2de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_LINE_FILE_NUM_BAD); 269*2de3b87aSKai Wang return (DW_DLV_ERROR); 270*2de3b87aSKai Wang } 271*2de3b87aSKai Wang 272*2de3b87aSKai Wang if (lf->lf_fullpath) { 273*2de3b87aSKai Wang *ret_linesrc = (char *) lf->lf_fullpath; 274*2de3b87aSKai Wang return (DW_DLV_OK); 275*2de3b87aSKai Wang } 276*2de3b87aSKai Wang 277*2de3b87aSKai Wang *ret_linesrc = lf->lf_fname; 278*2de3b87aSKai Wang 279*2de3b87aSKai Wang return (DW_DLV_OK); 280*2de3b87aSKai Wang } 281*2de3b87aSKai Wang 282*2de3b87aSKai Wang int 283*2de3b87aSKai Wang dwarf_lineblock(Dwarf_Line ln, Dwarf_Bool *ret_bool, Dwarf_Error *error) 284*2de3b87aSKai Wang { 285*2de3b87aSKai Wang 286*2de3b87aSKai Wang if (ln == NULL || ret_bool == NULL) { 287*2de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 288*2de3b87aSKai Wang return (DW_DLV_ERROR); 289*2de3b87aSKai Wang } 290*2de3b87aSKai Wang 291*2de3b87aSKai Wang *ret_bool = ln->ln_bblock; 292*2de3b87aSKai Wang 293*2de3b87aSKai Wang return (DW_DLV_OK); 294*2de3b87aSKai Wang } 295