xref: /titanic_52/usr/src/lib/libdwarf/common/dwarf_line.c (revision 7fd791373689a6af05e27efec3b1ab556e02aa23)
1*7fd79137SRobert Mustacchi /*
2*7fd79137SRobert Mustacchi   Copyright (C) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
3*7fd79137SRobert Mustacchi   Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
4*7fd79137SRobert Mustacchi 
5*7fd79137SRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
6*7fd79137SRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
7*7fd79137SRobert Mustacchi   as published by the Free Software Foundation.
8*7fd79137SRobert Mustacchi 
9*7fd79137SRobert Mustacchi   This program is distributed in the hope that it would be useful, but
10*7fd79137SRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
11*7fd79137SRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12*7fd79137SRobert Mustacchi 
13*7fd79137SRobert Mustacchi   Further, this software is distributed without any warranty that it is
14*7fd79137SRobert Mustacchi   free of the rightful claim of any third person regarding infringement
15*7fd79137SRobert Mustacchi   or the like.  Any license provided herein, whether implied or
16*7fd79137SRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
17*7fd79137SRobert Mustacchi   any, provided herein do not apply to combinations of this program with
18*7fd79137SRobert Mustacchi   other software, or any other product whatsoever.
19*7fd79137SRobert Mustacchi 
20*7fd79137SRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
21*7fd79137SRobert Mustacchi   License along with this program; if not, write the Free Software
22*7fd79137SRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
23*7fd79137SRobert Mustacchi   USA.
24*7fd79137SRobert Mustacchi 
25*7fd79137SRobert Mustacchi   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
26*7fd79137SRobert Mustacchi   Mountain View, CA 94043, or:
27*7fd79137SRobert Mustacchi 
28*7fd79137SRobert Mustacchi   http://www.sgi.com
29*7fd79137SRobert Mustacchi 
30*7fd79137SRobert Mustacchi   For further information regarding this notice, see:
31*7fd79137SRobert Mustacchi 
32*7fd79137SRobert Mustacchi   http://oss.sgi.com/projects/GenInfo/NoticeExplan
33*7fd79137SRobert Mustacchi 
34*7fd79137SRobert Mustacchi */
35*7fd79137SRobert Mustacchi /* The address of the Free Software Foundation is
36*7fd79137SRobert Mustacchi    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
37*7fd79137SRobert Mustacchi    Boston, MA 02110-1301, USA.
38*7fd79137SRobert Mustacchi    SGI has moved from the Crittenden Lane address.
39*7fd79137SRobert Mustacchi */
40*7fd79137SRobert Mustacchi 
41*7fd79137SRobert Mustacchi 
42*7fd79137SRobert Mustacchi 
43*7fd79137SRobert Mustacchi 
44*7fd79137SRobert Mustacchi #include "config.h"
45*7fd79137SRobert Mustacchi #include "dwarf_incl.h"
46*7fd79137SRobert Mustacchi #include <stdio.h>
47*7fd79137SRobert Mustacchi #include <stdlib.h>
48*7fd79137SRobert Mustacchi #include "dwarf_line.h"
49*7fd79137SRobert Mustacchi 
50*7fd79137SRobert Mustacchi static int
51*7fd79137SRobert Mustacchi is_path_separator(Dwarf_Small s)
52*7fd79137SRobert Mustacchi {
53*7fd79137SRobert Mustacchi     if(s == '/') {
54*7fd79137SRobert Mustacchi         return 1;
55*7fd79137SRobert Mustacchi     }
56*7fd79137SRobert Mustacchi #ifdef HAVE_WINDOWS_PATH
57*7fd79137SRobert Mustacchi     if(s == '\\') {
58*7fd79137SRobert Mustacchi         return 1;
59*7fd79137SRobert Mustacchi     }
60*7fd79137SRobert Mustacchi #endif
61*7fd79137SRobert Mustacchi     return 0;
62*7fd79137SRobert Mustacchi }
63*7fd79137SRobert Mustacchi 
64*7fd79137SRobert Mustacchi /* Return 0 if false, 1 if true.
65*7fd79137SRobert Mustacchi    If HAVE_WINDOWS_PATH is defined we
66*7fd79137SRobert Mustacchi    attempt to handle windows full paths:
67*7fd79137SRobert Mustacchi    \\something   or  C:cwdpath.c
68*7fd79137SRobert Mustacchi */
69*7fd79137SRobert Mustacchi static int
70*7fd79137SRobert Mustacchi file_name_is_full_path(Dwarf_Small  *fname)
71*7fd79137SRobert Mustacchi {
72*7fd79137SRobert Mustacchi     Dwarf_Small firstc = *fname;
73*7fd79137SRobert Mustacchi     if(is_path_separator(firstc)) {
74*7fd79137SRobert Mustacchi         /* Full path. */
75*7fd79137SRobert Mustacchi         return 1;
76*7fd79137SRobert Mustacchi     }
77*7fd79137SRobert Mustacchi     if(!firstc) {
78*7fd79137SRobert Mustacchi         return 0;
79*7fd79137SRobert Mustacchi     }
80*7fd79137SRobert Mustacchi #ifdef HAVE_WINDOWS_PATH
81*7fd79137SRobert Mustacchi     if((firstc >= 'A' && firstc <= 'Z') ||
82*7fd79137SRobert Mustacchi        (firstc >= 'a' && firstc <= 'z')) {
83*7fd79137SRobert Mustacchi          Dwarf_Small secondc = fname[1];
84*7fd79137SRobert Mustacchi          if (secondc == ':') {
85*7fd79137SRobert Mustacchi              return 1;
86*7fd79137SRobert Mustacchi          }
87*7fd79137SRobert Mustacchi     }
88*7fd79137SRobert Mustacchi #endif
89*7fd79137SRobert Mustacchi     return 0;
90*7fd79137SRobert Mustacchi }
91*7fd79137SRobert Mustacchi 
92*7fd79137SRobert Mustacchi /*
93*7fd79137SRobert Mustacchi     Although source files is supposed to return the
94*7fd79137SRobert Mustacchi     source files in the compilation-unit, it does
95*7fd79137SRobert Mustacchi     not look for any in the statement program.  In
96*7fd79137SRobert Mustacchi     other words, it ignores those defined using the
97*7fd79137SRobert Mustacchi     extended opcode DW_LNE_define_file.
98*7fd79137SRobert Mustacchi */
99*7fd79137SRobert Mustacchi int
100*7fd79137SRobert Mustacchi dwarf_srcfiles(Dwarf_Die die,
101*7fd79137SRobert Mustacchi                char ***srcfiles,
102*7fd79137SRobert Mustacchi                Dwarf_Signed * srcfilecount, Dwarf_Error * error)
103*7fd79137SRobert Mustacchi {
104*7fd79137SRobert Mustacchi     /* This pointer is used to scan the portion of the .debug_line
105*7fd79137SRobert Mustacchi        section for the current cu. */
106*7fd79137SRobert Mustacchi     Dwarf_Small *line_ptr;
107*7fd79137SRobert Mustacchi 
108*7fd79137SRobert Mustacchi     /* Pointer to a DW_AT_stmt_list attribute in case it exists in the
109*7fd79137SRobert Mustacchi        die. */
110*7fd79137SRobert Mustacchi     Dwarf_Attribute stmt_list_attr;
111*7fd79137SRobert Mustacchi 
112*7fd79137SRobert Mustacchi     /* Pointer to DW_AT_comp_dir attribute in die. */
113*7fd79137SRobert Mustacchi     Dwarf_Attribute comp_dir_attr;
114*7fd79137SRobert Mustacchi 
115*7fd79137SRobert Mustacchi     /* Pointer to name of compilation directory. */
116*7fd79137SRobert Mustacchi     Dwarf_Small *comp_dir = 0;
117*7fd79137SRobert Mustacchi 
118*7fd79137SRobert Mustacchi     /* Offset into .debug_line specified by a DW_AT_stmt_list
119*7fd79137SRobert Mustacchi        attribute. */
120*7fd79137SRobert Mustacchi     Dwarf_Unsigned line_offset = 0;
121*7fd79137SRobert Mustacchi 
122*7fd79137SRobert Mustacchi     /* This points to a block of char *'s, each of which points to a
123*7fd79137SRobert Mustacchi        file name. */
124*7fd79137SRobert Mustacchi     char **ret_files = 0;
125*7fd79137SRobert Mustacchi 
126*7fd79137SRobert Mustacchi     /* The Dwarf_Debug this die belongs to. */
127*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
128*7fd79137SRobert Mustacchi 
129*7fd79137SRobert Mustacchi     /* Used to chain the file names. */
130*7fd79137SRobert Mustacchi     Dwarf_Chain curr_chain = NULL;
131*7fd79137SRobert Mustacchi     Dwarf_Chain prev_chain = NULL;
132*7fd79137SRobert Mustacchi     Dwarf_Chain head_chain = NULL;
133*7fd79137SRobert Mustacchi     Dwarf_Half attrform = 0;
134*7fd79137SRobert Mustacchi     int resattr = DW_DLV_ERROR;
135*7fd79137SRobert Mustacchi     int lres = DW_DLV_ERROR;
136*7fd79137SRobert Mustacchi     struct Line_Table_Prefix_s line_prefix;
137*7fd79137SRobert Mustacchi     int i = 0;
138*7fd79137SRobert Mustacchi     int res = DW_DLV_ERROR;
139*7fd79137SRobert Mustacchi 
140*7fd79137SRobert Mustacchi     /* ***** BEGIN CODE ***** */
141*7fd79137SRobert Mustacchi     /* Reset error. */
142*7fd79137SRobert Mustacchi     if (error != NULL)
143*7fd79137SRobert Mustacchi         *error = NULL;
144*7fd79137SRobert Mustacchi 
145*7fd79137SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
146*7fd79137SRobert Mustacchi     dbg = die->di_cu_context->cc_dbg;
147*7fd79137SRobert Mustacchi 
148*7fd79137SRobert Mustacchi     resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
149*7fd79137SRobert Mustacchi     if (resattr != DW_DLV_OK) {
150*7fd79137SRobert Mustacchi         return resattr;
151*7fd79137SRobert Mustacchi     }
152*7fd79137SRobert Mustacchi 
153*7fd79137SRobert Mustacchi     if (dbg->de_debug_line.dss_index == 0) {
154*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_NULL);
155*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
156*7fd79137SRobert Mustacchi     }
157*7fd79137SRobert Mustacchi 
158*7fd79137SRobert Mustacchi     res = _dwarf_load_section(dbg, &dbg->de_debug_line,error);
159*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK) {
160*7fd79137SRobert Mustacchi         return res;
161*7fd79137SRobert Mustacchi     }
162*7fd79137SRobert Mustacchi 
163*7fd79137SRobert Mustacchi     lres = dwarf_whatform(stmt_list_attr,&attrform,error);
164*7fd79137SRobert Mustacchi     if (lres != DW_DLV_OK) {
165*7fd79137SRobert Mustacchi         return lres;
166*7fd79137SRobert Mustacchi     }
167*7fd79137SRobert Mustacchi     if (attrform != DW_FORM_data4 && attrform != DW_FORM_data8 &&
168*7fd79137SRobert Mustacchi         attrform != DW_FORM_sec_offset ) {
169*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
170*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
171*7fd79137SRobert Mustacchi     }
172*7fd79137SRobert Mustacchi     lres = dwarf_global_formref(stmt_list_attr, &line_offset, error);
173*7fd79137SRobert Mustacchi     if (lres != DW_DLV_OK) {
174*7fd79137SRobert Mustacchi         return lres;
175*7fd79137SRobert Mustacchi     }
176*7fd79137SRobert Mustacchi     if (line_offset >= dbg->de_debug_line.dss_size) {
177*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
178*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
179*7fd79137SRobert Mustacchi     }
180*7fd79137SRobert Mustacchi     line_ptr = dbg->de_debug_line.dss_data + line_offset;
181*7fd79137SRobert Mustacchi     dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
182*7fd79137SRobert Mustacchi 
183*7fd79137SRobert Mustacchi     /*
184*7fd79137SRobert Mustacchi        If die has DW_AT_comp_dir attribute, get the string that names
185*7fd79137SRobert Mustacchi        the compilation directory. */
186*7fd79137SRobert Mustacchi     resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
187*7fd79137SRobert Mustacchi     if (resattr == DW_DLV_ERROR) {
188*7fd79137SRobert Mustacchi         return resattr;
189*7fd79137SRobert Mustacchi     }
190*7fd79137SRobert Mustacchi     if (resattr == DW_DLV_OK) {
191*7fd79137SRobert Mustacchi         int cres = DW_DLV_ERROR;
192*7fd79137SRobert Mustacchi         char *cdir = 0;
193*7fd79137SRobert Mustacchi 
194*7fd79137SRobert Mustacchi         cres = dwarf_formstring(comp_dir_attr, &cdir, error);
195*7fd79137SRobert Mustacchi         if (cres == DW_DLV_ERROR) {
196*7fd79137SRobert Mustacchi             return cres;
197*7fd79137SRobert Mustacchi         } else if (cres == DW_DLV_OK) {
198*7fd79137SRobert Mustacchi             comp_dir = (Dwarf_Small *) cdir;
199*7fd79137SRobert Mustacchi         }
200*7fd79137SRobert Mustacchi     }
201*7fd79137SRobert Mustacchi     if (resattr == DW_DLV_OK) {
202*7fd79137SRobert Mustacchi         dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
203*7fd79137SRobert Mustacchi     }
204*7fd79137SRobert Mustacchi     dwarf_init_line_table_prefix(&line_prefix);
205*7fd79137SRobert Mustacchi     {
206*7fd79137SRobert Mustacchi         Dwarf_Small *line_ptr_out = 0;
207*7fd79137SRobert Mustacchi         int dres = dwarf_read_line_table_prefix(dbg,
208*7fd79137SRobert Mustacchi             line_ptr,
209*7fd79137SRobert Mustacchi             dbg->de_debug_line.dss_size,
210*7fd79137SRobert Mustacchi             &line_ptr_out,
211*7fd79137SRobert Mustacchi             &line_prefix,
212*7fd79137SRobert Mustacchi             NULL, NULL,error,
213*7fd79137SRobert Mustacchi             0);
214*7fd79137SRobert Mustacchi 
215*7fd79137SRobert Mustacchi         if (dres == DW_DLV_ERROR) {
216*7fd79137SRobert Mustacchi             dwarf_free_line_table_prefix(&line_prefix);
217*7fd79137SRobert Mustacchi             return dres;
218*7fd79137SRobert Mustacchi         }
219*7fd79137SRobert Mustacchi         if (dres == DW_DLV_NO_ENTRY) {
220*7fd79137SRobert Mustacchi             dwarf_free_line_table_prefix(&line_prefix);
221*7fd79137SRobert Mustacchi             return dres;
222*7fd79137SRobert Mustacchi         }
223*7fd79137SRobert Mustacchi 
224*7fd79137SRobert Mustacchi         line_ptr = line_ptr_out;
225*7fd79137SRobert Mustacchi     }
226*7fd79137SRobert Mustacchi 
227*7fd79137SRobert Mustacchi     for (i = 0; i < line_prefix.pf_files_count; ++i) {
228*7fd79137SRobert Mustacchi         struct Line_Table_File_Entry_s *fe =
229*7fd79137SRobert Mustacchi             line_prefix.pf_line_table_file_entries + i;
230*7fd79137SRobert Mustacchi         char *file_name = (char *) fe->lte_filename;
231*7fd79137SRobert Mustacchi         char *dir_name = 0;
232*7fd79137SRobert Mustacchi         char *full_name = 0;
233*7fd79137SRobert Mustacchi         Dwarf_Unsigned dir_index = fe->lte_directory_index;
234*7fd79137SRobert Mustacchi 
235*7fd79137SRobert Mustacchi         if (dir_index == 0) {
236*7fd79137SRobert Mustacchi             dir_name = (char *) comp_dir;
237*7fd79137SRobert Mustacchi         } else {
238*7fd79137SRobert Mustacchi             dir_name =
239*7fd79137SRobert Mustacchi                 (char *) line_prefix.pf_include_directories[
240*7fd79137SRobert Mustacchi                     fe->lte_directory_index - 1];
241*7fd79137SRobert Mustacchi         }
242*7fd79137SRobert Mustacchi 
243*7fd79137SRobert Mustacchi         /* dir_name can be NULL if there is no DW_AT_comp_dir */
244*7fd79137SRobert Mustacchi         if(dir_name == 0 || file_name_is_full_path((unsigned char *)file_name)) {
245*7fd79137SRobert Mustacchi             /* This is safe because dwarf_dealloc is careful to not
246*7fd79137SRobert Mustacchi                dealloc strings which are part of the raw .debug_* data.
247*7fd79137SRobert Mustacchi              */
248*7fd79137SRobert Mustacchi             full_name = file_name;
249*7fd79137SRobert Mustacchi         } else {
250*7fd79137SRobert Mustacchi             full_name = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING,
251*7fd79137SRobert Mustacchi                                                   strlen(dir_name) + 1 +
252*7fd79137SRobert Mustacchi                                                   strlen(file_name) +
253*7fd79137SRobert Mustacchi                                                   1);
254*7fd79137SRobert Mustacchi             if (full_name == NULL) {
255*7fd79137SRobert Mustacchi                 dwarf_free_line_table_prefix(&line_prefix);
256*7fd79137SRobert Mustacchi                 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
257*7fd79137SRobert Mustacchi                 return (DW_DLV_ERROR);
258*7fd79137SRobert Mustacchi             }
259*7fd79137SRobert Mustacchi 
260*7fd79137SRobert Mustacchi             /* This is not careful to avoid // in the output, Nothing
261*7fd79137SRobert Mustacchi                forces a 'canonical' name format here. Unclear if this
262*7fd79137SRobert Mustacchi                needs to be fixed. */
263*7fd79137SRobert Mustacchi             strcpy(full_name, dir_name);
264*7fd79137SRobert Mustacchi             strcat(full_name, "/");
265*7fd79137SRobert Mustacchi             strcat(full_name, file_name);
266*7fd79137SRobert Mustacchi         }
267*7fd79137SRobert Mustacchi         curr_chain =
268*7fd79137SRobert Mustacchi             (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
269*7fd79137SRobert Mustacchi         if (curr_chain == NULL) {
270*7fd79137SRobert Mustacchi             dwarf_free_line_table_prefix(&line_prefix);
271*7fd79137SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
272*7fd79137SRobert Mustacchi             return (DW_DLV_ERROR);
273*7fd79137SRobert Mustacchi         }
274*7fd79137SRobert Mustacchi         curr_chain->ch_item = full_name;
275*7fd79137SRobert Mustacchi         if (head_chain == NULL)
276*7fd79137SRobert Mustacchi             head_chain = prev_chain = curr_chain;
277*7fd79137SRobert Mustacchi         else {
278*7fd79137SRobert Mustacchi             prev_chain->ch_next = curr_chain;
279*7fd79137SRobert Mustacchi             prev_chain = curr_chain;
280*7fd79137SRobert Mustacchi         }
281*7fd79137SRobert Mustacchi     }
282*7fd79137SRobert Mustacchi 
283*7fd79137SRobert Mustacchi     curr_chain = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
284*7fd79137SRobert Mustacchi     if (curr_chain == NULL) {
285*7fd79137SRobert Mustacchi         dwarf_free_line_table_prefix(&line_prefix);
286*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
287*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
288*7fd79137SRobert Mustacchi     }
289*7fd79137SRobert Mustacchi 
290*7fd79137SRobert Mustacchi 
291*7fd79137SRobert Mustacchi 
292*7fd79137SRobert Mustacchi 
293*7fd79137SRobert Mustacchi     if (line_prefix.pf_files_count == 0) {
294*7fd79137SRobert Mustacchi         *srcfiles = NULL;
295*7fd79137SRobert Mustacchi         *srcfilecount = 0;
296*7fd79137SRobert Mustacchi         dwarf_free_line_table_prefix(&line_prefix);
297*7fd79137SRobert Mustacchi         return (DW_DLV_NO_ENTRY);
298*7fd79137SRobert Mustacchi     }
299*7fd79137SRobert Mustacchi 
300*7fd79137SRobert Mustacchi     ret_files = (char **)
301*7fd79137SRobert Mustacchi         _dwarf_get_alloc(dbg, DW_DLA_LIST, line_prefix.pf_files_count);
302*7fd79137SRobert Mustacchi     if (ret_files == NULL) {
303*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
304*7fd79137SRobert Mustacchi         dwarf_free_line_table_prefix(&line_prefix);
305*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
306*7fd79137SRobert Mustacchi     }
307*7fd79137SRobert Mustacchi 
308*7fd79137SRobert Mustacchi     curr_chain = head_chain;
309*7fd79137SRobert Mustacchi     for (i = 0; i < line_prefix.pf_files_count; i++) {
310*7fd79137SRobert Mustacchi         *(ret_files + i) = curr_chain->ch_item;
311*7fd79137SRobert Mustacchi         prev_chain = curr_chain;
312*7fd79137SRobert Mustacchi         curr_chain = curr_chain->ch_next;
313*7fd79137SRobert Mustacchi         dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
314*7fd79137SRobert Mustacchi     }
315*7fd79137SRobert Mustacchi 
316*7fd79137SRobert Mustacchi     *srcfiles = ret_files;
317*7fd79137SRobert Mustacchi     *srcfilecount = line_prefix.pf_files_count;
318*7fd79137SRobert Mustacchi     dwarf_free_line_table_prefix(&line_prefix);
319*7fd79137SRobert Mustacchi     return (DW_DLV_OK);
320*7fd79137SRobert Mustacchi }
321*7fd79137SRobert Mustacchi 
322*7fd79137SRobert Mustacchi 
323*7fd79137SRobert Mustacchi /*
324*7fd79137SRobert Mustacchi         return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR
325*7fd79137SRobert Mustacchi */
326*7fd79137SRobert Mustacchi int
327*7fd79137SRobert Mustacchi _dwarf_internal_srclines(Dwarf_Die die,
328*7fd79137SRobert Mustacchi     Dwarf_Line ** linebuf,
329*7fd79137SRobert Mustacchi     Dwarf_Signed * count,
330*7fd79137SRobert Mustacchi     Dwarf_Bool doaddrs,
331*7fd79137SRobert Mustacchi     Dwarf_Bool dolines, Dwarf_Error * error)
332*7fd79137SRobert Mustacchi {
333*7fd79137SRobert Mustacchi     /* This pointer is used to scan the portion of the .debug_line
334*7fd79137SRobert Mustacchi        section for the current cu. */
335*7fd79137SRobert Mustacchi     Dwarf_Small *line_ptr = 0;
336*7fd79137SRobert Mustacchi 
337*7fd79137SRobert Mustacchi     /* This points to the last byte of the .debug_line portion for the
338*7fd79137SRobert Mustacchi        current cu. */
339*7fd79137SRobert Mustacchi     Dwarf_Small *line_ptr_end = 0;
340*7fd79137SRobert Mustacchi 
341*7fd79137SRobert Mustacchi     /* Pointer to a DW_AT_stmt_list attribute in case it exists in the
342*7fd79137SRobert Mustacchi        die. */
343*7fd79137SRobert Mustacchi     Dwarf_Attribute stmt_list_attr = 0;
344*7fd79137SRobert Mustacchi 
345*7fd79137SRobert Mustacchi     /* Pointer to DW_AT_comp_dir attribute in die. */
346*7fd79137SRobert Mustacchi     Dwarf_Attribute comp_dir_attr = 0;
347*7fd79137SRobert Mustacchi 
348*7fd79137SRobert Mustacchi     /* Pointer to name of compilation directory. */
349*7fd79137SRobert Mustacchi     Dwarf_Small *comp_dir = NULL;
350*7fd79137SRobert Mustacchi 
351*7fd79137SRobert Mustacchi     /* Offset into .debug_line specified by a DW_AT_stmt_list
352*7fd79137SRobert Mustacchi        attribute. */
353*7fd79137SRobert Mustacchi     Dwarf_Unsigned line_offset = 0;
354*7fd79137SRobert Mustacchi 
355*7fd79137SRobert Mustacchi     Dwarf_File_Entry file_entries = 0;
356*7fd79137SRobert Mustacchi 
357*7fd79137SRobert Mustacchi     /* These are the state machine state variables. */
358*7fd79137SRobert Mustacchi     Dwarf_Addr address = 0;
359*7fd79137SRobert Mustacchi     Dwarf_Word file = 1;
360*7fd79137SRobert Mustacchi     Dwarf_Word line = 1;
361*7fd79137SRobert Mustacchi     Dwarf_Word column = 0;
362*7fd79137SRobert Mustacchi 
363*7fd79137SRobert Mustacchi     /* Phony init. See below for true initialization. */
364*7fd79137SRobert Mustacchi     Dwarf_Bool is_stmt = false;
365*7fd79137SRobert Mustacchi 
366*7fd79137SRobert Mustacchi     Dwarf_Bool basic_block = false;
367*7fd79137SRobert Mustacchi     Dwarf_Bool prologue_end = false;
368*7fd79137SRobert Mustacchi     Dwarf_Bool epilogue_begin = false;
369*7fd79137SRobert Mustacchi     Dwarf_Small isa = 0;
370*7fd79137SRobert Mustacchi     Dwarf_Bool end_sequence = false;
371*7fd79137SRobert Mustacchi 
372*7fd79137SRobert Mustacchi     /* These pointers are used to build the list of files names by this
373*7fd79137SRobert Mustacchi        cu.  cur_file_entry points to the file name being added, and
374*7fd79137SRobert Mustacchi        prev_file_entry to the previous one. */
375*7fd79137SRobert Mustacchi     Dwarf_File_Entry cur_file_entry, prev_file_entry;
376*7fd79137SRobert Mustacchi 
377*7fd79137SRobert Mustacchi     Dwarf_Sword i = 0;
378*7fd79137SRobert Mustacchi     Dwarf_Sword file_entry_count = 0;
379*7fd79137SRobert Mustacchi 
380*7fd79137SRobert Mustacchi     /* This is the current opcode read from the statement program. */
381*7fd79137SRobert Mustacchi     Dwarf_Small opcode = 0;
382*7fd79137SRobert Mustacchi 
383*7fd79137SRobert Mustacchi     /* Pointer to a Dwarf_Line_Context_s structure that contains the
384*7fd79137SRobert Mustacchi        context such as file names and include directories for the set
385*7fd79137SRobert Mustacchi        of lines being generated. */
386*7fd79137SRobert Mustacchi     Dwarf_Line_Context line_context = 0;
387*7fd79137SRobert Mustacchi 
388*7fd79137SRobert Mustacchi     /* This is a pointer to the current line being added to the line
389*7fd79137SRobert Mustacchi        matrix. */
390*7fd79137SRobert Mustacchi     Dwarf_Line curr_line = 0;
391*7fd79137SRobert Mustacchi 
392*7fd79137SRobert Mustacchi     /* These variables are used to decode leb128 numbers. Leb128_num
393*7fd79137SRobert Mustacchi        holds the decoded number, and leb128_length is its length in
394*7fd79137SRobert Mustacchi        bytes. */
395*7fd79137SRobert Mustacchi     Dwarf_Word leb128_num = 0;
396*7fd79137SRobert Mustacchi     Dwarf_Word leb128_length = 0;
397*7fd79137SRobert Mustacchi     Dwarf_Sword advance_line = 0;
398*7fd79137SRobert Mustacchi 
399*7fd79137SRobert Mustacchi     /* This is the operand of the latest fixed_advance_pc extended
400*7fd79137SRobert Mustacchi        opcode. */
401*7fd79137SRobert Mustacchi     Dwarf_Half fixed_advance_pc = 0;
402*7fd79137SRobert Mustacchi 
403*7fd79137SRobert Mustacchi     /* Counts the number of lines in the line matrix. */
404*7fd79137SRobert Mustacchi     Dwarf_Sword line_count = 0;
405*7fd79137SRobert Mustacchi 
406*7fd79137SRobert Mustacchi     /* This is the length of an extended opcode instr.  */
407*7fd79137SRobert Mustacchi     Dwarf_Word instr_length = 0;
408*7fd79137SRobert Mustacchi     Dwarf_Small ext_opcode = 0;
409*7fd79137SRobert Mustacchi     struct Line_Table_Prefix_s prefix;
410*7fd79137SRobert Mustacchi 
411*7fd79137SRobert Mustacchi     /* Used to chain together pointers to line table entries that are
412*7fd79137SRobert Mustacchi        later used to create a block of Dwarf_Line entries. */
413*7fd79137SRobert Mustacchi     Dwarf_Chain chain_line = NULL;
414*7fd79137SRobert Mustacchi     Dwarf_Chain head_chain = NULL;
415*7fd79137SRobert Mustacchi     Dwarf_Chain curr_chain = NULL;
416*7fd79137SRobert Mustacchi 
417*7fd79137SRobert Mustacchi     /* This points to a block of Dwarf_Lines, a pointer to which is
418*7fd79137SRobert Mustacchi        returned in linebuf. */
419*7fd79137SRobert Mustacchi     Dwarf_Line *block_line = 0;
420*7fd79137SRobert Mustacchi 
421*7fd79137SRobert Mustacchi     /* The Dwarf_Debug this die belongs to. */
422*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
423*7fd79137SRobert Mustacchi     int resattr = DW_DLV_ERROR;
424*7fd79137SRobert Mustacchi     int lres = DW_DLV_ERROR;
425*7fd79137SRobert Mustacchi     Dwarf_Half address_size = 0;
426*7fd79137SRobert Mustacchi 
427*7fd79137SRobert Mustacchi     int res = DW_DLV_ERROR;
428*7fd79137SRobert Mustacchi 
429*7fd79137SRobert Mustacchi     /* ***** BEGIN CODE ***** */
430*7fd79137SRobert Mustacchi     if (error != NULL)
431*7fd79137SRobert Mustacchi         *error = NULL;
432*7fd79137SRobert Mustacchi 
433*7fd79137SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
434*7fd79137SRobert Mustacchi     dbg = die->di_cu_context->cc_dbg;
435*7fd79137SRobert Mustacchi 
436*7fd79137SRobert Mustacchi     res = _dwarf_load_section(dbg, &dbg->de_debug_line,error);
437*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK) {
438*7fd79137SRobert Mustacchi         return res;
439*7fd79137SRobert Mustacchi     }
440*7fd79137SRobert Mustacchi     address_size = _dwarf_get_address_size(dbg, die);
441*7fd79137SRobert Mustacchi     resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
442*7fd79137SRobert Mustacchi     if (resattr != DW_DLV_OK) {
443*7fd79137SRobert Mustacchi         return resattr;
444*7fd79137SRobert Mustacchi     }
445*7fd79137SRobert Mustacchi 
446*7fd79137SRobert Mustacchi     lres = dwarf_formudata(stmt_list_attr, &line_offset, error);
447*7fd79137SRobert Mustacchi     if (lres != DW_DLV_OK) {
448*7fd79137SRobert Mustacchi         return lres;
449*7fd79137SRobert Mustacchi     }
450*7fd79137SRobert Mustacchi 
451*7fd79137SRobert Mustacchi     if (line_offset >= dbg->de_debug_line.dss_size) {
452*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
453*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
454*7fd79137SRobert Mustacchi     }
455*7fd79137SRobert Mustacchi     line_ptr = dbg->de_debug_line.dss_data + line_offset;
456*7fd79137SRobert Mustacchi     dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
457*7fd79137SRobert Mustacchi 
458*7fd79137SRobert Mustacchi     /* If die has DW_AT_comp_dir attribute, get the string that names
459*7fd79137SRobert Mustacchi        the compilation directory. */
460*7fd79137SRobert Mustacchi     resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
461*7fd79137SRobert Mustacchi     if (resattr == DW_DLV_ERROR) {
462*7fd79137SRobert Mustacchi         return resattr;
463*7fd79137SRobert Mustacchi     }
464*7fd79137SRobert Mustacchi     if (resattr == DW_DLV_OK) {
465*7fd79137SRobert Mustacchi         int cres = DW_DLV_ERROR;
466*7fd79137SRobert Mustacchi         char *cdir = 0;
467*7fd79137SRobert Mustacchi 
468*7fd79137SRobert Mustacchi         cres = dwarf_formstring(comp_dir_attr, &cdir, error);
469*7fd79137SRobert Mustacchi         if (cres == DW_DLV_ERROR) {
470*7fd79137SRobert Mustacchi             return cres;
471*7fd79137SRobert Mustacchi         } else if (cres == DW_DLV_OK) {
472*7fd79137SRobert Mustacchi             comp_dir = (Dwarf_Small *) cdir;
473*7fd79137SRobert Mustacchi         }
474*7fd79137SRobert Mustacchi     }
475*7fd79137SRobert Mustacchi     if (resattr == DW_DLV_OK) {
476*7fd79137SRobert Mustacchi         dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
477*7fd79137SRobert Mustacchi     }
478*7fd79137SRobert Mustacchi     dwarf_init_line_table_prefix(&prefix);
479*7fd79137SRobert Mustacchi 
480*7fd79137SRobert Mustacchi     {
481*7fd79137SRobert Mustacchi         Dwarf_Small *newlinep = 0;
482*7fd79137SRobert Mustacchi         int res = dwarf_read_line_table_prefix(dbg,
483*7fd79137SRobert Mustacchi             line_ptr,
484*7fd79137SRobert Mustacchi             dbg->de_debug_line.dss_size,
485*7fd79137SRobert Mustacchi             &newlinep,
486*7fd79137SRobert Mustacchi             &prefix,
487*7fd79137SRobert Mustacchi             NULL,NULL,
488*7fd79137SRobert Mustacchi             error,
489*7fd79137SRobert Mustacchi             0);
490*7fd79137SRobert Mustacchi 
491*7fd79137SRobert Mustacchi         if (res == DW_DLV_ERROR) {
492*7fd79137SRobert Mustacchi             dwarf_free_line_table_prefix(&prefix);
493*7fd79137SRobert Mustacchi             return res;
494*7fd79137SRobert Mustacchi         }
495*7fd79137SRobert Mustacchi         if (res == DW_DLV_NO_ENTRY) {
496*7fd79137SRobert Mustacchi             dwarf_free_line_table_prefix(&prefix);
497*7fd79137SRobert Mustacchi             return res;
498*7fd79137SRobert Mustacchi         }
499*7fd79137SRobert Mustacchi         line_ptr_end = prefix.pf_line_ptr_end;
500*7fd79137SRobert Mustacchi         line_ptr = newlinep;
501*7fd79137SRobert Mustacchi     }
502*7fd79137SRobert Mustacchi 
503*7fd79137SRobert Mustacchi 
504*7fd79137SRobert Mustacchi     /* Set up context structure for this set of lines. */
505*7fd79137SRobert Mustacchi     line_context = (Dwarf_Line_Context)
506*7fd79137SRobert Mustacchi         _dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1);
507*7fd79137SRobert Mustacchi     if (line_context == NULL) {
508*7fd79137SRobert Mustacchi         dwarf_free_line_table_prefix(&prefix);
509*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
510*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
511*7fd79137SRobert Mustacchi     }
512*7fd79137SRobert Mustacchi 
513*7fd79137SRobert Mustacchi     /* Fill out a Dwarf_File_Entry list as we use that to implement the
514*7fd79137SRobert Mustacchi        define_file operation. */
515*7fd79137SRobert Mustacchi     file_entries = prev_file_entry = NULL;
516*7fd79137SRobert Mustacchi     for (i = 0; i < prefix.pf_files_count; ++i) {
517*7fd79137SRobert Mustacchi         struct Line_Table_File_Entry_s *pfxfile =
518*7fd79137SRobert Mustacchi             prefix.pf_line_table_file_entries + i;
519*7fd79137SRobert Mustacchi 
520*7fd79137SRobert Mustacchi         cur_file_entry = (Dwarf_File_Entry)
521*7fd79137SRobert Mustacchi             _dwarf_get_alloc(dbg, DW_DLA_FILE_ENTRY, 1);
522*7fd79137SRobert Mustacchi         if (cur_file_entry == NULL) {
523*7fd79137SRobert Mustacchi             dwarf_free_line_table_prefix(&prefix);
524*7fd79137SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
525*7fd79137SRobert Mustacchi             return (DW_DLV_ERROR);
526*7fd79137SRobert Mustacchi         }
527*7fd79137SRobert Mustacchi 
528*7fd79137SRobert Mustacchi         cur_file_entry->fi_file_name = pfxfile->lte_filename;
529*7fd79137SRobert Mustacchi         cur_file_entry->fi_dir_index = pfxfile->lte_directory_index;
530*7fd79137SRobert Mustacchi         cur_file_entry->fi_time_last_mod =
531*7fd79137SRobert Mustacchi             pfxfile->lte_last_modification_time;
532*7fd79137SRobert Mustacchi 
533*7fd79137SRobert Mustacchi         cur_file_entry->fi_file_length = pfxfile->lte_length_of_file;
534*7fd79137SRobert Mustacchi 
535*7fd79137SRobert Mustacchi         if (file_entries == NULL)
536*7fd79137SRobert Mustacchi             file_entries = cur_file_entry;
537*7fd79137SRobert Mustacchi         else
538*7fd79137SRobert Mustacchi             prev_file_entry->fi_next = cur_file_entry;
539*7fd79137SRobert Mustacchi         prev_file_entry = cur_file_entry;
540*7fd79137SRobert Mustacchi 
541*7fd79137SRobert Mustacchi         file_entry_count++;
542*7fd79137SRobert Mustacchi     }
543*7fd79137SRobert Mustacchi 
544*7fd79137SRobert Mustacchi 
545*7fd79137SRobert Mustacchi     /* Initialize the one state machine variable that depends on the
546*7fd79137SRobert Mustacchi        prefix.  */
547*7fd79137SRobert Mustacchi     is_stmt = prefix.pf_default_is_stmt;
548*7fd79137SRobert Mustacchi 
549*7fd79137SRobert Mustacchi 
550*7fd79137SRobert Mustacchi     /* Start of statement program.  */
551*7fd79137SRobert Mustacchi     while (line_ptr < line_ptr_end) {
552*7fd79137SRobert Mustacchi         int type;
553*7fd79137SRobert Mustacchi 
554*7fd79137SRobert Mustacchi         opcode = *(Dwarf_Small *) line_ptr;
555*7fd79137SRobert Mustacchi         line_ptr++;
556*7fd79137SRobert Mustacchi 
557*7fd79137SRobert Mustacchi 
558*7fd79137SRobert Mustacchi         /* 'type' is the output */
559*7fd79137SRobert Mustacchi         WHAT_IS_OPCODE(type, opcode, prefix.pf_opcode_base,
560*7fd79137SRobert Mustacchi                        prefix.pf_opcode_length_table, line_ptr,
561*7fd79137SRobert Mustacchi                        prefix.pf_std_op_count);
562*7fd79137SRobert Mustacchi 
563*7fd79137SRobert Mustacchi         if (type == LOP_DISCARD) {
564*7fd79137SRobert Mustacchi             int oc;
565*7fd79137SRobert Mustacchi             int opcnt = prefix.pf_opcode_length_table[opcode];
566*7fd79137SRobert Mustacchi 
567*7fd79137SRobert Mustacchi             for (oc = 0; oc < opcnt; oc++) {
568*7fd79137SRobert Mustacchi                 /*
569*7fd79137SRobert Mustacchi                  ** Read and discard operands we don't
570*7fd79137SRobert Mustacchi                  ** understand.
571*7fd79137SRobert Mustacchi                  ** arbitrary choice of unsigned read.
572*7fd79137SRobert Mustacchi                  ** signed read would work as well.
573*7fd79137SRobert Mustacchi                  */
574*7fd79137SRobert Mustacchi                 Dwarf_Unsigned utmp2;
575*7fd79137SRobert Mustacchi 
576*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(line_ptr, utmp2);
577*7fd79137SRobert Mustacchi             }
578*7fd79137SRobert Mustacchi         } else if (type == LOP_SPECIAL) {
579*7fd79137SRobert Mustacchi             /* This op code is a special op in the object, no matter
580*7fd79137SRobert Mustacchi                that it might fall into the standard op range in this
581*7fd79137SRobert Mustacchi                compile. That is, these are special opcodes between
582*7fd79137SRobert Mustacchi                opcode_base and MAX_LINE_OP_CODE.  (including
583*7fd79137SRobert Mustacchi                opcode_base and MAX_LINE_OP_CODE) */
584*7fd79137SRobert Mustacchi 
585*7fd79137SRobert Mustacchi             opcode = opcode - prefix.pf_opcode_base;
586*7fd79137SRobert Mustacchi             address = address + prefix.pf_minimum_instruction_length *
587*7fd79137SRobert Mustacchi                 (opcode / prefix.pf_line_range);
588*7fd79137SRobert Mustacchi             line =
589*7fd79137SRobert Mustacchi                 line + prefix.pf_line_base +
590*7fd79137SRobert Mustacchi                 opcode % prefix.pf_line_range;
591*7fd79137SRobert Mustacchi 
592*7fd79137SRobert Mustacchi             if (dolines) {
593*7fd79137SRobert Mustacchi                 curr_line =
594*7fd79137SRobert Mustacchi                     (Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1);
595*7fd79137SRobert Mustacchi                 if (curr_line == NULL) {
596*7fd79137SRobert Mustacchi                     dwarf_free_line_table_prefix(&prefix);
597*7fd79137SRobert Mustacchi                     _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
598*7fd79137SRobert Mustacchi                     return (DW_DLV_ERROR);
599*7fd79137SRobert Mustacchi                 }
600*7fd79137SRobert Mustacchi 
601*7fd79137SRobert Mustacchi                 curr_line->li_address = address;
602*7fd79137SRobert Mustacchi                 curr_line->li_addr_line.li_l_data.li_file =
603*7fd79137SRobert Mustacchi                     (Dwarf_Sword) file;
604*7fd79137SRobert Mustacchi                 curr_line->li_addr_line.li_l_data.li_line =
605*7fd79137SRobert Mustacchi                     (Dwarf_Sword) line;
606*7fd79137SRobert Mustacchi                 curr_line->li_addr_line.li_l_data.li_column =
607*7fd79137SRobert Mustacchi                     (Dwarf_Half) column;
608*7fd79137SRobert Mustacchi                 curr_line->li_addr_line.li_l_data.li_is_stmt = is_stmt;
609*7fd79137SRobert Mustacchi                 curr_line->li_addr_line.li_l_data.li_basic_block =
610*7fd79137SRobert Mustacchi                     basic_block;
611*7fd79137SRobert Mustacchi                 curr_line->li_addr_line.li_l_data.li_end_sequence =
612*7fd79137SRobert Mustacchi                     curr_line->li_addr_line.li_l_data.
613*7fd79137SRobert Mustacchi                     li_epilogue_begin = epilogue_begin;
614*7fd79137SRobert Mustacchi                 curr_line->li_addr_line.li_l_data.li_prologue_end =
615*7fd79137SRobert Mustacchi                     prologue_end;
616*7fd79137SRobert Mustacchi                 curr_line->li_addr_line.li_l_data.li_isa = isa;
617*7fd79137SRobert Mustacchi                 curr_line->li_context = line_context;
618*7fd79137SRobert Mustacchi                 line_count++;
619*7fd79137SRobert Mustacchi 
620*7fd79137SRobert Mustacchi                 chain_line = (Dwarf_Chain)
621*7fd79137SRobert Mustacchi                     _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
622*7fd79137SRobert Mustacchi                 if (chain_line == NULL) {
623*7fd79137SRobert Mustacchi                     dwarf_free_line_table_prefix(&prefix);
624*7fd79137SRobert Mustacchi                     _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
625*7fd79137SRobert Mustacchi                     return (DW_DLV_ERROR);
626*7fd79137SRobert Mustacchi                 }
627*7fd79137SRobert Mustacchi                 chain_line->ch_item = curr_line;
628*7fd79137SRobert Mustacchi 
629*7fd79137SRobert Mustacchi                 if (head_chain == NULL)
630*7fd79137SRobert Mustacchi                     head_chain = curr_chain = chain_line;
631*7fd79137SRobert Mustacchi                 else {
632*7fd79137SRobert Mustacchi                     curr_chain->ch_next = chain_line;
633*7fd79137SRobert Mustacchi                     curr_chain = chain_line;
634*7fd79137SRobert Mustacchi                 }
635*7fd79137SRobert Mustacchi             }
636*7fd79137SRobert Mustacchi 
637*7fd79137SRobert Mustacchi             basic_block = false;
638*7fd79137SRobert Mustacchi         } else if (type == LOP_STANDARD) {
639*7fd79137SRobert Mustacchi             switch (opcode) {
640*7fd79137SRobert Mustacchi 
641*7fd79137SRobert Mustacchi             case DW_LNS_copy:{
642*7fd79137SRobert Mustacchi                     if (dolines) {
643*7fd79137SRobert Mustacchi 
644*7fd79137SRobert Mustacchi                         curr_line =
645*7fd79137SRobert Mustacchi                             (Dwarf_Line) _dwarf_get_alloc(dbg,
646*7fd79137SRobert Mustacchi                                                           DW_DLA_LINE,
647*7fd79137SRobert Mustacchi                                                           1);
648*7fd79137SRobert Mustacchi                         if (curr_line == NULL) {
649*7fd79137SRobert Mustacchi                             dwarf_free_line_table_prefix(&prefix);
650*7fd79137SRobert Mustacchi                             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
651*7fd79137SRobert Mustacchi                             return (DW_DLV_ERROR);
652*7fd79137SRobert Mustacchi                         }
653*7fd79137SRobert Mustacchi 
654*7fd79137SRobert Mustacchi                         curr_line->li_address = address;
655*7fd79137SRobert Mustacchi                         curr_line->li_addr_line.li_l_data.li_file =
656*7fd79137SRobert Mustacchi                             (Dwarf_Sword) file;
657*7fd79137SRobert Mustacchi                         curr_line->li_addr_line.li_l_data.li_line =
658*7fd79137SRobert Mustacchi                             (Dwarf_Sword) line;
659*7fd79137SRobert Mustacchi                         curr_line->li_addr_line.li_l_data.li_column =
660*7fd79137SRobert Mustacchi                             (Dwarf_Half) column;
661*7fd79137SRobert Mustacchi                         curr_line->li_addr_line.li_l_data.li_is_stmt =
662*7fd79137SRobert Mustacchi                             is_stmt;
663*7fd79137SRobert Mustacchi                         curr_line->li_addr_line.li_l_data.
664*7fd79137SRobert Mustacchi                             li_basic_block = basic_block;
665*7fd79137SRobert Mustacchi                         curr_line->li_addr_line.li_l_data.
666*7fd79137SRobert Mustacchi                             li_end_sequence = end_sequence;
667*7fd79137SRobert Mustacchi                         curr_line->li_context = line_context;
668*7fd79137SRobert Mustacchi                         curr_line->li_addr_line.li_l_data.
669*7fd79137SRobert Mustacchi                             li_epilogue_begin = epilogue_begin;
670*7fd79137SRobert Mustacchi                         curr_line->li_addr_line.li_l_data.
671*7fd79137SRobert Mustacchi                             li_prologue_end = prologue_end;
672*7fd79137SRobert Mustacchi                         curr_line->li_addr_line.li_l_data.li_isa = isa;
673*7fd79137SRobert Mustacchi                         line_count++;
674*7fd79137SRobert Mustacchi 
675*7fd79137SRobert Mustacchi                         chain_line = (Dwarf_Chain)
676*7fd79137SRobert Mustacchi                             _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
677*7fd79137SRobert Mustacchi                         if (chain_line == NULL) {
678*7fd79137SRobert Mustacchi                             dwarf_free_line_table_prefix(&prefix);
679*7fd79137SRobert Mustacchi                             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
680*7fd79137SRobert Mustacchi                             return (DW_DLV_ERROR);
681*7fd79137SRobert Mustacchi                         }
682*7fd79137SRobert Mustacchi                         chain_line->ch_item = curr_line;
683*7fd79137SRobert Mustacchi                         if (head_chain == NULL)
684*7fd79137SRobert Mustacchi                             head_chain = curr_chain = chain_line;
685*7fd79137SRobert Mustacchi                         else {
686*7fd79137SRobert Mustacchi                             curr_chain->ch_next = chain_line;
687*7fd79137SRobert Mustacchi                             curr_chain = chain_line;
688*7fd79137SRobert Mustacchi                         }
689*7fd79137SRobert Mustacchi                     }
690*7fd79137SRobert Mustacchi 
691*7fd79137SRobert Mustacchi                     basic_block = false;
692*7fd79137SRobert Mustacchi                     prologue_end = false;
693*7fd79137SRobert Mustacchi                     epilogue_begin = false;
694*7fd79137SRobert Mustacchi                     break;
695*7fd79137SRobert Mustacchi                 }
696*7fd79137SRobert Mustacchi 
697*7fd79137SRobert Mustacchi             case DW_LNS_advance_pc:{
698*7fd79137SRobert Mustacchi                     Dwarf_Unsigned utmp2;
699*7fd79137SRobert Mustacchi 
700*7fd79137SRobert Mustacchi                     DECODE_LEB128_UWORD(line_ptr, utmp2);
701*7fd79137SRobert Mustacchi                     leb128_num = (Dwarf_Word) utmp2;
702*7fd79137SRobert Mustacchi                     address =
703*7fd79137SRobert Mustacchi                         address +
704*7fd79137SRobert Mustacchi                         prefix.pf_minimum_instruction_length *
705*7fd79137SRobert Mustacchi                         leb128_num;
706*7fd79137SRobert Mustacchi                     break;
707*7fd79137SRobert Mustacchi                 }
708*7fd79137SRobert Mustacchi 
709*7fd79137SRobert Mustacchi             case DW_LNS_advance_line:{
710*7fd79137SRobert Mustacchi                     Dwarf_Signed stmp;
711*7fd79137SRobert Mustacchi 
712*7fd79137SRobert Mustacchi                     DECODE_LEB128_SWORD(line_ptr, stmp);
713*7fd79137SRobert Mustacchi                     advance_line = (Dwarf_Sword) stmp;
714*7fd79137SRobert Mustacchi                     line = line + advance_line;
715*7fd79137SRobert Mustacchi                     break;
716*7fd79137SRobert Mustacchi                 }
717*7fd79137SRobert Mustacchi 
718*7fd79137SRobert Mustacchi             case DW_LNS_set_file:{
719*7fd79137SRobert Mustacchi                     Dwarf_Unsigned utmp2;
720*7fd79137SRobert Mustacchi 
721*7fd79137SRobert Mustacchi                     DECODE_LEB128_UWORD(line_ptr, utmp2);
722*7fd79137SRobert Mustacchi                     file = (Dwarf_Word) utmp2;
723*7fd79137SRobert Mustacchi                     break;
724*7fd79137SRobert Mustacchi                 }
725*7fd79137SRobert Mustacchi 
726*7fd79137SRobert Mustacchi             case DW_LNS_set_column:{
727*7fd79137SRobert Mustacchi                     Dwarf_Unsigned utmp2;
728*7fd79137SRobert Mustacchi 
729*7fd79137SRobert Mustacchi                     DECODE_LEB128_UWORD(line_ptr, utmp2);
730*7fd79137SRobert Mustacchi                     column = (Dwarf_Word) utmp2;
731*7fd79137SRobert Mustacchi                     break;
732*7fd79137SRobert Mustacchi                 }
733*7fd79137SRobert Mustacchi 
734*7fd79137SRobert Mustacchi             case DW_LNS_negate_stmt:{
735*7fd79137SRobert Mustacchi 
736*7fd79137SRobert Mustacchi                     is_stmt = !is_stmt;
737*7fd79137SRobert Mustacchi                     break;
738*7fd79137SRobert Mustacchi                 }
739*7fd79137SRobert Mustacchi 
740*7fd79137SRobert Mustacchi             case DW_LNS_set_basic_block:{
741*7fd79137SRobert Mustacchi 
742*7fd79137SRobert Mustacchi                     basic_block = true;
743*7fd79137SRobert Mustacchi                     break;
744*7fd79137SRobert Mustacchi                 }
745*7fd79137SRobert Mustacchi 
746*7fd79137SRobert Mustacchi             case DW_LNS_const_add_pc:{
747*7fd79137SRobert Mustacchi                     opcode = MAX_LINE_OP_CODE - prefix.pf_opcode_base;
748*7fd79137SRobert Mustacchi                     address = address +
749*7fd79137SRobert Mustacchi                         prefix.pf_minimum_instruction_length * (opcode /
750*7fd79137SRobert Mustacchi                             prefix.
751*7fd79137SRobert Mustacchi                             pf_line_range);
752*7fd79137SRobert Mustacchi                     break;
753*7fd79137SRobert Mustacchi                 }
754*7fd79137SRobert Mustacchi 
755*7fd79137SRobert Mustacchi             case DW_LNS_fixed_advance_pc:{
756*7fd79137SRobert Mustacchi 
757*7fd79137SRobert Mustacchi                     READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half,
758*7fd79137SRobert Mustacchi                                    line_ptr, sizeof(Dwarf_Half));
759*7fd79137SRobert Mustacchi                     line_ptr += sizeof(Dwarf_Half);
760*7fd79137SRobert Mustacchi                     address = address + fixed_advance_pc;
761*7fd79137SRobert Mustacchi                     break;
762*7fd79137SRobert Mustacchi                 }
763*7fd79137SRobert Mustacchi 
764*7fd79137SRobert Mustacchi                 /* New in DWARF3 */
765*7fd79137SRobert Mustacchi             case DW_LNS_set_prologue_end:{
766*7fd79137SRobert Mustacchi 
767*7fd79137SRobert Mustacchi                     prologue_end = true;
768*7fd79137SRobert Mustacchi                     break;
769*7fd79137SRobert Mustacchi 
770*7fd79137SRobert Mustacchi 
771*7fd79137SRobert Mustacchi                 }
772*7fd79137SRobert Mustacchi                 /* New in DWARF3 */
773*7fd79137SRobert Mustacchi             case DW_LNS_set_epilogue_begin:{
774*7fd79137SRobert Mustacchi                     epilogue_begin = true;
775*7fd79137SRobert Mustacchi                     break;
776*7fd79137SRobert Mustacchi                 }
777*7fd79137SRobert Mustacchi 
778*7fd79137SRobert Mustacchi                 /* New in DWARF3 */
779*7fd79137SRobert Mustacchi             case DW_LNS_set_isa:{
780*7fd79137SRobert Mustacchi                     Dwarf_Unsigned utmp2;
781*7fd79137SRobert Mustacchi 
782*7fd79137SRobert Mustacchi                     DECODE_LEB128_UWORD(line_ptr, utmp2);
783*7fd79137SRobert Mustacchi                     isa = utmp2;
784*7fd79137SRobert Mustacchi                     if (isa != utmp2) {
785*7fd79137SRobert Mustacchi                         /* The value of the isa did not fit in our
786*7fd79137SRobert Mustacchi                            local so we record it wrong. declare an
787*7fd79137SRobert Mustacchi                            error. */
788*7fd79137SRobert Mustacchi                         dwarf_free_line_table_prefix(&prefix);
789*7fd79137SRobert Mustacchi 
790*7fd79137SRobert Mustacchi                         _dwarf_error(dbg, error,
791*7fd79137SRobert Mustacchi                                      DW_DLE_LINE_NUM_OPERANDS_BAD);
792*7fd79137SRobert Mustacchi                         return (DW_DLV_ERROR);
793*7fd79137SRobert Mustacchi                     }
794*7fd79137SRobert Mustacchi                     break;
795*7fd79137SRobert Mustacchi                 }
796*7fd79137SRobert Mustacchi             }
797*7fd79137SRobert Mustacchi 
798*7fd79137SRobert Mustacchi         } else if (type == LOP_EXTENDED) {
799*7fd79137SRobert Mustacchi             Dwarf_Unsigned utmp3;
800*7fd79137SRobert Mustacchi 
801*7fd79137SRobert Mustacchi             DECODE_LEB128_UWORD(line_ptr, utmp3);
802*7fd79137SRobert Mustacchi             instr_length = (Dwarf_Word) utmp3;
803*7fd79137SRobert Mustacchi             /* Dwarf_Small is a ubyte and the extended opcode is a
804*7fd79137SRobert Mustacchi                ubyte, though not stated as clearly in the 2.0.0 spec as
805*7fd79137SRobert Mustacchi                one might hope. */
806*7fd79137SRobert Mustacchi             ext_opcode = *(Dwarf_Small *) line_ptr;
807*7fd79137SRobert Mustacchi             line_ptr++;
808*7fd79137SRobert Mustacchi             switch (ext_opcode) {
809*7fd79137SRobert Mustacchi 
810*7fd79137SRobert Mustacchi             case DW_LNE_end_sequence:{
811*7fd79137SRobert Mustacchi                     end_sequence = true;
812*7fd79137SRobert Mustacchi 
813*7fd79137SRobert Mustacchi                     if (dolines) {
814*7fd79137SRobert Mustacchi                         curr_line = (Dwarf_Line)
815*7fd79137SRobert Mustacchi                             _dwarf_get_alloc(dbg, DW_DLA_LINE, 1);
816*7fd79137SRobert Mustacchi                         if (curr_line == NULL) {
817*7fd79137SRobert Mustacchi                             dwarf_free_line_table_prefix(&prefix);
818*7fd79137SRobert Mustacchi                             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
819*7fd79137SRobert Mustacchi                             return (DW_DLV_ERROR);
820*7fd79137SRobert Mustacchi                         }
821*7fd79137SRobert Mustacchi 
822*7fd79137SRobert Mustacchi                         curr_line->li_address = address;
823*7fd79137SRobert Mustacchi                         curr_line->li_addr_line.li_l_data.li_file =
824*7fd79137SRobert Mustacchi                             (Dwarf_Sword) file;
825*7fd79137SRobert Mustacchi                         curr_line->li_addr_line.li_l_data.li_line =
826*7fd79137SRobert Mustacchi                             (Dwarf_Sword) line;
827*7fd79137SRobert Mustacchi                         curr_line->li_addr_line.li_l_data.li_column =
828*7fd79137SRobert Mustacchi                             (Dwarf_Half) column;
829*7fd79137SRobert Mustacchi                         curr_line->li_addr_line.li_l_data.li_is_stmt =
830*7fd79137SRobert Mustacchi                             prefix.pf_default_is_stmt;
831*7fd79137SRobert Mustacchi                         curr_line->li_addr_line.li_l_data.
832*7fd79137SRobert Mustacchi                             li_basic_block = basic_block;
833*7fd79137SRobert Mustacchi                         curr_line->li_addr_line.li_l_data.
834*7fd79137SRobert Mustacchi                             li_end_sequence = end_sequence;
835*7fd79137SRobert Mustacchi                         curr_line->li_context = line_context;
836*7fd79137SRobert Mustacchi                         curr_line->li_addr_line.li_l_data.
837*7fd79137SRobert Mustacchi                             li_epilogue_begin = epilogue_begin;
838*7fd79137SRobert Mustacchi                         curr_line->li_addr_line.li_l_data.
839*7fd79137SRobert Mustacchi                             li_prologue_end = prologue_end;
840*7fd79137SRobert Mustacchi                         curr_line->li_addr_line.li_l_data.li_isa = isa;
841*7fd79137SRobert Mustacchi                         line_count++;
842*7fd79137SRobert Mustacchi 
843*7fd79137SRobert Mustacchi                         chain_line = (Dwarf_Chain)
844*7fd79137SRobert Mustacchi                             _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
845*7fd79137SRobert Mustacchi                         if (chain_line == NULL) {
846*7fd79137SRobert Mustacchi                             dwarf_free_line_table_prefix(&prefix);
847*7fd79137SRobert Mustacchi                             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
848*7fd79137SRobert Mustacchi                             return (DW_DLV_ERROR);
849*7fd79137SRobert Mustacchi                         }
850*7fd79137SRobert Mustacchi                         chain_line->ch_item = curr_line;
851*7fd79137SRobert Mustacchi 
852*7fd79137SRobert Mustacchi                         if (head_chain == NULL)
853*7fd79137SRobert Mustacchi                             head_chain = curr_chain = chain_line;
854*7fd79137SRobert Mustacchi                         else {
855*7fd79137SRobert Mustacchi                             curr_chain->ch_next = chain_line;
856*7fd79137SRobert Mustacchi                             curr_chain = chain_line;
857*7fd79137SRobert Mustacchi                         }
858*7fd79137SRobert Mustacchi                     }
859*7fd79137SRobert Mustacchi 
860*7fd79137SRobert Mustacchi                     address = 0;
861*7fd79137SRobert Mustacchi                     file = 1;
862*7fd79137SRobert Mustacchi                     line = 1;
863*7fd79137SRobert Mustacchi                     column = 0;
864*7fd79137SRobert Mustacchi                     is_stmt = prefix.pf_default_is_stmt;
865*7fd79137SRobert Mustacchi                     basic_block = false;
866*7fd79137SRobert Mustacchi                     end_sequence = false;
867*7fd79137SRobert Mustacchi                     prologue_end = false;
868*7fd79137SRobert Mustacchi                     epilogue_begin = false;
869*7fd79137SRobert Mustacchi 
870*7fd79137SRobert Mustacchi 
871*7fd79137SRobert Mustacchi                     break;
872*7fd79137SRobert Mustacchi                 }
873*7fd79137SRobert Mustacchi 
874*7fd79137SRobert Mustacchi             case DW_LNE_set_address:{
875*7fd79137SRobert Mustacchi                     {
876*7fd79137SRobert Mustacchi                         READ_UNALIGNED(dbg, address, Dwarf_Addr,
877*7fd79137SRobert Mustacchi                                        line_ptr, address_size);
878*7fd79137SRobert Mustacchi                         if (doaddrs) {
879*7fd79137SRobert Mustacchi                             curr_line =
880*7fd79137SRobert Mustacchi                                 (Dwarf_Line) _dwarf_get_alloc(dbg,
881*7fd79137SRobert Mustacchi                                                               DW_DLA_LINE,
882*7fd79137SRobert Mustacchi                                                               1);
883*7fd79137SRobert Mustacchi                             if (curr_line == NULL) {
884*7fd79137SRobert Mustacchi                                 dwarf_free_line_table_prefix(&prefix);
885*7fd79137SRobert Mustacchi                                 _dwarf_error(dbg, error,
886*7fd79137SRobert Mustacchi                                              DW_DLE_ALLOC_FAIL);
887*7fd79137SRobert Mustacchi                                 return (DW_DLV_ERROR);
888*7fd79137SRobert Mustacchi                             }
889*7fd79137SRobert Mustacchi 
890*7fd79137SRobert Mustacchi                             curr_line->li_address = address;
891*7fd79137SRobert Mustacchi                             curr_line->li_addr_line.li_offset =
892*7fd79137SRobert Mustacchi                                 line_ptr - dbg->de_debug_line.dss_data;
893*7fd79137SRobert Mustacchi 
894*7fd79137SRobert Mustacchi                             line_count++;
895*7fd79137SRobert Mustacchi 
896*7fd79137SRobert Mustacchi                             chain_line = (Dwarf_Chain)
897*7fd79137SRobert Mustacchi                                 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
898*7fd79137SRobert Mustacchi                             if (chain_line == NULL) {
899*7fd79137SRobert Mustacchi                                 dwarf_free_line_table_prefix(&prefix);
900*7fd79137SRobert Mustacchi                                 _dwarf_error(dbg, error,
901*7fd79137SRobert Mustacchi                                              DW_DLE_ALLOC_FAIL);
902*7fd79137SRobert Mustacchi                                 return (DW_DLV_ERROR);
903*7fd79137SRobert Mustacchi                             }
904*7fd79137SRobert Mustacchi                             chain_line->ch_item = curr_line;
905*7fd79137SRobert Mustacchi 
906*7fd79137SRobert Mustacchi                             if (head_chain == NULL)
907*7fd79137SRobert Mustacchi                                 head_chain = curr_chain = chain_line;
908*7fd79137SRobert Mustacchi                             else {
909*7fd79137SRobert Mustacchi                                 curr_chain->ch_next = chain_line;
910*7fd79137SRobert Mustacchi                                 curr_chain = chain_line;
911*7fd79137SRobert Mustacchi                             }
912*7fd79137SRobert Mustacchi                         }
913*7fd79137SRobert Mustacchi 
914*7fd79137SRobert Mustacchi                         line_ptr += address_size;
915*7fd79137SRobert Mustacchi                     }
916*7fd79137SRobert Mustacchi 
917*7fd79137SRobert Mustacchi                     break;
918*7fd79137SRobert Mustacchi                 }
919*7fd79137SRobert Mustacchi 
920*7fd79137SRobert Mustacchi             case DW_LNE_define_file:{
921*7fd79137SRobert Mustacchi 
922*7fd79137SRobert Mustacchi                     if (dolines) {
923*7fd79137SRobert Mustacchi                         cur_file_entry = (Dwarf_File_Entry)
924*7fd79137SRobert Mustacchi                             _dwarf_get_alloc(dbg, DW_DLA_FILE_ENTRY, 1);
925*7fd79137SRobert Mustacchi                         if (cur_file_entry == NULL) {
926*7fd79137SRobert Mustacchi                             dwarf_free_line_table_prefix(&prefix);
927*7fd79137SRobert Mustacchi                             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
928*7fd79137SRobert Mustacchi                             return (DW_DLV_ERROR);
929*7fd79137SRobert Mustacchi                         }
930*7fd79137SRobert Mustacchi 
931*7fd79137SRobert Mustacchi                         cur_file_entry->fi_file_name =
932*7fd79137SRobert Mustacchi                             (Dwarf_Small *) line_ptr;
933*7fd79137SRobert Mustacchi                         line_ptr =
934*7fd79137SRobert Mustacchi                             line_ptr + strlen((char *) line_ptr) + 1;
935*7fd79137SRobert Mustacchi 
936*7fd79137SRobert Mustacchi                         cur_file_entry->fi_dir_index = (Dwarf_Sword)
937*7fd79137SRobert Mustacchi                             _dwarf_decode_u_leb128(line_ptr,
938*7fd79137SRobert Mustacchi                                                    &leb128_length);
939*7fd79137SRobert Mustacchi                         line_ptr = line_ptr + leb128_length;
940*7fd79137SRobert Mustacchi 
941*7fd79137SRobert Mustacchi                         cur_file_entry->fi_time_last_mod =
942*7fd79137SRobert Mustacchi                             _dwarf_decode_u_leb128(line_ptr,
943*7fd79137SRobert Mustacchi                                                    &leb128_length);
944*7fd79137SRobert Mustacchi                         line_ptr = line_ptr + leb128_length;
945*7fd79137SRobert Mustacchi 
946*7fd79137SRobert Mustacchi                         cur_file_entry->fi_file_length =
947*7fd79137SRobert Mustacchi                             _dwarf_decode_u_leb128(line_ptr,
948*7fd79137SRobert Mustacchi                                                    &leb128_length);
949*7fd79137SRobert Mustacchi                         line_ptr = line_ptr + leb128_length;
950*7fd79137SRobert Mustacchi 
951*7fd79137SRobert Mustacchi                         if (file_entries == NULL)
952*7fd79137SRobert Mustacchi                             file_entries = cur_file_entry;
953*7fd79137SRobert Mustacchi                         else
954*7fd79137SRobert Mustacchi                             prev_file_entry->fi_next = cur_file_entry;
955*7fd79137SRobert Mustacchi                         prev_file_entry = cur_file_entry;
956*7fd79137SRobert Mustacchi 
957*7fd79137SRobert Mustacchi                         file_entry_count++;
958*7fd79137SRobert Mustacchi                     }
959*7fd79137SRobert Mustacchi                     break;
960*7fd79137SRobert Mustacchi                 }
961*7fd79137SRobert Mustacchi 
962*7fd79137SRobert Mustacchi             default:{
963*7fd79137SRobert Mustacchi                  /* This is an extended op code we do not know about,
964*7fd79137SRobert Mustacchi                     other than we know now many bytes it is
965*7fd79137SRobert Mustacchi                     and the op code and the bytes of operand. */
966*7fd79137SRobert Mustacchi                  Dwarf_Unsigned remaining_bytes = instr_length -1;
967*7fd79137SRobert Mustacchi                  if(instr_length < 1 || remaining_bytes > DW_LNE_LEN_MAX) {
968*7fd79137SRobert Mustacchi                       dwarf_free_line_table_prefix(&prefix);
969*7fd79137SRobert Mustacchi                       _dwarf_error(dbg, error,
970*7fd79137SRobert Mustacchi                                  DW_DLE_LINE_EXT_OPCODE_BAD);
971*7fd79137SRobert Mustacchi                       return (DW_DLV_ERROR);
972*7fd79137SRobert Mustacchi                  }
973*7fd79137SRobert Mustacchi                  line_ptr += remaining_bytes;
974*7fd79137SRobert Mustacchi                  break;
975*7fd79137SRobert Mustacchi                 }
976*7fd79137SRobert Mustacchi             }
977*7fd79137SRobert Mustacchi 
978*7fd79137SRobert Mustacchi         }
979*7fd79137SRobert Mustacchi     }
980*7fd79137SRobert Mustacchi 
981*7fd79137SRobert Mustacchi     block_line = (Dwarf_Line *)
982*7fd79137SRobert Mustacchi         _dwarf_get_alloc(dbg, DW_DLA_LIST, line_count);
983*7fd79137SRobert Mustacchi     if (block_line == NULL) {
984*7fd79137SRobert Mustacchi         dwarf_free_line_table_prefix(&prefix);
985*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
986*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
987*7fd79137SRobert Mustacchi     }
988*7fd79137SRobert Mustacchi 
989*7fd79137SRobert Mustacchi     curr_chain = head_chain;
990*7fd79137SRobert Mustacchi     for (i = 0; i < line_count; i++) {
991*7fd79137SRobert Mustacchi         *(block_line + i) = curr_chain->ch_item;
992*7fd79137SRobert Mustacchi         head_chain = curr_chain;
993*7fd79137SRobert Mustacchi         curr_chain = curr_chain->ch_next;
994*7fd79137SRobert Mustacchi         dwarf_dealloc(dbg, head_chain, DW_DLA_CHAIN);
995*7fd79137SRobert Mustacchi     }
996*7fd79137SRobert Mustacchi 
997*7fd79137SRobert Mustacchi     line_context->lc_file_entries = file_entries;
998*7fd79137SRobert Mustacchi     line_context->lc_file_entry_count = file_entry_count;
999*7fd79137SRobert Mustacchi     line_context->lc_include_directories_count =
1000*7fd79137SRobert Mustacchi         prefix.pf_include_directories_count;
1001*7fd79137SRobert Mustacchi     if (prefix.pf_include_directories_count > 0) {
1002*7fd79137SRobert Mustacchi         /* This gets a pointer to the *first* include dir. The others
1003*7fd79137SRobert Mustacchi            follow directly with the standard DWARF2/3 NUL byte
1004*7fd79137SRobert Mustacchi            following the last. */
1005*7fd79137SRobert Mustacchi         line_context->lc_include_directories =
1006*7fd79137SRobert Mustacchi             prefix.pf_include_directories[0];
1007*7fd79137SRobert Mustacchi     }
1008*7fd79137SRobert Mustacchi 
1009*7fd79137SRobert Mustacchi     line_context->lc_line_count = line_count;
1010*7fd79137SRobert Mustacchi     line_context->lc_compilation_directory = comp_dir;
1011*7fd79137SRobert Mustacchi     line_context->lc_version_number = prefix.pf_version;
1012*7fd79137SRobert Mustacchi     line_context->lc_dbg = dbg;
1013*7fd79137SRobert Mustacchi     *count = line_count;
1014*7fd79137SRobert Mustacchi 
1015*7fd79137SRobert Mustacchi     *linebuf = block_line;
1016*7fd79137SRobert Mustacchi     dwarf_free_line_table_prefix(&prefix);
1017*7fd79137SRobert Mustacchi     return (DW_DLV_OK);
1018*7fd79137SRobert Mustacchi }
1019*7fd79137SRobert Mustacchi 
1020*7fd79137SRobert Mustacchi int
1021*7fd79137SRobert Mustacchi dwarf_srclines(Dwarf_Die die,
1022*7fd79137SRobert Mustacchi                Dwarf_Line ** linebuf,
1023*7fd79137SRobert Mustacchi                Dwarf_Signed * linecount, Dwarf_Error * error)
1024*7fd79137SRobert Mustacchi {
1025*7fd79137SRobert Mustacchi     Dwarf_Signed count = 0;
1026*7fd79137SRobert Mustacchi     int res  = _dwarf_internal_srclines(die, linebuf, &count,
1027*7fd79137SRobert Mustacchi         /* addrlist= */ false,
1028*7fd79137SRobert Mustacchi         /* linelist= */ true, error);
1029*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK) {
1030*7fd79137SRobert Mustacchi         return res;
1031*7fd79137SRobert Mustacchi     }
1032*7fd79137SRobert Mustacchi     *linecount = count;
1033*7fd79137SRobert Mustacchi     return res;
1034*7fd79137SRobert Mustacchi }
1035*7fd79137SRobert Mustacchi 
1036*7fd79137SRobert Mustacchi 
1037*7fd79137SRobert Mustacchi 
1038*7fd79137SRobert Mustacchi /* Every line table entry (except DW_DLE_end_sequence,
1039*7fd79137SRobert Mustacchi    which is returned using dwarf_lineendsequence())
1040*7fd79137SRobert Mustacchi    potentially has the begin-statement
1041*7fd79137SRobert Mustacchi    flag marked 'on'.   This returns thru *return_bool,
1042*7fd79137SRobert Mustacchi    the begin-statement flag.
1043*7fd79137SRobert Mustacchi */
1044*7fd79137SRobert Mustacchi 
1045*7fd79137SRobert Mustacchi int
1046*7fd79137SRobert Mustacchi dwarf_linebeginstatement(Dwarf_Line line,
1047*7fd79137SRobert Mustacchi     Dwarf_Bool * return_bool, Dwarf_Error * error)
1048*7fd79137SRobert Mustacchi {
1049*7fd79137SRobert Mustacchi     if (line == NULL || return_bool == 0) {
1050*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1051*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1052*7fd79137SRobert Mustacchi     }
1053*7fd79137SRobert Mustacchi 
1054*7fd79137SRobert Mustacchi     *return_bool = (line->li_addr_line.li_l_data.li_is_stmt);
1055*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1056*7fd79137SRobert Mustacchi }
1057*7fd79137SRobert Mustacchi 
1058*7fd79137SRobert Mustacchi /* At the end of any contiguous line-table there may be
1059*7fd79137SRobert Mustacchi    a DW_LNE_end_sequence operator.
1060*7fd79137SRobert Mustacchi    This returns non-zero thru *return_bool
1061*7fd79137SRobert Mustacchi    if and only if this 'line' entry was a DW_LNE_end_sequence.
1062*7fd79137SRobert Mustacchi 
1063*7fd79137SRobert Mustacchi    Within a compilation unit or function there may be multiple
1064*7fd79137SRobert Mustacchi    line tables, each ending with a DW_LNE_end_sequence.
1065*7fd79137SRobert Mustacchi    Each table describes a contiguous region.
1066*7fd79137SRobert Mustacchi    Because compilers may split function code up in arbitrary ways
1067*7fd79137SRobert Mustacchi    compilers may need to emit multiple contigous regions (ie
1068*7fd79137SRobert Mustacchi    line tables) for a single function.
1069*7fd79137SRobert Mustacchi    See the DWARF3 spec section 6.2.
1070*7fd79137SRobert Mustacchi */
1071*7fd79137SRobert Mustacchi int
1072*7fd79137SRobert Mustacchi dwarf_lineendsequence(Dwarf_Line line,
1073*7fd79137SRobert Mustacchi     Dwarf_Bool * return_bool, Dwarf_Error * error)
1074*7fd79137SRobert Mustacchi {
1075*7fd79137SRobert Mustacchi     if (line == NULL) {
1076*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1077*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1078*7fd79137SRobert Mustacchi     }
1079*7fd79137SRobert Mustacchi 
1080*7fd79137SRobert Mustacchi     *return_bool = (line->li_addr_line.li_l_data.li_end_sequence);
1081*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1082*7fd79137SRobert Mustacchi }
1083*7fd79137SRobert Mustacchi 
1084*7fd79137SRobert Mustacchi 
1085*7fd79137SRobert Mustacchi /* Each 'line' entry has a line-number.
1086*7fd79137SRobert Mustacchi    If the entry is a DW_LNE_end_sequence the line-number is
1087*7fd79137SRobert Mustacchi    meaningless (see dwarf_lineendsequence(), just above).
1088*7fd79137SRobert Mustacchi */
1089*7fd79137SRobert Mustacchi int
1090*7fd79137SRobert Mustacchi dwarf_lineno(Dwarf_Line line,
1091*7fd79137SRobert Mustacchi     Dwarf_Unsigned * ret_lineno, Dwarf_Error * error)
1092*7fd79137SRobert Mustacchi {
1093*7fd79137SRobert Mustacchi     if (line == NULL || ret_lineno == 0) {
1094*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1095*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1096*7fd79137SRobert Mustacchi     }
1097*7fd79137SRobert Mustacchi 
1098*7fd79137SRobert Mustacchi     *ret_lineno = (line->li_addr_line.li_l_data.li_line);
1099*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1100*7fd79137SRobert Mustacchi }
1101*7fd79137SRobert Mustacchi 
1102*7fd79137SRobert Mustacchi /* Each 'line' entry has a file-number, and index into the file table.
1103*7fd79137SRobert Mustacchi    If the entry is a DW_LNE_end_sequence the index is
1104*7fd79137SRobert Mustacchi    meaningless (see dwarf_lineendsequence(), just above).
1105*7fd79137SRobert Mustacchi    The file number returned is an index into the file table
1106*7fd79137SRobert Mustacchi    produced by dwarf_srcfiles(), but care is required: the
1107*7fd79137SRobert Mustacchi    li_file begins with 1 for real files, so that the li_file returned here
1108*7fd79137SRobert Mustacchi    is 1 greater than its index into the dwarf_srcfiles() output array.
1109*7fd79137SRobert Mustacchi    And entries from DW_LNE_define_file don't appear in
1110*7fd79137SRobert Mustacchi    the dwarf_srcfiles() output so file indexes from here may exceed
1111*7fd79137SRobert Mustacchi    the size of the dwarf_srcfiles() output array size.
1112*7fd79137SRobert Mustacchi */
1113*7fd79137SRobert Mustacchi int
1114*7fd79137SRobert Mustacchi dwarf_line_srcfileno(Dwarf_Line line,
1115*7fd79137SRobert Mustacchi     Dwarf_Unsigned * ret_fileno, Dwarf_Error * error)
1116*7fd79137SRobert Mustacchi {
1117*7fd79137SRobert Mustacchi     if (line == NULL || ret_fileno == 0) {
1118*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1119*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1120*7fd79137SRobert Mustacchi     }
1121*7fd79137SRobert Mustacchi     /* li_file must be <= line->li_context->lc_file_entry_count else it
1122*7fd79137SRobert Mustacchi        is trash. li_file 0 means not attributable to any source file
1123*7fd79137SRobert Mustacchi        per dwarf2/3 spec. */
1124*7fd79137SRobert Mustacchi 
1125*7fd79137SRobert Mustacchi     *ret_fileno = (line->li_addr_line.li_l_data.li_file);
1126*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1127*7fd79137SRobert Mustacchi }
1128*7fd79137SRobert Mustacchi 
1129*7fd79137SRobert Mustacchi 
1130*7fd79137SRobert Mustacchi /* Each 'line' entry has a line-address.
1131*7fd79137SRobert Mustacchi    If the entry is a DW_LNE_end_sequence the adddress
1132*7fd79137SRobert Mustacchi    is one-beyond the last address this contigous region
1133*7fd79137SRobert Mustacchi    covers, so the address is not inside the region,
1134*7fd79137SRobert Mustacchi    but is just outside it.
1135*7fd79137SRobert Mustacchi */
1136*7fd79137SRobert Mustacchi int
1137*7fd79137SRobert Mustacchi dwarf_lineaddr(Dwarf_Line line,
1138*7fd79137SRobert Mustacchi     Dwarf_Addr * ret_lineaddr, Dwarf_Error * error)
1139*7fd79137SRobert Mustacchi {
1140*7fd79137SRobert Mustacchi     if (line == NULL || ret_lineaddr == 0) {
1141*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1142*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1143*7fd79137SRobert Mustacchi     }
1144*7fd79137SRobert Mustacchi 
1145*7fd79137SRobert Mustacchi     *ret_lineaddr = (line->li_address);
1146*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1147*7fd79137SRobert Mustacchi }
1148*7fd79137SRobert Mustacchi 
1149*7fd79137SRobert Mustacchi 
1150*7fd79137SRobert Mustacchi /* Each 'line' entry has a column-within-line (offset
1151*7fd79137SRobert Mustacchi    within the line) where the
1152*7fd79137SRobert Mustacchi    source text begins.
1153*7fd79137SRobert Mustacchi    If the entry is a DW_LNE_end_sequence the line-number is
1154*7fd79137SRobert Mustacchi    meaningless (see dwarf_lineendsequence(), just above).
1155*7fd79137SRobert Mustacchi    Lines of text begin at column 1.  The value 0
1156*7fd79137SRobert Mustacchi    means the line begins at the left edge of the line.
1157*7fd79137SRobert Mustacchi    (See the DWARF3 spec, section 6.2.2).
1158*7fd79137SRobert Mustacchi */
1159*7fd79137SRobert Mustacchi int
1160*7fd79137SRobert Mustacchi dwarf_lineoff(Dwarf_Line line,
1161*7fd79137SRobert Mustacchi     Dwarf_Signed * ret_lineoff, Dwarf_Error * error)
1162*7fd79137SRobert Mustacchi {
1163*7fd79137SRobert Mustacchi     if (line == NULL || ret_lineoff == 0) {
1164*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1165*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1166*7fd79137SRobert Mustacchi     }
1167*7fd79137SRobert Mustacchi 
1168*7fd79137SRobert Mustacchi     *ret_lineoff =
1169*7fd79137SRobert Mustacchi         (line->li_addr_line.li_l_data.li_column ==
1170*7fd79137SRobert Mustacchi          0 ? -1 : line->li_addr_line.li_l_data.li_column);
1171*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1172*7fd79137SRobert Mustacchi }
1173*7fd79137SRobert Mustacchi 
1174*7fd79137SRobert Mustacchi 
1175*7fd79137SRobert Mustacchi int
1176*7fd79137SRobert Mustacchi dwarf_linesrc(Dwarf_Line line, char **ret_linesrc, Dwarf_Error * error)
1177*7fd79137SRobert Mustacchi {
1178*7fd79137SRobert Mustacchi     Dwarf_Signed i = 0;
1179*7fd79137SRobert Mustacchi     Dwarf_File_Entry file_entry;
1180*7fd79137SRobert Mustacchi     Dwarf_Small *name_buffer = 0;
1181*7fd79137SRobert Mustacchi     Dwarf_Small *include_directories = 0;
1182*7fd79137SRobert Mustacchi     Dwarf_Small include_direc_full_path = 0;
1183*7fd79137SRobert Mustacchi     Dwarf_Small file_name_full_path = 0;
1184*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
1185*7fd79137SRobert Mustacchi     unsigned int comp_dir_len = 0;
1186*7fd79137SRobert Mustacchi 
1187*7fd79137SRobert Mustacchi     if (line == NULL) {
1188*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1189*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1190*7fd79137SRobert Mustacchi     }
1191*7fd79137SRobert Mustacchi 
1192*7fd79137SRobert Mustacchi     if (line->li_context == NULL) {
1193*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL);
1194*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1195*7fd79137SRobert Mustacchi     }
1196*7fd79137SRobert Mustacchi     dbg = line->li_context->lc_dbg;
1197*7fd79137SRobert Mustacchi 
1198*7fd79137SRobert Mustacchi     if (line->li_addr_line.li_l_data.li_file >
1199*7fd79137SRobert Mustacchi         line->li_context->lc_file_entry_count) {
1200*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_LINE_FILE_NUM_BAD);
1201*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1202*7fd79137SRobert Mustacchi     }
1203*7fd79137SRobert Mustacchi 
1204*7fd79137SRobert Mustacchi     if (line->li_addr_line.li_l_data.li_file == 0) {
1205*7fd79137SRobert Mustacchi         /* No file name known: see dwarf2/3 spec. */
1206*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME);
1207*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1208*7fd79137SRobert Mustacchi     }
1209*7fd79137SRobert Mustacchi     file_entry = line->li_context->lc_file_entries;
1210*7fd79137SRobert Mustacchi     /* ASSERT: li_file > 0, dwarf correctness issue, see line table
1211*7fd79137SRobert Mustacchi        definition of dwarf2/3 spec. */
1212*7fd79137SRobert Mustacchi     /* Example: if li_file is 2 and lc_file_entry_count is 3,
1213*7fd79137SRobert Mustacchi        file_entry is file 3 (1 based), aka 2( 0 based) file_entry->next
1214*7fd79137SRobert Mustacchi        is file 2 (1 based), aka 1( 0 based) file_entry->next->next is
1215*7fd79137SRobert Mustacchi        file 1 (1 based), aka 0( 0 based) file_entry->next->next->next
1216*7fd79137SRobert Mustacchi        is NULL.
1217*7fd79137SRobert Mustacchi 
1218*7fd79137SRobert Mustacchi        and this loop finds the file_entry we need (2 (1 based) in this
1219*7fd79137SRobert Mustacchi        case). Because lc_file_entries are in reverse order and
1220*7fd79137SRobert Mustacchi        effectively zero based as a count whereas li_file is 1 based. */
1221*7fd79137SRobert Mustacchi     for (i = line->li_addr_line.li_l_data.li_file - 1; i > 0; i--)
1222*7fd79137SRobert Mustacchi         file_entry = file_entry->fi_next;
1223*7fd79137SRobert Mustacchi 
1224*7fd79137SRobert Mustacchi     if (file_entry->fi_file_name == NULL) {
1225*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME);
1226*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1227*7fd79137SRobert Mustacchi     }
1228*7fd79137SRobert Mustacchi 
1229*7fd79137SRobert Mustacchi     file_name_full_path = file_name_is_full_path(file_entry->fi_file_name);
1230*7fd79137SRobert Mustacchi     if (file_name_full_path) {
1231*7fd79137SRobert Mustacchi         *ret_linesrc = ((char *) file_entry->fi_file_name);
1232*7fd79137SRobert Mustacchi         return DW_DLV_OK;
1233*7fd79137SRobert Mustacchi     }
1234*7fd79137SRobert Mustacchi 
1235*7fd79137SRobert Mustacchi     if (file_entry->fi_dir_index == 0) {
1236*7fd79137SRobert Mustacchi 
1237*7fd79137SRobert Mustacchi         /* dir_index of 0 means that the compilation was in the
1238*7fd79137SRobert Mustacchi            'current directory of compilation' */
1239*7fd79137SRobert Mustacchi         if (line->li_context->lc_compilation_directory == NULL) {
1240*7fd79137SRobert Mustacchi             /* we don't actually *have* a current directory of
1241*7fd79137SRobert Mustacchi                compilation: DW_AT_comp_dir was not present Rather than
1242*7fd79137SRobert Mustacchi                emitting DW_DLE_NO_COMP_DIR lets just make an empty name
1243*7fd79137SRobert Mustacchi                here. In other words, do the best we can with what we do
1244*7fd79137SRobert Mustacchi                have instead of reporting an error. _dwarf_error(dbg,
1245*7fd79137SRobert Mustacchi                error, DW_DLE_NO_COMP_DIR); return(DW_DLV_ERROR); */
1246*7fd79137SRobert Mustacchi             comp_dir_len = 0;
1247*7fd79137SRobert Mustacchi         } else {
1248*7fd79137SRobert Mustacchi             comp_dir_len = strlen((char *)
1249*7fd79137SRobert Mustacchi                                   (line->li_context->
1250*7fd79137SRobert Mustacchi                                    lc_compilation_directory));
1251*7fd79137SRobert Mustacchi         }
1252*7fd79137SRobert Mustacchi 
1253*7fd79137SRobert Mustacchi         name_buffer =
1254*7fd79137SRobert Mustacchi             _dwarf_get_alloc(line->li_context->lc_dbg, DW_DLA_STRING,
1255*7fd79137SRobert Mustacchi                              comp_dir_len + 1 +
1256*7fd79137SRobert Mustacchi                              strlen((char *) file_entry->fi_file_name) +
1257*7fd79137SRobert Mustacchi                              1);
1258*7fd79137SRobert Mustacchi         if (name_buffer == NULL) {
1259*7fd79137SRobert Mustacchi             _dwarf_error(line->li_context->lc_dbg, error,
1260*7fd79137SRobert Mustacchi                          DW_DLE_ALLOC_FAIL);
1261*7fd79137SRobert Mustacchi             return (DW_DLV_ERROR);
1262*7fd79137SRobert Mustacchi         }
1263*7fd79137SRobert Mustacchi 
1264*7fd79137SRobert Mustacchi         if (comp_dir_len > 0) {
1265*7fd79137SRobert Mustacchi             /* if comp_dir_len is 0 we do not want to put a / in front
1266*7fd79137SRobert Mustacchi                of the fi_file_name as we just don't know anything. */
1267*7fd79137SRobert Mustacchi             strcpy((char *) name_buffer,
1268*7fd79137SRobert Mustacchi                    (char *) (line->li_context->
1269*7fd79137SRobert Mustacchi                              lc_compilation_directory));
1270*7fd79137SRobert Mustacchi             strcat((char *) name_buffer, "/");
1271*7fd79137SRobert Mustacchi         }
1272*7fd79137SRobert Mustacchi         strcat((char *) name_buffer, (char *) file_entry->fi_file_name);
1273*7fd79137SRobert Mustacchi         *ret_linesrc = ((char *) name_buffer);
1274*7fd79137SRobert Mustacchi         return DW_DLV_OK;
1275*7fd79137SRobert Mustacchi     }
1276*7fd79137SRobert Mustacchi 
1277*7fd79137SRobert Mustacchi     if (file_entry->fi_dir_index >
1278*7fd79137SRobert Mustacchi         line->li_context->lc_include_directories_count) {
1279*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_INCL_DIR_NUM_BAD);
1280*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1281*7fd79137SRobert Mustacchi     }
1282*7fd79137SRobert Mustacchi 
1283*7fd79137SRobert Mustacchi     include_directories = line->li_context->lc_include_directories;
1284*7fd79137SRobert Mustacchi     for (i = file_entry->fi_dir_index - 1; i > 0; i--)
1285*7fd79137SRobert Mustacchi         include_directories += strlen((char *) include_directories) + 1;
1286*7fd79137SRobert Mustacchi 
1287*7fd79137SRobert Mustacchi     if (line->li_context->lc_compilation_directory) {
1288*7fd79137SRobert Mustacchi         comp_dir_len = strlen((char *)
1289*7fd79137SRobert Mustacchi             (line->li_context->lc_compilation_directory));
1290*7fd79137SRobert Mustacchi     } else {
1291*7fd79137SRobert Mustacchi         /* No DW_AT_comp_dir present. Do the best we can without it. */
1292*7fd79137SRobert Mustacchi         comp_dir_len = 0;
1293*7fd79137SRobert Mustacchi     }
1294*7fd79137SRobert Mustacchi 
1295*7fd79137SRobert Mustacchi     include_direc_full_path = file_name_is_full_path(include_directories);
1296*7fd79137SRobert Mustacchi     name_buffer = _dwarf_get_alloc(dbg, DW_DLA_STRING,
1297*7fd79137SRobert Mustacchi         (include_direc_full_path ?  0 : comp_dir_len + 1) +
1298*7fd79137SRobert Mustacchi             strlen((char *)include_directories) + 1 +
1299*7fd79137SRobert Mustacchi             strlen((char *)file_entry->fi_file_name) + 1);
1300*7fd79137SRobert Mustacchi     if (name_buffer == NULL) {
1301*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1302*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1303*7fd79137SRobert Mustacchi     }
1304*7fd79137SRobert Mustacchi 
1305*7fd79137SRobert Mustacchi     if (!include_direc_full_path) {
1306*7fd79137SRobert Mustacchi         if (comp_dir_len > 0) {
1307*7fd79137SRobert Mustacchi             strcpy((char *)name_buffer,
1308*7fd79137SRobert Mustacchi                 (char *)line->li_context->lc_compilation_directory);
1309*7fd79137SRobert Mustacchi             /* Who provides the / needed after the compilation
1310*7fd79137SRobert Mustacchi                directory? */
1311*7fd79137SRobert Mustacchi             if (!is_path_separator(name_buffer[comp_dir_len - 1])) {
1312*7fd79137SRobert Mustacchi                 /* Here we provide the / separator. It
1313*7fd79137SRobert Mustacchi                    should work ok for Windows */
1314*7fd79137SRobert Mustacchi                 /* Overwrite previous nul terminator with needed / */
1315*7fd79137SRobert Mustacchi                 name_buffer[comp_dir_len] = '/';
1316*7fd79137SRobert Mustacchi                 name_buffer[comp_dir_len + 1] = 0;
1317*7fd79137SRobert Mustacchi             }
1318*7fd79137SRobert Mustacchi         }
1319*7fd79137SRobert Mustacchi     } else {
1320*7fd79137SRobert Mustacchi         strcpy((char *) name_buffer, "");
1321*7fd79137SRobert Mustacchi     }
1322*7fd79137SRobert Mustacchi     strcat((char *) name_buffer, (char *) include_directories);
1323*7fd79137SRobert Mustacchi     strcat((char *) name_buffer, "/");
1324*7fd79137SRobert Mustacchi     strcat((char *) name_buffer, (char *) file_entry->fi_file_name);
1325*7fd79137SRobert Mustacchi     *ret_linesrc = ((char *) name_buffer);
1326*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1327*7fd79137SRobert Mustacchi }
1328*7fd79137SRobert Mustacchi 
1329*7fd79137SRobert Mustacchi /* Every line table entry potentially has the basic-block-start
1330*7fd79137SRobert Mustacchi    flag marked 'on'.   This returns thru *return_bool,
1331*7fd79137SRobert Mustacchi    the basic-block-start flag.
1332*7fd79137SRobert Mustacchi */
1333*7fd79137SRobert Mustacchi int
1334*7fd79137SRobert Mustacchi dwarf_lineblock(Dwarf_Line line,
1335*7fd79137SRobert Mustacchi     Dwarf_Bool * return_bool, Dwarf_Error * error)
1336*7fd79137SRobert Mustacchi {
1337*7fd79137SRobert Mustacchi     if (line == NULL) {
1338*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1339*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1340*7fd79137SRobert Mustacchi     }
1341*7fd79137SRobert Mustacchi     *return_bool = (line->li_addr_line.li_l_data.li_basic_block);
1342*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1343*7fd79137SRobert Mustacchi }
1344*7fd79137SRobert Mustacchi 
1345*7fd79137SRobert Mustacchi 
1346*7fd79137SRobert Mustacchi #if 0                           /* Ignore this.  This needs major
1347*7fd79137SRobert Mustacchi                                    re-work. */
1348*7fd79137SRobert Mustacchi /*
1349*7fd79137SRobert Mustacchi     This routine works by looking for exact matches between
1350*7fd79137SRobert Mustacchi     the current line address and pc, and crossovers from
1351*7fd79137SRobert Mustacchi     from less than pc value to greater than.  At each line
1352*7fd79137SRobert Mustacchi     that satisfies the above, it records a pointer to the
1353*7fd79137SRobert Mustacchi     line, and the difference between the address and pc.
1354*7fd79137SRobert Mustacchi     It then scans these pointers and picks out those with
1355*7fd79137SRobert Mustacchi     the smallest difference between pc and address.
1356*7fd79137SRobert Mustacchi */
1357*7fd79137SRobert Mustacchi int
1358*7fd79137SRobert Mustacchi dwarf_pclines(Dwarf_Debug dbg,
1359*7fd79137SRobert Mustacchi               Dwarf_Addr pc,
1360*7fd79137SRobert Mustacchi               Dwarf_Line ** linebuf,
1361*7fd79137SRobert Mustacchi               Dwarf_Signed slide,
1362*7fd79137SRobert Mustacchi               Dwarf_Signed * linecount, Dwarf_Error * error)
1363*7fd79137SRobert Mustacchi {
1364*7fd79137SRobert Mustacchi     /*
1365*7fd79137SRobert Mustacchi        Scans the line matrix for the current cu to which a pointer
1366*7fd79137SRobert Mustacchi        exists in dbg. */
1367*7fd79137SRobert Mustacchi     Dwarf_Line line;
1368*7fd79137SRobert Mustacchi     Dwarf_Line prev_line;
1369*7fd79137SRobert Mustacchi 
1370*7fd79137SRobert Mustacchi     /*
1371*7fd79137SRobert Mustacchi        These flags are for efficiency reasons. Check_line is true
1372*7fd79137SRobert Mustacchi        initially, but set false when the address of the current line is
1373*7fd79137SRobert Mustacchi        greater than pc.  It is set true only when the address of the
1374*7fd79137SRobert Mustacchi        current line falls below pc.  This assumes that addresses within
1375*7fd79137SRobert Mustacchi        the same segment increase, and we are only interested in the
1376*7fd79137SRobert Mustacchi        switch from a less than pc address to a greater than. First_line
1377*7fd79137SRobert Mustacchi        is set true initially, but set false after the first line is
1378*7fd79137SRobert Mustacchi        scanned.  This is to prevent looking at the address of previous
1379*7fd79137SRobert Mustacchi        line when slide is DW_DLS_BACKWARD, and the first line is being
1380*7fd79137SRobert Mustacchi        scanned. */
1381*7fd79137SRobert Mustacchi     Dwarf_Bool check_line, first_line;
1382*7fd79137SRobert Mustacchi 
1383*7fd79137SRobert Mustacchi     /*
1384*7fd79137SRobert Mustacchi        Diff tracks the smallest difference a line address and the input
1385*7fd79137SRobert Mustacchi        pc value. */
1386*7fd79137SRobert Mustacchi     Dwarf_Signed diff, i;
1387*7fd79137SRobert Mustacchi 
1388*7fd79137SRobert Mustacchi     /*
1389*7fd79137SRobert Mustacchi        For the slide = DW_DLS_BACKWARD case, pc_less is the value of
1390*7fd79137SRobert Mustacchi        the address of the line immediately preceding the first line
1391*7fd79137SRobert Mustacchi        that has value greater than pc. For the slide = DW_DLS_FORWARD
1392*7fd79137SRobert Mustacchi        case, pc_more is the values of address for the first line that
1393*7fd79137SRobert Mustacchi        is greater than pc. Diff is the difference between either of the
1394*7fd79137SRobert Mustacchi        these values and pc. */
1395*7fd79137SRobert Mustacchi     Dwarf_Addr pc_less, pc_more;
1396*7fd79137SRobert Mustacchi 
1397*7fd79137SRobert Mustacchi     /*
1398*7fd79137SRobert Mustacchi        Pc_line_buf points to a chain of pointers to lines of which
1399*7fd79137SRobert Mustacchi        those with a diff equal to the smallest difference will be
1400*7fd79137SRobert Mustacchi        returned. */
1401*7fd79137SRobert Mustacchi     Dwarf_Line *pc_line_buf, *pc_line;
1402*7fd79137SRobert Mustacchi 
1403*7fd79137SRobert Mustacchi     /*
1404*7fd79137SRobert Mustacchi        Chain_count counts the number of lines in the above chain for
1405*7fd79137SRobert Mustacchi        which the diff is equal to the smallest difference This is the
1406*7fd79137SRobert Mustacchi        number returned by this routine. */
1407*7fd79137SRobert Mustacchi     Dwarf_Signed chain_count;
1408*7fd79137SRobert Mustacchi 
1409*7fd79137SRobert Mustacchi     chain_head = NULL;
1410*7fd79137SRobert Mustacchi 
1411*7fd79137SRobert Mustacchi     check_line = true;
1412*7fd79137SRobert Mustacchi     first_line = true;
1413*7fd79137SRobert Mustacchi     diff = MAX_LINE_DIFF;
1414*7fd79137SRobert Mustacchi 
1415*7fd79137SRobert Mustacchi     for (i = 0; i < dbg->de_cu_line_count; i++) {
1416*7fd79137SRobert Mustacchi 
1417*7fd79137SRobert Mustacchi         line = *(dbg->de_cu_line_ptr + i);
1418*7fd79137SRobert Mustacchi         prev_line = first_line ? NULL : *(dbg->de_cu_line_ptr + i - 1);
1419*7fd79137SRobert Mustacchi 
1420*7fd79137SRobert Mustacchi         if (line->li_address == pc) {
1421*7fd79137SRobert Mustacchi             chain_ptr = (struct chain *)
1422*7fd79137SRobert Mustacchi                 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
1423*7fd79137SRobert Mustacchi             if (chain_ptr == NULL) {
1424*7fd79137SRobert Mustacchi                 _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
1425*7fd79137SRobert Mustacchi                 return (DW_DLV_ERROR);
1426*7fd79137SRobert Mustacchi             }
1427*7fd79137SRobert Mustacchi 
1428*7fd79137SRobert Mustacchi             chain_ptr->line = line;
1429*7fd79137SRobert Mustacchi             chain_ptr->diff = diff = 0;
1430*7fd79137SRobert Mustacchi             chain_ptr->next = chain_head;
1431*7fd79137SRobert Mustacchi             chain_head = chain_ptr;
1432*7fd79137SRobert Mustacchi         } else
1433*7fd79137SRobert Mustacchi             /*
1434*7fd79137SRobert Mustacchi                Look for crossover from less than pc address to greater
1435*7fd79137SRobert Mustacchi                than. */
1436*7fd79137SRobert Mustacchi         if (check_line && line->li_address > pc &&
1437*7fd79137SRobert Mustacchi                 (first_line ? 0 : prev_line->li_address) < pc)
1438*7fd79137SRobert Mustacchi 
1439*7fd79137SRobert Mustacchi             if (slide == DW_DLS_BACKWARD && !first_line) {
1440*7fd79137SRobert Mustacchi                 pc_less = prev_line->li_address;
1441*7fd79137SRobert Mustacchi                 if (pc - pc_less <= diff) {
1442*7fd79137SRobert Mustacchi                     chain_ptr = (struct chain *)
1443*7fd79137SRobert Mustacchi                         _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
1444*7fd79137SRobert Mustacchi                     if (chain_ptr == NULL) {
1445*7fd79137SRobert Mustacchi                         _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
1446*7fd79137SRobert Mustacchi                         return (DW_DLV_ERROR);
1447*7fd79137SRobert Mustacchi                     }
1448*7fd79137SRobert Mustacchi 
1449*7fd79137SRobert Mustacchi                     chain_ptr->line = prev_line;
1450*7fd79137SRobert Mustacchi                     chain_ptr->diff = diff = pc - pc_less;
1451*7fd79137SRobert Mustacchi                     chain_ptr->next = chain_head;
1452*7fd79137SRobert Mustacchi                     chain_head = chain_ptr;
1453*7fd79137SRobert Mustacchi                 }
1454*7fd79137SRobert Mustacchi                 check_line = false;
1455*7fd79137SRobert Mustacchi             } else if (slide == DW_DLS_FORWARD) {
1456*7fd79137SRobert Mustacchi                 pc_more = line->li_address;
1457*7fd79137SRobert Mustacchi                 if (pc_more - pc <= diff) {
1458*7fd79137SRobert Mustacchi                     chain_ptr = (struct chain *)
1459*7fd79137SRobert Mustacchi                         _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
1460*7fd79137SRobert Mustacchi                     if (chain_ptr == NULL) {
1461*7fd79137SRobert Mustacchi                         _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
1462*7fd79137SRobert Mustacchi                         return (DW_DLV_ERROR);
1463*7fd79137SRobert Mustacchi                     }
1464*7fd79137SRobert Mustacchi 
1465*7fd79137SRobert Mustacchi                     chain_ptr->line = line;
1466*7fd79137SRobert Mustacchi                     chain_ptr->diff = diff = pc_more - pc;
1467*7fd79137SRobert Mustacchi                     chain_ptr->next = chain_head;
1468*7fd79137SRobert Mustacchi                     chain_head = chain_ptr;
1469*7fd79137SRobert Mustacchi                 }
1470*7fd79137SRobert Mustacchi                 check_line = false;
1471*7fd79137SRobert Mustacchi             } else
1472*7fd79137SRobert Mustacchi                 /* Check addresses only when they go */
1473*7fd79137SRobert Mustacchi                 /* below pc.  */
1474*7fd79137SRobert Mustacchi             if (line->li_address < pc)
1475*7fd79137SRobert Mustacchi                 check_line = true;
1476*7fd79137SRobert Mustacchi 
1477*7fd79137SRobert Mustacchi         first_line = false;
1478*7fd79137SRobert Mustacchi     }
1479*7fd79137SRobert Mustacchi 
1480*7fd79137SRobert Mustacchi     chain_count = 0;
1481*7fd79137SRobert Mustacchi     for (chain_ptr = chain_head; chain_ptr != NULL;
1482*7fd79137SRobert Mustacchi          chain_ptr = chain_ptr->next)
1483*7fd79137SRobert Mustacchi         if (chain_ptr->diff == diff)
1484*7fd79137SRobert Mustacchi             chain_count++;
1485*7fd79137SRobert Mustacchi 
1486*7fd79137SRobert Mustacchi     pc_line_buf = pc_line = (Dwarf_Line)
1487*7fd79137SRobert Mustacchi         _dwarf_get_alloc(dbg, DW_DLA_LIST, chain_count);
1488*7fd79137SRobert Mustacchi     for (chain_ptr = chain_head; chain_ptr != NULL;
1489*7fd79137SRobert Mustacchi          chain_ptr = chain_ptr->next)
1490*7fd79137SRobert Mustacchi         if (chain_ptr->diff == diff) {
1491*7fd79137SRobert Mustacchi             *pc_line = chain_ptr->line;
1492*7fd79137SRobert Mustacchi             pc_line++;
1493*7fd79137SRobert Mustacchi         }
1494*7fd79137SRobert Mustacchi 
1495*7fd79137SRobert Mustacchi     for (chain_ptr = chain_head; chain_ptr != NULL;) {
1496*7fd79137SRobert Mustacchi         chain_head = chain_ptr;
1497*7fd79137SRobert Mustacchi         chain_ptr = chain_ptr->next;
1498*7fd79137SRobert Mustacchi         dwarf_dealloc(dbg, chain_head, DW_DLA_CHAIN);
1499*7fd79137SRobert Mustacchi     }
1500*7fd79137SRobert Mustacchi 
1501*7fd79137SRobert Mustacchi     *linebuf = pc_line_buf;
1502*7fd79137SRobert Mustacchi     return (chain_count);
1503*7fd79137SRobert Mustacchi }
1504*7fd79137SRobert Mustacchi #endif
1505*7fd79137SRobert Mustacchi 
1506*7fd79137SRobert Mustacchi 
1507*7fd79137SRobert Mustacchi 
1508*7fd79137SRobert Mustacchi /*
1509*7fd79137SRobert Mustacchi    It's impossible for callers of dwarf_srclines() to get to and
1510*7fd79137SRobert Mustacchi    free all the resources (in particular, the li_context and its
1511*7fd79137SRobert Mustacchi    lc_file_entries).
1512*7fd79137SRobert Mustacchi    So this function, new July 2005, does it.
1513*7fd79137SRobert Mustacchi */
1514*7fd79137SRobert Mustacchi 
1515*7fd79137SRobert Mustacchi void
1516*7fd79137SRobert Mustacchi dwarf_srclines_dealloc(Dwarf_Debug dbg, Dwarf_Line * linebuf,
1517*7fd79137SRobert Mustacchi     Dwarf_Signed count)
1518*7fd79137SRobert Mustacchi {
1519*7fd79137SRobert Mustacchi 
1520*7fd79137SRobert Mustacchi     Dwarf_Signed i = 0;
1521*7fd79137SRobert Mustacchi     struct Dwarf_Line_Context_s *context = 0;
1522*7fd79137SRobert Mustacchi 
1523*7fd79137SRobert Mustacchi     if (count > 0) {
1524*7fd79137SRobert Mustacchi         /* All these entries share a single context */
1525*7fd79137SRobert Mustacchi         context = linebuf[0]->li_context;
1526*7fd79137SRobert Mustacchi     }
1527*7fd79137SRobert Mustacchi     for (i = 0; i < count; ++i) {
1528*7fd79137SRobert Mustacchi         dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE);
1529*7fd79137SRobert Mustacchi     }
1530*7fd79137SRobert Mustacchi     dwarf_dealloc(dbg, linebuf, DW_DLA_LIST);
1531*7fd79137SRobert Mustacchi 
1532*7fd79137SRobert Mustacchi     if (context) {
1533*7fd79137SRobert Mustacchi         Dwarf_File_Entry fe = context->lc_file_entries;
1534*7fd79137SRobert Mustacchi 
1535*7fd79137SRobert Mustacchi         while (fe) {
1536*7fd79137SRobert Mustacchi             Dwarf_File_Entry fenext = fe->fi_next;
1537*7fd79137SRobert Mustacchi 
1538*7fd79137SRobert Mustacchi             dwarf_dealloc(dbg, fe, DW_DLA_FILE_ENTRY);
1539*7fd79137SRobert Mustacchi             fe = fenext;
1540*7fd79137SRobert Mustacchi         }
1541*7fd79137SRobert Mustacchi         dwarf_dealloc(dbg, context, DW_DLA_LINE_CONTEXT);
1542*7fd79137SRobert Mustacchi     }
1543*7fd79137SRobert Mustacchi 
1544*7fd79137SRobert Mustacchi     return;
1545*7fd79137SRobert Mustacchi }
1546*7fd79137SRobert Mustacchi 
1547*7fd79137SRobert Mustacchi /* Operand counts per standard operand.
1548*7fd79137SRobert Mustacchi    The initial zero is for DW_LNS_copy.
1549*7fd79137SRobert Mustacchi    This is an economical way to verify we understand the table
1550*7fd79137SRobert Mustacchi    of standard-opcode-lengths in the line table prologue.  */
1551*7fd79137SRobert Mustacchi #define STANDARD_OPERAND_COUNT_DWARF2 9
1552*7fd79137SRobert Mustacchi #define STANDARD_OPERAND_COUNT_DWARF3 12
1553*7fd79137SRobert Mustacchi static unsigned char
1554*7fd79137SRobert Mustacchi   dwarf_standard_opcode_operand_count[STANDARD_OPERAND_COUNT_DWARF3] = {
1555*7fd79137SRobert Mustacchi     /* DWARF2 */
1556*7fd79137SRobert Mustacchi     0,
1557*7fd79137SRobert Mustacchi     1, 1, 1, 1,
1558*7fd79137SRobert Mustacchi     0, 0, 0,
1559*7fd79137SRobert Mustacchi     1,
1560*7fd79137SRobert Mustacchi     /* Following are new for DWARF3. */
1561*7fd79137SRobert Mustacchi     0, 0, 1
1562*7fd79137SRobert Mustacchi };
1563*7fd79137SRobert Mustacchi 
1564*7fd79137SRobert Mustacchi /* We have a normal standard opcode base, but
1565*7fd79137SRobert Mustacchi    an arm compiler emitted a non-standard table!
1566*7fd79137SRobert Mustacchi    This could lead to problems...
1567*7fd79137SRobert Mustacchi    ARM C/C++ Compiler, RVCT4.0 [Build 4
1568*7fd79137SRobert Mustacchi    00] seems to get the table wrong .  */
1569*7fd79137SRobert Mustacchi static unsigned char
1570*7fd79137SRobert Mustacchi dwarf_arm_standard_opcode_operand_count[STANDARD_OPERAND_COUNT_DWARF3] = {
1571*7fd79137SRobert Mustacchi     /* DWARF2 */
1572*7fd79137SRobert Mustacchi     0,
1573*7fd79137SRobert Mustacchi     1, 1, 1, 1,
1574*7fd79137SRobert Mustacchi     0, 0, 0,
1575*7fd79137SRobert Mustacchi     0,  /* <<< --- this is wrong */
1576*7fd79137SRobert Mustacchi     /* Following are new for DWARF3. */
1577*7fd79137SRobert Mustacchi     0, 0, 1
1578*7fd79137SRobert Mustacchi };
1579*7fd79137SRobert Mustacchi 
1580*7fd79137SRobert Mustacchi static void
1581*7fd79137SRobert Mustacchi print_header_issue(Dwarf_Debug dbg,
1582*7fd79137SRobert Mustacchi     char *specific_msg,
1583*7fd79137SRobert Mustacchi     Dwarf_Small *data_start,
1584*7fd79137SRobert Mustacchi     int *err_count_out)
1585*7fd79137SRobert Mustacchi {
1586*7fd79137SRobert Mustacchi     if(!err_count_out)
1587*7fd79137SRobert Mustacchi         return;
1588*7fd79137SRobert Mustacchi     printf("*** DWARF CHECK: "
1589*7fd79137SRobert Mustacchi         "line table header: %s",
1590*7fd79137SRobert Mustacchi         specific_msg);
1591*7fd79137SRobert Mustacchi     if( data_start >= dbg->de_debug_line.dss_data &&
1592*7fd79137SRobert Mustacchi         (data_start < (dbg->de_debug_line.dss_data +
1593*7fd79137SRobert Mustacchi         dbg->de_debug_line.dss_size))) {
1594*7fd79137SRobert Mustacchi         Dwarf_Unsigned off = data_start - dbg->de_debug_line.dss_data;
1595*7fd79137SRobert Mustacchi         printf(" at .debug_line section offset 0x%" DW_PR_DUx
1596*7fd79137SRobert Mustacchi             "  ( %" DW_PR_DUu " ) ",
1597*7fd79137SRobert Mustacchi             off,off);
1598*7fd79137SRobert Mustacchi     } else {
1599*7fd79137SRobert Mustacchi         printf(" (unknown section location) ");
1600*7fd79137SRobert Mustacchi     }
1601*7fd79137SRobert Mustacchi     printf("***\n");
1602*7fd79137SRobert Mustacchi     *err_count_out += 1;
1603*7fd79137SRobert Mustacchi }
1604*7fd79137SRobert Mustacchi 
1605*7fd79137SRobert Mustacchi 
1606*7fd79137SRobert Mustacchi 
1607*7fd79137SRobert Mustacchi /* Common line table prefix reading code.
1608*7fd79137SRobert Mustacchi    Returns DW_DLV_OK, DW_DLV_ERROR.
1609*7fd79137SRobert Mustacchi    DW_DLV_NO_ENTRY cannot be returned, but callers should
1610*7fd79137SRobert Mustacchi    assume it is possible.
1611*7fd79137SRobert Mustacchi 
1612*7fd79137SRobert Mustacchi    The prefix_out area must be initialized properly before calling this.
1613*7fd79137SRobert Mustacchi 
1614*7fd79137SRobert Mustacchi    Has the side effect of allocating arrays which
1615*7fd79137SRobert Mustacchi    must be freed (see the Line_Table_Prefix_s struct which
1616*7fd79137SRobert Mustacchi    holds the pointers to space we allocate here).
1617*7fd79137SRobert Mustacchi 
1618*7fd79137SRobert Mustacchi    bogus_bytes_ptr and bogus_bytes are output values which
1619*7fd79137SRobert Mustacchi    let a print-program notify the user of some surprising bytes
1620*7fd79137SRobert Mustacchi    after a line table header and before the line table instructions.
1621*7fd79137SRobert Mustacchi    These can be ignored unless one is printing.
1622*7fd79137SRobert Mustacchi    And are ignored if NULL passed as the pointer.
1623*7fd79137SRobert Mustacchi */
1624*7fd79137SRobert Mustacchi 
1625*7fd79137SRobert Mustacchi /* err_count_out may be NULL, in which case we
1626*7fd79137SRobert Mustacchi    make no attempt to count checking-type errors.
1627*7fd79137SRobert Mustacchi    Checking-type errors do not stop us, we just report them.
1628*7fd79137SRobert Mustacchi */
1629*7fd79137SRobert Mustacchi int
1630*7fd79137SRobert Mustacchi dwarf_read_line_table_prefix(Dwarf_Debug dbg,
1631*7fd79137SRobert Mustacchi     Dwarf_Small * data_start,
1632*7fd79137SRobert Mustacchi     Dwarf_Unsigned data_length,
1633*7fd79137SRobert Mustacchi     Dwarf_Small ** updated_data_start_out,
1634*7fd79137SRobert Mustacchi     struct Line_Table_Prefix_s *prefix_out,
1635*7fd79137SRobert Mustacchi     Dwarf_Small ** bogus_bytes_ptr,
1636*7fd79137SRobert Mustacchi     Dwarf_Unsigned *bogus_bytes,
1637*7fd79137SRobert Mustacchi     Dwarf_Error * err,
1638*7fd79137SRobert Mustacchi     int *err_count_out)
1639*7fd79137SRobert Mustacchi {
1640*7fd79137SRobert Mustacchi     Dwarf_Small *line_ptr = data_start;
1641*7fd79137SRobert Mustacchi     Dwarf_Unsigned total_length = 0;
1642*7fd79137SRobert Mustacchi     int local_length_size = 0;
1643*7fd79137SRobert Mustacchi     int local_extension_size = 0;
1644*7fd79137SRobert Mustacchi     Dwarf_Unsigned prologue_length = 0;
1645*7fd79137SRobert Mustacchi     Dwarf_Half version = 0;
1646*7fd79137SRobert Mustacchi     Dwarf_Unsigned directories_count = 0;
1647*7fd79137SRobert Mustacchi     Dwarf_Unsigned directories_malloc = 0;
1648*7fd79137SRobert Mustacchi     Dwarf_Unsigned files_count = 0;
1649*7fd79137SRobert Mustacchi     Dwarf_Unsigned files_malloc = 0;
1650*7fd79137SRobert Mustacchi     Dwarf_Small *line_ptr_end = 0;
1651*7fd79137SRobert Mustacchi     Dwarf_Small *lp_begin = 0;
1652*7fd79137SRobert Mustacchi     if(bogus_bytes_ptr) *bogus_bytes_ptr = 0;
1653*7fd79137SRobert Mustacchi     if(bogus_bytes) *bogus_bytes= 0;
1654*7fd79137SRobert Mustacchi 
1655*7fd79137SRobert Mustacchi     prefix_out->pf_line_ptr_start = line_ptr;
1656*7fd79137SRobert Mustacchi     /* READ_AREA_LENGTH updates line_ptr for consumed bytes */
1657*7fd79137SRobert Mustacchi     READ_AREA_LENGTH(dbg, total_length, Dwarf_Unsigned,
1658*7fd79137SRobert Mustacchi                      line_ptr, local_length_size, local_extension_size);
1659*7fd79137SRobert Mustacchi 
1660*7fd79137SRobert Mustacchi 
1661*7fd79137SRobert Mustacchi     line_ptr_end = line_ptr + total_length;
1662*7fd79137SRobert Mustacchi     prefix_out->pf_line_ptr_end = line_ptr_end;
1663*7fd79137SRobert Mustacchi     prefix_out->pf_length_field_length = local_length_size +
1664*7fd79137SRobert Mustacchi         local_extension_size;
1665*7fd79137SRobert Mustacchi     /* ASSERT: prefix_out->pf_length_field_length == line_ptr
1666*7fd79137SRobert Mustacchi        -prefix_out->pf_line_ptr_start; */
1667*7fd79137SRobert Mustacchi     if (line_ptr_end > dbg->de_debug_line.dss_data +
1668*7fd79137SRobert Mustacchi         dbg->de_debug_line.dss_size) {
1669*7fd79137SRobert Mustacchi         _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
1670*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1671*7fd79137SRobert Mustacchi     }
1672*7fd79137SRobert Mustacchi     if (line_ptr_end > data_start + data_length) {
1673*7fd79137SRobert Mustacchi         _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
1674*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1675*7fd79137SRobert Mustacchi     }
1676*7fd79137SRobert Mustacchi     prefix_out->pf_total_length = total_length;
1677*7fd79137SRobert Mustacchi 
1678*7fd79137SRobert Mustacchi     READ_UNALIGNED(dbg, version, Dwarf_Half,
1679*7fd79137SRobert Mustacchi                    line_ptr, sizeof(Dwarf_Half));
1680*7fd79137SRobert Mustacchi     prefix_out->pf_version = version;
1681*7fd79137SRobert Mustacchi     line_ptr += sizeof(Dwarf_Half);
1682*7fd79137SRobert Mustacchi     if (version != CURRENT_VERSION_STAMP &&
1683*7fd79137SRobert Mustacchi         version != CURRENT_VERSION_STAMP3) {
1684*7fd79137SRobert Mustacchi         _dwarf_error(dbg, err, DW_DLE_VERSION_STAMP_ERROR);
1685*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1686*7fd79137SRobert Mustacchi     }
1687*7fd79137SRobert Mustacchi 
1688*7fd79137SRobert Mustacchi     READ_UNALIGNED(dbg, prologue_length, Dwarf_Unsigned,
1689*7fd79137SRobert Mustacchi                    line_ptr, local_length_size);
1690*7fd79137SRobert Mustacchi     prefix_out->pf_prologue_length = prologue_length;
1691*7fd79137SRobert Mustacchi     line_ptr += local_length_size;
1692*7fd79137SRobert Mustacchi     prefix_out->pf_line_prologue_start = line_ptr;
1693*7fd79137SRobert Mustacchi 
1694*7fd79137SRobert Mustacchi     prefix_out->pf_minimum_instruction_length =
1695*7fd79137SRobert Mustacchi         *(unsigned char *) line_ptr;
1696*7fd79137SRobert Mustacchi     line_ptr = line_ptr + sizeof(Dwarf_Small);
1697*7fd79137SRobert Mustacchi 
1698*7fd79137SRobert Mustacchi     prefix_out->pf_default_is_stmt = *(unsigned char *) line_ptr;
1699*7fd79137SRobert Mustacchi     line_ptr = line_ptr + sizeof(Dwarf_Small);
1700*7fd79137SRobert Mustacchi 
1701*7fd79137SRobert Mustacchi     prefix_out->pf_line_base = *(signed char *) line_ptr;
1702*7fd79137SRobert Mustacchi     line_ptr = line_ptr + sizeof(Dwarf_Sbyte);
1703*7fd79137SRobert Mustacchi 
1704*7fd79137SRobert Mustacchi     prefix_out->pf_line_range = *(unsigned char *) line_ptr;
1705*7fd79137SRobert Mustacchi     line_ptr = line_ptr + sizeof(Dwarf_Small);
1706*7fd79137SRobert Mustacchi 
1707*7fd79137SRobert Mustacchi     prefix_out->pf_opcode_base = *(unsigned char *) line_ptr;
1708*7fd79137SRobert Mustacchi     line_ptr = line_ptr + sizeof(Dwarf_Small);
1709*7fd79137SRobert Mustacchi 
1710*7fd79137SRobert Mustacchi     /* Set up the array of standard opcode lengths. */
1711*7fd79137SRobert Mustacchi     /* We think this works ok even for cross-endian processing of
1712*7fd79137SRobert Mustacchi        objects.  It might be wrong, we might need to specially process
1713*7fd79137SRobert Mustacchi        the array of ubyte into host order.  */
1714*7fd79137SRobert Mustacchi     prefix_out->pf_opcode_length_table = line_ptr;
1715*7fd79137SRobert Mustacchi 
1716*7fd79137SRobert Mustacchi     /* pf_opcode_base is one greater than the size of the array. */
1717*7fd79137SRobert Mustacchi     line_ptr += prefix_out->pf_opcode_base - 1;
1718*7fd79137SRobert Mustacchi 
1719*7fd79137SRobert Mustacchi     {
1720*7fd79137SRobert Mustacchi         /* Determine (as best we can) whether the
1721*7fd79137SRobert Mustacchi            pf_opcode_length_table holds 9 or 12 standard-conforming
1722*7fd79137SRobert Mustacchi            entries.  gcc4 upped to DWARF3's 12 without updating the
1723*7fd79137SRobert Mustacchi            version number.   */
1724*7fd79137SRobert Mustacchi         int operand_ck_fail = true;
1725*7fd79137SRobert Mustacchi 
1726*7fd79137SRobert Mustacchi         if (prefix_out->pf_opcode_base >= STANDARD_OPERAND_COUNT_DWARF3) {
1727*7fd79137SRobert Mustacchi             int mismatch = memcmp(dwarf_standard_opcode_operand_count,
1728*7fd79137SRobert Mustacchi                                   prefix_out->pf_opcode_length_table,
1729*7fd79137SRobert Mustacchi                                   STANDARD_OPERAND_COUNT_DWARF3);
1730*7fd79137SRobert Mustacchi             if(mismatch) {
1731*7fd79137SRobert Mustacchi                  if(err_count_out) {
1732*7fd79137SRobert Mustacchi                      print_header_issue(dbg,"standard-operands did not match",
1733*7fd79137SRobert Mustacchi                          data_start,err_count_out);
1734*7fd79137SRobert Mustacchi                  }
1735*7fd79137SRobert Mustacchi                  mismatch = memcmp(dwarf_arm_standard_opcode_operand_count,
1736*7fd79137SRobert Mustacchi                                   prefix_out->pf_opcode_length_table,
1737*7fd79137SRobert Mustacchi                                   STANDARD_OPERAND_COUNT_DWARF3);
1738*7fd79137SRobert Mustacchi                  if(!mismatch && err_count_out) {
1739*7fd79137SRobert Mustacchi                      print_header_issue(dbg,"arm (incorrect) operands in use",
1740*7fd79137SRobert Mustacchi                          data_start,err_count_out);
1741*7fd79137SRobert Mustacchi                  }
1742*7fd79137SRobert Mustacchi             }
1743*7fd79137SRobert Mustacchi             if (!mismatch) {
1744*7fd79137SRobert Mustacchi                 if (version == 2) {
1745*7fd79137SRobert Mustacchi                     if(err_count_out) {
1746*7fd79137SRobert Mustacchi                         print_header_issue(dbg,
1747*7fd79137SRobert Mustacchi                         "standard DWARF3 operands matched, but is DWARF2 linetable",
1748*7fd79137SRobert Mustacchi                             data_start,err_count_out);
1749*7fd79137SRobert Mustacchi                     }
1750*7fd79137SRobert Mustacchi                 }
1751*7fd79137SRobert Mustacchi                 operand_ck_fail = false;
1752*7fd79137SRobert Mustacchi                 prefix_out->pf_std_op_count =
1753*7fd79137SRobert Mustacchi                     STANDARD_OPERAND_COUNT_DWARF3;
1754*7fd79137SRobert Mustacchi             }
1755*7fd79137SRobert Mustacchi         }
1756*7fd79137SRobert Mustacchi         if (operand_ck_fail) {
1757*7fd79137SRobert Mustacchi             if (prefix_out->pf_opcode_base >=
1758*7fd79137SRobert Mustacchi                 STANDARD_OPERAND_COUNT_DWARF2) {
1759*7fd79137SRobert Mustacchi 
1760*7fd79137SRobert Mustacchi                 int mismatch =
1761*7fd79137SRobert Mustacchi                     memcmp(dwarf_standard_opcode_operand_count,
1762*7fd79137SRobert Mustacchi                            prefix_out->pf_opcode_length_table,
1763*7fd79137SRobert Mustacchi                            STANDARD_OPERAND_COUNT_DWARF2);
1764*7fd79137SRobert Mustacchi                 if(mismatch) {
1765*7fd79137SRobert Mustacchi                     if(err_count_out) {
1766*7fd79137SRobert Mustacchi                         print_header_issue(dbg,"standard-operands-lengths did not match",
1767*7fd79137SRobert Mustacchi                             data_start,err_count_out);
1768*7fd79137SRobert Mustacchi                     }
1769*7fd79137SRobert Mustacchi                     mismatch = memcmp(dwarf_arm_standard_opcode_operand_count,
1770*7fd79137SRobert Mustacchi                                   prefix_out->pf_opcode_length_table,
1771*7fd79137SRobert Mustacchi                                   STANDARD_OPERAND_COUNT_DWARF2);
1772*7fd79137SRobert Mustacchi                     if(!mismatch && err_count_out) {
1773*7fd79137SRobert Mustacchi                         print_header_issue(dbg,"arm (incorrect) operand in use",
1774*7fd79137SRobert Mustacchi                             data_start,err_count_out);
1775*7fd79137SRobert Mustacchi                     }
1776*7fd79137SRobert Mustacchi                 }
1777*7fd79137SRobert Mustacchi 
1778*7fd79137SRobert Mustacchi                 if (!mismatch) {
1779*7fd79137SRobert Mustacchi                     operand_ck_fail = false;
1780*7fd79137SRobert Mustacchi                     prefix_out->pf_std_op_count =
1781*7fd79137SRobert Mustacchi                         STANDARD_OPERAND_COUNT_DWARF2;
1782*7fd79137SRobert Mustacchi                 }
1783*7fd79137SRobert Mustacchi             }
1784*7fd79137SRobert Mustacchi         }
1785*7fd79137SRobert Mustacchi         if (operand_ck_fail) {
1786*7fd79137SRobert Mustacchi             /* Here we are not sure what the pf_std_op_count is. */
1787*7fd79137SRobert Mustacchi             _dwarf_error(dbg, err, DW_DLE_LINE_NUM_OPERANDS_BAD);
1788*7fd79137SRobert Mustacchi             return (DW_DLV_ERROR);
1789*7fd79137SRobert Mustacchi         }
1790*7fd79137SRobert Mustacchi     }
1791*7fd79137SRobert Mustacchi     /* At this point we no longer need to check operand counts. */
1792*7fd79137SRobert Mustacchi 
1793*7fd79137SRobert Mustacchi 
1794*7fd79137SRobert Mustacchi     directories_count = 0;
1795*7fd79137SRobert Mustacchi     directories_malloc = 5;
1796*7fd79137SRobert Mustacchi     prefix_out->pf_include_directories = malloc(sizeof(Dwarf_Small *) *
1797*7fd79137SRobert Mustacchi                                                 directories_malloc);
1798*7fd79137SRobert Mustacchi     if (prefix_out->pf_include_directories == NULL) {
1799*7fd79137SRobert Mustacchi         _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
1800*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1801*7fd79137SRobert Mustacchi     }
1802*7fd79137SRobert Mustacchi     memset(prefix_out->pf_include_directories, 0,
1803*7fd79137SRobert Mustacchi            sizeof(Dwarf_Small *) * directories_malloc);
1804*7fd79137SRobert Mustacchi 
1805*7fd79137SRobert Mustacchi     while ((*(char *) line_ptr) != '\0') {
1806*7fd79137SRobert Mustacchi         if (directories_count >= directories_malloc) {
1807*7fd79137SRobert Mustacchi             Dwarf_Unsigned expand = 2 * directories_malloc;
1808*7fd79137SRobert Mustacchi             Dwarf_Unsigned bytesalloc = sizeof(Dwarf_Small *) * expand;
1809*7fd79137SRobert Mustacchi             Dwarf_Small **newdirs =
1810*7fd79137SRobert Mustacchi                 realloc(prefix_out->pf_include_directories,
1811*7fd79137SRobert Mustacchi                         bytesalloc);
1812*7fd79137SRobert Mustacchi 
1813*7fd79137SRobert Mustacchi             if (!newdirs) {
1814*7fd79137SRobert Mustacchi                 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
1815*7fd79137SRobert Mustacchi                 return (DW_DLV_ERROR);
1816*7fd79137SRobert Mustacchi             }
1817*7fd79137SRobert Mustacchi             /* Doubled size, zero out second half. */
1818*7fd79137SRobert Mustacchi             memset(newdirs + directories_malloc, 0,
1819*7fd79137SRobert Mustacchi                    sizeof(Dwarf_Small *) * directories_malloc);
1820*7fd79137SRobert Mustacchi             directories_malloc = expand;
1821*7fd79137SRobert Mustacchi             prefix_out->pf_include_directories = newdirs;
1822*7fd79137SRobert Mustacchi         }
1823*7fd79137SRobert Mustacchi         prefix_out->pf_include_directories[directories_count] =
1824*7fd79137SRobert Mustacchi             line_ptr;
1825*7fd79137SRobert Mustacchi         line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
1826*7fd79137SRobert Mustacchi         directories_count++;
1827*7fd79137SRobert Mustacchi     }
1828*7fd79137SRobert Mustacchi     prefix_out->pf_include_directories_count = directories_count;
1829*7fd79137SRobert Mustacchi     line_ptr++;
1830*7fd79137SRobert Mustacchi 
1831*7fd79137SRobert Mustacchi     files_count = 0;
1832*7fd79137SRobert Mustacchi     files_malloc = 5;
1833*7fd79137SRobert Mustacchi     prefix_out->pf_line_table_file_entries =
1834*7fd79137SRobert Mustacchi         malloc(sizeof(struct Line_Table_File_Entry_s) * files_malloc);
1835*7fd79137SRobert Mustacchi     if (prefix_out->pf_line_table_file_entries == NULL) {
1836*7fd79137SRobert Mustacchi         _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
1837*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1838*7fd79137SRobert Mustacchi     }
1839*7fd79137SRobert Mustacchi     memset(prefix_out->pf_line_table_file_entries, 0,
1840*7fd79137SRobert Mustacchi            sizeof(struct Line_Table_File_Entry_s) * files_malloc);
1841*7fd79137SRobert Mustacchi 
1842*7fd79137SRobert Mustacchi     while (*(char *) line_ptr != '\0') {
1843*7fd79137SRobert Mustacchi         Dwarf_Unsigned utmp;
1844*7fd79137SRobert Mustacchi         Dwarf_Unsigned dir_index = 0;
1845*7fd79137SRobert Mustacchi         Dwarf_Unsigned lastmod = 0;
1846*7fd79137SRobert Mustacchi         Dwarf_Unsigned file_length = 0;
1847*7fd79137SRobert Mustacchi         struct Line_Table_File_Entry_s *curline;
1848*7fd79137SRobert Mustacchi         Dwarf_Word leb128_length = 0;
1849*7fd79137SRobert Mustacchi 
1850*7fd79137SRobert Mustacchi 
1851*7fd79137SRobert Mustacchi         if (files_count >= files_malloc) {
1852*7fd79137SRobert Mustacchi             Dwarf_Unsigned expand = 2 * files_malloc;
1853*7fd79137SRobert Mustacchi             struct Line_Table_File_Entry_s *newfiles =
1854*7fd79137SRobert Mustacchi                 realloc(prefix_out->pf_line_table_file_entries,
1855*7fd79137SRobert Mustacchi                         sizeof(struct Line_Table_File_Entry_s) *
1856*7fd79137SRobert Mustacchi                         expand);
1857*7fd79137SRobert Mustacchi             if (!newfiles) {
1858*7fd79137SRobert Mustacchi                 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
1859*7fd79137SRobert Mustacchi                 return (DW_DLV_ERROR);
1860*7fd79137SRobert Mustacchi             }
1861*7fd79137SRobert Mustacchi             memset(newfiles + files_malloc, 0,
1862*7fd79137SRobert Mustacchi                    sizeof(struct Line_Table_File_Entry_s) *
1863*7fd79137SRobert Mustacchi                    files_malloc);
1864*7fd79137SRobert Mustacchi             files_malloc = expand;
1865*7fd79137SRobert Mustacchi             prefix_out->pf_line_table_file_entries = newfiles;
1866*7fd79137SRobert Mustacchi         }
1867*7fd79137SRobert Mustacchi         curline = prefix_out->pf_line_table_file_entries + files_count;
1868*7fd79137SRobert Mustacchi 
1869*7fd79137SRobert Mustacchi         curline->lte_filename = line_ptr;
1870*7fd79137SRobert Mustacchi         line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
1871*7fd79137SRobert Mustacchi 
1872*7fd79137SRobert Mustacchi         DECODE_LEB128_UWORD(line_ptr, utmp);
1873*7fd79137SRobert Mustacchi         dir_index = (Dwarf_Sword) utmp;
1874*7fd79137SRobert Mustacchi         if (dir_index > directories_count) {
1875*7fd79137SRobert Mustacchi             _dwarf_error(dbg, err, DW_DLE_DIR_INDEX_BAD);
1876*7fd79137SRobert Mustacchi             return (DW_DLV_ERROR);
1877*7fd79137SRobert Mustacchi         }
1878*7fd79137SRobert Mustacchi         curline->lte_directory_index = dir_index;
1879*7fd79137SRobert Mustacchi 
1880*7fd79137SRobert Mustacchi         lastmod = _dwarf_decode_u_leb128(line_ptr, &leb128_length);
1881*7fd79137SRobert Mustacchi         line_ptr = line_ptr + leb128_length;
1882*7fd79137SRobert Mustacchi         curline->lte_last_modification_time = lastmod;
1883*7fd79137SRobert Mustacchi 
1884*7fd79137SRobert Mustacchi         /* Skip over file length. */
1885*7fd79137SRobert Mustacchi         file_length = _dwarf_decode_u_leb128(line_ptr, &leb128_length);
1886*7fd79137SRobert Mustacchi         line_ptr = line_ptr + leb128_length;
1887*7fd79137SRobert Mustacchi         curline->lte_length_of_file = file_length;
1888*7fd79137SRobert Mustacchi 
1889*7fd79137SRobert Mustacchi         ++files_count;
1890*7fd79137SRobert Mustacchi 
1891*7fd79137SRobert Mustacchi     }
1892*7fd79137SRobert Mustacchi     prefix_out->pf_files_count = files_count;
1893*7fd79137SRobert Mustacchi     /* Skip trailing nul byte */
1894*7fd79137SRobert Mustacchi     ++line_ptr;
1895*7fd79137SRobert Mustacchi 
1896*7fd79137SRobert Mustacchi 
1897*7fd79137SRobert Mustacchi     lp_begin = prefix_out->pf_line_prologue_start +
1898*7fd79137SRobert Mustacchi                      prefix_out->pf_prologue_length;
1899*7fd79137SRobert Mustacchi     if (line_ptr != lp_begin) {
1900*7fd79137SRobert Mustacchi         if(line_ptr > lp_begin) {
1901*7fd79137SRobert Mustacchi             _dwarf_error(dbg, err, DW_DLE_LINE_PROLOG_LENGTH_BAD);
1902*7fd79137SRobert Mustacchi             return (DW_DLV_ERROR);
1903*7fd79137SRobert Mustacchi         } else {
1904*7fd79137SRobert Mustacchi             /* Bug in compiler. These
1905*7fd79137SRobert Mustacchi              * bytes are really part of the instruction
1906*7fd79137SRobert Mustacchi              * stream.  The prefix_out->pf_prologue_length is
1907*7fd79137SRobert Mustacchi              * wrong (12 too high).  */
1908*7fd79137SRobert Mustacchi             if(bogus_bytes_ptr) {
1909*7fd79137SRobert Mustacchi                *bogus_bytes_ptr = line_ptr;
1910*7fd79137SRobert Mustacchi             }
1911*7fd79137SRobert Mustacchi             if(bogus_bytes) {
1912*7fd79137SRobert Mustacchi                /* How far off things are. We expect the
1913*7fd79137SRobert Mustacchi                   value 12 ! */
1914*7fd79137SRobert Mustacchi                *bogus_bytes = (lp_begin - line_ptr);
1915*7fd79137SRobert Mustacchi             }
1916*7fd79137SRobert Mustacchi         }
1917*7fd79137SRobert Mustacchi         /* Ignore the lp_begin calc. Assume line_ptr right.
1918*7fd79137SRobert Mustacchi            Making up for compiler bug. */
1919*7fd79137SRobert Mustacchi         lp_begin = line_ptr;
1920*7fd79137SRobert Mustacchi 
1921*7fd79137SRobert Mustacchi     }
1922*7fd79137SRobert Mustacchi 
1923*7fd79137SRobert Mustacchi     *updated_data_start_out = lp_begin;
1924*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1925*7fd79137SRobert Mustacchi }
1926*7fd79137SRobert Mustacchi 
1927*7fd79137SRobert Mustacchi 
1928*7fd79137SRobert Mustacchi /* Initialize the Line_Table_Prefix_s struct.
1929*7fd79137SRobert Mustacchi    memset is not guaranteed a portable initializer, but works
1930*7fd79137SRobert Mustacchi    fine for current architectures.   AFAIK.
1931*7fd79137SRobert Mustacchi */
1932*7fd79137SRobert Mustacchi void
1933*7fd79137SRobert Mustacchi dwarf_init_line_table_prefix(struct Line_Table_Prefix_s *pf)
1934*7fd79137SRobert Mustacchi {
1935*7fd79137SRobert Mustacchi     memset(pf, 0, sizeof(*pf));
1936*7fd79137SRobert Mustacchi }
1937*7fd79137SRobert Mustacchi 
1938*7fd79137SRobert Mustacchi /* Free any malloc'd area.  of the Line_Table_Prefix_s struct. */
1939*7fd79137SRobert Mustacchi void
1940*7fd79137SRobert Mustacchi dwarf_free_line_table_prefix(struct Line_Table_Prefix_s *pf)
1941*7fd79137SRobert Mustacchi {
1942*7fd79137SRobert Mustacchi     if (pf->pf_include_directories) {
1943*7fd79137SRobert Mustacchi         free(pf->pf_include_directories);
1944*7fd79137SRobert Mustacchi         pf->pf_include_directories = 0;
1945*7fd79137SRobert Mustacchi     }
1946*7fd79137SRobert Mustacchi     if (pf->pf_line_table_file_entries) {
1947*7fd79137SRobert Mustacchi         free(pf->pf_line_table_file_entries);
1948*7fd79137SRobert Mustacchi         pf->pf_line_table_file_entries = 0;
1949*7fd79137SRobert Mustacchi     }
1950*7fd79137SRobert Mustacchi     return;
1951*7fd79137SRobert Mustacchi }
1952