1 /* $NetBSD: dwarf_lineno.c,v 1.2 2014/03/09 16:58:04 christos Exp $ */
4 * Copyright (c) 2009,2011 Kai Wang
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
29 #include "_libdwarf.h"
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 ");
35 dwarf_srclines(Dwarf_Die die
, Dwarf_Line
**linebuf
, Dwarf_Signed
*linecount
,
45 dbg
= die
!= NULL
? die
->die_dbg
: NULL
;
47 if (die
== NULL
|| linebuf
== NULL
|| linecount
== NULL
) {
48 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARGUMENT
);
49 return (DW_DLV_ERROR
);
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
);
58 if (cu
->cu_lineinfo
== NULL
) {
59 if (_dwarf_lineno_init(die
, at
->u
[0].u64
, error
) !=
61 return (DW_DLV_ERROR
);
63 if (cu
->cu_lineinfo
== NULL
) {
64 DWARF_SET_ERROR(dbg
, error
, DW_DLE_NO_ENTRY
);
65 return (DW_DLV_NO_ENTRY
);
69 *linecount
= (Dwarf_Signed
) li
->li_lnlen
;
71 if (*linecount
== 0) {
72 DWARF_SET_ERROR(dbg
, error
, DW_DLE_NO_ENTRY
);
73 return (DW_DLV_NO_ENTRY
);
76 if (li
->li_lnarray
!= NULL
) {
77 *linebuf
= li
->li_lnarray
;
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
);
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
;
91 *linebuf
= li
->li_lnarray
;
97 dwarf_srcfiles(Dwarf_Die die
, char ***srcfiles
, Dwarf_Signed
*srccount
,
107 dbg
= die
!= NULL
? die
->die_dbg
: NULL
;
109 if (die
== NULL
|| srcfiles
== NULL
|| srccount
== NULL
) {
110 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARGUMENT
);
111 return (DW_DLV_ERROR
);
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
);
120 if (cu
->cu_lineinfo
== NULL
) {
121 if (_dwarf_lineno_init(die
, at
->u
[0].u64
, error
) !=
123 return (DW_DLV_ERROR
);
125 if (cu
->cu_lineinfo
== NULL
) {
126 DWARF_SET_ERROR(dbg
, error
, DW_DLE_NO_ENTRY
);
127 return (DW_DLV_NO_ENTRY
);
130 li
= cu
->cu_lineinfo
;
131 *srccount
= (Dwarf_Signed
) li
->li_lflen
;
133 if (*srccount
== 0) {
134 DWARF_SET_ERROR(dbg
, error
, DW_DLE_NO_ENTRY
);
135 return (DW_DLV_NO_ENTRY
);
138 if (li
->li_lfnarray
!= NULL
) {
139 *srcfiles
= li
->li_lfnarray
;
143 if ((li
->li_lfnarray
= malloc(*srccount
* sizeof(char *))) == NULL
) {
144 DWARF_SET_ERROR(dbg
, error
, DW_DLE_MEMORY
);
145 return (DW_DLV_ERROR
);
148 for (i
= 0, lf
= STAILQ_FIRST(&li
->li_lflist
);
149 i
< *srccount
&& lf
!= NULL
; i
++, lf
= STAILQ_NEXT(lf
, lf_next
)) {
151 li
->li_lfnarray
[i
] = lf
->lf_fullpath
;
153 li
->li_lfnarray
[i
] = lf
->lf_fname
;
156 *srcfiles
= li
->li_lfnarray
;
162 dwarf_linebeginstatement(Dwarf_Line ln
, Dwarf_Bool
*ret_bool
,
166 if (ln
== NULL
|| ret_bool
== NULL
) {
167 DWARF_SET_ERROR(NULL
, error
, DW_DLE_ARGUMENT
);
168 return (DW_DLV_ERROR
);
171 *ret_bool
= ln
->ln_stmt
;
177 dwarf_lineendsequence(Dwarf_Line ln
, Dwarf_Bool
*ret_bool
, Dwarf_Error
*error
)
180 if (ln
== NULL
|| ret_bool
== NULL
) {
181 DWARF_SET_ERROR(NULL
, error
, DW_DLE_ARGUMENT
);
182 return (DW_DLV_ERROR
);
185 *ret_bool
= ln
->ln_endseq
;
191 dwarf_lineno(Dwarf_Line ln
, Dwarf_Unsigned
*ret_lineno
, Dwarf_Error
*error
)
194 if (ln
== NULL
|| ret_lineno
== NULL
) {
195 DWARF_SET_ERROR(NULL
, error
, DW_DLE_ARGUMENT
);
196 return (DW_DLV_ERROR
);
199 *ret_lineno
= ln
->ln_lineno
;
205 dwarf_line_srcfileno(Dwarf_Line ln
, Dwarf_Unsigned
*ret_fileno
,
209 if (ln
== NULL
|| ret_fileno
== NULL
) {
210 DWARF_SET_ERROR(NULL
, error
, DW_DLE_ARGUMENT
);
211 return (DW_DLV_ERROR
);
214 *ret_fileno
= ln
->ln_fileno
;
220 dwarf_lineaddr(Dwarf_Line ln
, Dwarf_Addr
*ret_lineaddr
, Dwarf_Error
*error
)
223 if (ln
== NULL
|| ret_lineaddr
== NULL
) {
224 DWARF_SET_ERROR(NULL
, error
, DW_DLE_ARGUMENT
);
225 return (DW_DLV_ERROR
);
228 *ret_lineaddr
= ln
->ln_addr
;
234 dwarf_lineoff(Dwarf_Line ln
, Dwarf_Signed
*ret_lineoff
, Dwarf_Error
*error
)
237 if (ln
== NULL
|| ret_lineoff
== NULL
) {
238 DWARF_SET_ERROR(NULL
, error
, DW_DLE_ARGUMENT
);
239 return (DW_DLV_ERROR
);
242 if (ln
->ln_column
== 0)
245 *ret_lineoff
= (Dwarf_Signed
) ln
->ln_column
;
251 dwarf_linesrc(Dwarf_Line ln
, char **ret_linesrc
, Dwarf_Error
*error
)
257 if (ln
== NULL
|| ret_linesrc
== NULL
) {
258 DWARF_SET_ERROR(NULL
, error
, DW_DLE_ARGUMENT
);
259 return (DW_DLV_ERROR
);
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
))
271 DWARF_SET_ERROR(NULL
, error
, DW_DLE_LINE_FILE_NUM_BAD
);
272 return (DW_DLV_ERROR
);
275 if (lf
->lf_fullpath
) {
276 *ret_linesrc
= (char *) lf
->lf_fullpath
;
280 *ret_linesrc
= lf
->lf_fname
;
286 dwarf_lineblock(Dwarf_Line ln
, Dwarf_Bool
*ret_bool
, Dwarf_Error
*error
)
289 if (ln
== NULL
|| ret_bool
== NULL
) {
290 DWARF_SET_ERROR(NULL
, error
, DW_DLE_ARGUMENT
);
291 return (DW_DLV_ERROR
);
294 *ret_bool
= ln
->ln_bblock
;