Home | History | Annotate | Line # | Download | only in libdwarf
dwarf_lineno.c revision 1.2
      1 /*	$NetBSD: dwarf_lineno.c,v 1.2 2014/03/09 16:58:04 christos Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2009,2011 Kai Wang
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include "_libdwarf.h"
     30 
     31 __RCSID("$NetBSD: dwarf_lineno.c,v 1.2 2014/03/09 16:58:04 christos Exp $");
     32 ELFTC_VCSID("Id: dwarf_lineno.c 2074 2011-10-27 03:34:33Z jkoshy ");
     33 
     34 int
     35 dwarf_srclines(Dwarf_Die die, Dwarf_Line **linebuf, Dwarf_Signed *linecount,
     36     Dwarf_Error *error)
     37 {
     38 	Dwarf_LineInfo li;
     39 	Dwarf_Debug dbg;
     40 	Dwarf_Line ln;
     41 	Dwarf_CU cu;
     42 	Dwarf_Attribute at;
     43 	int i;
     44 
     45 	dbg = die != NULL ? die->die_dbg : NULL;
     46 
     47 	if (die == NULL || linebuf == NULL || linecount == NULL) {
     48 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
     49 		return (DW_DLV_ERROR);
     50 	}
     51 
     52 	if ((at = _dwarf_attr_find(die, DW_AT_stmt_list)) == NULL) {
     53 		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
     54 		return (DW_DLV_NO_ENTRY);
     55 	}
     56 
     57 	cu = die->die_cu;
     58 	if (cu->cu_lineinfo == NULL) {
     59 		if (_dwarf_lineno_init(die, at->u[0].u64, error) !=
     60 		    DW_DLE_NONE)
     61 			return (DW_DLV_ERROR);
     62 	}
     63 	if (cu->cu_lineinfo == NULL) {
     64 		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
     65 		return (DW_DLV_NO_ENTRY);
     66 	}
     67 
     68 	li = cu->cu_lineinfo;
     69 	*linecount = (Dwarf_Signed) li->li_lnlen;
     70 
     71 	if (*linecount == 0) {
     72 		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
     73 		return (DW_DLV_NO_ENTRY);
     74 	}
     75 
     76 	if (li->li_lnarray != NULL) {
     77 		*linebuf = li->li_lnarray;
     78 		return (DW_DLV_OK);
     79 	}
     80 
     81 	if ((li->li_lnarray = malloc(*linecount *
     82 	    sizeof(struct _Dwarf_Line))) == NULL) {
     83 		DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
     84 		return (DW_DLV_ERROR);
     85 	}
     86 
     87 	for (i = 0, ln = STAILQ_FIRST(&li->li_lnlist);
     88 	     i < *linecount && ln != NULL; i++, ln = STAILQ_NEXT(ln, ln_next))
     89 		li->li_lnarray[i] = ln;
     90 
     91 	*linebuf = li->li_lnarray;
     92 
     93 	return (DW_DLV_OK);
     94 }
     95 
     96 int
     97 dwarf_srcfiles(Dwarf_Die die, char ***srcfiles, Dwarf_Signed *srccount,
     98     Dwarf_Error *error)
     99 {
    100 	Dwarf_LineInfo li;
    101 	Dwarf_LineFile lf;
    102 	Dwarf_Debug dbg;
    103 	Dwarf_CU cu;
    104 	Dwarf_Attribute at;
    105 	int i;
    106 
    107 	dbg = die != NULL ? die->die_dbg : NULL;
    108 
    109 	if (die == NULL || srcfiles == NULL || srccount == NULL) {
    110 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
    111 		return (DW_DLV_ERROR);
    112 	}
    113 
    114 	if ((at = _dwarf_attr_find(die, DW_AT_stmt_list)) == NULL) {
    115 		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
    116 		return (DW_DLV_NO_ENTRY);
    117 	}
    118 
    119 	cu = die->die_cu;
    120 	if (cu->cu_lineinfo == NULL) {
    121 		if (_dwarf_lineno_init(die, at->u[0].u64, error) !=
    122 		    DW_DLE_NONE)
    123 			return (DW_DLV_ERROR);
    124 	}
    125 	if (cu->cu_lineinfo == NULL) {
    126 		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
    127 		return (DW_DLV_NO_ENTRY);
    128 	}
    129 
    130 	li = cu->cu_lineinfo;
    131 	*srccount = (Dwarf_Signed) li->li_lflen;
    132 
    133 	if (*srccount == 0) {
    134 		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
    135 		return (DW_DLV_NO_ENTRY);
    136 	}
    137 
    138 	if (li->li_lfnarray != NULL) {
    139 		*srcfiles = li->li_lfnarray;
    140 		return (DW_DLV_OK);
    141 	}
    142 
    143 	if ((li->li_lfnarray = malloc(*srccount * sizeof(char *))) == NULL) {
    144 		DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
    145 		return (DW_DLV_ERROR);
    146 	}
    147 
    148 	for (i = 0, lf = STAILQ_FIRST(&li->li_lflist);
    149 	     i < *srccount && lf != NULL; i++, lf = STAILQ_NEXT(lf, lf_next)) {
    150 		if (lf->lf_fullpath)
    151 			li->li_lfnarray[i] = lf->lf_fullpath;
    152 		else
    153 			li->li_lfnarray[i] = lf->lf_fname;
    154 	}
    155 
    156 	*srcfiles = li->li_lfnarray;
    157 
    158 	return (DW_DLV_OK);
    159 }
    160 
    161 int
    162 dwarf_linebeginstatement(Dwarf_Line ln, Dwarf_Bool *ret_bool,
    163     Dwarf_Error *error)
    164 {
    165 
    166 	if (ln == NULL || ret_bool == NULL) {
    167 		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
    168 		return (DW_DLV_ERROR);
    169 	}
    170 
    171 	*ret_bool = ln->ln_stmt;
    172 
    173 	return (DW_DLV_OK);
    174 }
    175 
    176 int
    177 dwarf_lineendsequence(Dwarf_Line ln, Dwarf_Bool *ret_bool, Dwarf_Error *error)
    178 {
    179 
    180 	if (ln == NULL || ret_bool == NULL) {
    181 		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
    182 		return (DW_DLV_ERROR);
    183 	}
    184 
    185 	*ret_bool = ln->ln_endseq;
    186 
    187 	return (DW_DLV_OK);
    188 }
    189 
    190 int
    191 dwarf_lineno(Dwarf_Line ln, Dwarf_Unsigned *ret_lineno, Dwarf_Error *error)
    192 {
    193 
    194 	if (ln == NULL || ret_lineno == NULL) {
    195 		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
    196 		return (DW_DLV_ERROR);
    197 	}
    198 
    199 	*ret_lineno = ln->ln_lineno;
    200 
    201 	return (DW_DLV_OK);
    202 }
    203 
    204 int
    205 dwarf_line_srcfileno(Dwarf_Line ln, Dwarf_Unsigned *ret_fileno,
    206     Dwarf_Error *error)
    207 {
    208 
    209 	if (ln == NULL || ret_fileno == NULL) {
    210 		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
    211 		return (DW_DLV_ERROR);
    212 	}
    213 
    214 	*ret_fileno = ln->ln_fileno;
    215 
    216 	return (DW_DLV_OK);
    217 }
    218 
    219 int
    220 dwarf_lineaddr(Dwarf_Line ln, Dwarf_Addr *ret_lineaddr, Dwarf_Error *error)
    221 {
    222 
    223 	if (ln == NULL || ret_lineaddr == NULL) {
    224 		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
    225 		return (DW_DLV_ERROR);
    226 	}
    227 
    228 	*ret_lineaddr = ln->ln_addr;
    229 
    230 	return (DW_DLV_OK);
    231 }
    232 
    233 int
    234 dwarf_lineoff(Dwarf_Line ln, Dwarf_Signed *ret_lineoff, Dwarf_Error *error)
    235 {
    236 
    237 	if (ln == NULL || ret_lineoff == NULL) {
    238 		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
    239 		return (DW_DLV_ERROR);
    240 	}
    241 
    242 	if (ln->ln_column == 0)
    243 		*ret_lineoff = -1;
    244 	else
    245 		*ret_lineoff = (Dwarf_Signed) ln->ln_column;
    246 
    247 	return (DW_DLV_OK);
    248 }
    249 
    250 int
    251 dwarf_linesrc(Dwarf_Line ln, char **ret_linesrc, Dwarf_Error *error)
    252 {
    253 	Dwarf_LineInfo li;
    254 	Dwarf_LineFile lf;
    255 	int i;
    256 
    257 	if (ln == NULL || ret_linesrc == NULL) {
    258 		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
    259 		return (DW_DLV_ERROR);
    260 	}
    261 
    262 	li = ln->ln_li;
    263 	assert(li != NULL);
    264 
    265 	for (i = 1, lf = STAILQ_FIRST(&li->li_lflist);
    266 	     (Dwarf_Unsigned) i < ln->ln_fileno && lf != NULL;
    267 	     i++, lf = STAILQ_NEXT(lf, lf_next))
    268 		;
    269 
    270 	if (lf == NULL) {
    271 		DWARF_SET_ERROR(NULL, error, DW_DLE_LINE_FILE_NUM_BAD);
    272 		return (DW_DLV_ERROR);
    273 	}
    274 
    275 	if (lf->lf_fullpath) {
    276 		*ret_linesrc = (char *) lf->lf_fullpath;
    277 		return (DW_DLV_OK);
    278 	}
    279 
    280 	*ret_linesrc = lf->lf_fname;
    281 
    282 	return (DW_DLV_OK);
    283 }
    284 
    285 int
    286 dwarf_lineblock(Dwarf_Line ln, Dwarf_Bool *ret_bool, Dwarf_Error *error)
    287 {
    288 
    289 	if (ln == NULL || ret_bool == NULL) {
    290 		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
    291 		return (DW_DLV_ERROR);
    292 	}
    293 
    294 	*ret_bool = ln->ln_bblock;
    295 
    296 	return (DW_DLV_OK);
    297 }
    298