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