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