1 /* $NetBSD: dwarf_lineno.c,v 1.3 2016/02/20 02:43:41 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.3 2016/02/20 02:43:41 christos Exp $"); 32 ELFTC_VCSID("Id: dwarf_lineno.c 2983 2014-02-09 00:24:31Z kaiwang27 "); 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 * sizeof(Dwarf_Line))) == 82 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