12de3b87aSKai Wang /*- 22de3b87aSKai Wang * Copyright (c) 2009,2011 Kai Wang 32de3b87aSKai Wang * All rights reserved. 42de3b87aSKai Wang * 52de3b87aSKai Wang * Redistribution and use in source and binary forms, with or without 62de3b87aSKai Wang * modification, are permitted provided that the following conditions 72de3b87aSKai Wang * are met: 82de3b87aSKai Wang * 1. Redistributions of source code must retain the above copyright 92de3b87aSKai Wang * notice, this list of conditions and the following disclaimer. 102de3b87aSKai Wang * 2. Redistributions in binary form must reproduce the above copyright 112de3b87aSKai Wang * notice, this list of conditions and the following disclaimer in the 122de3b87aSKai Wang * documentation and/or other materials provided with the distribution. 132de3b87aSKai Wang * 142de3b87aSKai Wang * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 152de3b87aSKai Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 162de3b87aSKai Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 172de3b87aSKai Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 182de3b87aSKai Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 192de3b87aSKai Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 202de3b87aSKai Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 212de3b87aSKai Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 222de3b87aSKai Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 232de3b87aSKai Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 242de3b87aSKai Wang * SUCH DAMAGE. 252de3b87aSKai Wang */ 262de3b87aSKai Wang 272de3b87aSKai Wang #include "_libdwarf.h" 282de3b87aSKai Wang 29*cf781b2eSEd Maste ELFTC_VCSID("$Id: dwarf_lineno.c 2983 2014-02-09 00:24:31Z kaiwang27 $"); 302de3b87aSKai Wang 312de3b87aSKai Wang int 322de3b87aSKai Wang dwarf_srclines(Dwarf_Die die, Dwarf_Line **linebuf, Dwarf_Signed *linecount, 332de3b87aSKai Wang Dwarf_Error *error) 342de3b87aSKai Wang { 352de3b87aSKai Wang Dwarf_LineInfo li; 362de3b87aSKai Wang Dwarf_Debug dbg; 372de3b87aSKai Wang Dwarf_Line ln; 382de3b87aSKai Wang Dwarf_CU cu; 392de3b87aSKai Wang Dwarf_Attribute at; 402de3b87aSKai Wang int i; 412de3b87aSKai Wang 422de3b87aSKai Wang dbg = die != NULL ? die->die_dbg : NULL; 432de3b87aSKai Wang 442de3b87aSKai Wang if (die == NULL || linebuf == NULL || linecount == NULL) { 452de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 462de3b87aSKai Wang return (DW_DLV_ERROR); 472de3b87aSKai Wang } 482de3b87aSKai Wang 492de3b87aSKai Wang if ((at = _dwarf_attr_find(die, DW_AT_stmt_list)) == NULL) { 502de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 512de3b87aSKai Wang return (DW_DLV_NO_ENTRY); 522de3b87aSKai Wang } 532de3b87aSKai Wang 542de3b87aSKai Wang cu = die->die_cu; 552de3b87aSKai Wang if (cu->cu_lineinfo == NULL) { 562de3b87aSKai Wang if (_dwarf_lineno_init(die, at->u[0].u64, error) != 572de3b87aSKai Wang DW_DLE_NONE) 582de3b87aSKai Wang return (DW_DLV_ERROR); 592de3b87aSKai Wang } 602de3b87aSKai Wang if (cu->cu_lineinfo == NULL) { 612de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 622de3b87aSKai Wang return (DW_DLV_NO_ENTRY); 632de3b87aSKai Wang } 642de3b87aSKai Wang 652de3b87aSKai Wang li = cu->cu_lineinfo; 662de3b87aSKai Wang *linecount = (Dwarf_Signed) li->li_lnlen; 672de3b87aSKai Wang 682de3b87aSKai Wang if (*linecount == 0) { 692de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 702de3b87aSKai Wang return (DW_DLV_NO_ENTRY); 712de3b87aSKai Wang } 722de3b87aSKai Wang 732de3b87aSKai Wang if (li->li_lnarray != NULL) { 742de3b87aSKai Wang *linebuf = li->li_lnarray; 752de3b87aSKai Wang return (DW_DLV_OK); 762de3b87aSKai Wang } 772de3b87aSKai Wang 78*cf781b2eSEd Maste if ((li->li_lnarray = malloc(*linecount * sizeof(Dwarf_Line))) == 79*cf781b2eSEd Maste NULL) { 802de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 812de3b87aSKai Wang return (DW_DLV_ERROR); 822de3b87aSKai Wang } 832de3b87aSKai Wang 842de3b87aSKai Wang for (i = 0, ln = STAILQ_FIRST(&li->li_lnlist); 852de3b87aSKai Wang i < *linecount && ln != NULL; i++, ln = STAILQ_NEXT(ln, ln_next)) 862de3b87aSKai Wang li->li_lnarray[i] = ln; 872de3b87aSKai Wang 882de3b87aSKai Wang *linebuf = li->li_lnarray; 892de3b87aSKai Wang 902de3b87aSKai Wang return (DW_DLV_OK); 912de3b87aSKai Wang } 922de3b87aSKai Wang 932de3b87aSKai Wang int 942de3b87aSKai Wang dwarf_srcfiles(Dwarf_Die die, char ***srcfiles, Dwarf_Signed *srccount, 952de3b87aSKai Wang Dwarf_Error *error) 962de3b87aSKai Wang { 972de3b87aSKai Wang Dwarf_LineInfo li; 982de3b87aSKai Wang Dwarf_LineFile lf; 992de3b87aSKai Wang Dwarf_Debug dbg; 1002de3b87aSKai Wang Dwarf_CU cu; 1012de3b87aSKai Wang Dwarf_Attribute at; 1022de3b87aSKai Wang int i; 1032de3b87aSKai Wang 1042de3b87aSKai Wang dbg = die != NULL ? die->die_dbg : NULL; 1052de3b87aSKai Wang 1062de3b87aSKai Wang if (die == NULL || srcfiles == NULL || srccount == NULL) { 1072de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 1082de3b87aSKai Wang return (DW_DLV_ERROR); 1092de3b87aSKai Wang } 1102de3b87aSKai Wang 1112de3b87aSKai Wang if ((at = _dwarf_attr_find(die, DW_AT_stmt_list)) == NULL) { 1122de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 1132de3b87aSKai Wang return (DW_DLV_NO_ENTRY); 1142de3b87aSKai Wang } 1152de3b87aSKai Wang 1162de3b87aSKai Wang cu = die->die_cu; 1172de3b87aSKai Wang if (cu->cu_lineinfo == NULL) { 1182de3b87aSKai Wang if (_dwarf_lineno_init(die, at->u[0].u64, error) != 1192de3b87aSKai Wang DW_DLE_NONE) 1202de3b87aSKai Wang return (DW_DLV_ERROR); 1212de3b87aSKai Wang } 1222de3b87aSKai Wang if (cu->cu_lineinfo == NULL) { 1232de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 1242de3b87aSKai Wang return (DW_DLV_NO_ENTRY); 1252de3b87aSKai Wang } 1262de3b87aSKai Wang 1272de3b87aSKai Wang li = cu->cu_lineinfo; 1282de3b87aSKai Wang *srccount = (Dwarf_Signed) li->li_lflen; 1292de3b87aSKai Wang 1302de3b87aSKai Wang if (*srccount == 0) { 1312de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 1322de3b87aSKai Wang return (DW_DLV_NO_ENTRY); 1332de3b87aSKai Wang } 1342de3b87aSKai Wang 1352de3b87aSKai Wang if (li->li_lfnarray != NULL) { 1362de3b87aSKai Wang *srcfiles = li->li_lfnarray; 1372de3b87aSKai Wang return (DW_DLV_OK); 1382de3b87aSKai Wang } 1392de3b87aSKai Wang 1402de3b87aSKai Wang if ((li->li_lfnarray = malloc(*srccount * sizeof(char *))) == NULL) { 1412de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 1422de3b87aSKai Wang return (DW_DLV_ERROR); 1432de3b87aSKai Wang } 1442de3b87aSKai Wang 1452de3b87aSKai Wang for (i = 0, lf = STAILQ_FIRST(&li->li_lflist); 1462de3b87aSKai Wang i < *srccount && lf != NULL; i++, lf = STAILQ_NEXT(lf, lf_next)) { 1472de3b87aSKai Wang if (lf->lf_fullpath) 1482de3b87aSKai Wang li->li_lfnarray[i] = lf->lf_fullpath; 1492de3b87aSKai Wang else 1502de3b87aSKai Wang li->li_lfnarray[i] = lf->lf_fname; 1512de3b87aSKai Wang } 1522de3b87aSKai Wang 1532de3b87aSKai Wang *srcfiles = li->li_lfnarray; 1542de3b87aSKai Wang 1552de3b87aSKai Wang return (DW_DLV_OK); 1562de3b87aSKai Wang } 1572de3b87aSKai Wang 1582de3b87aSKai Wang int 1592de3b87aSKai Wang dwarf_linebeginstatement(Dwarf_Line ln, Dwarf_Bool *ret_bool, 1602de3b87aSKai Wang Dwarf_Error *error) 1612de3b87aSKai Wang { 1622de3b87aSKai Wang 1632de3b87aSKai Wang if (ln == NULL || ret_bool == NULL) { 1642de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 1652de3b87aSKai Wang return (DW_DLV_ERROR); 1662de3b87aSKai Wang } 1672de3b87aSKai Wang 1682de3b87aSKai Wang *ret_bool = ln->ln_stmt; 1692de3b87aSKai Wang 1702de3b87aSKai Wang return (DW_DLV_OK); 1712de3b87aSKai Wang } 1722de3b87aSKai Wang 1732de3b87aSKai Wang int 1742de3b87aSKai Wang dwarf_lineendsequence(Dwarf_Line ln, Dwarf_Bool *ret_bool, Dwarf_Error *error) 1752de3b87aSKai Wang { 1762de3b87aSKai Wang 1772de3b87aSKai Wang if (ln == NULL || ret_bool == NULL) { 1782de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 1792de3b87aSKai Wang return (DW_DLV_ERROR); 1802de3b87aSKai Wang } 1812de3b87aSKai Wang 1822de3b87aSKai Wang *ret_bool = ln->ln_endseq; 1832de3b87aSKai Wang 1842de3b87aSKai Wang return (DW_DLV_OK); 1852de3b87aSKai Wang } 1862de3b87aSKai Wang 1872de3b87aSKai Wang int 1882de3b87aSKai Wang dwarf_lineno(Dwarf_Line ln, Dwarf_Unsigned *ret_lineno, Dwarf_Error *error) 1892de3b87aSKai Wang { 1902de3b87aSKai Wang 1912de3b87aSKai Wang if (ln == NULL || ret_lineno == NULL) { 1922de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 1932de3b87aSKai Wang return (DW_DLV_ERROR); 1942de3b87aSKai Wang } 1952de3b87aSKai Wang 1962de3b87aSKai Wang *ret_lineno = ln->ln_lineno; 1972de3b87aSKai Wang 1982de3b87aSKai Wang return (DW_DLV_OK); 1992de3b87aSKai Wang } 2002de3b87aSKai Wang 2012de3b87aSKai Wang int 2022de3b87aSKai Wang dwarf_line_srcfileno(Dwarf_Line ln, Dwarf_Unsigned *ret_fileno, 2032de3b87aSKai Wang Dwarf_Error *error) 2042de3b87aSKai Wang { 2052de3b87aSKai Wang 2062de3b87aSKai Wang if (ln == NULL || ret_fileno == NULL) { 2072de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 2082de3b87aSKai Wang return (DW_DLV_ERROR); 2092de3b87aSKai Wang } 2102de3b87aSKai Wang 2112de3b87aSKai Wang *ret_fileno = ln->ln_fileno; 2122de3b87aSKai Wang 2132de3b87aSKai Wang return (DW_DLV_OK); 2142de3b87aSKai Wang } 2152de3b87aSKai Wang 2162de3b87aSKai Wang int 2172de3b87aSKai Wang dwarf_lineaddr(Dwarf_Line ln, Dwarf_Addr *ret_lineaddr, Dwarf_Error *error) 2182de3b87aSKai Wang { 2192de3b87aSKai Wang 2202de3b87aSKai Wang if (ln == NULL || ret_lineaddr == NULL) { 2212de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 2222de3b87aSKai Wang return (DW_DLV_ERROR); 2232de3b87aSKai Wang } 2242de3b87aSKai Wang 2252de3b87aSKai Wang *ret_lineaddr = ln->ln_addr; 2262de3b87aSKai Wang 2272de3b87aSKai Wang return (DW_DLV_OK); 2282de3b87aSKai Wang } 2292de3b87aSKai Wang 2302de3b87aSKai Wang int 2312de3b87aSKai Wang dwarf_lineoff(Dwarf_Line ln, Dwarf_Signed *ret_lineoff, Dwarf_Error *error) 2322de3b87aSKai Wang { 2332de3b87aSKai Wang 2342de3b87aSKai Wang if (ln == NULL || ret_lineoff == NULL) { 2352de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 2362de3b87aSKai Wang return (DW_DLV_ERROR); 2372de3b87aSKai Wang } 2382de3b87aSKai Wang 2392de3b87aSKai Wang if (ln->ln_column == 0) 2402de3b87aSKai Wang *ret_lineoff = -1; 2412de3b87aSKai Wang else 2422de3b87aSKai Wang *ret_lineoff = (Dwarf_Signed) ln->ln_column; 2432de3b87aSKai Wang 2442de3b87aSKai Wang return (DW_DLV_OK); 2452de3b87aSKai Wang } 2462de3b87aSKai Wang 2472de3b87aSKai Wang int 2482de3b87aSKai Wang dwarf_linesrc(Dwarf_Line ln, char **ret_linesrc, Dwarf_Error *error) 2492de3b87aSKai Wang { 2502de3b87aSKai Wang Dwarf_LineInfo li; 2512de3b87aSKai Wang Dwarf_LineFile lf; 2522de3b87aSKai Wang int i; 2532de3b87aSKai Wang 2542de3b87aSKai Wang if (ln == NULL || ret_linesrc == NULL) { 2552de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 2562de3b87aSKai Wang return (DW_DLV_ERROR); 2572de3b87aSKai Wang } 2582de3b87aSKai Wang 2592de3b87aSKai Wang li = ln->ln_li; 2602de3b87aSKai Wang assert(li != NULL); 2612de3b87aSKai Wang 2622de3b87aSKai Wang for (i = 1, lf = STAILQ_FIRST(&li->li_lflist); 2632de3b87aSKai Wang (Dwarf_Unsigned) i < ln->ln_fileno && lf != NULL; 2642de3b87aSKai Wang i++, lf = STAILQ_NEXT(lf, lf_next)) 2652de3b87aSKai Wang ; 2662de3b87aSKai Wang 2672de3b87aSKai Wang if (lf == NULL) { 2682de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_LINE_FILE_NUM_BAD); 2692de3b87aSKai Wang return (DW_DLV_ERROR); 2702de3b87aSKai Wang } 2712de3b87aSKai Wang 2722de3b87aSKai Wang if (lf->lf_fullpath) { 2732de3b87aSKai Wang *ret_linesrc = (char *) lf->lf_fullpath; 2742de3b87aSKai Wang return (DW_DLV_OK); 2752de3b87aSKai Wang } 2762de3b87aSKai Wang 2772de3b87aSKai Wang *ret_linesrc = lf->lf_fname; 2782de3b87aSKai Wang 2792de3b87aSKai Wang return (DW_DLV_OK); 2802de3b87aSKai Wang } 2812de3b87aSKai Wang 2822de3b87aSKai Wang int 2832de3b87aSKai Wang dwarf_lineblock(Dwarf_Line ln, Dwarf_Bool *ret_bool, Dwarf_Error *error) 2842de3b87aSKai Wang { 2852de3b87aSKai Wang 2862de3b87aSKai Wang if (ln == NULL || ret_bool == NULL) { 2872de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 2882de3b87aSKai Wang return (DW_DLV_ERROR); 2892de3b87aSKai Wang } 2902de3b87aSKai Wang 2912de3b87aSKai Wang *ret_bool = ln->ln_bblock; 2922de3b87aSKai Wang 2932de3b87aSKai Wang return (DW_DLV_OK); 2942de3b87aSKai Wang } 295