xref: /titanic_44/usr/src/tools/ctf/dwarf/common/dwarf_line.c (revision 07dc1947c362e187fb955d283b692f8769dd5def)
149d3bc91SRichard Lowe /*
2*07dc1947SRichard Lowe   Copyright (C) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
3*07dc1947SRichard Lowe   Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
449d3bc91SRichard Lowe 
549d3bc91SRichard Lowe   This program is free software; you can redistribute it and/or modify it
649d3bc91SRichard Lowe   under the terms of version 2.1 of the GNU Lesser General Public License
749d3bc91SRichard Lowe   as published by the Free Software Foundation.
849d3bc91SRichard Lowe 
949d3bc91SRichard Lowe   This program is distributed in the hope that it would be useful, but
1049d3bc91SRichard Lowe   WITHOUT ANY WARRANTY; without even the implied warranty of
1149d3bc91SRichard Lowe   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1249d3bc91SRichard Lowe 
1349d3bc91SRichard Lowe   Further, this software is distributed without any warranty that it is
1449d3bc91SRichard Lowe   free of the rightful claim of any third person regarding infringement
1549d3bc91SRichard Lowe   or the like.  Any license provided herein, whether implied or
1649d3bc91SRichard Lowe   otherwise, applies only to this software file.  Patent licenses, if
1749d3bc91SRichard Lowe   any, provided herein do not apply to combinations of this program with
1849d3bc91SRichard Lowe   other software, or any other product whatsoever.
1949d3bc91SRichard Lowe 
2049d3bc91SRichard Lowe   You should have received a copy of the GNU Lesser General Public
2149d3bc91SRichard Lowe   License along with this program; if not, write the Free Software
22*07dc1947SRichard Lowe   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2349d3bc91SRichard Lowe   USA.
2449d3bc91SRichard Lowe 
25*07dc1947SRichard Lowe   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
2649d3bc91SRichard Lowe   Mountain View, CA 94043, or:
2749d3bc91SRichard Lowe 
2849d3bc91SRichard Lowe   http://www.sgi.com
2949d3bc91SRichard Lowe 
3049d3bc91SRichard Lowe   For further information regarding this notice, see:
3149d3bc91SRichard Lowe 
3249d3bc91SRichard Lowe   http://oss.sgi.com/projects/GenInfo/NoticeExplan
3349d3bc91SRichard Lowe 
3449d3bc91SRichard Lowe */
35*07dc1947SRichard Lowe /* The address of the Free Software Foundation is
36*07dc1947SRichard Lowe    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
37*07dc1947SRichard Lowe    Boston, MA 02110-1301, USA.
38*07dc1947SRichard Lowe    SGI has moved from the Crittenden Lane address.
39*07dc1947SRichard Lowe */
40*07dc1947SRichard Lowe 
4149d3bc91SRichard Lowe 
4249d3bc91SRichard Lowe 
4349d3bc91SRichard Lowe 
4449d3bc91SRichard Lowe #include "config.h"
4549d3bc91SRichard Lowe #include "dwarf_incl.h"
4649d3bc91SRichard Lowe #include <stdio.h>
47*07dc1947SRichard Lowe #include <stdlib.h>
4849d3bc91SRichard Lowe #include "dwarf_line.h"
4949d3bc91SRichard Lowe 
50*07dc1947SRichard Lowe static int
is_path_separator(Dwarf_Small s)51*07dc1947SRichard Lowe is_path_separator(Dwarf_Small s)
52*07dc1947SRichard Lowe {
53*07dc1947SRichard Lowe     if(s == '/') {
54*07dc1947SRichard Lowe         return 1;
55*07dc1947SRichard Lowe     }
56*07dc1947SRichard Lowe #ifdef HAVE_WINDOWS_PATH
57*07dc1947SRichard Lowe     if(s == '\\') {
58*07dc1947SRichard Lowe         return 1;
59*07dc1947SRichard Lowe     }
60*07dc1947SRichard Lowe #endif
61*07dc1947SRichard Lowe     return 0;
62*07dc1947SRichard Lowe }
63*07dc1947SRichard Lowe 
64*07dc1947SRichard Lowe /* Return 0 if false, 1 if true.
65*07dc1947SRichard Lowe    If HAVE_WINDOWS_PATH is defined we
66*07dc1947SRichard Lowe    attempt to handle windows full paths:
67*07dc1947SRichard Lowe    \\something   or  C:cwdpath.c
68*07dc1947SRichard Lowe */
69*07dc1947SRichard Lowe static int
file_name_is_full_path(Dwarf_Small * fname)70*07dc1947SRichard Lowe file_name_is_full_path(Dwarf_Small  *fname)
71*07dc1947SRichard Lowe {
72*07dc1947SRichard Lowe     Dwarf_Small firstc = *fname;
73*07dc1947SRichard Lowe     if(is_path_separator(firstc)) {
74*07dc1947SRichard Lowe         /* Full path. */
75*07dc1947SRichard Lowe         return 1;
76*07dc1947SRichard Lowe     }
77*07dc1947SRichard Lowe     if(!firstc) {
78*07dc1947SRichard Lowe         return 0;
79*07dc1947SRichard Lowe     }
80*07dc1947SRichard Lowe #ifdef HAVE_WINDOWS_PATH
81*07dc1947SRichard Lowe     if((firstc >= 'A' && firstc <= 'Z') ||
82*07dc1947SRichard Lowe        (firstc >= 'a' && firstc <= 'z')) {
83*07dc1947SRichard Lowe          Dwarf_Small secondc = fname[1];
84*07dc1947SRichard Lowe          if (secondc == ':') {
85*07dc1947SRichard Lowe              return 1;
86*07dc1947SRichard Lowe          }
87*07dc1947SRichard Lowe     }
88*07dc1947SRichard Lowe #endif
89*07dc1947SRichard Lowe     return 0;
90*07dc1947SRichard Lowe }
9149d3bc91SRichard Lowe 
9249d3bc91SRichard Lowe /*
9349d3bc91SRichard Lowe     Although source files is supposed to return the
9449d3bc91SRichard Lowe     source files in the compilation-unit, it does
9549d3bc91SRichard Lowe     not look for any in the statement program.  In
9649d3bc91SRichard Lowe     other words, it ignores those defined using the
9749d3bc91SRichard Lowe     extended opcode DW_LNE_define_file.
9849d3bc91SRichard Lowe */
9949d3bc91SRichard Lowe int
dwarf_srcfiles(Dwarf_Die die,char *** srcfiles,Dwarf_Signed * srcfilecount,Dwarf_Error * error)10049d3bc91SRichard Lowe dwarf_srcfiles(Dwarf_Die die,
10149d3bc91SRichard Lowe                char ***srcfiles,
10249d3bc91SRichard Lowe                Dwarf_Signed * srcfilecount, Dwarf_Error * error)
10349d3bc91SRichard Lowe {
104*07dc1947SRichard Lowe     /* This pointer is used to scan the portion of the .debug_line
10549d3bc91SRichard Lowe        section for the current cu. */
10649d3bc91SRichard Lowe     Dwarf_Small *line_ptr;
10749d3bc91SRichard Lowe 
108*07dc1947SRichard Lowe     /* Pointer to a DW_AT_stmt_list attribute in case it exists in the
10949d3bc91SRichard Lowe        die. */
11049d3bc91SRichard Lowe     Dwarf_Attribute stmt_list_attr;
11149d3bc91SRichard Lowe 
11249d3bc91SRichard Lowe     /* Pointer to DW_AT_comp_dir attribute in die. */
11349d3bc91SRichard Lowe     Dwarf_Attribute comp_dir_attr;
11449d3bc91SRichard Lowe 
11549d3bc91SRichard Lowe     /* Pointer to name of compilation directory. */
11649d3bc91SRichard Lowe     Dwarf_Small *comp_dir = 0;
11749d3bc91SRichard Lowe 
118*07dc1947SRichard Lowe     /* Offset into .debug_line specified by a DW_AT_stmt_list
11949d3bc91SRichard Lowe        attribute. */
12049d3bc91SRichard Lowe     Dwarf_Unsigned line_offset = 0;
12149d3bc91SRichard Lowe 
122*07dc1947SRichard Lowe     /* This points to a block of char *'s, each of which points to a
12349d3bc91SRichard Lowe        file name. */
12449d3bc91SRichard Lowe     char **ret_files = 0;
12549d3bc91SRichard Lowe 
12649d3bc91SRichard Lowe     /* The Dwarf_Debug this die belongs to. */
127*07dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
12849d3bc91SRichard Lowe 
12949d3bc91SRichard Lowe     /* Used to chain the file names. */
130*07dc1947SRichard Lowe     Dwarf_Chain curr_chain = NULL;
131*07dc1947SRichard Lowe     Dwarf_Chain prev_chain = NULL;
132*07dc1947SRichard Lowe     Dwarf_Chain head_chain = NULL;
133*07dc1947SRichard Lowe     Dwarf_Half attrform = 0;
134*07dc1947SRichard Lowe     int resattr = DW_DLV_ERROR;
135*07dc1947SRichard Lowe     int lres = DW_DLV_ERROR;
136*07dc1947SRichard Lowe     struct Line_Table_Prefix_s line_prefix;
137*07dc1947SRichard Lowe     int i = 0;
138*07dc1947SRichard Lowe     int res = DW_DLV_ERROR;
13949d3bc91SRichard Lowe 
14049d3bc91SRichard Lowe     /* ***** BEGIN CODE ***** */
14149d3bc91SRichard Lowe     /* Reset error. */
14249d3bc91SRichard Lowe     if (error != NULL)
14349d3bc91SRichard Lowe         *error = NULL;
14449d3bc91SRichard Lowe 
145*07dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
14649d3bc91SRichard Lowe     dbg = die->di_cu_context->cc_dbg;
14749d3bc91SRichard Lowe 
14849d3bc91SRichard Lowe     resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
14949d3bc91SRichard Lowe     if (resattr != DW_DLV_OK) {
15049d3bc91SRichard Lowe         return resattr;
15149d3bc91SRichard Lowe     }
15249d3bc91SRichard Lowe 
153*07dc1947SRichard Lowe     if (dbg->de_debug_line.dss_index == 0) {
15449d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_NULL);
15549d3bc91SRichard Lowe         return (DW_DLV_ERROR);
15649d3bc91SRichard Lowe     }
15749d3bc91SRichard Lowe 
158*07dc1947SRichard Lowe     res = _dwarf_load_section(dbg, &dbg->de_debug_line,error);
15949d3bc91SRichard Lowe     if (res != DW_DLV_OK) {
16049d3bc91SRichard Lowe         return res;
16149d3bc91SRichard Lowe     }
16249d3bc91SRichard Lowe 
163*07dc1947SRichard Lowe     lres = dwarf_whatform(stmt_list_attr,&attrform,error);
16449d3bc91SRichard Lowe     if (lres != DW_DLV_OK) {
16549d3bc91SRichard Lowe         return lres;
16649d3bc91SRichard Lowe     }
167*07dc1947SRichard Lowe     if (attrform != DW_FORM_data4 && attrform != DW_FORM_data8 &&
168*07dc1947SRichard Lowe         attrform != DW_FORM_sec_offset ) {
16949d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
17049d3bc91SRichard Lowe         return (DW_DLV_ERROR);
17149d3bc91SRichard Lowe     }
172*07dc1947SRichard Lowe     lres = dwarf_global_formref(stmt_list_attr, &line_offset, error);
173*07dc1947SRichard Lowe     if (lres != DW_DLV_OK) {
174*07dc1947SRichard Lowe         return lres;
175*07dc1947SRichard Lowe     }
176*07dc1947SRichard Lowe     if (line_offset >= dbg->de_debug_line.dss_size) {
177*07dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
178*07dc1947SRichard Lowe         return (DW_DLV_ERROR);
179*07dc1947SRichard Lowe     }
180*07dc1947SRichard Lowe     line_ptr = dbg->de_debug_line.dss_data + line_offset;
18149d3bc91SRichard Lowe     dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
18249d3bc91SRichard Lowe 
18349d3bc91SRichard Lowe     /*
18449d3bc91SRichard Lowe        If die has DW_AT_comp_dir attribute, get the string that names
18549d3bc91SRichard Lowe        the compilation directory. */
18649d3bc91SRichard Lowe     resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
18749d3bc91SRichard Lowe     if (resattr == DW_DLV_ERROR) {
18849d3bc91SRichard Lowe         return resattr;
18949d3bc91SRichard Lowe     }
19049d3bc91SRichard Lowe     if (resattr == DW_DLV_OK) {
191*07dc1947SRichard Lowe         int cres = DW_DLV_ERROR;
192*07dc1947SRichard Lowe         char *cdir = 0;
19349d3bc91SRichard Lowe 
19449d3bc91SRichard Lowe         cres = dwarf_formstring(comp_dir_attr, &cdir, error);
19549d3bc91SRichard Lowe         if (cres == DW_DLV_ERROR) {
19649d3bc91SRichard Lowe             return cres;
19749d3bc91SRichard Lowe         } else if (cres == DW_DLV_OK) {
19849d3bc91SRichard Lowe             comp_dir = (Dwarf_Small *) cdir;
19949d3bc91SRichard Lowe         }
20049d3bc91SRichard Lowe     }
20149d3bc91SRichard Lowe     if (resattr == DW_DLV_OK) {
20249d3bc91SRichard Lowe         dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
20349d3bc91SRichard Lowe     }
204*07dc1947SRichard Lowe     dwarf_init_line_table_prefix(&line_prefix);
205*07dc1947SRichard Lowe     {
206*07dc1947SRichard Lowe         Dwarf_Small *line_ptr_out = 0;
207*07dc1947SRichard Lowe         int dres = dwarf_read_line_table_prefix(dbg,
208*07dc1947SRichard Lowe             line_ptr,
209*07dc1947SRichard Lowe             dbg->de_debug_line.dss_size,
210*07dc1947SRichard Lowe             &line_ptr_out,
211*07dc1947SRichard Lowe             &line_prefix,
212*07dc1947SRichard Lowe             NULL, NULL,error,
213*07dc1947SRichard Lowe             0);
21449d3bc91SRichard Lowe 
215*07dc1947SRichard Lowe         if (dres == DW_DLV_ERROR) {
216*07dc1947SRichard Lowe             dwarf_free_line_table_prefix(&line_prefix);
217*07dc1947SRichard Lowe             return dres;
218*07dc1947SRichard Lowe         }
219*07dc1947SRichard Lowe         if (dres == DW_DLV_NO_ENTRY) {
220*07dc1947SRichard Lowe             dwarf_free_line_table_prefix(&line_prefix);
221*07dc1947SRichard Lowe             return dres;
22249d3bc91SRichard Lowe         }
22349d3bc91SRichard Lowe 
224*07dc1947SRichard Lowe         line_ptr = line_ptr_out;
22549d3bc91SRichard Lowe     }
22649d3bc91SRichard Lowe 
227*07dc1947SRichard Lowe     for (i = 0; i < line_prefix.pf_files_count; ++i) {
228*07dc1947SRichard Lowe         struct Line_Table_File_Entry_s *fe =
229*07dc1947SRichard Lowe             line_prefix.pf_line_table_file_entries + i;
230*07dc1947SRichard Lowe         char *file_name = (char *) fe->lte_filename;
231*07dc1947SRichard Lowe         char *dir_name = 0;
232*07dc1947SRichard Lowe         char *full_name = 0;
233*07dc1947SRichard Lowe         Dwarf_Unsigned dir_index = fe->lte_directory_index;
23449d3bc91SRichard Lowe 
235*07dc1947SRichard Lowe         if (dir_index == 0) {
23649d3bc91SRichard Lowe             dir_name = (char *) comp_dir;
237*07dc1947SRichard Lowe         } else {
238*07dc1947SRichard Lowe             dir_name =
239*07dc1947SRichard Lowe                 (char *) line_prefix.pf_include_directories[
240*07dc1947SRichard Lowe                     fe->lte_directory_index - 1];
24149d3bc91SRichard Lowe         }
24249d3bc91SRichard Lowe 
24349d3bc91SRichard Lowe         /* dir_name can be NULL if there is no DW_AT_comp_dir */
244*07dc1947SRichard Lowe         if(dir_name == 0 || file_name_is_full_path((unsigned char *)file_name)) {
245*07dc1947SRichard Lowe             /* This is safe because dwarf_dealloc is careful to not
246*07dc1947SRichard Lowe                dealloc strings which are part of the raw .debug_* data.
247*07dc1947SRichard Lowe              */
24849d3bc91SRichard Lowe             full_name = file_name;
249*07dc1947SRichard Lowe         } else {
25049d3bc91SRichard Lowe             full_name = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING,
25149d3bc91SRichard Lowe                                                   strlen(dir_name) + 1 +
25249d3bc91SRichard Lowe                                                   strlen(file_name) +
25349d3bc91SRichard Lowe                                                   1);
25449d3bc91SRichard Lowe             if (full_name == NULL) {
255*07dc1947SRichard Lowe                 dwarf_free_line_table_prefix(&line_prefix);
25649d3bc91SRichard Lowe                 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
25749d3bc91SRichard Lowe                 return (DW_DLV_ERROR);
25849d3bc91SRichard Lowe             }
25949d3bc91SRichard Lowe 
260*07dc1947SRichard Lowe             /* This is not careful to avoid // in the output, Nothing
261*07dc1947SRichard Lowe                forces a 'canonical' name format here. Unclear if this
262*07dc1947SRichard Lowe                needs to be fixed. */
26349d3bc91SRichard Lowe             strcpy(full_name, dir_name);
26449d3bc91SRichard Lowe             strcat(full_name, "/");
26549d3bc91SRichard Lowe             strcat(full_name, file_name);
26649d3bc91SRichard Lowe         }
26749d3bc91SRichard Lowe         curr_chain =
26849d3bc91SRichard Lowe             (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
26949d3bc91SRichard Lowe         if (curr_chain == NULL) {
270*07dc1947SRichard Lowe             dwarf_free_line_table_prefix(&line_prefix);
27149d3bc91SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
27249d3bc91SRichard Lowe             return (DW_DLV_ERROR);
27349d3bc91SRichard Lowe         }
27449d3bc91SRichard Lowe         curr_chain->ch_item = full_name;
27549d3bc91SRichard Lowe         if (head_chain == NULL)
27649d3bc91SRichard Lowe             head_chain = prev_chain = curr_chain;
27749d3bc91SRichard Lowe         else {
27849d3bc91SRichard Lowe             prev_chain->ch_next = curr_chain;
27949d3bc91SRichard Lowe             prev_chain = curr_chain;
28049d3bc91SRichard Lowe         }
28149d3bc91SRichard Lowe     }
28249d3bc91SRichard Lowe 
283*07dc1947SRichard Lowe     curr_chain = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
284*07dc1947SRichard Lowe     if (curr_chain == NULL) {
285*07dc1947SRichard Lowe         dwarf_free_line_table_prefix(&line_prefix);
28649d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
28749d3bc91SRichard Lowe         return (DW_DLV_ERROR);
28849d3bc91SRichard Lowe     }
28949d3bc91SRichard Lowe 
290*07dc1947SRichard Lowe 
291*07dc1947SRichard Lowe 
292*07dc1947SRichard Lowe 
293*07dc1947SRichard Lowe     if (line_prefix.pf_files_count == 0) {
294*07dc1947SRichard Lowe         *srcfiles = NULL;
295*07dc1947SRichard Lowe         *srcfilecount = 0;
296*07dc1947SRichard Lowe         dwarf_free_line_table_prefix(&line_prefix);
297*07dc1947SRichard Lowe         return (DW_DLV_NO_ENTRY);
298*07dc1947SRichard Lowe     }
299*07dc1947SRichard Lowe 
300*07dc1947SRichard Lowe     ret_files = (char **)
301*07dc1947SRichard Lowe         _dwarf_get_alloc(dbg, DW_DLA_LIST, line_prefix.pf_files_count);
302*07dc1947SRichard Lowe     if (ret_files == NULL) {
303*07dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
304*07dc1947SRichard Lowe         dwarf_free_line_table_prefix(&line_prefix);
305*07dc1947SRichard Lowe         return (DW_DLV_ERROR);
306*07dc1947SRichard Lowe     }
307*07dc1947SRichard Lowe 
30849d3bc91SRichard Lowe     curr_chain = head_chain;
309*07dc1947SRichard Lowe     for (i = 0; i < line_prefix.pf_files_count; i++) {
31049d3bc91SRichard Lowe         *(ret_files + i) = curr_chain->ch_item;
31149d3bc91SRichard Lowe         prev_chain = curr_chain;
31249d3bc91SRichard Lowe         curr_chain = curr_chain->ch_next;
31349d3bc91SRichard Lowe         dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
31449d3bc91SRichard Lowe     }
31549d3bc91SRichard Lowe 
31649d3bc91SRichard Lowe     *srcfiles = ret_files;
317*07dc1947SRichard Lowe     *srcfilecount = line_prefix.pf_files_count;
318*07dc1947SRichard Lowe     dwarf_free_line_table_prefix(&line_prefix);
31949d3bc91SRichard Lowe     return (DW_DLV_OK);
32049d3bc91SRichard Lowe }
32149d3bc91SRichard Lowe 
32249d3bc91SRichard Lowe 
32349d3bc91SRichard Lowe /*
32449d3bc91SRichard Lowe         return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR
32549d3bc91SRichard Lowe */
32649d3bc91SRichard Lowe int
_dwarf_internal_srclines(Dwarf_Die die,Dwarf_Line ** linebuf,Dwarf_Signed * count,Dwarf_Bool doaddrs,Dwarf_Bool dolines,Dwarf_Error * error)32749d3bc91SRichard Lowe _dwarf_internal_srclines(Dwarf_Die die,
32849d3bc91SRichard Lowe     Dwarf_Line ** linebuf,
32949d3bc91SRichard Lowe     Dwarf_Signed * count,
33049d3bc91SRichard Lowe     Dwarf_Bool doaddrs,
33149d3bc91SRichard Lowe     Dwarf_Bool dolines, Dwarf_Error * error)
33249d3bc91SRichard Lowe {
333*07dc1947SRichard Lowe     /* This pointer is used to scan the portion of the .debug_line
33449d3bc91SRichard Lowe        section for the current cu. */
335*07dc1947SRichard Lowe     Dwarf_Small *line_ptr = 0;
33649d3bc91SRichard Lowe 
337*07dc1947SRichard Lowe     /* This points to the last byte of the .debug_line portion for the
33849d3bc91SRichard Lowe        current cu. */
339*07dc1947SRichard Lowe     Dwarf_Small *line_ptr_end = 0;
34049d3bc91SRichard Lowe 
341*07dc1947SRichard Lowe     /* Pointer to a DW_AT_stmt_list attribute in case it exists in the
34249d3bc91SRichard Lowe        die. */
343*07dc1947SRichard Lowe     Dwarf_Attribute stmt_list_attr = 0;
34449d3bc91SRichard Lowe 
34549d3bc91SRichard Lowe     /* Pointer to DW_AT_comp_dir attribute in die. */
346*07dc1947SRichard Lowe     Dwarf_Attribute comp_dir_attr = 0;
34749d3bc91SRichard Lowe 
34849d3bc91SRichard Lowe     /* Pointer to name of compilation directory. */
34949d3bc91SRichard Lowe     Dwarf_Small *comp_dir = NULL;
35049d3bc91SRichard Lowe 
351*07dc1947SRichard Lowe     /* Offset into .debug_line specified by a DW_AT_stmt_list
35249d3bc91SRichard Lowe        attribute. */
353*07dc1947SRichard Lowe     Dwarf_Unsigned line_offset = 0;
35449d3bc91SRichard Lowe 
355*07dc1947SRichard Lowe     Dwarf_File_Entry file_entries = 0;
35649d3bc91SRichard Lowe 
35749d3bc91SRichard Lowe     /* These are the state machine state variables. */
358*07dc1947SRichard Lowe     Dwarf_Addr address = 0;
359*07dc1947SRichard Lowe     Dwarf_Word file = 1;
360*07dc1947SRichard Lowe     Dwarf_Word line = 1;
361*07dc1947SRichard Lowe     Dwarf_Word column = 0;
36249d3bc91SRichard Lowe 
363*07dc1947SRichard Lowe     /* Phony init. See below for true initialization. */
364*07dc1947SRichard Lowe     Dwarf_Bool is_stmt = false;
365*07dc1947SRichard Lowe 
366*07dc1947SRichard Lowe     Dwarf_Bool basic_block = false;
367*07dc1947SRichard Lowe     Dwarf_Bool prologue_end = false;
368*07dc1947SRichard Lowe     Dwarf_Bool epilogue_begin = false;
369*07dc1947SRichard Lowe     Dwarf_Small isa = 0;
370*07dc1947SRichard Lowe     Dwarf_Bool end_sequence = false;
371*07dc1947SRichard Lowe 
372*07dc1947SRichard Lowe     /* These pointers are used to build the list of files names by this
373*07dc1947SRichard Lowe        cu.  cur_file_entry points to the file name being added, and
374*07dc1947SRichard Lowe        prev_file_entry to the previous one. */
37549d3bc91SRichard Lowe     Dwarf_File_Entry cur_file_entry, prev_file_entry;
37649d3bc91SRichard Lowe 
377*07dc1947SRichard Lowe     Dwarf_Sword i = 0;
378*07dc1947SRichard Lowe     Dwarf_Sword file_entry_count = 0;
37949d3bc91SRichard Lowe 
380*07dc1947SRichard Lowe     /* This is the current opcode read from the statement program. */
381*07dc1947SRichard Lowe     Dwarf_Small opcode = 0;
38249d3bc91SRichard Lowe 
383*07dc1947SRichard Lowe     /* Pointer to a Dwarf_Line_Context_s structure that contains the
38449d3bc91SRichard Lowe        context such as file names and include directories for the set
38549d3bc91SRichard Lowe        of lines being generated. */
386*07dc1947SRichard Lowe     Dwarf_Line_Context line_context = 0;
38749d3bc91SRichard Lowe 
388*07dc1947SRichard Lowe     /* This is a pointer to the current line being added to the line
38949d3bc91SRichard Lowe        matrix. */
390*07dc1947SRichard Lowe     Dwarf_Line curr_line = 0;
39149d3bc91SRichard Lowe 
392*07dc1947SRichard Lowe     /* These variables are used to decode leb128 numbers. Leb128_num
39349d3bc91SRichard Lowe        holds the decoded number, and leb128_length is its length in
39449d3bc91SRichard Lowe        bytes. */
395*07dc1947SRichard Lowe     Dwarf_Word leb128_num = 0;
396*07dc1947SRichard Lowe     Dwarf_Word leb128_length = 0;
397*07dc1947SRichard Lowe     Dwarf_Sword advance_line = 0;
39849d3bc91SRichard Lowe 
399*07dc1947SRichard Lowe     /* This is the operand of the latest fixed_advance_pc extended
40049d3bc91SRichard Lowe        opcode. */
401*07dc1947SRichard Lowe     Dwarf_Half fixed_advance_pc = 0;
40249d3bc91SRichard Lowe 
403*07dc1947SRichard Lowe     /* Counts the number of lines in the line matrix. */
40449d3bc91SRichard Lowe     Dwarf_Sword line_count = 0;
40549d3bc91SRichard Lowe 
40649d3bc91SRichard Lowe     /* This is the length of an extended opcode instr.  */
407*07dc1947SRichard Lowe     Dwarf_Word instr_length = 0;
408*07dc1947SRichard Lowe     Dwarf_Small ext_opcode = 0;
409*07dc1947SRichard Lowe     struct Line_Table_Prefix_s prefix;
41049d3bc91SRichard Lowe 
411*07dc1947SRichard Lowe     /* Used to chain together pointers to line table entries that are
41249d3bc91SRichard Lowe        later used to create a block of Dwarf_Line entries. */
413*07dc1947SRichard Lowe     Dwarf_Chain chain_line = NULL;
414*07dc1947SRichard Lowe     Dwarf_Chain head_chain = NULL;
415*07dc1947SRichard Lowe     Dwarf_Chain curr_chain = NULL;
41649d3bc91SRichard Lowe 
417*07dc1947SRichard Lowe     /* This points to a block of Dwarf_Lines, a pointer to which is
41849d3bc91SRichard Lowe        returned in linebuf. */
419*07dc1947SRichard Lowe     Dwarf_Line *block_line = 0;
42049d3bc91SRichard Lowe 
42149d3bc91SRichard Lowe     /* The Dwarf_Debug this die belongs to. */
422*07dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
423*07dc1947SRichard Lowe     int resattr = DW_DLV_ERROR;
424*07dc1947SRichard Lowe     int lres = DW_DLV_ERROR;
425*07dc1947SRichard Lowe     Dwarf_Half address_size = 0;
42649d3bc91SRichard Lowe 
427*07dc1947SRichard Lowe     int res = DW_DLV_ERROR;
42849d3bc91SRichard Lowe 
42949d3bc91SRichard Lowe     /* ***** BEGIN CODE ***** */
43049d3bc91SRichard Lowe     if (error != NULL)
43149d3bc91SRichard Lowe         *error = NULL;
43249d3bc91SRichard Lowe 
433*07dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
43449d3bc91SRichard Lowe     dbg = die->di_cu_context->cc_dbg;
43549d3bc91SRichard Lowe 
436*07dc1947SRichard Lowe     res = _dwarf_load_section(dbg, &dbg->de_debug_line,error);
43749d3bc91SRichard Lowe     if (res != DW_DLV_OK) {
43849d3bc91SRichard Lowe         return res;
43949d3bc91SRichard Lowe     }
440*07dc1947SRichard Lowe     address_size = _dwarf_get_address_size(dbg, die);
44149d3bc91SRichard Lowe     resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
44249d3bc91SRichard Lowe     if (resattr != DW_DLV_OK) {
44349d3bc91SRichard Lowe         return resattr;
44449d3bc91SRichard Lowe     }
44549d3bc91SRichard Lowe 
44649d3bc91SRichard Lowe     lres = dwarf_formudata(stmt_list_attr, &line_offset, error);
44749d3bc91SRichard Lowe     if (lres != DW_DLV_OK) {
44849d3bc91SRichard Lowe         return lres;
44949d3bc91SRichard Lowe     }
45049d3bc91SRichard Lowe 
451*07dc1947SRichard Lowe     if (line_offset >= dbg->de_debug_line.dss_size) {
45249d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
45349d3bc91SRichard Lowe         return (DW_DLV_ERROR);
45449d3bc91SRichard Lowe     }
455*07dc1947SRichard Lowe     line_ptr = dbg->de_debug_line.dss_data + line_offset;
45649d3bc91SRichard Lowe     dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
45749d3bc91SRichard Lowe 
458*07dc1947SRichard Lowe     /* If die has DW_AT_comp_dir attribute, get the string that names
45949d3bc91SRichard Lowe        the compilation directory. */
46049d3bc91SRichard Lowe     resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
46149d3bc91SRichard Lowe     if (resattr == DW_DLV_ERROR) {
46249d3bc91SRichard Lowe         return resattr;
46349d3bc91SRichard Lowe     }
46449d3bc91SRichard Lowe     if (resattr == DW_DLV_OK) {
465*07dc1947SRichard Lowe         int cres = DW_DLV_ERROR;
466*07dc1947SRichard Lowe         char *cdir = 0;
46749d3bc91SRichard Lowe 
46849d3bc91SRichard Lowe         cres = dwarf_formstring(comp_dir_attr, &cdir, error);
46949d3bc91SRichard Lowe         if (cres == DW_DLV_ERROR) {
47049d3bc91SRichard Lowe             return cres;
47149d3bc91SRichard Lowe         } else if (cres == DW_DLV_OK) {
47249d3bc91SRichard Lowe             comp_dir = (Dwarf_Small *) cdir;
47349d3bc91SRichard Lowe         }
47449d3bc91SRichard Lowe     }
47549d3bc91SRichard Lowe     if (resattr == DW_DLV_OK) {
47649d3bc91SRichard Lowe         dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
47749d3bc91SRichard Lowe     }
478*07dc1947SRichard Lowe     dwarf_init_line_table_prefix(&prefix);
47949d3bc91SRichard Lowe 
480*07dc1947SRichard Lowe     {
481*07dc1947SRichard Lowe         Dwarf_Small *newlinep = 0;
482*07dc1947SRichard Lowe         int res = dwarf_read_line_table_prefix(dbg,
483*07dc1947SRichard Lowe             line_ptr,
484*07dc1947SRichard Lowe             dbg->de_debug_line.dss_size,
485*07dc1947SRichard Lowe             &newlinep,
486*07dc1947SRichard Lowe             &prefix,
487*07dc1947SRichard Lowe             NULL,NULL,
488*07dc1947SRichard Lowe             error,
489*07dc1947SRichard Lowe             0);
49049d3bc91SRichard Lowe 
491*07dc1947SRichard Lowe         if (res == DW_DLV_ERROR) {
492*07dc1947SRichard Lowe             dwarf_free_line_table_prefix(&prefix);
493*07dc1947SRichard Lowe             return res;
494*07dc1947SRichard Lowe         }
495*07dc1947SRichard Lowe         if (res == DW_DLV_NO_ENTRY) {
496*07dc1947SRichard Lowe             dwarf_free_line_table_prefix(&prefix);
497*07dc1947SRichard Lowe             return res;
498*07dc1947SRichard Lowe         }
499*07dc1947SRichard Lowe         line_ptr_end = prefix.pf_line_ptr_end;
500*07dc1947SRichard Lowe         line_ptr = newlinep;
50149d3bc91SRichard Lowe     }
50249d3bc91SRichard Lowe 
50349d3bc91SRichard Lowe 
504*07dc1947SRichard Lowe     /* Set up context structure for this set of lines. */
505*07dc1947SRichard Lowe     line_context = (Dwarf_Line_Context)
506*07dc1947SRichard Lowe         _dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1);
507*07dc1947SRichard Lowe     if (line_context == NULL) {
508*07dc1947SRichard Lowe         dwarf_free_line_table_prefix(&prefix);
50949d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
51049d3bc91SRichard Lowe         return (DW_DLV_ERROR);
51149d3bc91SRichard Lowe     }
51249d3bc91SRichard Lowe 
513*07dc1947SRichard Lowe     /* Fill out a Dwarf_File_Entry list as we use that to implement the
514*07dc1947SRichard Lowe        define_file operation. */
515*07dc1947SRichard Lowe     file_entries = prev_file_entry = NULL;
516*07dc1947SRichard Lowe     for (i = 0; i < prefix.pf_files_count; ++i) {
517*07dc1947SRichard Lowe         struct Line_Table_File_Entry_s *pfxfile =
518*07dc1947SRichard Lowe             prefix.pf_line_table_file_entries + i;
51949d3bc91SRichard Lowe 
520*07dc1947SRichard Lowe         cur_file_entry = (Dwarf_File_Entry)
521*07dc1947SRichard Lowe             _dwarf_get_alloc(dbg, DW_DLA_FILE_ENTRY, 1);
522*07dc1947SRichard Lowe         if (cur_file_entry == NULL) {
523*07dc1947SRichard Lowe             dwarf_free_line_table_prefix(&prefix);
524*07dc1947SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
525*07dc1947SRichard Lowe             return (DW_DLV_ERROR);
526*07dc1947SRichard Lowe         }
52749d3bc91SRichard Lowe 
528*07dc1947SRichard Lowe         cur_file_entry->fi_file_name = pfxfile->lte_filename;
529*07dc1947SRichard Lowe         cur_file_entry->fi_dir_index = pfxfile->lte_directory_index;
53049d3bc91SRichard Lowe         cur_file_entry->fi_time_last_mod =
531*07dc1947SRichard Lowe             pfxfile->lte_last_modification_time;
53249d3bc91SRichard Lowe 
533*07dc1947SRichard Lowe         cur_file_entry->fi_file_length = pfxfile->lte_length_of_file;
53449d3bc91SRichard Lowe 
53549d3bc91SRichard Lowe         if (file_entries == NULL)
53649d3bc91SRichard Lowe             file_entries = cur_file_entry;
53749d3bc91SRichard Lowe         else
53849d3bc91SRichard Lowe             prev_file_entry->fi_next = cur_file_entry;
53949d3bc91SRichard Lowe         prev_file_entry = cur_file_entry;
54049d3bc91SRichard Lowe 
54149d3bc91SRichard Lowe         file_entry_count++;
54249d3bc91SRichard Lowe     }
54349d3bc91SRichard Lowe 
54449d3bc91SRichard Lowe 
545*07dc1947SRichard Lowe     /* Initialize the one state machine variable that depends on the
546*07dc1947SRichard Lowe        prefix.  */
547*07dc1947SRichard Lowe     is_stmt = prefix.pf_default_is_stmt;
54849d3bc91SRichard Lowe 
54949d3bc91SRichard Lowe 
55049d3bc91SRichard Lowe     /* Start of statement program.  */
55149d3bc91SRichard Lowe     while (line_ptr < line_ptr_end) {
55249d3bc91SRichard Lowe         int type;
55349d3bc91SRichard Lowe 
55449d3bc91SRichard Lowe         opcode = *(Dwarf_Small *) line_ptr;
55549d3bc91SRichard Lowe         line_ptr++;
55649d3bc91SRichard Lowe 
55749d3bc91SRichard Lowe 
55849d3bc91SRichard Lowe         /* 'type' is the output */
559*07dc1947SRichard Lowe         WHAT_IS_OPCODE(type, opcode, prefix.pf_opcode_base,
560*07dc1947SRichard Lowe                        prefix.pf_opcode_length_table, line_ptr,
561*07dc1947SRichard Lowe                        prefix.pf_std_op_count);
56249d3bc91SRichard Lowe 
56349d3bc91SRichard Lowe         if (type == LOP_DISCARD) {
564*07dc1947SRichard Lowe             int oc;
565*07dc1947SRichard Lowe             int opcnt = prefix.pf_opcode_length_table[opcode];
566*07dc1947SRichard Lowe 
567*07dc1947SRichard Lowe             for (oc = 0; oc < opcnt; oc++) {
568*07dc1947SRichard Lowe                 /*
569*07dc1947SRichard Lowe                  ** Read and discard operands we don't
570*07dc1947SRichard Lowe                  ** understand.
571*07dc1947SRichard Lowe                  ** arbitrary choice of unsigned read.
572*07dc1947SRichard Lowe                  ** signed read would work as well.
573*07dc1947SRichard Lowe                  */
574*07dc1947SRichard Lowe                 Dwarf_Unsigned utmp2;
575*07dc1947SRichard Lowe 
576*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(line_ptr, utmp2);
577*07dc1947SRichard Lowe             }
57849d3bc91SRichard Lowe         } else if (type == LOP_SPECIAL) {
57949d3bc91SRichard Lowe             /* This op code is a special op in the object, no matter
58049d3bc91SRichard Lowe                that it might fall into the standard op range in this
581*07dc1947SRichard Lowe                compile. That is, these are special opcodes between
582*07dc1947SRichard Lowe                opcode_base and MAX_LINE_OP_CODE.  (including
583*07dc1947SRichard Lowe                opcode_base and MAX_LINE_OP_CODE) */
58449d3bc91SRichard Lowe 
585*07dc1947SRichard Lowe             opcode = opcode - prefix.pf_opcode_base;
586*07dc1947SRichard Lowe             address = address + prefix.pf_minimum_instruction_length *
587*07dc1947SRichard Lowe                 (opcode / prefix.pf_line_range);
588*07dc1947SRichard Lowe             line =
589*07dc1947SRichard Lowe                 line + prefix.pf_line_base +
590*07dc1947SRichard Lowe                 opcode % prefix.pf_line_range;
59149d3bc91SRichard Lowe 
59249d3bc91SRichard Lowe             if (dolines) {
59349d3bc91SRichard Lowe                 curr_line =
59449d3bc91SRichard Lowe                     (Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1);
59549d3bc91SRichard Lowe                 if (curr_line == NULL) {
596*07dc1947SRichard Lowe                     dwarf_free_line_table_prefix(&prefix);
59749d3bc91SRichard Lowe                     _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
59849d3bc91SRichard Lowe                     return (DW_DLV_ERROR);
59949d3bc91SRichard Lowe                 }
60049d3bc91SRichard Lowe 
60149d3bc91SRichard Lowe                 curr_line->li_address = address;
60249d3bc91SRichard Lowe                 curr_line->li_addr_line.li_l_data.li_file =
60349d3bc91SRichard Lowe                     (Dwarf_Sword) file;
60449d3bc91SRichard Lowe                 curr_line->li_addr_line.li_l_data.li_line =
60549d3bc91SRichard Lowe                     (Dwarf_Sword) line;
60649d3bc91SRichard Lowe                 curr_line->li_addr_line.li_l_data.li_column =
60749d3bc91SRichard Lowe                     (Dwarf_Half) column;
60849d3bc91SRichard Lowe                 curr_line->li_addr_line.li_l_data.li_is_stmt = is_stmt;
60949d3bc91SRichard Lowe                 curr_line->li_addr_line.li_l_data.li_basic_block =
61049d3bc91SRichard Lowe                     basic_block;
61149d3bc91SRichard Lowe                 curr_line->li_addr_line.li_l_data.li_end_sequence =
612*07dc1947SRichard Lowe                     curr_line->li_addr_line.li_l_data.
613*07dc1947SRichard Lowe                     li_epilogue_begin = epilogue_begin;
614*07dc1947SRichard Lowe                 curr_line->li_addr_line.li_l_data.li_prologue_end =
615*07dc1947SRichard Lowe                     prologue_end;
616*07dc1947SRichard Lowe                 curr_line->li_addr_line.li_l_data.li_isa = isa;
61749d3bc91SRichard Lowe                 curr_line->li_context = line_context;
61849d3bc91SRichard Lowe                 line_count++;
61949d3bc91SRichard Lowe 
62049d3bc91SRichard Lowe                 chain_line = (Dwarf_Chain)
62149d3bc91SRichard Lowe                     _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
62249d3bc91SRichard Lowe                 if (chain_line == NULL) {
623*07dc1947SRichard Lowe                     dwarf_free_line_table_prefix(&prefix);
62449d3bc91SRichard Lowe                     _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
62549d3bc91SRichard Lowe                     return (DW_DLV_ERROR);
62649d3bc91SRichard Lowe                 }
62749d3bc91SRichard Lowe                 chain_line->ch_item = curr_line;
62849d3bc91SRichard Lowe 
62949d3bc91SRichard Lowe                 if (head_chain == NULL)
63049d3bc91SRichard Lowe                     head_chain = curr_chain = chain_line;
63149d3bc91SRichard Lowe                 else {
63249d3bc91SRichard Lowe                     curr_chain->ch_next = chain_line;
63349d3bc91SRichard Lowe                     curr_chain = chain_line;
63449d3bc91SRichard Lowe                 }
63549d3bc91SRichard Lowe             }
63649d3bc91SRichard Lowe 
63749d3bc91SRichard Lowe             basic_block = false;
63849d3bc91SRichard Lowe         } else if (type == LOP_STANDARD) {
63949d3bc91SRichard Lowe             switch (opcode) {
64049d3bc91SRichard Lowe 
64149d3bc91SRichard Lowe             case DW_LNS_copy:{
64249d3bc91SRichard Lowe                     if (dolines) {
64349d3bc91SRichard Lowe 
64449d3bc91SRichard Lowe                         curr_line =
64549d3bc91SRichard Lowe                             (Dwarf_Line) _dwarf_get_alloc(dbg,
64649d3bc91SRichard Lowe                                                           DW_DLA_LINE,
64749d3bc91SRichard Lowe                                                           1);
64849d3bc91SRichard Lowe                         if (curr_line == NULL) {
649*07dc1947SRichard Lowe                             dwarf_free_line_table_prefix(&prefix);
65049d3bc91SRichard Lowe                             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
65149d3bc91SRichard Lowe                             return (DW_DLV_ERROR);
65249d3bc91SRichard Lowe                         }
65349d3bc91SRichard Lowe 
65449d3bc91SRichard Lowe                         curr_line->li_address = address;
65549d3bc91SRichard Lowe                         curr_line->li_addr_line.li_l_data.li_file =
65649d3bc91SRichard Lowe                             (Dwarf_Sword) file;
65749d3bc91SRichard Lowe                         curr_line->li_addr_line.li_l_data.li_line =
65849d3bc91SRichard Lowe                             (Dwarf_Sword) line;
65949d3bc91SRichard Lowe                         curr_line->li_addr_line.li_l_data.li_column =
66049d3bc91SRichard Lowe                             (Dwarf_Half) column;
66149d3bc91SRichard Lowe                         curr_line->li_addr_line.li_l_data.li_is_stmt =
66249d3bc91SRichard Lowe                             is_stmt;
66349d3bc91SRichard Lowe                         curr_line->li_addr_line.li_l_data.
66449d3bc91SRichard Lowe                             li_basic_block = basic_block;
66549d3bc91SRichard Lowe                         curr_line->li_addr_line.li_l_data.
66649d3bc91SRichard Lowe                             li_end_sequence = end_sequence;
66749d3bc91SRichard Lowe                         curr_line->li_context = line_context;
668*07dc1947SRichard Lowe                         curr_line->li_addr_line.li_l_data.
669*07dc1947SRichard Lowe                             li_epilogue_begin = epilogue_begin;
670*07dc1947SRichard Lowe                         curr_line->li_addr_line.li_l_data.
671*07dc1947SRichard Lowe                             li_prologue_end = prologue_end;
672*07dc1947SRichard Lowe                         curr_line->li_addr_line.li_l_data.li_isa = isa;
67349d3bc91SRichard Lowe                         line_count++;
67449d3bc91SRichard Lowe 
67549d3bc91SRichard Lowe                         chain_line = (Dwarf_Chain)
67649d3bc91SRichard Lowe                             _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
67749d3bc91SRichard Lowe                         if (chain_line == NULL) {
678*07dc1947SRichard Lowe                             dwarf_free_line_table_prefix(&prefix);
67949d3bc91SRichard Lowe                             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
68049d3bc91SRichard Lowe                             return (DW_DLV_ERROR);
68149d3bc91SRichard Lowe                         }
68249d3bc91SRichard Lowe                         chain_line->ch_item = curr_line;
68349d3bc91SRichard Lowe                         if (head_chain == NULL)
68449d3bc91SRichard Lowe                             head_chain = curr_chain = chain_line;
68549d3bc91SRichard Lowe                         else {
68649d3bc91SRichard Lowe                             curr_chain->ch_next = chain_line;
68749d3bc91SRichard Lowe                             curr_chain = chain_line;
68849d3bc91SRichard Lowe                         }
68949d3bc91SRichard Lowe                     }
69049d3bc91SRichard Lowe 
69149d3bc91SRichard Lowe                     basic_block = false;
692*07dc1947SRichard Lowe                     prologue_end = false;
693*07dc1947SRichard Lowe                     epilogue_begin = false;
69449d3bc91SRichard Lowe                     break;
69549d3bc91SRichard Lowe                 }
69649d3bc91SRichard Lowe 
69749d3bc91SRichard Lowe             case DW_LNS_advance_pc:{
69849d3bc91SRichard Lowe                     Dwarf_Unsigned utmp2;
69949d3bc91SRichard Lowe 
700*07dc1947SRichard Lowe                     DECODE_LEB128_UWORD(line_ptr, utmp2);
70149d3bc91SRichard Lowe                     leb128_num = (Dwarf_Word) utmp2;
70249d3bc91SRichard Lowe                     address =
70349d3bc91SRichard Lowe                         address +
704*07dc1947SRichard Lowe                         prefix.pf_minimum_instruction_length *
705*07dc1947SRichard Lowe                         leb128_num;
70649d3bc91SRichard Lowe                     break;
70749d3bc91SRichard Lowe                 }
70849d3bc91SRichard Lowe 
70949d3bc91SRichard Lowe             case DW_LNS_advance_line:{
71049d3bc91SRichard Lowe                     Dwarf_Signed stmp;
71149d3bc91SRichard Lowe 
712*07dc1947SRichard Lowe                     DECODE_LEB128_SWORD(line_ptr, stmp);
71349d3bc91SRichard Lowe                     advance_line = (Dwarf_Sword) stmp;
71449d3bc91SRichard Lowe                     line = line + advance_line;
71549d3bc91SRichard Lowe                     break;
71649d3bc91SRichard Lowe                 }
71749d3bc91SRichard Lowe 
71849d3bc91SRichard Lowe             case DW_LNS_set_file:{
71949d3bc91SRichard Lowe                     Dwarf_Unsigned utmp2;
72049d3bc91SRichard Lowe 
721*07dc1947SRichard Lowe                     DECODE_LEB128_UWORD(line_ptr, utmp2);
72249d3bc91SRichard Lowe                     file = (Dwarf_Word) utmp2;
72349d3bc91SRichard Lowe                     break;
72449d3bc91SRichard Lowe                 }
72549d3bc91SRichard Lowe 
72649d3bc91SRichard Lowe             case DW_LNS_set_column:{
72749d3bc91SRichard Lowe                     Dwarf_Unsigned utmp2;
72849d3bc91SRichard Lowe 
729*07dc1947SRichard Lowe                     DECODE_LEB128_UWORD(line_ptr, utmp2);
73049d3bc91SRichard Lowe                     column = (Dwarf_Word) utmp2;
73149d3bc91SRichard Lowe                     break;
73249d3bc91SRichard Lowe                 }
73349d3bc91SRichard Lowe 
73449d3bc91SRichard Lowe             case DW_LNS_negate_stmt:{
73549d3bc91SRichard Lowe 
73649d3bc91SRichard Lowe                     is_stmt = !is_stmt;
73749d3bc91SRichard Lowe                     break;
73849d3bc91SRichard Lowe                 }
73949d3bc91SRichard Lowe 
74049d3bc91SRichard Lowe             case DW_LNS_set_basic_block:{
74149d3bc91SRichard Lowe 
74249d3bc91SRichard Lowe                     basic_block = true;
74349d3bc91SRichard Lowe                     break;
74449d3bc91SRichard Lowe                 }
74549d3bc91SRichard Lowe 
74649d3bc91SRichard Lowe             case DW_LNS_const_add_pc:{
747*07dc1947SRichard Lowe                     opcode = MAX_LINE_OP_CODE - prefix.pf_opcode_base;
748*07dc1947SRichard Lowe                     address = address +
749*07dc1947SRichard Lowe                         prefix.pf_minimum_instruction_length * (opcode /
750*07dc1947SRichard Lowe                             prefix.
751*07dc1947SRichard Lowe                             pf_line_range);
75249d3bc91SRichard Lowe                     break;
75349d3bc91SRichard Lowe                 }
75449d3bc91SRichard Lowe 
75549d3bc91SRichard Lowe             case DW_LNS_fixed_advance_pc:{
75649d3bc91SRichard Lowe 
75749d3bc91SRichard Lowe                     READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half,
75849d3bc91SRichard Lowe                                    line_ptr, sizeof(Dwarf_Half));
75949d3bc91SRichard Lowe                     line_ptr += sizeof(Dwarf_Half);
76049d3bc91SRichard Lowe                     address = address + fixed_advance_pc;
76149d3bc91SRichard Lowe                     break;
76249d3bc91SRichard Lowe                 }
763*07dc1947SRichard Lowe 
764*07dc1947SRichard Lowe                 /* New in DWARF3 */
765*07dc1947SRichard Lowe             case DW_LNS_set_prologue_end:{
766*07dc1947SRichard Lowe 
767*07dc1947SRichard Lowe                     prologue_end = true;
768*07dc1947SRichard Lowe                     break;
769*07dc1947SRichard Lowe 
770*07dc1947SRichard Lowe 
771*07dc1947SRichard Lowe                 }
772*07dc1947SRichard Lowe                 /* New in DWARF3 */
773*07dc1947SRichard Lowe             case DW_LNS_set_epilogue_begin:{
774*07dc1947SRichard Lowe                     epilogue_begin = true;
775*07dc1947SRichard Lowe                     break;
776*07dc1947SRichard Lowe                 }
777*07dc1947SRichard Lowe 
778*07dc1947SRichard Lowe                 /* New in DWARF3 */
779*07dc1947SRichard Lowe             case DW_LNS_set_isa:{
780*07dc1947SRichard Lowe                     Dwarf_Unsigned utmp2;
781*07dc1947SRichard Lowe 
782*07dc1947SRichard Lowe                     DECODE_LEB128_UWORD(line_ptr, utmp2);
783*07dc1947SRichard Lowe                     isa = utmp2;
784*07dc1947SRichard Lowe                     if (isa != utmp2) {
785*07dc1947SRichard Lowe                         /* The value of the isa did not fit in our
786*07dc1947SRichard Lowe                            local so we record it wrong. declare an
787*07dc1947SRichard Lowe                            error. */
788*07dc1947SRichard Lowe                         dwarf_free_line_table_prefix(&prefix);
789*07dc1947SRichard Lowe 
790*07dc1947SRichard Lowe                         _dwarf_error(dbg, error,
791*07dc1947SRichard Lowe                                      DW_DLE_LINE_NUM_OPERANDS_BAD);
792*07dc1947SRichard Lowe                         return (DW_DLV_ERROR);
793*07dc1947SRichard Lowe                     }
794*07dc1947SRichard Lowe                     break;
795*07dc1947SRichard Lowe                 }
79649d3bc91SRichard Lowe             }
79749d3bc91SRichard Lowe 
79849d3bc91SRichard Lowe         } else if (type == LOP_EXTENDED) {
79949d3bc91SRichard Lowe             Dwarf_Unsigned utmp3;
80049d3bc91SRichard Lowe 
801*07dc1947SRichard Lowe             DECODE_LEB128_UWORD(line_ptr, utmp3);
80249d3bc91SRichard Lowe             instr_length = (Dwarf_Word) utmp3;
803*07dc1947SRichard Lowe             /* Dwarf_Small is a ubyte and the extended opcode is a
804*07dc1947SRichard Lowe                ubyte, though not stated as clearly in the 2.0.0 spec as
805*07dc1947SRichard Lowe                one might hope. */
80649d3bc91SRichard Lowe             ext_opcode = *(Dwarf_Small *) line_ptr;
80749d3bc91SRichard Lowe             line_ptr++;
80849d3bc91SRichard Lowe             switch (ext_opcode) {
80949d3bc91SRichard Lowe 
81049d3bc91SRichard Lowe             case DW_LNE_end_sequence:{
81149d3bc91SRichard Lowe                     end_sequence = true;
81249d3bc91SRichard Lowe 
81349d3bc91SRichard Lowe                     if (dolines) {
81449d3bc91SRichard Lowe                         curr_line = (Dwarf_Line)
81549d3bc91SRichard Lowe                             _dwarf_get_alloc(dbg, DW_DLA_LINE, 1);
81649d3bc91SRichard Lowe                         if (curr_line == NULL) {
817*07dc1947SRichard Lowe                             dwarf_free_line_table_prefix(&prefix);
81849d3bc91SRichard Lowe                             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
81949d3bc91SRichard Lowe                             return (DW_DLV_ERROR);
82049d3bc91SRichard Lowe                         }
82149d3bc91SRichard Lowe 
82249d3bc91SRichard Lowe                         curr_line->li_address = address;
82349d3bc91SRichard Lowe                         curr_line->li_addr_line.li_l_data.li_file =
82449d3bc91SRichard Lowe                             (Dwarf_Sword) file;
82549d3bc91SRichard Lowe                         curr_line->li_addr_line.li_l_data.li_line =
82649d3bc91SRichard Lowe                             (Dwarf_Sword) line;
82749d3bc91SRichard Lowe                         curr_line->li_addr_line.li_l_data.li_column =
82849d3bc91SRichard Lowe                             (Dwarf_Half) column;
82949d3bc91SRichard Lowe                         curr_line->li_addr_line.li_l_data.li_is_stmt =
830*07dc1947SRichard Lowe                             prefix.pf_default_is_stmt;
83149d3bc91SRichard Lowe                         curr_line->li_addr_line.li_l_data.
83249d3bc91SRichard Lowe                             li_basic_block = basic_block;
83349d3bc91SRichard Lowe                         curr_line->li_addr_line.li_l_data.
83449d3bc91SRichard Lowe                             li_end_sequence = end_sequence;
83549d3bc91SRichard Lowe                         curr_line->li_context = line_context;
836*07dc1947SRichard Lowe                         curr_line->li_addr_line.li_l_data.
837*07dc1947SRichard Lowe                             li_epilogue_begin = epilogue_begin;
838*07dc1947SRichard Lowe                         curr_line->li_addr_line.li_l_data.
839*07dc1947SRichard Lowe                             li_prologue_end = prologue_end;
840*07dc1947SRichard Lowe                         curr_line->li_addr_line.li_l_data.li_isa = isa;
84149d3bc91SRichard Lowe                         line_count++;
84249d3bc91SRichard Lowe 
84349d3bc91SRichard Lowe                         chain_line = (Dwarf_Chain)
84449d3bc91SRichard Lowe                             _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
84549d3bc91SRichard Lowe                         if (chain_line == NULL) {
846*07dc1947SRichard Lowe                             dwarf_free_line_table_prefix(&prefix);
84749d3bc91SRichard Lowe                             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
84849d3bc91SRichard Lowe                             return (DW_DLV_ERROR);
84949d3bc91SRichard Lowe                         }
85049d3bc91SRichard Lowe                         chain_line->ch_item = curr_line;
85149d3bc91SRichard Lowe 
85249d3bc91SRichard Lowe                         if (head_chain == NULL)
85349d3bc91SRichard Lowe                             head_chain = curr_chain = chain_line;
85449d3bc91SRichard Lowe                         else {
85549d3bc91SRichard Lowe                             curr_chain->ch_next = chain_line;
85649d3bc91SRichard Lowe                             curr_chain = chain_line;
85749d3bc91SRichard Lowe                         }
85849d3bc91SRichard Lowe                     }
85949d3bc91SRichard Lowe 
86049d3bc91SRichard Lowe                     address = 0;
86149d3bc91SRichard Lowe                     file = 1;
86249d3bc91SRichard Lowe                     line = 1;
86349d3bc91SRichard Lowe                     column = 0;
864*07dc1947SRichard Lowe                     is_stmt = prefix.pf_default_is_stmt;
86549d3bc91SRichard Lowe                     basic_block = false;
86649d3bc91SRichard Lowe                     end_sequence = false;
867*07dc1947SRichard Lowe                     prologue_end = false;
868*07dc1947SRichard Lowe                     epilogue_begin = false;
869*07dc1947SRichard Lowe 
87049d3bc91SRichard Lowe 
87149d3bc91SRichard Lowe                     break;
87249d3bc91SRichard Lowe                 }
87349d3bc91SRichard Lowe 
87449d3bc91SRichard Lowe             case DW_LNE_set_address:{
875*07dc1947SRichard Lowe                     {
87649d3bc91SRichard Lowe                         READ_UNALIGNED(dbg, address, Dwarf_Addr,
877*07dc1947SRichard Lowe                                        line_ptr, address_size);
87849d3bc91SRichard Lowe                         if (doaddrs) {
87949d3bc91SRichard Lowe                             curr_line =
88049d3bc91SRichard Lowe                                 (Dwarf_Line) _dwarf_get_alloc(dbg,
88149d3bc91SRichard Lowe                                                               DW_DLA_LINE,
88249d3bc91SRichard Lowe                                                               1);
88349d3bc91SRichard Lowe                             if (curr_line == NULL) {
884*07dc1947SRichard Lowe                                 dwarf_free_line_table_prefix(&prefix);
88549d3bc91SRichard Lowe                                 _dwarf_error(dbg, error,
88649d3bc91SRichard Lowe                                              DW_DLE_ALLOC_FAIL);
88749d3bc91SRichard Lowe                                 return (DW_DLV_ERROR);
88849d3bc91SRichard Lowe                             }
88949d3bc91SRichard Lowe 
89049d3bc91SRichard Lowe                             curr_line->li_address = address;
89149d3bc91SRichard Lowe                             curr_line->li_addr_line.li_offset =
892*07dc1947SRichard Lowe                                 line_ptr - dbg->de_debug_line.dss_data;
89349d3bc91SRichard Lowe 
89449d3bc91SRichard Lowe                             line_count++;
89549d3bc91SRichard Lowe 
89649d3bc91SRichard Lowe                             chain_line = (Dwarf_Chain)
89749d3bc91SRichard Lowe                                 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
89849d3bc91SRichard Lowe                             if (chain_line == NULL) {
899*07dc1947SRichard Lowe                                 dwarf_free_line_table_prefix(&prefix);
90049d3bc91SRichard Lowe                                 _dwarf_error(dbg, error,
90149d3bc91SRichard Lowe                                              DW_DLE_ALLOC_FAIL);
90249d3bc91SRichard Lowe                                 return (DW_DLV_ERROR);
90349d3bc91SRichard Lowe                             }
90449d3bc91SRichard Lowe                             chain_line->ch_item = curr_line;
90549d3bc91SRichard Lowe 
90649d3bc91SRichard Lowe                             if (head_chain == NULL)
90749d3bc91SRichard Lowe                                 head_chain = curr_chain = chain_line;
90849d3bc91SRichard Lowe                             else {
90949d3bc91SRichard Lowe                                 curr_chain->ch_next = chain_line;
91049d3bc91SRichard Lowe                                 curr_chain = chain_line;
91149d3bc91SRichard Lowe                             }
91249d3bc91SRichard Lowe                         }
91349d3bc91SRichard Lowe 
914*07dc1947SRichard Lowe                         line_ptr += address_size;
91549d3bc91SRichard Lowe                     }
91649d3bc91SRichard Lowe 
91749d3bc91SRichard Lowe                     break;
91849d3bc91SRichard Lowe                 }
91949d3bc91SRichard Lowe 
92049d3bc91SRichard Lowe             case DW_LNE_define_file:{
92149d3bc91SRichard Lowe 
92249d3bc91SRichard Lowe                     if (dolines) {
92349d3bc91SRichard Lowe                         cur_file_entry = (Dwarf_File_Entry)
92449d3bc91SRichard Lowe                             _dwarf_get_alloc(dbg, DW_DLA_FILE_ENTRY, 1);
92549d3bc91SRichard Lowe                         if (cur_file_entry == NULL) {
926*07dc1947SRichard Lowe                             dwarf_free_line_table_prefix(&prefix);
92749d3bc91SRichard Lowe                             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
92849d3bc91SRichard Lowe                             return (DW_DLV_ERROR);
92949d3bc91SRichard Lowe                         }
93049d3bc91SRichard Lowe 
93149d3bc91SRichard Lowe                         cur_file_entry->fi_file_name =
93249d3bc91SRichard Lowe                             (Dwarf_Small *) line_ptr;
93349d3bc91SRichard Lowe                         line_ptr =
93449d3bc91SRichard Lowe                             line_ptr + strlen((char *) line_ptr) + 1;
93549d3bc91SRichard Lowe 
936*07dc1947SRichard Lowe                         cur_file_entry->fi_dir_index = (Dwarf_Sword)
93749d3bc91SRichard Lowe                             _dwarf_decode_u_leb128(line_ptr,
93849d3bc91SRichard Lowe                                                    &leb128_length);
93949d3bc91SRichard Lowe                         line_ptr = line_ptr + leb128_length;
94049d3bc91SRichard Lowe 
94149d3bc91SRichard Lowe                         cur_file_entry->fi_time_last_mod =
94249d3bc91SRichard Lowe                             _dwarf_decode_u_leb128(line_ptr,
94349d3bc91SRichard Lowe                                                    &leb128_length);
94449d3bc91SRichard Lowe                         line_ptr = line_ptr + leb128_length;
94549d3bc91SRichard Lowe 
94649d3bc91SRichard Lowe                         cur_file_entry->fi_file_length =
94749d3bc91SRichard Lowe                             _dwarf_decode_u_leb128(line_ptr,
94849d3bc91SRichard Lowe                                                    &leb128_length);
94949d3bc91SRichard Lowe                         line_ptr = line_ptr + leb128_length;
95049d3bc91SRichard Lowe 
95149d3bc91SRichard Lowe                         if (file_entries == NULL)
95249d3bc91SRichard Lowe                             file_entries = cur_file_entry;
95349d3bc91SRichard Lowe                         else
95449d3bc91SRichard Lowe                             prev_file_entry->fi_next = cur_file_entry;
95549d3bc91SRichard Lowe                         prev_file_entry = cur_file_entry;
95649d3bc91SRichard Lowe 
95749d3bc91SRichard Lowe                         file_entry_count++;
95849d3bc91SRichard Lowe                     }
95949d3bc91SRichard Lowe                     break;
96049d3bc91SRichard Lowe                 }
96149d3bc91SRichard Lowe 
96249d3bc91SRichard Lowe             default:{
963*07dc1947SRichard Lowe                  /* This is an extended op code we do not know about,
964*07dc1947SRichard Lowe                     other than we know now many bytes it is
965*07dc1947SRichard Lowe                     and the op code and the bytes of operand. */
966*07dc1947SRichard Lowe                  Dwarf_Unsigned remaining_bytes = instr_length -1;
967*07dc1947SRichard Lowe                  if(instr_length < 1 || remaining_bytes > DW_LNE_LEN_MAX) {
968*07dc1947SRichard Lowe                       dwarf_free_line_table_prefix(&prefix);
96949d3bc91SRichard Lowe                       _dwarf_error(dbg, error,
97049d3bc91SRichard Lowe                                  DW_DLE_LINE_EXT_OPCODE_BAD);
97149d3bc91SRichard Lowe                       return (DW_DLV_ERROR);
97249d3bc91SRichard Lowe                  }
973*07dc1947SRichard Lowe                  line_ptr += remaining_bytes;
974*07dc1947SRichard Lowe                  break;
975*07dc1947SRichard Lowe                 }
97649d3bc91SRichard Lowe             }
97749d3bc91SRichard Lowe 
97849d3bc91SRichard Lowe         }
97949d3bc91SRichard Lowe     }
98049d3bc91SRichard Lowe 
98149d3bc91SRichard Lowe     block_line = (Dwarf_Line *)
98249d3bc91SRichard Lowe         _dwarf_get_alloc(dbg, DW_DLA_LIST, line_count);
98349d3bc91SRichard Lowe     if (block_line == NULL) {
984*07dc1947SRichard Lowe         dwarf_free_line_table_prefix(&prefix);
98549d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
98649d3bc91SRichard Lowe         return (DW_DLV_ERROR);
98749d3bc91SRichard Lowe     }
98849d3bc91SRichard Lowe 
98949d3bc91SRichard Lowe     curr_chain = head_chain;
99049d3bc91SRichard Lowe     for (i = 0; i < line_count; i++) {
99149d3bc91SRichard Lowe         *(block_line + i) = curr_chain->ch_item;
99249d3bc91SRichard Lowe         head_chain = curr_chain;
99349d3bc91SRichard Lowe         curr_chain = curr_chain->ch_next;
99449d3bc91SRichard Lowe         dwarf_dealloc(dbg, head_chain, DW_DLA_CHAIN);
99549d3bc91SRichard Lowe     }
99649d3bc91SRichard Lowe 
99749d3bc91SRichard Lowe     line_context->lc_file_entries = file_entries;
99849d3bc91SRichard Lowe     line_context->lc_file_entry_count = file_entry_count;
99949d3bc91SRichard Lowe     line_context->lc_include_directories_count =
1000*07dc1947SRichard Lowe         prefix.pf_include_directories_count;
1001*07dc1947SRichard Lowe     if (prefix.pf_include_directories_count > 0) {
1002*07dc1947SRichard Lowe         /* This gets a pointer to the *first* include dir. The others
1003*07dc1947SRichard Lowe            follow directly with the standard DWARF2/3 NUL byte
1004*07dc1947SRichard Lowe            following the last. */
1005*07dc1947SRichard Lowe         line_context->lc_include_directories =
1006*07dc1947SRichard Lowe             prefix.pf_include_directories[0];
1007*07dc1947SRichard Lowe     }
1008*07dc1947SRichard Lowe 
100949d3bc91SRichard Lowe     line_context->lc_line_count = line_count;
101049d3bc91SRichard Lowe     line_context->lc_compilation_directory = comp_dir;
1011*07dc1947SRichard Lowe     line_context->lc_version_number = prefix.pf_version;
101249d3bc91SRichard Lowe     line_context->lc_dbg = dbg;
101349d3bc91SRichard Lowe     *count = line_count;
101449d3bc91SRichard Lowe 
101549d3bc91SRichard Lowe     *linebuf = block_line;
1016*07dc1947SRichard Lowe     dwarf_free_line_table_prefix(&prefix);
101749d3bc91SRichard Lowe     return (DW_DLV_OK);
101849d3bc91SRichard Lowe }
101949d3bc91SRichard Lowe 
102049d3bc91SRichard Lowe int
dwarf_srclines(Dwarf_Die die,Dwarf_Line ** linebuf,Dwarf_Signed * linecount,Dwarf_Error * error)102149d3bc91SRichard Lowe dwarf_srclines(Dwarf_Die die,
102249d3bc91SRichard Lowe                Dwarf_Line ** linebuf,
102349d3bc91SRichard Lowe                Dwarf_Signed * linecount, Dwarf_Error * error)
102449d3bc91SRichard Lowe {
1025*07dc1947SRichard Lowe     Dwarf_Signed count = 0;
1026*07dc1947SRichard Lowe     int res  = _dwarf_internal_srclines(die, linebuf, &count,
1027*07dc1947SRichard Lowe         /* addrlist= */ false,
102849d3bc91SRichard Lowe         /* linelist= */ true, error);
102949d3bc91SRichard Lowe     if (res != DW_DLV_OK) {
103049d3bc91SRichard Lowe         return res;
103149d3bc91SRichard Lowe     }
103249d3bc91SRichard Lowe     *linecount = count;
103349d3bc91SRichard Lowe     return res;
103449d3bc91SRichard Lowe }
103549d3bc91SRichard Lowe 
103649d3bc91SRichard Lowe 
103749d3bc91SRichard Lowe 
1038*07dc1947SRichard Lowe /* Every line table entry (except DW_DLE_end_sequence,
1039*07dc1947SRichard Lowe    which is returned using dwarf_lineendsequence())
1040*07dc1947SRichard Lowe    potentially has the begin-statement
1041*07dc1947SRichard Lowe    flag marked 'on'.   This returns thru *return_bool,
1042*07dc1947SRichard Lowe    the begin-statement flag.
1043*07dc1947SRichard Lowe */
104449d3bc91SRichard Lowe 
104549d3bc91SRichard Lowe int
dwarf_linebeginstatement(Dwarf_Line line,Dwarf_Bool * return_bool,Dwarf_Error * error)104649d3bc91SRichard Lowe dwarf_linebeginstatement(Dwarf_Line line,
104749d3bc91SRichard Lowe     Dwarf_Bool * return_bool, Dwarf_Error * error)
104849d3bc91SRichard Lowe {
104949d3bc91SRichard Lowe     if (line == NULL || return_bool == 0) {
105049d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
105149d3bc91SRichard Lowe         return (DW_DLV_ERROR);
105249d3bc91SRichard Lowe     }
105349d3bc91SRichard Lowe 
105449d3bc91SRichard Lowe     *return_bool = (line->li_addr_line.li_l_data.li_is_stmt);
105549d3bc91SRichard Lowe     return DW_DLV_OK;
105649d3bc91SRichard Lowe }
105749d3bc91SRichard Lowe 
1058*07dc1947SRichard Lowe /* At the end of any contiguous line-table there may be
1059*07dc1947SRichard Lowe    a DW_LNE_end_sequence operator.
1060*07dc1947SRichard Lowe    This returns non-zero thru *return_bool
1061*07dc1947SRichard Lowe    if and only if this 'line' entry was a DW_LNE_end_sequence.
1062*07dc1947SRichard Lowe 
1063*07dc1947SRichard Lowe    Within a compilation unit or function there may be multiple
1064*07dc1947SRichard Lowe    line tables, each ending with a DW_LNE_end_sequence.
1065*07dc1947SRichard Lowe    Each table describes a contiguous region.
1066*07dc1947SRichard Lowe    Because compilers may split function code up in arbitrary ways
1067*07dc1947SRichard Lowe    compilers may need to emit multiple contigous regions (ie
1068*07dc1947SRichard Lowe    line tables) for a single function.
1069*07dc1947SRichard Lowe    See the DWARF3 spec section 6.2.
1070*07dc1947SRichard Lowe */
107149d3bc91SRichard Lowe int
dwarf_lineendsequence(Dwarf_Line line,Dwarf_Bool * return_bool,Dwarf_Error * error)107249d3bc91SRichard Lowe dwarf_lineendsequence(Dwarf_Line line,
107349d3bc91SRichard Lowe     Dwarf_Bool * return_bool, Dwarf_Error * error)
107449d3bc91SRichard Lowe {
107549d3bc91SRichard Lowe     if (line == NULL) {
107649d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
107749d3bc91SRichard Lowe         return (DW_DLV_ERROR);
107849d3bc91SRichard Lowe     }
107949d3bc91SRichard Lowe 
108049d3bc91SRichard Lowe     *return_bool = (line->li_addr_line.li_l_data.li_end_sequence);
108149d3bc91SRichard Lowe     return DW_DLV_OK;
108249d3bc91SRichard Lowe }
108349d3bc91SRichard Lowe 
108449d3bc91SRichard Lowe 
1085*07dc1947SRichard Lowe /* Each 'line' entry has a line-number.
1086*07dc1947SRichard Lowe    If the entry is a DW_LNE_end_sequence the line-number is
1087*07dc1947SRichard Lowe    meaningless (see dwarf_lineendsequence(), just above).
1088*07dc1947SRichard Lowe */
108949d3bc91SRichard Lowe int
dwarf_lineno(Dwarf_Line line,Dwarf_Unsigned * ret_lineno,Dwarf_Error * error)109049d3bc91SRichard Lowe dwarf_lineno(Dwarf_Line line,
109149d3bc91SRichard Lowe     Dwarf_Unsigned * ret_lineno, Dwarf_Error * error)
109249d3bc91SRichard Lowe {
109349d3bc91SRichard Lowe     if (line == NULL || ret_lineno == 0) {
109449d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
109549d3bc91SRichard Lowe         return (DW_DLV_ERROR);
109649d3bc91SRichard Lowe     }
109749d3bc91SRichard Lowe 
109849d3bc91SRichard Lowe     *ret_lineno = (line->li_addr_line.li_l_data.li_line);
109949d3bc91SRichard Lowe     return DW_DLV_OK;
110049d3bc91SRichard Lowe }
110149d3bc91SRichard Lowe 
1102*07dc1947SRichard Lowe /* Each 'line' entry has a file-number, and index into the file table.
1103*07dc1947SRichard Lowe    If the entry is a DW_LNE_end_sequence the index is
1104*07dc1947SRichard Lowe    meaningless (see dwarf_lineendsequence(), just above).
1105*07dc1947SRichard Lowe    The file number returned is an index into the file table
1106*07dc1947SRichard Lowe    produced by dwarf_srcfiles(), but care is required: the
1107*07dc1947SRichard Lowe    li_file begins with 1 for real files, so that the li_file returned here
1108*07dc1947SRichard Lowe    is 1 greater than its index into the dwarf_srcfiles() output array.
1109*07dc1947SRichard Lowe    And entries from DW_LNE_define_file don't appear in
1110*07dc1947SRichard Lowe    the dwarf_srcfiles() output so file indexes from here may exceed
1111*07dc1947SRichard Lowe    the size of the dwarf_srcfiles() output array size.
1112*07dc1947SRichard Lowe */
1113*07dc1947SRichard Lowe int
dwarf_line_srcfileno(Dwarf_Line line,Dwarf_Unsigned * ret_fileno,Dwarf_Error * error)1114*07dc1947SRichard Lowe dwarf_line_srcfileno(Dwarf_Line line,
1115*07dc1947SRichard Lowe     Dwarf_Unsigned * ret_fileno, Dwarf_Error * error)
1116*07dc1947SRichard Lowe {
1117*07dc1947SRichard Lowe     if (line == NULL || ret_fileno == 0) {
1118*07dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1119*07dc1947SRichard Lowe         return (DW_DLV_ERROR);
1120*07dc1947SRichard Lowe     }
1121*07dc1947SRichard Lowe     /* li_file must be <= line->li_context->lc_file_entry_count else it
1122*07dc1947SRichard Lowe        is trash. li_file 0 means not attributable to any source file
1123*07dc1947SRichard Lowe        per dwarf2/3 spec. */
112449d3bc91SRichard Lowe 
1125*07dc1947SRichard Lowe     *ret_fileno = (line->li_addr_line.li_l_data.li_file);
1126*07dc1947SRichard Lowe     return DW_DLV_OK;
1127*07dc1947SRichard Lowe }
1128*07dc1947SRichard Lowe 
1129*07dc1947SRichard Lowe 
1130*07dc1947SRichard Lowe /* Each 'line' entry has a line-address.
1131*07dc1947SRichard Lowe    If the entry is a DW_LNE_end_sequence the adddress
1132*07dc1947SRichard Lowe    is one-beyond the last address this contigous region
1133*07dc1947SRichard Lowe    covers, so the address is not inside the region,
1134*07dc1947SRichard Lowe    but is just outside it.
1135*07dc1947SRichard Lowe */
113649d3bc91SRichard Lowe int
dwarf_lineaddr(Dwarf_Line line,Dwarf_Addr * ret_lineaddr,Dwarf_Error * error)113749d3bc91SRichard Lowe dwarf_lineaddr(Dwarf_Line line,
113849d3bc91SRichard Lowe     Dwarf_Addr * ret_lineaddr, Dwarf_Error * error)
113949d3bc91SRichard Lowe {
114049d3bc91SRichard Lowe     if (line == NULL || ret_lineaddr == 0) {
114149d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
114249d3bc91SRichard Lowe         return (DW_DLV_ERROR);
114349d3bc91SRichard Lowe     }
114449d3bc91SRichard Lowe 
114549d3bc91SRichard Lowe     *ret_lineaddr = (line->li_address);
114649d3bc91SRichard Lowe     return DW_DLV_OK;
114749d3bc91SRichard Lowe }
114849d3bc91SRichard Lowe 
114949d3bc91SRichard Lowe 
1150*07dc1947SRichard Lowe /* Each 'line' entry has a column-within-line (offset
1151*07dc1947SRichard Lowe    within the line) where the
1152*07dc1947SRichard Lowe    source text begins.
1153*07dc1947SRichard Lowe    If the entry is a DW_LNE_end_sequence the line-number is
1154*07dc1947SRichard Lowe    meaningless (see dwarf_lineendsequence(), just above).
1155*07dc1947SRichard Lowe    Lines of text begin at column 1.  The value 0
1156*07dc1947SRichard Lowe    means the line begins at the left edge of the line.
1157*07dc1947SRichard Lowe    (See the DWARF3 spec, section 6.2.2).
1158*07dc1947SRichard Lowe */
115949d3bc91SRichard Lowe int
dwarf_lineoff(Dwarf_Line line,Dwarf_Signed * ret_lineoff,Dwarf_Error * error)116049d3bc91SRichard Lowe dwarf_lineoff(Dwarf_Line line,
116149d3bc91SRichard Lowe     Dwarf_Signed * ret_lineoff, Dwarf_Error * error)
116249d3bc91SRichard Lowe {
116349d3bc91SRichard Lowe     if (line == NULL || ret_lineoff == 0) {
116449d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
116549d3bc91SRichard Lowe         return (DW_DLV_ERROR);
116649d3bc91SRichard Lowe     }
116749d3bc91SRichard Lowe 
116849d3bc91SRichard Lowe     *ret_lineoff =
116949d3bc91SRichard Lowe         (line->li_addr_line.li_l_data.li_column ==
117049d3bc91SRichard Lowe          0 ? -1 : line->li_addr_line.li_l_data.li_column);
117149d3bc91SRichard Lowe     return DW_DLV_OK;
117249d3bc91SRichard Lowe }
117349d3bc91SRichard Lowe 
117449d3bc91SRichard Lowe 
117549d3bc91SRichard Lowe int
dwarf_linesrc(Dwarf_Line line,char ** ret_linesrc,Dwarf_Error * error)117649d3bc91SRichard Lowe dwarf_linesrc(Dwarf_Line line, char **ret_linesrc, Dwarf_Error * error)
117749d3bc91SRichard Lowe {
1178*07dc1947SRichard Lowe     Dwarf_Signed i = 0;
117949d3bc91SRichard Lowe     Dwarf_File_Entry file_entry;
1180*07dc1947SRichard Lowe     Dwarf_Small *name_buffer = 0;
1181*07dc1947SRichard Lowe     Dwarf_Small *include_directories = 0;
1182*07dc1947SRichard Lowe     Dwarf_Small include_direc_full_path = 0;
1183*07dc1947SRichard Lowe     Dwarf_Small file_name_full_path = 0;
1184*07dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
1185*07dc1947SRichard Lowe     unsigned int comp_dir_len = 0;
118649d3bc91SRichard Lowe 
118749d3bc91SRichard Lowe     if (line == NULL) {
118849d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
118949d3bc91SRichard Lowe         return (DW_DLV_ERROR);
119049d3bc91SRichard Lowe     }
119149d3bc91SRichard Lowe 
119249d3bc91SRichard Lowe     if (line->li_context == NULL) {
119349d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL);
119449d3bc91SRichard Lowe         return (DW_DLV_ERROR);
119549d3bc91SRichard Lowe     }
119649d3bc91SRichard Lowe     dbg = line->li_context->lc_dbg;
119749d3bc91SRichard Lowe 
119849d3bc91SRichard Lowe     if (line->li_addr_line.li_l_data.li_file >
119949d3bc91SRichard Lowe         line->li_context->lc_file_entry_count) {
120049d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_LINE_FILE_NUM_BAD);
120149d3bc91SRichard Lowe         return (DW_DLV_ERROR);
120249d3bc91SRichard Lowe     }
120349d3bc91SRichard Lowe 
1204*07dc1947SRichard Lowe     if (line->li_addr_line.li_l_data.li_file == 0) {
1205*07dc1947SRichard Lowe         /* No file name known: see dwarf2/3 spec. */
1206*07dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME);
1207*07dc1947SRichard Lowe         return (DW_DLV_ERROR);
1208*07dc1947SRichard Lowe     }
120949d3bc91SRichard Lowe     file_entry = line->li_context->lc_file_entries;
1210*07dc1947SRichard Lowe     /* ASSERT: li_file > 0, dwarf correctness issue, see line table
1211*07dc1947SRichard Lowe        definition of dwarf2/3 spec. */
1212*07dc1947SRichard Lowe     /* Example: if li_file is 2 and lc_file_entry_count is 3,
1213*07dc1947SRichard Lowe        file_entry is file 3 (1 based), aka 2( 0 based) file_entry->next
1214*07dc1947SRichard Lowe        is file 2 (1 based), aka 1( 0 based) file_entry->next->next is
1215*07dc1947SRichard Lowe        file 1 (1 based), aka 0( 0 based) file_entry->next->next->next
1216*07dc1947SRichard Lowe        is NULL.
1217*07dc1947SRichard Lowe 
1218*07dc1947SRichard Lowe        and this loop finds the file_entry we need (2 (1 based) in this
1219*07dc1947SRichard Lowe        case). Because lc_file_entries are in reverse order and
1220*07dc1947SRichard Lowe        effectively zero based as a count whereas li_file is 1 based. */
122149d3bc91SRichard Lowe     for (i = line->li_addr_line.li_l_data.li_file - 1; i > 0; i--)
122249d3bc91SRichard Lowe         file_entry = file_entry->fi_next;
122349d3bc91SRichard Lowe 
122449d3bc91SRichard Lowe     if (file_entry->fi_file_name == NULL) {
122549d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME);
122649d3bc91SRichard Lowe         return (DW_DLV_ERROR);
122749d3bc91SRichard Lowe     }
122849d3bc91SRichard Lowe 
1229*07dc1947SRichard Lowe     file_name_full_path = file_name_is_full_path(file_entry->fi_file_name);
1230*07dc1947SRichard Lowe     if (file_name_full_path) {
123149d3bc91SRichard Lowe         *ret_linesrc = ((char *) file_entry->fi_file_name);
123249d3bc91SRichard Lowe         return DW_DLV_OK;
123349d3bc91SRichard Lowe     }
123449d3bc91SRichard Lowe 
123549d3bc91SRichard Lowe     if (file_entry->fi_dir_index == 0) {
123649d3bc91SRichard Lowe 
123749d3bc91SRichard Lowe         /* dir_index of 0 means that the compilation was in the
123849d3bc91SRichard Lowe            'current directory of compilation' */
123949d3bc91SRichard Lowe         if (line->li_context->lc_compilation_directory == NULL) {
124049d3bc91SRichard Lowe             /* we don't actually *have* a current directory of
124149d3bc91SRichard Lowe                compilation: DW_AT_comp_dir was not present Rather than
124249d3bc91SRichard Lowe                emitting DW_DLE_NO_COMP_DIR lets just make an empty name
124349d3bc91SRichard Lowe                here. In other words, do the best we can with what we do
124449d3bc91SRichard Lowe                have instead of reporting an error. _dwarf_error(dbg,
124549d3bc91SRichard Lowe                error, DW_DLE_NO_COMP_DIR); return(DW_DLV_ERROR); */
124649d3bc91SRichard Lowe             comp_dir_len = 0;
124749d3bc91SRichard Lowe         } else {
124849d3bc91SRichard Lowe             comp_dir_len = strlen((char *)
124949d3bc91SRichard Lowe                                   (line->li_context->
125049d3bc91SRichard Lowe                                    lc_compilation_directory));
125149d3bc91SRichard Lowe         }
125249d3bc91SRichard Lowe 
125349d3bc91SRichard Lowe         name_buffer =
125449d3bc91SRichard Lowe             _dwarf_get_alloc(line->li_context->lc_dbg, DW_DLA_STRING,
125549d3bc91SRichard Lowe                              comp_dir_len + 1 +
125649d3bc91SRichard Lowe                              strlen((char *) file_entry->fi_file_name) +
125749d3bc91SRichard Lowe                              1);
125849d3bc91SRichard Lowe         if (name_buffer == NULL) {
125949d3bc91SRichard Lowe             _dwarf_error(line->li_context->lc_dbg, error,
126049d3bc91SRichard Lowe                          DW_DLE_ALLOC_FAIL);
126149d3bc91SRichard Lowe             return (DW_DLV_ERROR);
126249d3bc91SRichard Lowe         }
126349d3bc91SRichard Lowe 
126449d3bc91SRichard Lowe         if (comp_dir_len > 0) {
126549d3bc91SRichard Lowe             /* if comp_dir_len is 0 we do not want to put a / in front
126649d3bc91SRichard Lowe                of the fi_file_name as we just don't know anything. */
126749d3bc91SRichard Lowe             strcpy((char *) name_buffer,
126849d3bc91SRichard Lowe                    (char *) (line->li_context->
126949d3bc91SRichard Lowe                              lc_compilation_directory));
127049d3bc91SRichard Lowe             strcat((char *) name_buffer, "/");
127149d3bc91SRichard Lowe         }
127249d3bc91SRichard Lowe         strcat((char *) name_buffer, (char *) file_entry->fi_file_name);
127349d3bc91SRichard Lowe         *ret_linesrc = ((char *) name_buffer);
127449d3bc91SRichard Lowe         return DW_DLV_OK;
127549d3bc91SRichard Lowe     }
127649d3bc91SRichard Lowe 
127749d3bc91SRichard Lowe     if (file_entry->fi_dir_index >
127849d3bc91SRichard Lowe         line->li_context->lc_include_directories_count) {
127949d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_INCL_DIR_NUM_BAD);
128049d3bc91SRichard Lowe         return (DW_DLV_ERROR);
128149d3bc91SRichard Lowe     }
128249d3bc91SRichard Lowe 
128349d3bc91SRichard Lowe     include_directories = line->li_context->lc_include_directories;
128449d3bc91SRichard Lowe     for (i = file_entry->fi_dir_index - 1; i > 0; i--)
128549d3bc91SRichard Lowe         include_directories += strlen((char *) include_directories) + 1;
128649d3bc91SRichard Lowe 
128749d3bc91SRichard Lowe     if (line->li_context->lc_compilation_directory) {
128849d3bc91SRichard Lowe         comp_dir_len = strlen((char *)
1289*07dc1947SRichard Lowe             (line->li_context->lc_compilation_directory));
129049d3bc91SRichard Lowe     } else {
129149d3bc91SRichard Lowe         /* No DW_AT_comp_dir present. Do the best we can without it. */
129249d3bc91SRichard Lowe         comp_dir_len = 0;
129349d3bc91SRichard Lowe     }
129449d3bc91SRichard Lowe 
1295*07dc1947SRichard Lowe     include_direc_full_path = file_name_is_full_path(include_directories);
129649d3bc91SRichard Lowe     name_buffer = _dwarf_get_alloc(dbg, DW_DLA_STRING,
1297*07dc1947SRichard Lowe         (include_direc_full_path ?  0 : comp_dir_len + 1) +
1298*07dc1947SRichard Lowe             strlen((char *)include_directories) + 1 +
1299*07dc1947SRichard Lowe             strlen((char *)file_entry->fi_file_name) + 1);
130049d3bc91SRichard Lowe     if (name_buffer == NULL) {
130149d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
130249d3bc91SRichard Lowe         return (DW_DLV_ERROR);
130349d3bc91SRichard Lowe     }
130449d3bc91SRichard Lowe 
1305*07dc1947SRichard Lowe     if (!include_direc_full_path) {
130649d3bc91SRichard Lowe         if (comp_dir_len > 0) {
130749d3bc91SRichard Lowe             strcpy((char *)name_buffer,
130849d3bc91SRichard Lowe                 (char *)line->li_context->lc_compilation_directory);
130949d3bc91SRichard Lowe             /* Who provides the / needed after the compilation
131049d3bc91SRichard Lowe                directory? */
1311*07dc1947SRichard Lowe             if (!is_path_separator(name_buffer[comp_dir_len - 1])) {
1312*07dc1947SRichard Lowe                 /* Here we provide the / separator. It
1313*07dc1947SRichard Lowe                    should work ok for Windows */
1314*07dc1947SRichard Lowe                 /* Overwrite previous nul terminator with needed / */
1315*07dc1947SRichard Lowe                 name_buffer[comp_dir_len] = '/';
131649d3bc91SRichard Lowe                 name_buffer[comp_dir_len + 1] = 0;
131749d3bc91SRichard Lowe             }
131849d3bc91SRichard Lowe         }
131949d3bc91SRichard Lowe     } else {
132049d3bc91SRichard Lowe         strcpy((char *) name_buffer, "");
132149d3bc91SRichard Lowe     }
132249d3bc91SRichard Lowe     strcat((char *) name_buffer, (char *) include_directories);
132349d3bc91SRichard Lowe     strcat((char *) name_buffer, "/");
132449d3bc91SRichard Lowe     strcat((char *) name_buffer, (char *) file_entry->fi_file_name);
132549d3bc91SRichard Lowe     *ret_linesrc = ((char *) name_buffer);
132649d3bc91SRichard Lowe     return DW_DLV_OK;
132749d3bc91SRichard Lowe }
132849d3bc91SRichard Lowe 
1329*07dc1947SRichard Lowe /* Every line table entry potentially has the basic-block-start
1330*07dc1947SRichard Lowe    flag marked 'on'.   This returns thru *return_bool,
1331*07dc1947SRichard Lowe    the basic-block-start flag.
1332*07dc1947SRichard Lowe */
133349d3bc91SRichard Lowe int
dwarf_lineblock(Dwarf_Line line,Dwarf_Bool * return_bool,Dwarf_Error * error)133449d3bc91SRichard Lowe dwarf_lineblock(Dwarf_Line line,
133549d3bc91SRichard Lowe     Dwarf_Bool * return_bool, Dwarf_Error * error)
133649d3bc91SRichard Lowe {
133749d3bc91SRichard Lowe     if (line == NULL) {
133849d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
133949d3bc91SRichard Lowe         return (DW_DLV_ERROR);
134049d3bc91SRichard Lowe     }
134149d3bc91SRichard Lowe     *return_bool = (line->li_addr_line.li_l_data.li_basic_block);
134249d3bc91SRichard Lowe     return DW_DLV_OK;
134349d3bc91SRichard Lowe }
134449d3bc91SRichard Lowe 
134549d3bc91SRichard Lowe 
134649d3bc91SRichard Lowe #if 0                           /* Ignore this.  This needs major
134749d3bc91SRichard Lowe                                    re-work. */
134849d3bc91SRichard Lowe /*
134949d3bc91SRichard Lowe     This routine works by looking for exact matches between
135049d3bc91SRichard Lowe     the current line address and pc, and crossovers from
135149d3bc91SRichard Lowe     from less than pc value to greater than.  At each line
135249d3bc91SRichard Lowe     that satisfies the above, it records a pointer to the
135349d3bc91SRichard Lowe     line, and the difference between the address and pc.
135449d3bc91SRichard Lowe     It then scans these pointers and picks out those with
135549d3bc91SRichard Lowe     the smallest difference between pc and address.
135649d3bc91SRichard Lowe */
135749d3bc91SRichard Lowe int
135849d3bc91SRichard Lowe dwarf_pclines(Dwarf_Debug dbg,
135949d3bc91SRichard Lowe               Dwarf_Addr pc,
136049d3bc91SRichard Lowe               Dwarf_Line ** linebuf,
136149d3bc91SRichard Lowe               Dwarf_Signed slide,
136249d3bc91SRichard Lowe               Dwarf_Signed * linecount, Dwarf_Error * error)
136349d3bc91SRichard Lowe {
136449d3bc91SRichard Lowe     /*
136549d3bc91SRichard Lowe        Scans the line matrix for the current cu to which a pointer
136649d3bc91SRichard Lowe        exists in dbg. */
136749d3bc91SRichard Lowe     Dwarf_Line line;
136849d3bc91SRichard Lowe     Dwarf_Line prev_line;
136949d3bc91SRichard Lowe 
137049d3bc91SRichard Lowe     /*
137149d3bc91SRichard Lowe        These flags are for efficiency reasons. Check_line is true
1372*07dc1947SRichard Lowe        initially, but set false when the address of the current line is
1373*07dc1947SRichard Lowe        greater than pc.  It is set true only when the address of the
1374*07dc1947SRichard Lowe        current line falls below pc.  This assumes that addresses within
1375*07dc1947SRichard Lowe        the same segment increase, and we are only interested in the
1376*07dc1947SRichard Lowe        switch from a less than pc address to a greater than. First_line
1377*07dc1947SRichard Lowe        is set true initially, but set false after the first line is
1378*07dc1947SRichard Lowe        scanned.  This is to prevent looking at the address of previous
1379*07dc1947SRichard Lowe        line when slide is DW_DLS_BACKWARD, and the first line is being
1380*07dc1947SRichard Lowe        scanned. */
138149d3bc91SRichard Lowe     Dwarf_Bool check_line, first_line;
138249d3bc91SRichard Lowe 
138349d3bc91SRichard Lowe     /*
1384*07dc1947SRichard Lowe        Diff tracks the smallest difference a line address and the input
1385*07dc1947SRichard Lowe        pc value. */
138649d3bc91SRichard Lowe     Dwarf_Signed diff, i;
138749d3bc91SRichard Lowe 
138849d3bc91SRichard Lowe     /*
138949d3bc91SRichard Lowe        For the slide = DW_DLS_BACKWARD case, pc_less is the value of
139049d3bc91SRichard Lowe        the address of the line immediately preceding the first line
139149d3bc91SRichard Lowe        that has value greater than pc. For the slide = DW_DLS_FORWARD
139249d3bc91SRichard Lowe        case, pc_more is the values of address for the first line that
1393*07dc1947SRichard Lowe        is greater than pc. Diff is the difference between either of the
1394*07dc1947SRichard Lowe        these values and pc. */
139549d3bc91SRichard Lowe     Dwarf_Addr pc_less, pc_more;
139649d3bc91SRichard Lowe 
139749d3bc91SRichard Lowe     /*
139849d3bc91SRichard Lowe        Pc_line_buf points to a chain of pointers to lines of which
139949d3bc91SRichard Lowe        those with a diff equal to the smallest difference will be
140049d3bc91SRichard Lowe        returned. */
140149d3bc91SRichard Lowe     Dwarf_Line *pc_line_buf, *pc_line;
140249d3bc91SRichard Lowe 
140349d3bc91SRichard Lowe     /*
140449d3bc91SRichard Lowe        Chain_count counts the number of lines in the above chain for
140549d3bc91SRichard Lowe        which the diff is equal to the smallest difference This is the
140649d3bc91SRichard Lowe        number returned by this routine. */
140749d3bc91SRichard Lowe     Dwarf_Signed chain_count;
140849d3bc91SRichard Lowe 
140949d3bc91SRichard Lowe     chain_head = NULL;
141049d3bc91SRichard Lowe 
141149d3bc91SRichard Lowe     check_line = true;
141249d3bc91SRichard Lowe     first_line = true;
141349d3bc91SRichard Lowe     diff = MAX_LINE_DIFF;
141449d3bc91SRichard Lowe 
141549d3bc91SRichard Lowe     for (i = 0; i < dbg->de_cu_line_count; i++) {
141649d3bc91SRichard Lowe 
141749d3bc91SRichard Lowe         line = *(dbg->de_cu_line_ptr + i);
141849d3bc91SRichard Lowe         prev_line = first_line ? NULL : *(dbg->de_cu_line_ptr + i - 1);
141949d3bc91SRichard Lowe 
142049d3bc91SRichard Lowe         if (line->li_address == pc) {
142149d3bc91SRichard Lowe             chain_ptr = (struct chain *)
142249d3bc91SRichard Lowe                 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
142349d3bc91SRichard Lowe             if (chain_ptr == NULL) {
142449d3bc91SRichard Lowe                 _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
142549d3bc91SRichard Lowe                 return (DW_DLV_ERROR);
142649d3bc91SRichard Lowe             }
142749d3bc91SRichard Lowe 
142849d3bc91SRichard Lowe             chain_ptr->line = line;
142949d3bc91SRichard Lowe             chain_ptr->diff = diff = 0;
143049d3bc91SRichard Lowe             chain_ptr->next = chain_head;
143149d3bc91SRichard Lowe             chain_head = chain_ptr;
143249d3bc91SRichard Lowe         } else
143349d3bc91SRichard Lowe             /*
143449d3bc91SRichard Lowe                Look for crossover from less than pc address to greater
143549d3bc91SRichard Lowe                than. */
143649d3bc91SRichard Lowe         if (check_line && line->li_address > pc &&
143749d3bc91SRichard Lowe                 (first_line ? 0 : prev_line->li_address) < pc)
143849d3bc91SRichard Lowe 
143949d3bc91SRichard Lowe             if (slide == DW_DLS_BACKWARD && !first_line) {
144049d3bc91SRichard Lowe                 pc_less = prev_line->li_address;
144149d3bc91SRichard Lowe                 if (pc - pc_less <= diff) {
144249d3bc91SRichard Lowe                     chain_ptr = (struct chain *)
144349d3bc91SRichard Lowe                         _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
144449d3bc91SRichard Lowe                     if (chain_ptr == NULL) {
144549d3bc91SRichard Lowe                         _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
144649d3bc91SRichard Lowe                         return (DW_DLV_ERROR);
144749d3bc91SRichard Lowe                     }
144849d3bc91SRichard Lowe 
144949d3bc91SRichard Lowe                     chain_ptr->line = prev_line;
145049d3bc91SRichard Lowe                     chain_ptr->diff = diff = pc - pc_less;
145149d3bc91SRichard Lowe                     chain_ptr->next = chain_head;
145249d3bc91SRichard Lowe                     chain_head = chain_ptr;
145349d3bc91SRichard Lowe                 }
145449d3bc91SRichard Lowe                 check_line = false;
145549d3bc91SRichard Lowe             } else if (slide == DW_DLS_FORWARD) {
145649d3bc91SRichard Lowe                 pc_more = line->li_address;
145749d3bc91SRichard Lowe                 if (pc_more - pc <= diff) {
145849d3bc91SRichard Lowe                     chain_ptr = (struct chain *)
145949d3bc91SRichard Lowe                         _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
146049d3bc91SRichard Lowe                     if (chain_ptr == NULL) {
146149d3bc91SRichard Lowe                         _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
146249d3bc91SRichard Lowe                         return (DW_DLV_ERROR);
146349d3bc91SRichard Lowe                     }
146449d3bc91SRichard Lowe 
146549d3bc91SRichard Lowe                     chain_ptr->line = line;
146649d3bc91SRichard Lowe                     chain_ptr->diff = diff = pc_more - pc;
146749d3bc91SRichard Lowe                     chain_ptr->next = chain_head;
146849d3bc91SRichard Lowe                     chain_head = chain_ptr;
146949d3bc91SRichard Lowe                 }
147049d3bc91SRichard Lowe                 check_line = false;
147149d3bc91SRichard Lowe             } else
147249d3bc91SRichard Lowe                 /* Check addresses only when they go */
147349d3bc91SRichard Lowe                 /* below pc.  */
147449d3bc91SRichard Lowe             if (line->li_address < pc)
147549d3bc91SRichard Lowe                 check_line = true;
147649d3bc91SRichard Lowe 
147749d3bc91SRichard Lowe         first_line = false;
147849d3bc91SRichard Lowe     }
147949d3bc91SRichard Lowe 
148049d3bc91SRichard Lowe     chain_count = 0;
148149d3bc91SRichard Lowe     for (chain_ptr = chain_head; chain_ptr != NULL;
148249d3bc91SRichard Lowe          chain_ptr = chain_ptr->next)
148349d3bc91SRichard Lowe         if (chain_ptr->diff == diff)
148449d3bc91SRichard Lowe             chain_count++;
148549d3bc91SRichard Lowe 
148649d3bc91SRichard Lowe     pc_line_buf = pc_line = (Dwarf_Line)
148749d3bc91SRichard Lowe         _dwarf_get_alloc(dbg, DW_DLA_LIST, chain_count);
148849d3bc91SRichard Lowe     for (chain_ptr = chain_head; chain_ptr != NULL;
148949d3bc91SRichard Lowe          chain_ptr = chain_ptr->next)
149049d3bc91SRichard Lowe         if (chain_ptr->diff == diff) {
149149d3bc91SRichard Lowe             *pc_line = chain_ptr->line;
149249d3bc91SRichard Lowe             pc_line++;
149349d3bc91SRichard Lowe         }
149449d3bc91SRichard Lowe 
149549d3bc91SRichard Lowe     for (chain_ptr = chain_head; chain_ptr != NULL;) {
149649d3bc91SRichard Lowe         chain_head = chain_ptr;
149749d3bc91SRichard Lowe         chain_ptr = chain_ptr->next;
149849d3bc91SRichard Lowe         dwarf_dealloc(dbg, chain_head, DW_DLA_CHAIN);
149949d3bc91SRichard Lowe     }
150049d3bc91SRichard Lowe 
150149d3bc91SRichard Lowe     *linebuf = pc_line_buf;
150249d3bc91SRichard Lowe     return (chain_count);
150349d3bc91SRichard Lowe }
150449d3bc91SRichard Lowe #endif
150549d3bc91SRichard Lowe 
150649d3bc91SRichard Lowe 
1507*07dc1947SRichard Lowe 
150849d3bc91SRichard Lowe /*
1509*07dc1947SRichard Lowe    It's impossible for callers of dwarf_srclines() to get to and
1510*07dc1947SRichard Lowe    free all the resources (in particular, the li_context and its
1511*07dc1947SRichard Lowe    lc_file_entries).
1512*07dc1947SRichard Lowe    So this function, new July 2005, does it.
151349d3bc91SRichard Lowe */
1514*07dc1947SRichard Lowe 
1515*07dc1947SRichard Lowe void
dwarf_srclines_dealloc(Dwarf_Debug dbg,Dwarf_Line * linebuf,Dwarf_Signed count)1516*07dc1947SRichard Lowe dwarf_srclines_dealloc(Dwarf_Debug dbg, Dwarf_Line * linebuf,
1517*07dc1947SRichard Lowe     Dwarf_Signed count)
151849d3bc91SRichard Lowe {
151949d3bc91SRichard Lowe 
1520*07dc1947SRichard Lowe     Dwarf_Signed i = 0;
1521*07dc1947SRichard Lowe     struct Dwarf_Line_Context_s *context = 0;
152249d3bc91SRichard Lowe 
1523*07dc1947SRichard Lowe     if (count > 0) {
1524*07dc1947SRichard Lowe         /* All these entries share a single context */
1525*07dc1947SRichard Lowe         context = linebuf[0]->li_context;
1526*07dc1947SRichard Lowe     }
1527*07dc1947SRichard Lowe     for (i = 0; i < count; ++i) {
152849d3bc91SRichard Lowe         dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE);
152949d3bc91SRichard Lowe     }
153049d3bc91SRichard Lowe     dwarf_dealloc(dbg, linebuf, DW_DLA_LIST);
1531*07dc1947SRichard Lowe 
1532*07dc1947SRichard Lowe     if (context) {
1533*07dc1947SRichard Lowe         Dwarf_File_Entry fe = context->lc_file_entries;
1534*07dc1947SRichard Lowe 
1535*07dc1947SRichard Lowe         while (fe) {
1536*07dc1947SRichard Lowe             Dwarf_File_Entry fenext = fe->fi_next;
1537*07dc1947SRichard Lowe 
1538*07dc1947SRichard Lowe             dwarf_dealloc(dbg, fe, DW_DLA_FILE_ENTRY);
1539*07dc1947SRichard Lowe             fe = fenext;
1540*07dc1947SRichard Lowe         }
1541*07dc1947SRichard Lowe         dwarf_dealloc(dbg, context, DW_DLA_LINE_CONTEXT);
1542*07dc1947SRichard Lowe     }
1543*07dc1947SRichard Lowe 
1544*07dc1947SRichard Lowe     return;
1545*07dc1947SRichard Lowe }
1546*07dc1947SRichard Lowe 
1547*07dc1947SRichard Lowe /* Operand counts per standard operand.
1548*07dc1947SRichard Lowe    The initial zero is for DW_LNS_copy.
1549*07dc1947SRichard Lowe    This is an economical way to verify we understand the table
1550*07dc1947SRichard Lowe    of standard-opcode-lengths in the line table prologue.  */
1551*07dc1947SRichard Lowe #define STANDARD_OPERAND_COUNT_DWARF2 9
1552*07dc1947SRichard Lowe #define STANDARD_OPERAND_COUNT_DWARF3 12
1553*07dc1947SRichard Lowe static unsigned char
1554*07dc1947SRichard Lowe   dwarf_standard_opcode_operand_count[STANDARD_OPERAND_COUNT_DWARF3] = {
1555*07dc1947SRichard Lowe     /* DWARF2 */
1556*07dc1947SRichard Lowe     0,
1557*07dc1947SRichard Lowe     1, 1, 1, 1,
1558*07dc1947SRichard Lowe     0, 0, 0,
1559*07dc1947SRichard Lowe     1,
1560*07dc1947SRichard Lowe     /* Following are new for DWARF3. */
1561*07dc1947SRichard Lowe     0, 0, 1
1562*07dc1947SRichard Lowe };
1563*07dc1947SRichard Lowe 
1564*07dc1947SRichard Lowe /* We have a normal standard opcode base, but
1565*07dc1947SRichard Lowe    an arm compiler emitted a non-standard table!
1566*07dc1947SRichard Lowe    This could lead to problems...
1567*07dc1947SRichard Lowe    ARM C/C++ Compiler, RVCT4.0 [Build 4
1568*07dc1947SRichard Lowe    00] seems to get the table wrong .  */
1569*07dc1947SRichard Lowe static unsigned char
1570*07dc1947SRichard Lowe dwarf_arm_standard_opcode_operand_count[STANDARD_OPERAND_COUNT_DWARF3] = {
1571*07dc1947SRichard Lowe     /* DWARF2 */
1572*07dc1947SRichard Lowe     0,
1573*07dc1947SRichard Lowe     1, 1, 1, 1,
1574*07dc1947SRichard Lowe     0, 0, 0,
1575*07dc1947SRichard Lowe     0,  /* <<< --- this is wrong */
1576*07dc1947SRichard Lowe     /* Following are new for DWARF3. */
1577*07dc1947SRichard Lowe     0, 0, 1
1578*07dc1947SRichard Lowe };
1579*07dc1947SRichard Lowe 
1580*07dc1947SRichard Lowe static void
print_header_issue(Dwarf_Debug dbg,char * specific_msg,Dwarf_Small * data_start,int * err_count_out)1581*07dc1947SRichard Lowe print_header_issue(Dwarf_Debug dbg,
1582*07dc1947SRichard Lowe     char *specific_msg,
1583*07dc1947SRichard Lowe     Dwarf_Small *data_start,
1584*07dc1947SRichard Lowe     int *err_count_out)
1585*07dc1947SRichard Lowe {
1586*07dc1947SRichard Lowe     if(!err_count_out)
1587*07dc1947SRichard Lowe         return;
1588*07dc1947SRichard Lowe     printf("*** DWARF CHECK: "
1589*07dc1947SRichard Lowe         "line table header: %s",
1590*07dc1947SRichard Lowe         specific_msg);
1591*07dc1947SRichard Lowe     if( data_start >= dbg->de_debug_line.dss_data &&
1592*07dc1947SRichard Lowe         (data_start < (dbg->de_debug_line.dss_data +
1593*07dc1947SRichard Lowe         dbg->de_debug_line.dss_size))) {
1594*07dc1947SRichard Lowe         Dwarf_Unsigned off = data_start - dbg->de_debug_line.dss_data;
1595*07dc1947SRichard Lowe         printf(" at .debug_line section offset 0x%" DW_PR_DUx
1596*07dc1947SRichard Lowe             "  ( %" DW_PR_DUu " ) ",
1597*07dc1947SRichard Lowe             off,off);
1598*07dc1947SRichard Lowe     } else {
1599*07dc1947SRichard Lowe         printf(" (unknown section location) ");
1600*07dc1947SRichard Lowe     }
1601*07dc1947SRichard Lowe     printf("***\n");
1602*07dc1947SRichard Lowe     *err_count_out += 1;
1603*07dc1947SRichard Lowe }
1604*07dc1947SRichard Lowe 
1605*07dc1947SRichard Lowe 
1606*07dc1947SRichard Lowe 
1607*07dc1947SRichard Lowe /* Common line table prefix reading code.
1608*07dc1947SRichard Lowe    Returns DW_DLV_OK, DW_DLV_ERROR.
1609*07dc1947SRichard Lowe    DW_DLV_NO_ENTRY cannot be returned, but callers should
1610*07dc1947SRichard Lowe    assume it is possible.
1611*07dc1947SRichard Lowe 
1612*07dc1947SRichard Lowe    The prefix_out area must be initialized properly before calling this.
1613*07dc1947SRichard Lowe 
1614*07dc1947SRichard Lowe    Has the side effect of allocating arrays which
1615*07dc1947SRichard Lowe    must be freed (see the Line_Table_Prefix_s struct which
1616*07dc1947SRichard Lowe    holds the pointers to space we allocate here).
1617*07dc1947SRichard Lowe 
1618*07dc1947SRichard Lowe    bogus_bytes_ptr and bogus_bytes are output values which
1619*07dc1947SRichard Lowe    let a print-program notify the user of some surprising bytes
1620*07dc1947SRichard Lowe    after a line table header and before the line table instructions.
1621*07dc1947SRichard Lowe    These can be ignored unless one is printing.
1622*07dc1947SRichard Lowe    And are ignored if NULL passed as the pointer.
1623*07dc1947SRichard Lowe */
1624*07dc1947SRichard Lowe 
1625*07dc1947SRichard Lowe /* err_count_out may be NULL, in which case we
1626*07dc1947SRichard Lowe    make no attempt to count checking-type errors.
1627*07dc1947SRichard Lowe    Checking-type errors do not stop us, we just report them.
1628*07dc1947SRichard Lowe */
1629*07dc1947SRichard Lowe 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*07dc1947SRichard Lowe dwarf_read_line_table_prefix(Dwarf_Debug dbg,
1631*07dc1947SRichard Lowe     Dwarf_Small * data_start,
1632*07dc1947SRichard Lowe     Dwarf_Unsigned data_length,
1633*07dc1947SRichard Lowe     Dwarf_Small ** updated_data_start_out,
1634*07dc1947SRichard Lowe     struct Line_Table_Prefix_s *prefix_out,
1635*07dc1947SRichard Lowe     Dwarf_Small ** bogus_bytes_ptr,
1636*07dc1947SRichard Lowe     Dwarf_Unsigned *bogus_bytes,
1637*07dc1947SRichard Lowe     Dwarf_Error * err,
1638*07dc1947SRichard Lowe     int *err_count_out)
1639*07dc1947SRichard Lowe {
1640*07dc1947SRichard Lowe     Dwarf_Small *line_ptr = data_start;
1641*07dc1947SRichard Lowe     Dwarf_Unsigned total_length = 0;
1642*07dc1947SRichard Lowe     int local_length_size = 0;
1643*07dc1947SRichard Lowe     int local_extension_size = 0;
1644*07dc1947SRichard Lowe     Dwarf_Unsigned prologue_length = 0;
1645*07dc1947SRichard Lowe     Dwarf_Half version = 0;
1646*07dc1947SRichard Lowe     Dwarf_Unsigned directories_count = 0;
1647*07dc1947SRichard Lowe     Dwarf_Unsigned directories_malloc = 0;
1648*07dc1947SRichard Lowe     Dwarf_Unsigned files_count = 0;
1649*07dc1947SRichard Lowe     Dwarf_Unsigned files_malloc = 0;
1650*07dc1947SRichard Lowe     Dwarf_Small *line_ptr_end = 0;
1651*07dc1947SRichard Lowe     Dwarf_Small *lp_begin = 0;
1652*07dc1947SRichard Lowe     if(bogus_bytes_ptr) *bogus_bytes_ptr = 0;
1653*07dc1947SRichard Lowe     if(bogus_bytes) *bogus_bytes= 0;
1654*07dc1947SRichard Lowe 
1655*07dc1947SRichard Lowe     prefix_out->pf_line_ptr_start = line_ptr;
1656*07dc1947SRichard Lowe     /* READ_AREA_LENGTH updates line_ptr for consumed bytes */
1657*07dc1947SRichard Lowe     READ_AREA_LENGTH(dbg, total_length, Dwarf_Unsigned,
1658*07dc1947SRichard Lowe                      line_ptr, local_length_size, local_extension_size);
1659*07dc1947SRichard Lowe 
1660*07dc1947SRichard Lowe 
1661*07dc1947SRichard Lowe     line_ptr_end = line_ptr + total_length;
1662*07dc1947SRichard Lowe     prefix_out->pf_line_ptr_end = line_ptr_end;
1663*07dc1947SRichard Lowe     prefix_out->pf_length_field_length = local_length_size +
1664*07dc1947SRichard Lowe         local_extension_size;
1665*07dc1947SRichard Lowe     /* ASSERT: prefix_out->pf_length_field_length == line_ptr
1666*07dc1947SRichard Lowe        -prefix_out->pf_line_ptr_start; */
1667*07dc1947SRichard Lowe     if (line_ptr_end > dbg->de_debug_line.dss_data +
1668*07dc1947SRichard Lowe         dbg->de_debug_line.dss_size) {
1669*07dc1947SRichard Lowe         _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
1670*07dc1947SRichard Lowe         return (DW_DLV_ERROR);
1671*07dc1947SRichard Lowe     }
1672*07dc1947SRichard Lowe     if (line_ptr_end > data_start + data_length) {
1673*07dc1947SRichard Lowe         _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
1674*07dc1947SRichard Lowe         return (DW_DLV_ERROR);
1675*07dc1947SRichard Lowe     }
1676*07dc1947SRichard Lowe     prefix_out->pf_total_length = total_length;
1677*07dc1947SRichard Lowe 
1678*07dc1947SRichard Lowe     READ_UNALIGNED(dbg, version, Dwarf_Half,
1679*07dc1947SRichard Lowe                    line_ptr, sizeof(Dwarf_Half));
1680*07dc1947SRichard Lowe     prefix_out->pf_version = version;
1681*07dc1947SRichard Lowe     line_ptr += sizeof(Dwarf_Half);
1682*07dc1947SRichard Lowe     if (version != CURRENT_VERSION_STAMP &&
1683*07dc1947SRichard Lowe         version != CURRENT_VERSION_STAMP3) {
1684*07dc1947SRichard Lowe         _dwarf_error(dbg, err, DW_DLE_VERSION_STAMP_ERROR);
1685*07dc1947SRichard Lowe         return (DW_DLV_ERROR);
1686*07dc1947SRichard Lowe     }
1687*07dc1947SRichard Lowe 
1688*07dc1947SRichard Lowe     READ_UNALIGNED(dbg, prologue_length, Dwarf_Unsigned,
1689*07dc1947SRichard Lowe                    line_ptr, local_length_size);
1690*07dc1947SRichard Lowe     prefix_out->pf_prologue_length = prologue_length;
1691*07dc1947SRichard Lowe     line_ptr += local_length_size;
1692*07dc1947SRichard Lowe     prefix_out->pf_line_prologue_start = line_ptr;
1693*07dc1947SRichard Lowe 
1694*07dc1947SRichard Lowe     prefix_out->pf_minimum_instruction_length =
1695*07dc1947SRichard Lowe         *(unsigned char *) line_ptr;
1696*07dc1947SRichard Lowe     line_ptr = line_ptr + sizeof(Dwarf_Small);
1697*07dc1947SRichard Lowe 
1698*07dc1947SRichard Lowe     prefix_out->pf_default_is_stmt = *(unsigned char *) line_ptr;
1699*07dc1947SRichard Lowe     line_ptr = line_ptr + sizeof(Dwarf_Small);
1700*07dc1947SRichard Lowe 
1701*07dc1947SRichard Lowe     prefix_out->pf_line_base = *(signed char *) line_ptr;
1702*07dc1947SRichard Lowe     line_ptr = line_ptr + sizeof(Dwarf_Sbyte);
1703*07dc1947SRichard Lowe 
1704*07dc1947SRichard Lowe     prefix_out->pf_line_range = *(unsigned char *) line_ptr;
1705*07dc1947SRichard Lowe     line_ptr = line_ptr + sizeof(Dwarf_Small);
1706*07dc1947SRichard Lowe 
1707*07dc1947SRichard Lowe     prefix_out->pf_opcode_base = *(unsigned char *) line_ptr;
1708*07dc1947SRichard Lowe     line_ptr = line_ptr + sizeof(Dwarf_Small);
1709*07dc1947SRichard Lowe 
1710*07dc1947SRichard Lowe     /* Set up the array of standard opcode lengths. */
1711*07dc1947SRichard Lowe     /* We think this works ok even for cross-endian processing of
1712*07dc1947SRichard Lowe        objects.  It might be wrong, we might need to specially process
1713*07dc1947SRichard Lowe        the array of ubyte into host order.  */
1714*07dc1947SRichard Lowe     prefix_out->pf_opcode_length_table = line_ptr;
1715*07dc1947SRichard Lowe 
1716*07dc1947SRichard Lowe     /* pf_opcode_base is one greater than the size of the array. */
1717*07dc1947SRichard Lowe     line_ptr += prefix_out->pf_opcode_base - 1;
1718*07dc1947SRichard Lowe 
1719*07dc1947SRichard Lowe     {
1720*07dc1947SRichard Lowe         /* Determine (as best we can) whether the
1721*07dc1947SRichard Lowe            pf_opcode_length_table holds 9 or 12 standard-conforming
1722*07dc1947SRichard Lowe            entries.  gcc4 upped to DWARF3's 12 without updating the
1723*07dc1947SRichard Lowe            version number.   */
1724*07dc1947SRichard Lowe         int operand_ck_fail = true;
1725*07dc1947SRichard Lowe 
1726*07dc1947SRichard Lowe         if (prefix_out->pf_opcode_base >= STANDARD_OPERAND_COUNT_DWARF3) {
1727*07dc1947SRichard Lowe             int mismatch = memcmp(dwarf_standard_opcode_operand_count,
1728*07dc1947SRichard Lowe                                   prefix_out->pf_opcode_length_table,
1729*07dc1947SRichard Lowe                                   STANDARD_OPERAND_COUNT_DWARF3);
1730*07dc1947SRichard Lowe             if(mismatch) {
1731*07dc1947SRichard Lowe                  if(err_count_out) {
1732*07dc1947SRichard Lowe                      print_header_issue(dbg,"standard-operands did not match",
1733*07dc1947SRichard Lowe                          data_start,err_count_out);
1734*07dc1947SRichard Lowe                  }
1735*07dc1947SRichard Lowe                  mismatch = memcmp(dwarf_arm_standard_opcode_operand_count,
1736*07dc1947SRichard Lowe                                   prefix_out->pf_opcode_length_table,
1737*07dc1947SRichard Lowe                                   STANDARD_OPERAND_COUNT_DWARF3);
1738*07dc1947SRichard Lowe                  if(!mismatch && err_count_out) {
1739*07dc1947SRichard Lowe                      print_header_issue(dbg,"arm (incorrect) operands in use",
1740*07dc1947SRichard Lowe                          data_start,err_count_out);
1741*07dc1947SRichard Lowe                  }
1742*07dc1947SRichard Lowe             }
1743*07dc1947SRichard Lowe             if (!mismatch) {
1744*07dc1947SRichard Lowe                 if (version == 2) {
1745*07dc1947SRichard Lowe                     if(err_count_out) {
1746*07dc1947SRichard Lowe                         print_header_issue(dbg,
1747*07dc1947SRichard Lowe                         "standard DWARF3 operands matched, but is DWARF2 linetable",
1748*07dc1947SRichard Lowe                             data_start,err_count_out);
1749*07dc1947SRichard Lowe                     }
1750*07dc1947SRichard Lowe                 }
1751*07dc1947SRichard Lowe                 operand_ck_fail = false;
1752*07dc1947SRichard Lowe                 prefix_out->pf_std_op_count =
1753*07dc1947SRichard Lowe                     STANDARD_OPERAND_COUNT_DWARF3;
1754*07dc1947SRichard Lowe             }
1755*07dc1947SRichard Lowe         }
1756*07dc1947SRichard Lowe         if (operand_ck_fail) {
1757*07dc1947SRichard Lowe             if (prefix_out->pf_opcode_base >=
1758*07dc1947SRichard Lowe                 STANDARD_OPERAND_COUNT_DWARF2) {
1759*07dc1947SRichard Lowe 
1760*07dc1947SRichard Lowe                 int mismatch =
1761*07dc1947SRichard Lowe                     memcmp(dwarf_standard_opcode_operand_count,
1762*07dc1947SRichard Lowe                            prefix_out->pf_opcode_length_table,
1763*07dc1947SRichard Lowe                            STANDARD_OPERAND_COUNT_DWARF2);
1764*07dc1947SRichard Lowe                 if(mismatch) {
1765*07dc1947SRichard Lowe                     if(err_count_out) {
1766*07dc1947SRichard Lowe                         print_header_issue(dbg,"standard-operands-lengths did not match",
1767*07dc1947SRichard Lowe                             data_start,err_count_out);
1768*07dc1947SRichard Lowe                     }
1769*07dc1947SRichard Lowe                     mismatch = memcmp(dwarf_arm_standard_opcode_operand_count,
1770*07dc1947SRichard Lowe                                   prefix_out->pf_opcode_length_table,
1771*07dc1947SRichard Lowe                                   STANDARD_OPERAND_COUNT_DWARF2);
1772*07dc1947SRichard Lowe                     if(!mismatch && err_count_out) {
1773*07dc1947SRichard Lowe                         print_header_issue(dbg,"arm (incorrect) operand in use",
1774*07dc1947SRichard Lowe                             data_start,err_count_out);
1775*07dc1947SRichard Lowe                     }
1776*07dc1947SRichard Lowe                 }
1777*07dc1947SRichard Lowe 
1778*07dc1947SRichard Lowe                 if (!mismatch) {
1779*07dc1947SRichard Lowe                     operand_ck_fail = false;
1780*07dc1947SRichard Lowe                     prefix_out->pf_std_op_count =
1781*07dc1947SRichard Lowe                         STANDARD_OPERAND_COUNT_DWARF2;
1782*07dc1947SRichard Lowe                 }
1783*07dc1947SRichard Lowe             }
1784*07dc1947SRichard Lowe         }
1785*07dc1947SRichard Lowe         if (operand_ck_fail) {
1786*07dc1947SRichard Lowe             /* Here we are not sure what the pf_std_op_count is. */
1787*07dc1947SRichard Lowe             _dwarf_error(dbg, err, DW_DLE_LINE_NUM_OPERANDS_BAD);
1788*07dc1947SRichard Lowe             return (DW_DLV_ERROR);
1789*07dc1947SRichard Lowe         }
1790*07dc1947SRichard Lowe     }
1791*07dc1947SRichard Lowe     /* At this point we no longer need to check operand counts. */
1792*07dc1947SRichard Lowe 
1793*07dc1947SRichard Lowe 
1794*07dc1947SRichard Lowe     directories_count = 0;
1795*07dc1947SRichard Lowe     directories_malloc = 5;
1796*07dc1947SRichard Lowe     prefix_out->pf_include_directories = malloc(sizeof(Dwarf_Small *) *
1797*07dc1947SRichard Lowe                                                 directories_malloc);
1798*07dc1947SRichard Lowe     if (prefix_out->pf_include_directories == NULL) {
1799*07dc1947SRichard Lowe         _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
1800*07dc1947SRichard Lowe         return (DW_DLV_ERROR);
1801*07dc1947SRichard Lowe     }
1802*07dc1947SRichard Lowe     memset(prefix_out->pf_include_directories, 0,
1803*07dc1947SRichard Lowe            sizeof(Dwarf_Small *) * directories_malloc);
1804*07dc1947SRichard Lowe 
1805*07dc1947SRichard Lowe     while ((*(char *) line_ptr) != '\0') {
1806*07dc1947SRichard Lowe         if (directories_count >= directories_malloc) {
1807*07dc1947SRichard Lowe             Dwarf_Unsigned expand = 2 * directories_malloc;
1808*07dc1947SRichard Lowe             Dwarf_Unsigned bytesalloc = sizeof(Dwarf_Small *) * expand;
1809*07dc1947SRichard Lowe             Dwarf_Small **newdirs =
1810*07dc1947SRichard Lowe                 realloc(prefix_out->pf_include_directories,
1811*07dc1947SRichard Lowe                         bytesalloc);
1812*07dc1947SRichard Lowe 
1813*07dc1947SRichard Lowe             if (!newdirs) {
1814*07dc1947SRichard Lowe                 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
1815*07dc1947SRichard Lowe                 return (DW_DLV_ERROR);
1816*07dc1947SRichard Lowe             }
1817*07dc1947SRichard Lowe             /* Doubled size, zero out second half. */
1818*07dc1947SRichard Lowe             memset(newdirs + directories_malloc, 0,
1819*07dc1947SRichard Lowe                    sizeof(Dwarf_Small *) * directories_malloc);
1820*07dc1947SRichard Lowe             directories_malloc = expand;
1821*07dc1947SRichard Lowe             prefix_out->pf_include_directories = newdirs;
1822*07dc1947SRichard Lowe         }
1823*07dc1947SRichard Lowe         prefix_out->pf_include_directories[directories_count] =
1824*07dc1947SRichard Lowe             line_ptr;
1825*07dc1947SRichard Lowe         line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
1826*07dc1947SRichard Lowe         directories_count++;
1827*07dc1947SRichard Lowe     }
1828*07dc1947SRichard Lowe     prefix_out->pf_include_directories_count = directories_count;
1829*07dc1947SRichard Lowe     line_ptr++;
1830*07dc1947SRichard Lowe 
1831*07dc1947SRichard Lowe     files_count = 0;
1832*07dc1947SRichard Lowe     files_malloc = 5;
1833*07dc1947SRichard Lowe     prefix_out->pf_line_table_file_entries =
1834*07dc1947SRichard Lowe         malloc(sizeof(struct Line_Table_File_Entry_s) * files_malloc);
1835*07dc1947SRichard Lowe     if (prefix_out->pf_line_table_file_entries == NULL) {
1836*07dc1947SRichard Lowe         _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
1837*07dc1947SRichard Lowe         return (DW_DLV_ERROR);
1838*07dc1947SRichard Lowe     }
1839*07dc1947SRichard Lowe     memset(prefix_out->pf_line_table_file_entries, 0,
1840*07dc1947SRichard Lowe            sizeof(struct Line_Table_File_Entry_s) * files_malloc);
1841*07dc1947SRichard Lowe 
1842*07dc1947SRichard Lowe     while (*(char *) line_ptr != '\0') {
1843*07dc1947SRichard Lowe         Dwarf_Unsigned utmp;
1844*07dc1947SRichard Lowe         Dwarf_Unsigned dir_index = 0;
1845*07dc1947SRichard Lowe         Dwarf_Unsigned lastmod = 0;
1846*07dc1947SRichard Lowe         Dwarf_Unsigned file_length = 0;
1847*07dc1947SRichard Lowe         struct Line_Table_File_Entry_s *curline;
1848*07dc1947SRichard Lowe         Dwarf_Word leb128_length = 0;
1849*07dc1947SRichard Lowe 
1850*07dc1947SRichard Lowe 
1851*07dc1947SRichard Lowe         if (files_count >= files_malloc) {
1852*07dc1947SRichard Lowe             Dwarf_Unsigned expand = 2 * files_malloc;
1853*07dc1947SRichard Lowe             struct Line_Table_File_Entry_s *newfiles =
1854*07dc1947SRichard Lowe                 realloc(prefix_out->pf_line_table_file_entries,
1855*07dc1947SRichard Lowe                         sizeof(struct Line_Table_File_Entry_s) *
1856*07dc1947SRichard Lowe                         expand);
1857*07dc1947SRichard Lowe             if (!newfiles) {
1858*07dc1947SRichard Lowe                 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
1859*07dc1947SRichard Lowe                 return (DW_DLV_ERROR);
1860*07dc1947SRichard Lowe             }
1861*07dc1947SRichard Lowe             memset(newfiles + files_malloc, 0,
1862*07dc1947SRichard Lowe                    sizeof(struct Line_Table_File_Entry_s) *
1863*07dc1947SRichard Lowe                    files_malloc);
1864*07dc1947SRichard Lowe             files_malloc = expand;
1865*07dc1947SRichard Lowe             prefix_out->pf_line_table_file_entries = newfiles;
1866*07dc1947SRichard Lowe         }
1867*07dc1947SRichard Lowe         curline = prefix_out->pf_line_table_file_entries + files_count;
1868*07dc1947SRichard Lowe 
1869*07dc1947SRichard Lowe         curline->lte_filename = line_ptr;
1870*07dc1947SRichard Lowe         line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
1871*07dc1947SRichard Lowe 
1872*07dc1947SRichard Lowe         DECODE_LEB128_UWORD(line_ptr, utmp);
1873*07dc1947SRichard Lowe         dir_index = (Dwarf_Sword) utmp;
1874*07dc1947SRichard Lowe         if (dir_index > directories_count) {
1875*07dc1947SRichard Lowe             _dwarf_error(dbg, err, DW_DLE_DIR_INDEX_BAD);
1876*07dc1947SRichard Lowe             return (DW_DLV_ERROR);
1877*07dc1947SRichard Lowe         }
1878*07dc1947SRichard Lowe         curline->lte_directory_index = dir_index;
1879*07dc1947SRichard Lowe 
1880*07dc1947SRichard Lowe         lastmod = _dwarf_decode_u_leb128(line_ptr, &leb128_length);
1881*07dc1947SRichard Lowe         line_ptr = line_ptr + leb128_length;
1882*07dc1947SRichard Lowe         curline->lte_last_modification_time = lastmod;
1883*07dc1947SRichard Lowe 
1884*07dc1947SRichard Lowe         /* Skip over file length. */
1885*07dc1947SRichard Lowe         file_length = _dwarf_decode_u_leb128(line_ptr, &leb128_length);
1886*07dc1947SRichard Lowe         line_ptr = line_ptr + leb128_length;
1887*07dc1947SRichard Lowe         curline->lte_length_of_file = file_length;
1888*07dc1947SRichard Lowe 
1889*07dc1947SRichard Lowe         ++files_count;
1890*07dc1947SRichard Lowe 
1891*07dc1947SRichard Lowe     }
1892*07dc1947SRichard Lowe     prefix_out->pf_files_count = files_count;
1893*07dc1947SRichard Lowe     /* Skip trailing nul byte */
1894*07dc1947SRichard Lowe     ++line_ptr;
1895*07dc1947SRichard Lowe 
1896*07dc1947SRichard Lowe 
1897*07dc1947SRichard Lowe     lp_begin = prefix_out->pf_line_prologue_start +
1898*07dc1947SRichard Lowe                      prefix_out->pf_prologue_length;
1899*07dc1947SRichard Lowe     if (line_ptr != lp_begin) {
1900*07dc1947SRichard Lowe         if(line_ptr > lp_begin) {
1901*07dc1947SRichard Lowe             _dwarf_error(dbg, err, DW_DLE_LINE_PROLOG_LENGTH_BAD);
1902*07dc1947SRichard Lowe             return (DW_DLV_ERROR);
1903*07dc1947SRichard Lowe         } else {
1904*07dc1947SRichard Lowe             /* Bug in compiler. These
1905*07dc1947SRichard Lowe              * bytes are really part of the instruction
1906*07dc1947SRichard Lowe              * stream.  The prefix_out->pf_prologue_length is
1907*07dc1947SRichard Lowe              * wrong (12 too high).  */
1908*07dc1947SRichard Lowe             if(bogus_bytes_ptr) {
1909*07dc1947SRichard Lowe                *bogus_bytes_ptr = line_ptr;
1910*07dc1947SRichard Lowe             }
1911*07dc1947SRichard Lowe             if(bogus_bytes) {
1912*07dc1947SRichard Lowe                /* How far off things are. We expect the
1913*07dc1947SRichard Lowe                   value 12 ! */
1914*07dc1947SRichard Lowe                *bogus_bytes = (lp_begin - line_ptr);
1915*07dc1947SRichard Lowe             }
1916*07dc1947SRichard Lowe         }
1917*07dc1947SRichard Lowe         /* Ignore the lp_begin calc. Assume line_ptr right.
1918*07dc1947SRichard Lowe            Making up for compiler bug. */
1919*07dc1947SRichard Lowe         lp_begin = line_ptr;
1920*07dc1947SRichard Lowe 
1921*07dc1947SRichard Lowe     }
1922*07dc1947SRichard Lowe 
1923*07dc1947SRichard Lowe     *updated_data_start_out = lp_begin;
192449d3bc91SRichard Lowe     return DW_DLV_OK;
192549d3bc91SRichard Lowe }
1926*07dc1947SRichard Lowe 
1927*07dc1947SRichard Lowe 
1928*07dc1947SRichard Lowe /* Initialize the Line_Table_Prefix_s struct.
1929*07dc1947SRichard Lowe    memset is not guaranteed a portable initializer, but works
1930*07dc1947SRichard Lowe    fine for current architectures.   AFAIK.
1931*07dc1947SRichard Lowe */
1932*07dc1947SRichard Lowe void
dwarf_init_line_table_prefix(struct Line_Table_Prefix_s * pf)1933*07dc1947SRichard Lowe dwarf_init_line_table_prefix(struct Line_Table_Prefix_s *pf)
1934*07dc1947SRichard Lowe {
1935*07dc1947SRichard Lowe     memset(pf, 0, sizeof(*pf));
1936*07dc1947SRichard Lowe }
1937*07dc1947SRichard Lowe 
1938*07dc1947SRichard Lowe /* Free any malloc'd area.  of the Line_Table_Prefix_s struct. */
1939*07dc1947SRichard Lowe void
dwarf_free_line_table_prefix(struct Line_Table_Prefix_s * pf)1940*07dc1947SRichard Lowe dwarf_free_line_table_prefix(struct Line_Table_Prefix_s *pf)
1941*07dc1947SRichard Lowe {
1942*07dc1947SRichard Lowe     if (pf->pf_include_directories) {
1943*07dc1947SRichard Lowe         free(pf->pf_include_directories);
1944*07dc1947SRichard Lowe         pf->pf_include_directories = 0;
1945*07dc1947SRichard Lowe     }
1946*07dc1947SRichard Lowe     if (pf->pf_line_table_file_entries) {
1947*07dc1947SRichard Lowe         free(pf->pf_line_table_file_entries);
1948*07dc1947SRichard Lowe         pf->pf_line_table_file_entries = 0;
1949*07dc1947SRichard Lowe     }
1950*07dc1947SRichard Lowe     return;
1951*07dc1947SRichard Lowe }
1952