1 /* $NetBSD: dwarf_lineno.c,v 1.4 2022/05/01 17:20:47 jkoshy 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.4 2022/05/01 17:20:47 jkoshy Exp $");
32 ELFTC_VCSID("Id: dwarf_lineno.c 2983 2014-02-09 00:24:31Z kaiwang27");
33
34 int
dwarf_srclines(Dwarf_Die die,Dwarf_Line ** linebuf,Dwarf_Signed * linecount,Dwarf_Error * error)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
dwarf_srcfiles(Dwarf_Die die,char *** srcfiles,Dwarf_Signed * srccount,Dwarf_Error * error)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
dwarf_linebeginstatement(Dwarf_Line ln,Dwarf_Bool * ret_bool,Dwarf_Error * error)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
dwarf_lineendsequence(Dwarf_Line ln,Dwarf_Bool * ret_bool,Dwarf_Error * error)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
dwarf_lineno(Dwarf_Line ln,Dwarf_Unsigned * ret_lineno,Dwarf_Error * error)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
dwarf_line_srcfileno(Dwarf_Line ln,Dwarf_Unsigned * ret_fileno,Dwarf_Error * error)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
dwarf_lineaddr(Dwarf_Line ln,Dwarf_Addr * ret_lineaddr,Dwarf_Error * error)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
dwarf_lineoff(Dwarf_Line ln,Dwarf_Signed * ret_lineoff,Dwarf_Error * error)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
dwarf_linesrc(Dwarf_Line ln,char ** ret_linesrc,Dwarf_Error * error)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
dwarf_lineblock(Dwarf_Line ln,Dwarf_Bool * ret_bool,Dwarf_Error * error)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