xref: /illumos-gate/usr/src/lib/libdwarf/common/dwarf_line.c (revision 4d9fdb46b215739778ebc12079842c9905586999)
1 /*
2    Copyright (C) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
3    Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved.
4    Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved.
5    Portions Copyright (C) 2015-2015 Google, Inc. All Rights Reserved.
6 
7    This program is free software; you can redistribute it and/or modify it
8    under the terms of version 2.1 of the GNU Lesser General Public License
9    as published by the Free Software Foundation.
10 
11    This program is distributed in the hope that it would be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 
15    Further, this software is distributed without any warranty that it is
16    free of the rightful claim of any third person regarding infringement
17    or the like.  Any license provided herein, whether implied or
18    otherwise, applies only to this software file.  Patent licenses, if
19    any, provided herein do not apply to combinations of this program with
20    other software, or any other product whatsoever.
21 
22    You should have received a copy of the GNU Lesser General Public
23    License along with this program; if not, write the Free Software
24    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
25    USA.
26 
27 */
28 
29 #include "config.h"
30 #include <stdio.h>
31 #ifdef HAVE_STDLIB_H
32 #include <stdlib.h>
33 #endif /* HAVE_STDLIB_H */
34 #include "dwarf_incl.h"
35 #include "dwarf_alloc.h"
36 #include "dwarf_error.h"
37 #include "dwarf_util.h"
38 #include "dwarf_line.h"
39 #include "dwarfstring.h"
40 
41 /* Line Register Set initial conditions. */
42 static struct Dwarf_Line_Registers_s _dwarf_line_table_regs_default_values = {
43     /* Dwarf_Addr lr_address */ 0,
44     /* Dwarf_Unsigned lr_file */ 1,
45     /* Dwarf_Unsigned lr_line */  1,
46     /* Dwarf_Unsigned lr_column */  0,
47     /* Dwarf_Bool lr_is_stmt */  false,
48     /* Dwarf_Bool lr_basic_block */  false,
49     /* Dwarf_Bool lr_end_sequence */  false,
50     /* Dwarf_Bool lr_prologue_end */  false,
51     /* Dwarf_Bool lr_epilogue_begin */  false,
52     /* Dwarf_Small lr_isa */  0,
53     /* Dwarf_Unsigned lr_op_index  */  0,
54     /* Dwarf_Unsigned lr_discriminator */  0,
55     /* Dwarf_Unsigned lr_call_context */  0,
56     /* Dwarf_Unsigned lr_subprogram */  0,
57 };
58 
59 void
_dwarf_set_line_table_regs_default_values(Dwarf_Line_Registers regs,unsigned lineversion,Dwarf_Bool is_stmt)60 _dwarf_set_line_table_regs_default_values(Dwarf_Line_Registers regs,
61     unsigned lineversion,
62     Dwarf_Bool is_stmt)
63 {
64     *regs = _dwarf_line_table_regs_default_values;
65     if (lineversion == DW_LINE_VERSION5) {
66         /* DWARF5 file base is zero. */
67         regs->lr_file = 0;
68     }
69     regs->lr_is_stmt = is_stmt;
70 }
71 
72 
73 static int
is_path_separator(Dwarf_Small s)74 is_path_separator(Dwarf_Small s)
75 {
76     if (s == '/') {
77         return 1;
78     }
79 #ifdef HAVE_WINDOWS_PATH
80     if (s == '\\') {
81         return 1;
82     }
83 #endif
84     return 0;
85 }
86 
87 /*  Return 0 if false, 1 if true.
88     If HAVE_WINDOWS_PATH is defined we
89     attempt to handle windows full paths:
90     \\something   or  C:cwdpath.c
91 */
92 int
_dwarf_file_name_is_full_path(Dwarf_Small * fname)93 _dwarf_file_name_is_full_path(Dwarf_Small  *fname)
94 {
95     Dwarf_Small firstc = *fname;
96     if (is_path_separator(firstc)) {
97         /* Full path. */
98         return 1;
99     }
100     if (!firstc) {
101         return 0;
102     }
103 /*  This is a windows path test, but we do have
104     a few windows paths in our regression tests...
105     This is extremely unlikely to cause UN*X/POSIX
106     users any problems. */
107     if ((firstc >= 'A' && firstc <= 'Z') ||
108         (firstc >= 'a' && firstc <= 'z')) {
109 
110         Dwarf_Small secondc = fname[1];
111         if (secondc == ':') {
112             return 1;
113         }
114     }
115 /* End Windows style */
116     return 0;
117 }
118 #include "dwarf_line_table_reader_common.h"
119 
120 static void
special_cat(char * dst,char * src,UNUSEDARG int srclen)121 special_cat(char *dst,char *src,
122     UNUSEDARG int srclen)
123 {
124 #if defined (HAVE_WINDOWS_PATH)
125     /*  Always '/' instead of '\\', this is a Windows -> Unix
126         issue. */
127     int i1 = 0;
128     int i2 = 0;
129 
130     for ( ; dst[i1] ; ++i1) {
131     }
132     for (; i2 < srclen; ++i2,++i1) {
133         dst[i1] = src[i2];
134         if (dst[i1] == '\\') {
135             dst[i1] = '/';
136         }
137     }
138 #else
139     strcat(dst, src);
140 #endif /* HAVE_WINDOWS_PATH */
141     return;
142 }
143 
144 /*  With this routine we ensure the file full path
145     is calculated identically for
146     dwarf_srcfiles() and dwarf_filename()
147 
148     As of March 14 2020 this *always*
149     does an allocation for the string. dwarf_dealloc
150     is crucial to do no matter what.
151     So we have consistency.
152 
153     dwarf_finish() will do the dealloc if nothing else does.
154     Unless the calling application did the call
155     dwarf_set_de_alloc_flag(0).
156 */
157 static int
create_fullest_file_path(Dwarf_Debug dbg,Dwarf_File_Entry fe,Dwarf_Line_Context line_context,char ** name_ptr_out,Dwarf_Error * error)158 create_fullest_file_path(Dwarf_Debug dbg,
159     Dwarf_File_Entry fe,
160     Dwarf_Line_Context line_context,
161     char ** name_ptr_out,
162     Dwarf_Error *error)
163 {
164     Dwarf_Unsigned dirno = 0;
165     char *full_name = 0;
166     char *file_name = 0;
167 
168     dirno = fe->fi_dir_index;
169     file_name = (char *) fe->fi_file_name;
170     if (!file_name) {
171         _dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME);
172         return (DW_DLV_ERROR);
173     }
174     if (_dwarf_file_name_is_full_path((Dwarf_Small *)file_name)) {
175         {   unsigned len = strlen(file_name);
176             char *tmp = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING,
177                 len+1);
178             if(tmp) {
179                 tmp[0] = 0;
180                 special_cat(tmp,file_name,len);
181                 *name_ptr_out = tmp;
182                 return DW_DLV_OK;
183             }
184             _dwarf_error(dbg,error,DW_DLE_ALLOC_FAIL);
185             return DW_DLV_ERROR;
186         }
187     } else {
188         char *comp_dir_name = "";
189         char *inc_dir_name = "";
190         Dwarf_Unsigned incdirnamelen = 0;
191         Dwarf_Unsigned filenamelen = strlen(file_name);
192         Dwarf_Unsigned compdirnamelen = 0;
193 
194         if (line_context->lc_compilation_directory) {
195             comp_dir_name =
196                 (char *)line_context->lc_compilation_directory;
197             compdirnamelen = strlen(comp_dir_name);
198         }
199 
200         if (dirno > line_context->lc_include_directories_count) {
201             _dwarf_error(dbg, error, DW_DLE_INCL_DIR_NUM_BAD);
202             return (DW_DLV_ERROR);
203         }
204         if (dirno > 0 && fe->fi_dir_index > 0) {
205             inc_dir_name = (char *) line_context->lc_include_directories[
206                 fe->fi_dir_index - 1];
207             if (!inc_dir_name) {
208                 /*  This should never ever happen except in case
209                     of a corrupted object file. */
210                 inc_dir_name = "<erroneous NULL include dir pointer>";
211             }
212             incdirnamelen = strlen(inc_dir_name);
213         }
214         full_name = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING,
215             compdirnamelen + 1 +
216             incdirnamelen + 1 +
217             filenamelen + 1);
218         if (full_name == NULL) {
219             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
220             return (DW_DLV_ERROR);
221         }
222         if (fe->fi_dir_index == 0) {
223             /*  Just use comp dir name */
224             if (compdirnamelen > 0) {
225                 special_cat(full_name,comp_dir_name,compdirnamelen);
226                 strcat(full_name, "/");
227             }
228             special_cat(full_name,file_name,filenamelen);
229             *name_ptr_out =  full_name;
230             return DW_DLV_OK;
231         }
232         if (incdirnamelen > 0 &&
233             _dwarf_file_name_is_full_path((Dwarf_Small*)inc_dir_name) ) {
234             /*  Just use inc dir. */
235             special_cat(full_name,inc_dir_name,incdirnamelen);
236             strcat(full_name,"/");
237             special_cat(full_name,file_name,filenamelen);
238             *name_ptr_out = full_name;
239             return DW_DLV_OK;
240         }
241         /* Concat all three names. */
242         if (compdirnamelen > 0) {
243             special_cat(full_name,comp_dir_name,compdirnamelen);
244             strcat(full_name, "/");
245         }
246         if (incdirnamelen > 0) {
247             special_cat(full_name,inc_dir_name,incdirnamelen);
248             strcat(full_name, "/");
249         }
250         special_cat(full_name,file_name,filenamelen);
251     }
252     *name_ptr_out = full_name;
253     return DW_DLV_OK;
254 }
255 
256 /*  Although source files is supposed to return the
257     source files in the compilation-unit, it does
258     not look for any in the statement program.  In
259     other words, it ignores those defined using the
260     extended opcode DW_LNE_define_file.
261     We do not know of a producer that uses DW_LNE_define_file.
262 
263     In DWARF2,3,4 the array of sourcefiles is represented
264     differently than DWARF5.
265     DWARF 2,3,4,:
266         Take the line number from macro information or lines data
267         and subtract 1 to  index into srcfiles.  Any with line
268         number zero can be assumed to refer to DW_AT_name from the
269         CU DIE, but zero really means "no file".
270     DWARF 5:
271         Just like DW4, but  index 1 refers to the
272         same string as DW_AT_name of the CU DIE.
273 */
274 int
dwarf_srcfiles(Dwarf_Die die,char *** srcfiles,Dwarf_Signed * srcfilecount,Dwarf_Error * error)275 dwarf_srcfiles(Dwarf_Die die,
276     char ***srcfiles,
277     Dwarf_Signed * srcfilecount, Dwarf_Error * error)
278 {
279     /*  This pointer is used to scan the portion of the .debug_line
280         section for the current cu. */
281     Dwarf_Small *line_ptr = 0;
282 
283     /*  Pointer to a DW_AT_stmt_list attribute in case it exists in the
284         die. */
285     Dwarf_Attribute stmt_list_attr = 0;
286 
287     const char * const_comp_name = 0;
288     /*  Pointer to name of compilation directory. */
289     const char * const_comp_dir = 0;
290     Dwarf_Small *comp_dir = 0;
291 
292     /*  Offset into .debug_line specified by a DW_AT_stmt_list
293         attribute. */
294     Dwarf_Unsigned line_offset = 0;
295 
296     /*  This points to a block of char *'s, each of which points to a
297         file name. */
298     char **ret_files = 0;
299 
300     /*  The Dwarf_Debug this die belongs to. */
301     Dwarf_Debug dbg = 0;
302     Dwarf_CU_Context context = 0;
303     Dwarf_Line_Context  line_context = 0;
304 
305     /*  Used to chain the file names. */
306     Dwarf_Chain curr_chain = NULL;
307     Dwarf_Chain prev_chain = NULL;
308     Dwarf_Chain head_chain = NULL;
309 
310     Dwarf_Half attrform = 0;
311     int resattr = DW_DLV_ERROR;
312     int lres = DW_DLV_ERROR;
313     unsigned i = 0;
314     int res = DW_DLV_ERROR;
315     Dwarf_Small *section_start = 0;
316 
317     /*  ***** BEGIN CODE ***** */
318     /*  Reset error. */
319 
320     if (error != NULL) {
321         *error = NULL;
322     }
323 
324     CHECK_DIE(die, DW_DLV_ERROR);
325     context = die->di_cu_context;
326     dbg = context->cc_dbg;
327 
328     resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
329     if (resattr != DW_DLV_OK) {
330         return resattr;
331     }
332 
333     if (dbg->de_debug_line.dss_index == 0) {
334         dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
335         _dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_NULL);
336         return (DW_DLV_ERROR);
337     }
338 
339     res = _dwarf_load_section(dbg, &dbg->de_debug_line,error);
340     if (res != DW_DLV_OK) {
341         dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
342         return res;
343     }
344     if (!dbg->de_debug_line.dss_size) {
345         dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
346         return (DW_DLV_NO_ENTRY);
347     }
348     section_start = dbg->de_debug_line.dss_data;
349 
350     lres = dwarf_whatform(stmt_list_attr,&attrform,error);
351     if (lres != DW_DLV_OK) {
352         dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
353         return lres;
354     }
355     if (attrform != DW_FORM_data4 && attrform != DW_FORM_data8 &&
356         attrform != DW_FORM_sec_offset  &&
357         attrform != DW_FORM_GNU_ref_alt) {
358         dwarfstring m;
359         dwarfstring f;
360         const char *formname = 0;
361 
362         dwarfstring_constructor(&f);
363         dwarf_get_FORM_name(attrform,&formname);
364         if (!formname) {
365             dwarfstring_append_printf_u(&f,"Invalid Form Code "
366                 " 0x" DW_PR_DUx,attrform);
367         } else {
368             dwarfstring_append(&f,(char *)formname);
369         }
370         dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
371         dwarfstring_constructor(&m);
372         dwarfstring_append_printf_s(&m,
373             "DW_DLE_LINE_OFFSET_WRONG_FORM: form %s "
374             "instead of an allowed section offset form.",
375             dwarfstring_string(&f));
376         _dwarf_error_string(dbg, error, DW_DLE_LINE_OFFSET_WRONG_FORM,
377             dwarfstring_string(&m));
378         dwarfstring_destructor(&m);
379         dwarfstring_destructor(&f);
380         return (DW_DLV_ERROR);
381     }
382     lres = dwarf_global_formref(stmt_list_attr, &line_offset, error);
383     if (lres != DW_DLV_OK) {
384         dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
385         return lres;
386     }
387     if (line_offset >= dbg->de_debug_line.dss_size) {
388         dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
389         _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
390         return (DW_DLV_ERROR);
391     }
392     line_ptr = dbg->de_debug_line.dss_data + line_offset;
393     {
394         Dwarf_Unsigned fission_offset = 0;
395         Dwarf_Unsigned fission_size = 0;
396         int resl = _dwarf_get_fission_addition_die(die, DW_SECT_LINE,
397             &fission_offset,&fission_size,error);
398         if(resl != DW_DLV_OK) {
399             dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
400             return resl;
401         }
402         line_ptr += fission_offset;
403         if (line_ptr > dbg->de_debug_line.dss_data +
404             dbg->de_debug_line.dss_size) {
405             dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
406             _dwarf_error(dbg, error, DW_DLE_FISSION_ADDITION_ERROR);
407             return DW_DLV_ERROR;
408         }
409     }
410     dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
411     stmt_list_attr = 0;
412 
413     resattr = _dwarf_internal_get_die_comp_dir(die, &const_comp_dir,
414         &const_comp_name,error);
415     if (resattr == DW_DLV_ERROR) {
416         return resattr;
417     }
418 
419     /* Horrible cast away const to match historical interfaces. */
420     comp_dir = (Dwarf_Small *)const_comp_dir;
421     line_context = (Dwarf_Line_Context)
422         _dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1);
423     if (line_context == NULL) {
424         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
425         return (DW_DLV_ERROR);
426     }
427     line_context->lc_new_style_access = false;
428     /*  We are in dwarf_srcfiles() */
429     {
430         Dwarf_Small *line_ptr_out = 0;
431         int dres = 0;
432 
433         dres = _dwarf_read_line_table_header(dbg,
434             context,
435             section_start,
436             line_ptr,
437             dbg->de_debug_line.dss_size,
438             &line_ptr_out,
439             line_context,
440             NULL, NULL,error,
441             0);
442 
443         if (dres == DW_DLV_ERROR) {
444             dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
445             line_context = 0;
446             return dres;
447         }
448         if (dres == DW_DLV_NO_ENTRY) {
449             dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
450             line_context = 0;
451             return dres;
452         }
453     }
454     /*  For DWARF5, use of DW_AT_comp_dir not needed.
455         Line table file names and directories
456         start with comp_dir and name.  FIXME DWARF5 */
457     line_context->lc_compilation_directory = comp_dir;
458     /* We are in dwarf_srcfiles() */
459     {
460         Dwarf_File_Entry fe = 0;
461         Dwarf_File_Entry fe2 =line_context->lc_file_entries;
462         Dwarf_Signed baseindex = 0;
463         Dwarf_Signed file_count = 0;
464         Dwarf_Signed endindex = 0;
465 
466         res =  dwarf_srclines_files_indexes(line_context, &baseindex,
467             &file_count, &endindex, error);
468         if (res != DW_DLV_OK) {
469             return res;
470         }
471         for (i = baseindex; i < endindex; ++i,fe2 = fe->fi_next ) {
472             int sres = 0;
473             char *name_out = 0;
474 
475             fe = fe2;
476             sres = create_fullest_file_path(dbg,fe,line_context,
477                 &name_out,error);
478             if (sres != DW_DLV_OK) {
479                 dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
480                 /* This can leak some strings */
481                 return sres;
482             }
483             curr_chain =
484                 (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
485             if (curr_chain == NULL) {
486                 dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
487                 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
488                 return (DW_DLV_ERROR);
489             }
490             curr_chain->ch_item = name_out;
491             if (head_chain == NULL) {
492                 head_chain = prev_chain = curr_chain;
493             } else {
494                 prev_chain->ch_next = curr_chain;
495                 prev_chain = curr_chain;
496             }
497         }
498     }
499     if (!head_chain) {
500         dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
501         *srcfiles = NULL;
502         *srcfilecount = 0;
503         return DW_DLV_NO_ENTRY;
504     }
505 
506     /* We are in dwarf_srcfiles() */
507     if (line_context->lc_file_entry_count == 0) {
508         dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
509         *srcfiles = NULL;
510         *srcfilecount = 0;
511         return DW_DLV_NO_ENTRY;
512     }
513 
514     ret_files = (char **)
515         _dwarf_get_alloc(dbg, DW_DLA_LIST,
516         line_context->lc_file_entry_count);
517     if (ret_files == NULL) {
518         dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
519         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
520         return (DW_DLV_ERROR);
521     }
522 
523     curr_chain = head_chain;
524     for (i = 0; i < line_context->lc_file_entry_count; i++) {
525         *(ret_files + i) = curr_chain->ch_item;
526         curr_chain->ch_item = 0;
527         prev_chain = curr_chain;
528         curr_chain = curr_chain->ch_next;
529         dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
530     }
531     /*  Our chain is not recorded in the line_context so
532         the line_context destructor will not destroy our
533         list of strings or our strings.
534         Our caller has to do the deallocations.  */
535     *srcfiles = ret_files;
536     *srcfilecount = line_context->lc_file_entry_count;
537     dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
538     return (DW_DLV_OK);
539 }
540 
541 
542 
543 /*  Return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR
544     doaddrs is true iff this is being called for SGI IRIX rqs processing
545     (ie, not a normal libdwarf dwarf_srclines or two-level  user call at all).
546     dolines is true iff this is called by a dwarf_srclines call.
547 
548     In case of error or NO_ENTRY in this code we use the
549     dwarf_srcline_dealloc(line_context)
550     and dealloc of DW_DLA_LINE_CONTEXT
551     from the new interface for uniformity here.
552 */
553 
554 int
_dwarf_internal_srclines(Dwarf_Die die,Dwarf_Bool is_new_interface,Dwarf_Unsigned * version,Dwarf_Small * table_count,Dwarf_Line_Context * line_context_out,Dwarf_Line ** linebuf,Dwarf_Signed * linecount,Dwarf_Line ** linebuf_actuals,Dwarf_Signed * linecount_actuals,Dwarf_Bool doaddrs,Dwarf_Bool dolines,Dwarf_Error * error)555 _dwarf_internal_srclines(Dwarf_Die die,
556     Dwarf_Bool is_new_interface,
557     Dwarf_Unsigned * version,
558     Dwarf_Small    * table_count, /* returns 0,1, or 2 */
559     Dwarf_Line_Context *line_context_out,
560     Dwarf_Line ** linebuf,
561     Dwarf_Signed * linecount,
562     Dwarf_Line ** linebuf_actuals,
563     Dwarf_Signed * linecount_actuals,
564     Dwarf_Bool doaddrs,
565     Dwarf_Bool dolines,
566     Dwarf_Error * error)
567 {
568     /*  This pointer is used to scan the portion of the .debug_line
569         section for the current cu. */
570     Dwarf_Small *line_ptr = 0;
571 
572     /*  This points to the last byte of the .debug_line portion for the
573         current cu. */
574     Dwarf_Small *line_ptr_end = 0;
575 
576     /*  For two-level line tables, this points to the first byte of the
577         actuals table (and the end of the logicals table) for the current
578         cu. */
579     Dwarf_Small *line_ptr_actuals = 0;
580     Dwarf_Small *section_start = 0;
581     Dwarf_Small *section_end = 0;
582 
583     /*  Pointer to a DW_AT_stmt_list attribute in case it exists in the
584         die. */
585     Dwarf_Attribute stmt_list_attr = 0;
586 
587     const char * const_comp_name = 0;
588     /*  Pointer to name of compilation directory. */
589     const char * const_comp_dir = NULL;
590     Dwarf_Small *comp_dir = NULL;
591 
592     /*  Offset into .debug_line specified by a DW_AT_stmt_list
593         attribute. */
594     Dwarf_Unsigned line_offset = 0;
595 
596     /*  Pointer to a Dwarf_Line_Context_s structure that contains the
597         context such as file names and include directories for the set
598         of lines being generated.
599         This is always recorded on an
600         DW_LNS_end_sequence operator,
601         on  all special opcodes, and on DW_LNS_copy.
602         */
603     Dwarf_Line_Context line_context = 0;
604     Dwarf_CU_Context   cu_context = 0;
605     Dwarf_Unsigned fission_offset = 0;
606 
607     /*  The Dwarf_Debug this die belongs to. */
608     Dwarf_Debug dbg = 0;
609     int resattr = DW_DLV_ERROR;
610     int lres = DW_DLV_ERROR;
611     Dwarf_Half address_size = 0;
612     Dwarf_Small * orig_line_ptr = 0;
613 
614     int res = DW_DLV_ERROR;
615 
616     /*  ***** BEGIN CODE ***** */
617     if (error != NULL) {
618         *error = NULL;
619     }
620 
621     CHECK_DIE(die, DW_DLV_ERROR);
622     cu_context = die->di_cu_context;
623     dbg = cu_context->cc_dbg;
624 
625     res = _dwarf_load_section(dbg, &dbg->de_debug_line,error);
626     if (res != DW_DLV_OK) {
627         return res;
628     }
629     if (!dbg->de_debug_line.dss_size) {
630         return (DW_DLV_NO_ENTRY);
631     }
632 
633     address_size = _dwarf_get_address_size(dbg, die);
634     resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
635     if (resattr != DW_DLV_OK) {
636         return resattr;
637     }
638     lres = dwarf_global_formref(stmt_list_attr, &line_offset, error);
639     if (lres != DW_DLV_OK) {
640         dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
641         return lres;
642     }
643 
644     if (line_offset >= dbg->de_debug_line.dss_size) {
645         dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
646         _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
647         return (DW_DLV_ERROR);
648     }
649     section_start = dbg->de_debug_line.dss_data;
650     section_end = section_start  +dbg->de_debug_line.dss_size;
651     {
652         Dwarf_Unsigned fission_size = 0;
653         int resf = _dwarf_get_fission_addition_die(die, DW_SECT_LINE,
654             &fission_offset,&fission_size,error);
655         if(resf != DW_DLV_OK) {
656             dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
657             return resf;
658         }
659         line_ptr += fission_offset;
660         if (line_ptr > section_end) {
661             _dwarf_error(dbg, error, DW_DLE_FISSION_ADDITION_ERROR);
662             return DW_DLV_ERROR;
663         }
664     }
665 
666     section_start = dbg->de_debug_line.dss_data;
667     section_end = section_start  +dbg->de_debug_line.dss_size;
668     orig_line_ptr = section_start + line_offset + fission_offset;
669     line_ptr = orig_line_ptr;
670     dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
671     if ((line_offset + fission_offset) > dbg->de_debug_line.dss_size) {
672         _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
673         return DW_DLV_ERROR;
674     }
675     if (line_ptr > section_end) {
676         _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
677         return DW_DLV_ERROR;
678     }
679 
680     /*  If die has DW_AT_comp_dir attribute, get the string that names
681         the compilation directory. */
682     resattr = _dwarf_internal_get_die_comp_dir(die, &const_comp_dir,
683         &const_comp_name,error);
684     if (resattr == DW_DLV_ERROR) {
685         return resattr;
686     }
687     /* Horrible cast to match historic interfaces. */
688     comp_dir = (Dwarf_Small *)const_comp_dir;
689     line_context = (Dwarf_Line_Context)
690         _dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1);
691     if (line_context == NULL) {
692         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
693         return (DW_DLV_ERROR);
694     }
695     line_context->lc_new_style_access = is_new_interface;
696     line_context->lc_compilation_directory = comp_dir;
697     /*  We are in dwarf_internal_srclines() */
698     {
699         Dwarf_Small *newlinep = 0;
700         int resp = _dwarf_read_line_table_header(dbg,
701             cu_context,
702             section_start,
703             line_ptr,
704             dbg->de_debug_line.dss_size,
705             &newlinep,
706             line_context,
707             NULL,NULL,
708             error,
709             0);
710 
711         if (resp == DW_DLV_ERROR) {
712             if(is_new_interface) {
713                 dwarf_srclines_dealloc_b(line_context);
714             } else {
715                 dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT);
716             }
717             return resp;
718         }
719         if (resp == DW_DLV_NO_ENTRY) {
720             if(is_new_interface) {
721                 dwarf_srclines_dealloc_b(line_context);
722             } else {
723                 dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT);
724             }
725             return resp;
726         }
727         line_ptr_end = line_context->lc_line_ptr_end;
728         line_ptr = newlinep;
729         if (line_context->lc_actuals_table_offset > 0) {
730             line_ptr_actuals = line_context->lc_line_prologue_start +
731                 line_context->lc_actuals_table_offset;
732         }
733     }
734 
735 
736     if (line_ptr_actuals == 0) {
737         /* ASSERT: lc_table_count == 1 or lc_table_count == 0 */
738         int err_count_out = 0;
739         /* Normal style (single level) line table. */
740         Dwarf_Bool is_actuals_table = false;
741         Dwarf_Bool local_is_single_table = true;
742         res = read_line_table_program(dbg,
743             line_ptr, line_ptr_end, orig_line_ptr,
744             section_start,
745             line_context,
746             address_size, doaddrs, dolines,
747             local_is_single_table,
748             is_actuals_table,
749             error,
750             &err_count_out);
751         if (res != DW_DLV_OK) {
752             if(is_new_interface) {
753                 dwarf_srclines_dealloc_b(line_context);
754             } else {
755                 dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT);
756             }
757             return res;
758         }
759         if (linebuf)
760             *linebuf = line_context->lc_linebuf_logicals;
761         if (linecount)
762             *linecount =  line_context->lc_linecount_logicals;
763         if (linebuf_actuals) {
764             *linebuf_actuals = NULL;
765         }
766         if (linecount_actuals) {
767             *linecount_actuals = 0;
768         }
769     } else {
770         Dwarf_Bool is_actuals_table = false;
771         Dwarf_Bool local2_is_single_table = false;
772         int err_count_out = 0;
773 
774         line_context->lc_is_single_table  = false;
775         /*  Two-level line table.
776             First read the logicals table. */
777         res = read_line_table_program(dbg,
778             line_ptr, line_ptr_actuals, orig_line_ptr,
779             section_start,
780             line_context,
781             address_size, doaddrs, dolines,
782             local2_is_single_table,
783             is_actuals_table, error,
784             &err_count_out);
785         if (res != DW_DLV_OK) {
786             if(is_new_interface) {
787                 dwarf_srclines_dealloc_b(line_context);
788             } else {
789                 dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT);
790             }
791             return res;
792         }
793         if (linebuf) {
794             *linebuf = line_context->lc_linebuf_logicals;
795         } else {
796         }
797         if (linecount) {
798             *linecount =  line_context->lc_linecount_logicals;
799         }
800         if (is_new_interface) {
801             /* ASSERT: linebuf_actuals == NULL  */
802             is_actuals_table = true;
803             /* The call requested an actuals table
804                 and one is present. So now read that one. */
805             res = read_line_table_program(dbg,
806 
807                 line_ptr_actuals, line_ptr_end, orig_line_ptr,
808                 section_start,
809                 line_context,
810                 address_size, doaddrs, dolines,
811                 local2_is_single_table,
812                 is_actuals_table, error,
813                 &err_count_out);
814             if (res != DW_DLV_OK) {
815                 dwarf_srclines_dealloc_b(line_context);
816                 return res;
817             }
818             if (linebuf_actuals) {
819                 *linebuf_actuals = line_context->lc_linebuf_actuals;
820             }
821             if (linecount_actuals != NULL) {
822                 *linecount_actuals = line_context->lc_linecount_actuals;
823             }
824         }
825     }
826     if (!is_new_interface && linecount &&
827         (linecount == 0 ||*linecount == 0) &&
828         (linecount_actuals == 0  || *linecount_actuals == 0)) {
829         /*  Here we have no actual lines of any kind. In other words,
830             it looks like a debugfission line table skeleton or
831             a caller not prepared for skeletons or two-level reading..
832             In that case there are no line entries so the context
833             had nowhere to be recorded. Hence we have to delete it
834             else we would leak the context.  */
835         dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
836         line_context = 0;
837         return DW_DLV_OK;
838     }
839     *table_count = line_context->lc_table_count;
840     if (version != NULL) {
841         *version = line_context->lc_version_number;
842     }
843     *line_context_out = line_context;
844     return (DW_DLV_OK);
845 }
846 
847 int
dwarf_get_ranges_section_name(Dwarf_Debug dbg,const char ** section_name_out,Dwarf_Error * error)848 dwarf_get_ranges_section_name(Dwarf_Debug dbg,
849     const char **section_name_out,
850     Dwarf_Error * error)
851 {
852     struct Dwarf_Section_s *sec = 0;
853     if (error != NULL) {
854         *error = NULL;
855     }
856     sec = &dbg->de_debug_ranges;
857     if (sec->dss_size == 0) {
858         /* We don't have such a  section at all. */
859         return DW_DLV_NO_ENTRY;
860     }
861     *section_name_out = sec->dss_name;
862     return DW_DLV_OK;
863 }
864 
865 int
dwarf_get_aranges_section_name(Dwarf_Debug dbg,const char ** section_name_out,Dwarf_Error * error)866 dwarf_get_aranges_section_name(Dwarf_Debug dbg,
867     const char **section_name_out,
868     Dwarf_Error * error)
869 {
870     struct Dwarf_Section_s *sec = 0;
871     if (error != NULL) {
872         *error = NULL;
873     }
874     sec = &dbg->de_debug_aranges;
875     if (sec->dss_size == 0) {
876         /* We don't have such a  section at all. */
877         return DW_DLV_NO_ENTRY;
878     }
879     *section_name_out = sec->dss_name;
880     return DW_DLV_OK;
881 }
882 
883 int
dwarf_get_line_section_name_from_die(Dwarf_Die die,const char ** section_name_out,Dwarf_Error * error)884 dwarf_get_line_section_name_from_die(Dwarf_Die die,
885     const char **section_name_out,
886     Dwarf_Error * error)
887 {
888     /*  The Dwarf_Debug this die belongs to. */
889     Dwarf_Debug dbg = 0;
890     struct Dwarf_Section_s *sec = 0;
891 
892     /*  ***** BEGIN CODE ***** */
893     if (error) {
894         *error = NULL;
895     }
896 
897     CHECK_DIE(die, DW_DLV_ERROR);
898     dbg = die->di_cu_context->cc_dbg;
899     sec = &dbg->de_debug_line;
900     if (sec->dss_size == 0) {
901         /* We don't have such a  section at all. */
902         return DW_DLV_NO_ENTRY;
903     }
904     *section_name_out = sec->dss_name;
905     return DW_DLV_OK;
906 }
907 
908 int
dwarf_get_string_section_name(Dwarf_Debug dbg,const char ** section_name_out,Dwarf_Error * error)909 dwarf_get_string_section_name(Dwarf_Debug dbg,
910     const char **section_name_out,
911     Dwarf_Error * error)
912 {
913     struct Dwarf_Section_s *sec = 0;
914 
915     /*  ***** BEGIN CODE ***** */
916     if (error != NULL) {
917         *error = NULL;
918     }
919 
920     sec = &dbg->de_debug_str;
921     if (sec->dss_size == 0) {
922         /* We don't have such a  section at all. */
923         return DW_DLV_NO_ENTRY;
924     }
925     *section_name_out = sec->dss_name;
926     return DW_DLV_OK;
927 }
928 
929 
930 int
dwarf_srclines(Dwarf_Die die,Dwarf_Line ** linebuf,Dwarf_Signed * linecount,Dwarf_Error * error)931 dwarf_srclines(Dwarf_Die die,
932     Dwarf_Line ** linebuf,
933     Dwarf_Signed * linecount, Dwarf_Error * error)
934 {
935     Dwarf_Unsigned version = 0;
936     Dwarf_Line_Context line_context = 0;
937     Dwarf_Small    table_count = 0;
938     Dwarf_Bool is_new_interface = false;
939     int res  = _dwarf_internal_srclines(die,
940         is_new_interface,
941         &version,
942         &table_count,
943         &line_context,
944         linebuf,
945         linecount,
946         /* linebuf_actuals */ 0,
947         /*linecount_actuals*/0,
948         /* addrlist= */ false,
949         /* linelist= */ true,
950         error);
951     return res;
952 }
953 
954 int
dwarf_srclines_two_level(Dwarf_Die die,Dwarf_Unsigned * version,Dwarf_Line ** linebuf,Dwarf_Signed * linecount,Dwarf_Line ** linebuf_actuals,Dwarf_Signed * linecount_actuals,Dwarf_Error * error)955 dwarf_srclines_two_level(Dwarf_Die die,
956     Dwarf_Unsigned * version,
957     Dwarf_Line    ** linebuf,
958     Dwarf_Signed   * linecount,
959     Dwarf_Line    ** linebuf_actuals,
960     Dwarf_Signed   * linecount_actuals,
961     Dwarf_Error    * error)
962 {
963     Dwarf_Line_Context line_context = 0;
964     Dwarf_Small table_count = 0;
965     Dwarf_Bool is_new_interface = false;
966     int res  = _dwarf_internal_srclines(die,
967         is_new_interface,
968         version,
969         &table_count,
970         &line_context,
971         linebuf,
972         linecount,
973         linebuf_actuals,
974         linecount_actuals,
975         /* addrlist= */ false,
976         /* linelist= */ true,
977         error);
978    return res;
979 }
980 
981 /* New October 2015. */
982 int
dwarf_srclines_b(Dwarf_Die die,Dwarf_Unsigned * version_out,Dwarf_Small * table_count,Dwarf_Line_Context * line_context,Dwarf_Error * error)983 dwarf_srclines_b(Dwarf_Die die,
984     Dwarf_Unsigned  * version_out,
985     Dwarf_Small     * table_count,
986     Dwarf_Line_Context * line_context,
987     Dwarf_Error * error)
988 {
989     Dwarf_Signed linecount_actuals = 0;
990     Dwarf_Line *linebuf = 0;
991     Dwarf_Line *linebuf_actuals = 0;
992     Dwarf_Signed linecount = 0;
993     Dwarf_Bool is_new_interface = true;
994     int res = 0;
995     Dwarf_Unsigned tcount = 0;
996 
997     res  = _dwarf_internal_srclines(die,
998         is_new_interface,
999         version_out,
1000         table_count,
1001         line_context,
1002         &linebuf,
1003         &linecount,
1004         &linebuf_actuals,
1005         &linecount_actuals,
1006         /* addrlist= */ false,
1007         /* linelist= */ true,
1008         error);
1009     if (res == DW_DLV_OK) {
1010         (*line_context)->lc_new_style_access = true;
1011     }
1012     if(linecount_actuals ) {
1013         tcount++;
1014     }
1015     if(linecount ) {
1016         tcount++;
1017     }
1018     *table_count = tcount;
1019     return res;
1020 }
1021 
1022 
1023 /* New October 2015. */
1024 int
dwarf_srclines_from_linecontext(Dwarf_Line_Context line_context,Dwarf_Line ** linebuf,Dwarf_Signed * linecount,Dwarf_Error * error)1025 dwarf_srclines_from_linecontext(Dwarf_Line_Context line_context,
1026     Dwarf_Line**     linebuf,
1027     Dwarf_Signed *   linecount,
1028     Dwarf_Error  *    error)
1029 {
1030     if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
1031         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
1032         return (DW_DLV_ERROR);
1033     }
1034     if (!line_context->lc_new_style_access) {
1035         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
1036         return (DW_DLV_ERROR);
1037     }
1038     *linebuf =           line_context->lc_linebuf_logicals;
1039     *linecount =         line_context->lc_linecount_logicals;
1040     return DW_DLV_OK;
1041 }
1042 
1043 /* New October 2015. */
1044 int
dwarf_srclines_two_level_from_linecontext(Dwarf_Line_Context line_context,Dwarf_Line ** linebuf,Dwarf_Signed * linecount,Dwarf_Line ** linebuf_actuals,Dwarf_Signed * linecount_actuals,Dwarf_Error * error)1045 dwarf_srclines_two_level_from_linecontext(Dwarf_Line_Context line_context,
1046     Dwarf_Line**     linebuf,
1047     Dwarf_Signed *   linecount,
1048     Dwarf_Line**     linebuf_actuals,
1049     Dwarf_Signed *   linecount_actuals,
1050     Dwarf_Error  *    error)
1051 {
1052     if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
1053         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
1054         return (DW_DLV_ERROR);
1055     }
1056     if (!line_context->lc_new_style_access) {
1057         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
1058         return (DW_DLV_ERROR);
1059     }
1060     *linebuf =           line_context->lc_linebuf_logicals;
1061     *linecount =         line_context->lc_linecount_logicals;
1062     *linebuf_actuals =    line_context->lc_linebuf_actuals;
1063     *linecount_actuals = line_context->lc_linecount_actuals;
1064     return DW_DLV_OK;
1065 }
1066 
1067 
1068 /* New October 2015. */
1069 int
dwarf_srclines_table_offset(Dwarf_Line_Context line_context,Dwarf_Unsigned * offset,Dwarf_Error * error)1070 dwarf_srclines_table_offset(Dwarf_Line_Context line_context,
1071     Dwarf_Unsigned * offset,
1072     Dwarf_Error  *    error)
1073 {
1074     if (!line_context ){
1075         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
1076         return (DW_DLV_ERROR);
1077     }
1078     if( line_context->lc_magic != DW_CONTEXT_MAGIC) {
1079         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
1080         return (DW_DLV_ERROR);
1081     }
1082     *offset = line_context->lc_section_offset;
1083     return DW_DLV_OK;
1084 }
1085 
1086 /* New October 2015. */
1087 /*  If the CU DIE  has no DW_AT_comp_dir then
1088     the pointer pushed back to *compilation_directory
1089     will be NULL.
1090     Foy DWARF5 the line table header has the compilation
1091     directory. FIXME DWARF5.
1092     */
dwarf_srclines_comp_dir(Dwarf_Line_Context line_context,const char ** compilation_directory,Dwarf_Error * error)1093 int dwarf_srclines_comp_dir(Dwarf_Line_Context line_context,
1094     const char **  compilation_directory,
1095     Dwarf_Error  *  error)
1096 {
1097     if (!line_context ){
1098         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
1099         return (DW_DLV_ERROR);
1100     }
1101     if( line_context->lc_magic != DW_CONTEXT_MAGIC) {
1102         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
1103         return (DW_DLV_ERROR);
1104     }
1105     *compilation_directory =
1106         (const char *)line_context->lc_compilation_directory;
1107     return DW_DLV_OK;
1108 }
1109 
1110 
1111 
1112 
1113 /* New October 2015. */
1114 int
dwarf_srclines_subprog_count(Dwarf_Line_Context line_context,Dwarf_Signed * count_out,Dwarf_Error * error)1115 dwarf_srclines_subprog_count(Dwarf_Line_Context line_context,
1116     Dwarf_Signed * count_out,
1117     Dwarf_Error * error)
1118 {
1119     if (!line_context ){
1120         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
1121         return (DW_DLV_ERROR);
1122     }
1123     if( line_context->lc_magic != DW_CONTEXT_MAGIC) {
1124         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
1125         return (DW_DLV_ERROR);
1126     }
1127     *count_out = line_context->lc_subprogs_count;
1128     return DW_DLV_OK;
1129 }
1130 /* New October 2015. */
1131 /*  Index says which to return.  Valid indexes are
1132     1-lc_subprogs_count
1133     */
1134 int
dwarf_srclines_subprog_data(Dwarf_Line_Context line_context,Dwarf_Signed index_in,const char ** name,Dwarf_Unsigned * decl_file,Dwarf_Unsigned * decl_line,Dwarf_Error * error)1135 dwarf_srclines_subprog_data(Dwarf_Line_Context line_context,
1136     Dwarf_Signed index_in,
1137     const char ** name,
1138     Dwarf_Unsigned *decl_file,
1139     Dwarf_Unsigned *decl_line,
1140     Dwarf_Error *error)
1141 {
1142     /*  Negative values not sensible. Leaving traditional
1143         signed interfaces. */
1144     Dwarf_Unsigned index = (Dwarf_Unsigned)index_in;
1145     Dwarf_Subprog_Entry sub = 0;
1146     if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
1147         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
1148         return (DW_DLV_ERROR);
1149     }
1150     if (index < 1 || index > line_context->lc_subprogs_count) {
1151         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_INDEX_WRONG);
1152         return (DW_DLV_ERROR);
1153     }
1154     sub = line_context->lc_subprogs + (index-1);
1155     *name = (const char *)sub->ds_subprog_name;
1156     *decl_file = sub->ds_decl_file;
1157     *decl_line = sub->ds_decl_line;
1158     return DW_DLV_OK;
1159 }
1160 
1161 /*  New October 2015. See also
1162     dwarf_srclines_files_indexes() */
1163 int
dwarf_srclines_files_count(Dwarf_Line_Context line_context,Dwarf_Signed * count_out,Dwarf_Error * error)1164 dwarf_srclines_files_count(Dwarf_Line_Context line_context,
1165     Dwarf_Signed *count_out,
1166     Dwarf_Error *error)
1167 {
1168     if (!line_context ||
1169         line_context->lc_magic != DW_CONTEXT_MAGIC) {
1170         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
1171         return (DW_DLV_ERROR);
1172     }
1173     /*  Negative values not sensible. Leaving traditional
1174         signed interfaces. */
1175     *count_out = (Dwarf_Signed)line_context->lc_file_entry_count;
1176     return DW_DLV_OK;
1177 }
1178 
1179 /* New October 2015. */
1180 int
dwarf_srclines_files_data(Dwarf_Line_Context line_context,Dwarf_Signed index_in,const char ** name,Dwarf_Unsigned * directory_index,Dwarf_Unsigned * last_mod_time,Dwarf_Unsigned * file_length,Dwarf_Error * error)1181 dwarf_srclines_files_data(Dwarf_Line_Context line_context,
1182     Dwarf_Signed     index_in,
1183     const char **    name,
1184     Dwarf_Unsigned * directory_index,
1185     Dwarf_Unsigned * last_mod_time,
1186     Dwarf_Unsigned * file_length,
1187     Dwarf_Error    * error)
1188 {
1189     return dwarf_srclines_files_data_b(
1190         line_context,index_in,name,directory_index,
1191         last_mod_time,file_length,0,error);
1192 }
1193 
1194 
1195 /* New March 2018 making iteration through file names. */
1196 int
dwarf_srclines_files_indexes(Dwarf_Line_Context line_context,Dwarf_Signed * baseindex,Dwarf_Signed * file_count,Dwarf_Signed * endindex,Dwarf_Error * error)1197 dwarf_srclines_files_indexes(Dwarf_Line_Context line_context,
1198     Dwarf_Signed   *baseindex,
1199     Dwarf_Signed   *file_count,
1200     Dwarf_Signed   *endindex,
1201     Dwarf_Error    * error)
1202 {
1203     if(line_context->lc_magic != DW_CONTEXT_MAGIC) {
1204         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
1205         return DW_DLV_ERROR;
1206     }
1207     *baseindex  = line_context->lc_file_entry_baseindex;
1208     *file_count = line_context->lc_file_entry_count;
1209     *endindex   = line_context->lc_file_entry_endindex;
1210     return DW_DLV_OK;
1211 }
1212 
1213 /* New March 2018 adding DWARF5 data. */
1214 int
dwarf_srclines_files_data_b(Dwarf_Line_Context line_context,Dwarf_Signed index_in,const char ** name,Dwarf_Unsigned * directory_index,Dwarf_Unsigned * last_mod_time,Dwarf_Unsigned * file_length,Dwarf_Form_Data16 ** data16ptr,Dwarf_Error * error)1215 dwarf_srclines_files_data_b(Dwarf_Line_Context line_context,
1216     Dwarf_Signed     index_in,
1217     const char **    name,
1218     Dwarf_Unsigned * directory_index,
1219     Dwarf_Unsigned * last_mod_time,
1220     Dwarf_Unsigned * file_length,
1221     Dwarf_Form_Data16 ** data16ptr,
1222     Dwarf_Error    * error)
1223 {
1224     Dwarf_File_Entry fi = 0;
1225     Dwarf_Signed i  =0;
1226     Dwarf_Signed baseindex = 0;
1227     Dwarf_Signed file_count = 0;
1228     Dwarf_Signed endindex = 0;
1229     /*  Negative values not sensible. Leaving traditional
1230         signed interfaces. */
1231     Dwarf_Signed index = index_in;
1232     int res = 0;
1233 
1234 
1235     if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
1236         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
1237         return (DW_DLV_ERROR);
1238     }
1239 
1240     /*  Special accomodation of the special gnu experimental
1241         version number (a high number) so we cannot just
1242         say '5 or greater'. This is awkward, but at least
1243         if there is a version 6 or later it still allows
1244         the experimental table.  */
1245     res =  dwarf_srclines_files_indexes(line_context, &baseindex,
1246         &file_count, &endindex, error);
1247     if (res != DW_DLV_OK) {
1248         return res;
1249     }
1250     fi = line_context->lc_file_entries;
1251     if (index < baseindex || index >= endindex) {
1252         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_INDEX_WRONG);
1253             return DW_DLV_ERROR;
1254     }
1255     for ( i = baseindex;i < index; i++) {
1256         fi = fi->fi_next;
1257         if(!fi) {
1258             _dwarf_error(NULL, error, DW_DLE_LINE_HEADER_CORRUPT);
1259                 return DW_DLV_ERROR;
1260         }
1261     }
1262 
1263     if(name) {
1264         *name = (const char *)fi->fi_file_name;
1265     }
1266     if (directory_index) {
1267         *directory_index = fi->fi_dir_index;
1268     }
1269     if (last_mod_time) {
1270         *last_mod_time = fi->fi_time_last_mod;
1271     }
1272     if (file_length) {
1273         *file_length = fi->fi_file_length;
1274     }
1275     if (data16ptr) {
1276         if (fi->fi_md5_present) {
1277             *data16ptr = &fi->fi_md5_value;
1278         } else {
1279             *data16ptr = 0;
1280         }
1281     }
1282     return DW_DLV_OK;
1283 }
1284 
1285 
1286 
1287 
1288 /* New October 2015. */
1289 int
dwarf_srclines_include_dir_count(Dwarf_Line_Context line_context,Dwarf_Signed * count,Dwarf_Error * error)1290 dwarf_srclines_include_dir_count(Dwarf_Line_Context line_context,
1291     Dwarf_Signed * count,
1292     Dwarf_Error  * error)
1293 {
1294     if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
1295         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
1296         return (DW_DLV_ERROR);
1297     }
1298     *count = line_context->lc_include_directories_count;
1299     return DW_DLV_OK;
1300 }
1301 
1302 /* New October 2015. */
1303 int
dwarf_srclines_include_dir_data(Dwarf_Line_Context line_context,Dwarf_Signed index_in,const char ** name,Dwarf_Error * error)1304 dwarf_srclines_include_dir_data(Dwarf_Line_Context line_context,
1305     Dwarf_Signed   index_in,
1306     const char  ** name,
1307     Dwarf_Error *  error)
1308 {
1309     /*  It never made sense that the srclines used a signed count.
1310         But that cannot be fixed in interfaces for compatibility.
1311         So we adjust here. */
1312     Dwarf_Unsigned index = index_in;
1313 
1314     if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
1315         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
1316         return (DW_DLV_ERROR);
1317     }
1318     if (index < 1 || index > line_context->lc_include_directories_count) {
1319         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_INDEX_WRONG);
1320         return (DW_DLV_ERROR);
1321     }
1322     *name = (const char *)(line_context->lc_include_directories[index-1]);
1323     return DW_DLV_OK;
1324 }
1325 
1326 /* New October 2015. */
1327 int
dwarf_srclines_version(Dwarf_Line_Context line_context,Dwarf_Unsigned * version_out,Dwarf_Small * table_count_out,Dwarf_Error * error)1328 dwarf_srclines_version(Dwarf_Line_Context line_context,
1329     Dwarf_Unsigned *version_out,
1330     Dwarf_Small    *table_count_out,
1331     Dwarf_Error *error)
1332 {
1333     if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
1334         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
1335         return (DW_DLV_ERROR);
1336     }
1337     *version_out = line_context->lc_version_number;
1338     *table_count_out = line_context->lc_table_count;
1339     return DW_DLV_OK;
1340 }
1341 
1342 
1343 
1344 /*  Every line table entry (except DW_DLE_end_sequence,
1345     which is returned using dwarf_lineendsequence())
1346     potentially has the begin-statement
1347     flag marked 'on'.   This returns thru *return_bool,
1348     the begin-statement flag.  */
1349 
1350 int
dwarf_linebeginstatement(Dwarf_Line line,Dwarf_Bool * return_bool,Dwarf_Error * error)1351 dwarf_linebeginstatement(Dwarf_Line line,
1352     Dwarf_Bool * return_bool, Dwarf_Error * error)
1353 {
1354     if (line == NULL || return_bool == 0) {
1355         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1356         return (DW_DLV_ERROR);
1357     }
1358 
1359     *return_bool = (line->li_addr_line.li_l_data.li_is_stmt);
1360     return DW_DLV_OK;
1361 }
1362 
1363 /*  At the end of any contiguous line-table there may be
1364     a DW_LNE_end_sequence operator.
1365     This returns non-zero thru *return_bool
1366     if and only if this 'line' entry was a DW_LNE_end_sequence.
1367 
1368     Within a compilation unit or function there may be multiple
1369     line tables, each ending with a DW_LNE_end_sequence.
1370     Each table describes a contiguous region.
1371     Because compilers may split function code up in arbitrary ways
1372     compilers may need to emit multiple contigous regions (ie
1373     line tables) for a single function.
1374     See the DWARF3 spec section 6.2.  */
1375 int
dwarf_lineendsequence(Dwarf_Line line,Dwarf_Bool * return_bool,Dwarf_Error * error)1376 dwarf_lineendsequence(Dwarf_Line line,
1377     Dwarf_Bool * return_bool, Dwarf_Error * error)
1378 {
1379     if (line == NULL) {
1380         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1381         return (DW_DLV_ERROR);
1382     }
1383 
1384     *return_bool = (line->li_addr_line.li_l_data.li_end_sequence);
1385     return DW_DLV_OK;
1386 }
1387 
1388 
1389 /*  Each 'line' entry has a line-number.
1390     If the entry is a DW_LNE_end_sequence the line-number is
1391     meaningless (see dwarf_lineendsequence(), just above).  */
1392 int
dwarf_lineno(Dwarf_Line line,Dwarf_Unsigned * ret_lineno,Dwarf_Error * error)1393 dwarf_lineno(Dwarf_Line line,
1394     Dwarf_Unsigned * ret_lineno, Dwarf_Error * error)
1395 {
1396     if (line == NULL || ret_lineno == 0) {
1397         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1398         return (DW_DLV_ERROR);
1399     }
1400 
1401     *ret_lineno = (line->li_addr_line.li_l_data.li_line);
1402     return DW_DLV_OK;
1403 }
1404 
1405 /*  Each 'line' entry has a file-number, and index into the file table.
1406     If the entry is a DW_LNE_end_sequence the index is
1407     meaningless (see dwarf_lineendsequence(), just above).
1408     The file number returned is an index into the file table
1409     produced by dwarf_srcfiles(), but care is required: the
1410     li_file begins with 1 for DWARF2,3,4
1411     files, so that the li_file returned here
1412     is 1 greater than its index into the dwarf_srcfiles() output array.
1413 
1414     And entries from DW_LNE_define_file don't appear in
1415     the dwarf_srcfiles() output so file indexes from here may exceed
1416     the size of the dwarf_srcfiles() output array size.
1417 */
1418 int
dwarf_line_srcfileno(Dwarf_Line line,Dwarf_Unsigned * ret_fileno,Dwarf_Error * error)1419 dwarf_line_srcfileno(Dwarf_Line line,
1420     Dwarf_Unsigned * ret_fileno, Dwarf_Error * error)
1421 {
1422     if (line == NULL || ret_fileno == 0) {
1423         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1424         return DW_DLV_ERROR;
1425     }
1426     /*  li_file must be <= line->li_context->lc_file_entry_count else
1427         it is trash. li_file 0 means not attributable to
1428         any source file per dwarf2/3 spec.
1429         For DWARF5, li_file < lc_file_entry_count */
1430     *ret_fileno = (line->li_addr_line.li_l_data.li_file);
1431     return DW_DLV_OK;
1432 }
1433 
1434 /*  Each 'line' entry has an is_addr_set attribute.
1435     If the entry is a DW_LNE_set_address, return TRUE through
1436     the *is_addr_set pointer.  */
1437 int
dwarf_line_is_addr_set(Dwarf_Line line,Dwarf_Bool * is_addr_set,Dwarf_Error * error)1438 dwarf_line_is_addr_set(Dwarf_Line line,
1439     Dwarf_Bool *is_addr_set, Dwarf_Error * error)
1440 {
1441     if (line == NULL) {
1442         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1443         return (DW_DLV_ERROR);
1444     }
1445 
1446     *is_addr_set = (line->li_addr_line.li_l_data.li_is_addr_set);
1447     return DW_DLV_OK;
1448 }
1449 
1450 /*  Each 'line' entry has a line-address.
1451     If the entry is a DW_LNE_end_sequence the adddress
1452     is one-beyond the last address this contigous region
1453     covers, so the address is not inside the region,
1454     but is just outside it.  */
1455 int
dwarf_lineaddr(Dwarf_Line line,Dwarf_Addr * ret_lineaddr,Dwarf_Error * error)1456 dwarf_lineaddr(Dwarf_Line line,
1457     Dwarf_Addr * ret_lineaddr, Dwarf_Error * error)
1458 {
1459     if (line == NULL || ret_lineaddr == 0) {
1460         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1461         return (DW_DLV_ERROR);
1462     }
1463 
1464     *ret_lineaddr = (line->li_address);
1465     return DW_DLV_OK;
1466 }
1467 
1468 
1469 /*  Obsolete: do not use this function.
1470     December 2011: For reasons lost in the mists of history,
1471     this returned -1, not zero (through the pointer
1472     ret_lineoff), if the column was zero.
1473     That was always bogus, even in DWARF2.
1474     It is also bogus that the column value is signed, but
1475     it is painful to change the argument type in 2011, so leave it.
1476     */
1477 int
dwarf_lineoff(Dwarf_Line line,Dwarf_Signed * ret_lineoff,Dwarf_Error * error)1478 dwarf_lineoff(Dwarf_Line line,
1479     Dwarf_Signed * ret_lineoff, Dwarf_Error * error)
1480 {
1481     if (line == NULL || ret_lineoff == 0) {
1482         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1483         return (DW_DLV_ERROR);
1484     }
1485     *ret_lineoff = (
1486         (line->li_addr_line.li_l_data.li_column == 0) ?
1487             -1 : line->li_addr_line.li_l_data.li_column);
1488     return DW_DLV_OK;
1489 }
1490 /*  Each 'line' entry has a column-within-line (offset
1491     within the line) where the
1492     source text begins.
1493     If the entry is a DW_LNE_end_sequence the line-number is
1494     meaningless (see dwarf_lineendsequence(), just above).
1495     Lines of text begin at column 1.  The value 0
1496     means the line begins at the left edge of the line.
1497     (See the DWARF3 spec, section 6.2.2).
1498     So 0 and 1 mean essentially the same thing.
1499     dwarf_lineoff_b() is new in December 2011.
1500     */
1501 int
dwarf_lineoff_b(Dwarf_Line line,Dwarf_Unsigned * ret_lineoff,Dwarf_Error * error)1502 dwarf_lineoff_b(Dwarf_Line line,
1503     Dwarf_Unsigned * ret_lineoff, Dwarf_Error * error)
1504 {
1505     if (line == NULL || ret_lineoff == 0) {
1506         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1507         return (DW_DLV_ERROR);
1508     }
1509 
1510     *ret_lineoff = line->li_addr_line.li_l_data.li_column;
1511     return DW_DLV_OK;
1512 }
1513 
1514 
1515 static int
dwarf_filename(Dwarf_Line_Context context,Dwarf_Signed fileno_in,char ** ret_filename,Dwarf_Error * error)1516 dwarf_filename(Dwarf_Line_Context context,
1517     Dwarf_Signed fileno_in,
1518     char **ret_filename, Dwarf_Error *error)
1519 {
1520     Dwarf_Signed i = 0;
1521     Dwarf_File_Entry file_entry = 0;
1522     Dwarf_Debug dbg = context->lc_dbg;
1523     int res = 0;
1524     Dwarf_Signed baseindex = 0;
1525     Dwarf_Signed file_count = 0;
1526     Dwarf_Signed endindex = 0;
1527     /*  Negative values not sensible. Leaving traditional
1528         signed interfaces in place. */
1529     Dwarf_Signed fileno = fileno_in;
1530     unsigned linetab_version = context->lc_version_number;
1531 
1532     res =  dwarf_srclines_files_indexes(context, &baseindex,
1533         &file_count, &endindex, error);
1534     if (res != DW_DLV_OK) {
1535         return res;
1536     }
1537     if (fileno >= endindex) {
1538         dwarfstring m;
1539 
1540         dwarfstring_constructor(&m);
1541         dwarfstring_append_printf_i(&m,
1542             "DW_DLE_NO_FILE_NAME: the file number is %d ",
1543             fileno);
1544         dwarfstring_append_printf_u(&m,
1545             "( this is a DWARF 0x%x linetable)",
1546             linetab_version);
1547         dwarfstring_append_printf_i(&m,
1548             " yet the highest allowed file name index is %d.",
1549             endindex-1);
1550         _dwarf_error_string(dbg, error, DW_DLE_NO_FILE_NAME,
1551             dwarfstring_string(&m));
1552         dwarfstring_destructor(&m);
1553         return DW_DLV_ERROR;
1554     } else {
1555         if (linetab_version <= DW_LINE_VERSION4 ||
1556             linetab_version == EXPERIMENTAL_LINE_TABLES_VERSION) {
1557             if (!fileno) {
1558                 return DW_DLV_NO_ENTRY;
1559             }
1560             /* else ok */
1561         }  /* else DWARF 5 line index 0 is fine */
1562     }
1563 
1564     file_entry = context->lc_file_entries;
1565     /*  zero fileno allowed for DWARF5 table. For DWARF4,
1566         zero fileno handled above. */
1567     for (i =  baseindex; i < fileno ; i++) {
1568         file_entry = file_entry->fi_next;
1569     }
1570 
1571     res = create_fullest_file_path(dbg,
1572         file_entry,context, ret_filename,error);
1573     return res;
1574 }
1575 
1576 int
dwarf_linesrc(Dwarf_Line line,char ** ret_linesrc,Dwarf_Error * error)1577 dwarf_linesrc(Dwarf_Line line, char **ret_linesrc, Dwarf_Error * error)
1578 {
1579     if (line == NULL) {
1580         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1581         return DW_DLV_ERROR;
1582     }
1583     if (line->li_context == NULL) {
1584         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL);
1585         return DW_DLV_ERROR;
1586     }
1587     return dwarf_filename(line->li_context,
1588         line->li_addr_line.li_l_data.li_file, ret_linesrc, error);
1589 }
1590 
1591 /*  Every line table entry potentially has the basic-block-start
1592     flag marked 'on'.   This returns thru *return_bool,
1593     the basic-block-start flag.
1594 */
1595 int
dwarf_lineblock(Dwarf_Line line,Dwarf_Bool * return_bool,Dwarf_Error * error)1596 dwarf_lineblock(Dwarf_Line line,
1597     Dwarf_Bool * return_bool, Dwarf_Error * error)
1598 {
1599     if (line == NULL) {
1600         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1601         return (DW_DLV_ERROR);
1602     }
1603     *return_bool = (line->li_addr_line.li_l_data.li_basic_block);
1604     return DW_DLV_OK;
1605 }
1606 
1607 /* We gather these into one call as it's likely one
1608    will want all or none of them.  */
dwarf_prologue_end_etc(Dwarf_Line line,Dwarf_Bool * prologue_end,Dwarf_Bool * epilogue_begin,Dwarf_Unsigned * isa,Dwarf_Unsigned * discriminator,Dwarf_Error * error)1609 int dwarf_prologue_end_etc(Dwarf_Line  line,
1610     Dwarf_Bool  *    prologue_end,
1611     Dwarf_Bool  *    epilogue_begin,
1612     Dwarf_Unsigned * isa,
1613     Dwarf_Unsigned * discriminator,
1614     Dwarf_Error *    error)
1615 {
1616     if (line == NULL) {
1617         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1618         return (DW_DLV_ERROR);
1619     }
1620     *prologue_end = (line->li_addr_line.li_l_data.li_prologue_end);
1621     *epilogue_begin = (line->li_addr_line.li_l_data.li_epilogue_begin);
1622     *isa = (line->li_addr_line.li_l_data.li_isa);
1623     *discriminator = (line->li_addr_line.li_l_data.li_discriminator);
1624     return DW_DLV_OK;
1625 }
1626 
1627 int
dwarf_linelogical(Dwarf_Line line,Dwarf_Unsigned * logical,Dwarf_Error * error)1628 dwarf_linelogical(Dwarf_Line line,
1629     Dwarf_Unsigned * logical,
1630     Dwarf_Error*     error)
1631 {
1632     if (line == NULL) {
1633         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1634         return (DW_DLV_ERROR);
1635     }
1636     *logical = (line->li_addr_line.li_l_data.li_line);
1637     return DW_DLV_OK;
1638 }
1639 
1640 int
dwarf_linecontext(Dwarf_Line line,Dwarf_Unsigned * context,Dwarf_Error * error)1641 dwarf_linecontext(Dwarf_Line line,
1642     Dwarf_Unsigned * context,
1643     Dwarf_Error*     error)
1644 {
1645     if (line == NULL) {
1646         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1647         return (DW_DLV_ERROR);
1648     }
1649     *context = (line->li_addr_line.li_l_data.li_call_context);
1650     return DW_DLV_OK;
1651 }
1652 
1653 int
dwarf_line_subprogno(Dwarf_Line line,Dwarf_Unsigned * subprog,Dwarf_Error * error)1654 dwarf_line_subprogno(Dwarf_Line line,
1655     Dwarf_Unsigned * subprog,
1656     Dwarf_Error *    error)
1657 {
1658     if (line == NULL) {
1659         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1660         return (DW_DLV_ERROR);
1661     }
1662     *subprog = (line->li_addr_line.li_l_data.li_subprogram);
1663     return DW_DLV_OK;
1664 }
1665 
1666 int
dwarf_line_subprog(Dwarf_Line line,char ** subprog_name,char ** decl_filename,Dwarf_Unsigned * decl_line,Dwarf_Error * error)1667 dwarf_line_subprog(Dwarf_Line line,
1668     char   **        subprog_name,
1669     char   **        decl_filename,
1670     Dwarf_Unsigned * decl_line,
1671     Dwarf_Error *    error)
1672 {
1673     Dwarf_Unsigned subprog_no;
1674     Dwarf_Subprog_Entry subprog;
1675     Dwarf_Debug dbg;
1676     int res;
1677 
1678     if (line == NULL) {
1679         _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
1680         return DW_DLV_ERROR;
1681     }
1682 
1683     if (line->li_context == NULL) {
1684         _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL);
1685         return DW_DLV_ERROR;
1686     }
1687 
1688     dbg = line->li_context->lc_dbg;
1689 
1690     subprog_no = line->li_addr_line.li_l_data.li_subprogram;
1691     if (subprog_no == 0) {
1692         *subprog_name = NULL;
1693         *decl_filename = NULL;
1694         *decl_line = 0;
1695         return DW_DLV_OK;
1696     }
1697 
1698     if (subprog_no > line->li_context->lc_subprogs_count) {
1699         _dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME);
1700         return DW_DLV_ERROR;
1701     }
1702 
1703     /*  Adjusting for 1 origin subprog no */
1704     subprog = &line->li_context->lc_subprogs[subprog_no - 1];
1705 
1706     *subprog_name = (char *)subprog->ds_subprog_name;
1707     *decl_line = subprog->ds_decl_line;
1708 
1709     res = dwarf_filename(line->li_context,
1710         subprog->ds_decl_file,
1711         decl_filename, error);
1712     if (res != DW_DLV_OK) {
1713         *decl_filename = NULL;
1714         return res;
1715     }
1716     return DW_DLV_OK;
1717 }
1718 
1719 /*  This is another line_context_destructor. */
1720 static void
delete_line_context_itself(Dwarf_Line_Context context)1721 delete_line_context_itself(Dwarf_Line_Context context)
1722 {
1723 
1724 
1725     Dwarf_Debug dbg = 0;
1726     Dwarf_File_Entry fe = 0;
1727 
1728     if(context->lc_magic != DW_CONTEXT_MAGIC) {
1729         /* Something is wrong. */
1730         return;
1731     }
1732     dbg = context->lc_dbg;
1733     fe = context->lc_file_entries;
1734     while (fe) {
1735         Dwarf_File_Entry fenext = fe->fi_next;
1736         fe->fi_next = 0;
1737         free(fe);
1738         fe = fenext;
1739     }
1740     context->lc_file_entries = 0;
1741     context->lc_file_entry_count = 0;
1742     context->lc_file_entry_baseindex = 0;
1743     context->lc_file_entry_endindex = 0;
1744     if (context->lc_subprogs) {
1745         free(context->lc_subprogs);
1746         context->lc_subprogs = 0;
1747     }
1748     free(context->lc_directory_format_values);
1749     context->lc_directory_format_values = 0;
1750     free(context->lc_file_format_values);
1751     context->lc_file_format_values = 0;
1752     if (context->lc_include_directories) {
1753         free(context->lc_include_directories);
1754         context->lc_include_directories = 0;
1755     }
1756     context->lc_magic = 0xdead;
1757     dwarf_dealloc(dbg, context, DW_DLA_LINE_CONTEXT);
1758 }
1759 
1760 /*  It's impossible for callers of dwarf_srclines() to get to and
1761     free all the resources (in particular, the li_context and its
1762     lc_file_entries).
1763     So this function, new July 2005, does it.
1764 
1765     As of September 2015 this will now delete either
1766     table of a two-level line table.
1767     In the two-level case one calls it once each on
1768     both the logicals and actuals tables.
1769     (in either order, the order is not critical).
1770     Once  the  logicals table is dealloced any
1771     use of the actuals table will surely result in chaos.
1772     Just do the two calls one after the other.
1773 
1774     In the standard single-table case (DWARF 2,3,4)
1775     one calls it just once on the
1776     linebuf.  Old style dealloc. Should never be used with
1777     dwarf_srclines_b(), but if it is there
1778     are no bad consequences..
1779 
1780     Those using standard DWARF should use
1781     dwarf_srclines_b() and dwarf_srclines_dealloc_b()
1782     instead of dwarf_srclines and dwarf_srclines_dealloc()
1783     as that gives access to various bits of useful information.
1784     */
1785 
1786 void
dwarf_srclines_dealloc(Dwarf_Debug dbg,Dwarf_Line * linebuf,Dwarf_Signed count)1787 dwarf_srclines_dealloc(Dwarf_Debug dbg, Dwarf_Line * linebuf,
1788     Dwarf_Signed count)
1789 {
1790     Dwarf_Signed i = 0;
1791     /*  alternate_data_count is a failsafe to prevent
1792         duplicate frees when there is inappropriate mixing
1793         of new interface and this old routine */
1794     Dwarf_Bool alternate_data_count = 0;
1795 
1796     struct Dwarf_Line_Context_s *line_context = 0;
1797 
1798 
1799     if(!linebuf) {
1800         return;
1801     }
1802     if (count > 0) {
1803         /*  All these entries share a single line_context, and
1804             for two-levels tables each table gets it too.
1805             Hence we will dealloc ONLY if !is_actuals_table
1806             so for single and two-level tables the space
1807             is deallocated. */
1808         line_context = linebuf[0]->li_context;
1809         if (line_context && line_context->lc_magic != DW_CONTEXT_MAGIC ) {
1810             /* Something is very wrong. */
1811             line_context = 0;
1812         } else if (line_context) {
1813             if (linebuf == line_context->lc_linebuf_logicals) {
1814                 line_context->lc_linebuf_logicals = 0;
1815                 line_context->lc_linecount_logicals = 0;
1816                 alternate_data_count = line_context->lc_linecount_actuals;
1817                 /* Ok to delete logicals */
1818             } else if (linebuf == line_context->lc_linebuf_actuals) {
1819                 /* Ok to delete actuals */
1820                 line_context->lc_linebuf_actuals = 0;
1821                 line_context->lc_linecount_actuals = 0;
1822                 alternate_data_count = line_context->lc_linecount_logicals;
1823             } else {
1824                 /* Something is wrong very wrong. */
1825                 return;
1826             }
1827         }  else {
1828             /*  Else: impossible. Unless the caller
1829                 passed in a bogus linebuf. */
1830             line_context = 0;
1831         }
1832     }
1833 
1834     /*  Here we actually delete a set of lines. */
1835     for (i = 0; i < count; ++i) {
1836         dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE);
1837     }
1838     dwarf_dealloc(dbg, linebuf, DW_DLA_LIST);
1839 
1840     if (line_context && !line_context->lc_new_style_access
1841         && !alternate_data_count ) {
1842         /*  There is nothing left
1843             referencing this line_context. */
1844         dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
1845     }
1846     return;
1847 }
1848 
1849 /*  New October 2015.
1850     This should be used to deallocate all
1851     lines data that is
1852     set up by dwarf_srclines_b().
1853     This and dwarf_srclines_b() are now (October 2015)
1854     the preferred routine to use.  */
1855 void
dwarf_srclines_dealloc_b(Dwarf_Line_Context line_context)1856 dwarf_srclines_dealloc_b(Dwarf_Line_Context line_context)
1857 {
1858     Dwarf_Line *linestable = 0;
1859     Dwarf_Signed linescount = 0;
1860     Dwarf_Signed i = 0;
1861     Dwarf_Debug dbg = 0;
1862 
1863     if(!line_context) {
1864         return;
1865     }
1866     if(line_context->lc_magic != DW_CONTEXT_MAGIC) {
1867         /* Something is wrong. */
1868         return; }
1869     dbg = line_context->lc_dbg;
1870     if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
1871         /*  Something is badly wrong here.*/
1872         return;
1873     }
1874     linestable = line_context->lc_linebuf_logicals;
1875     if (linestable) {
1876         linescount = line_context->lc_linecount_logicals;
1877         for (i = 0; i < linescount ; ++i) {
1878             dwarf_dealloc(dbg, linestable[i], DW_DLA_LINE);
1879         }
1880         dwarf_dealloc(dbg, linestable, DW_DLA_LIST);
1881     }
1882     line_context->lc_linebuf_logicals = 0;
1883     line_context->lc_linecount_logicals = 0;
1884 
1885     linestable = line_context->lc_linebuf_actuals;
1886     if (linestable) {
1887         linescount = line_context->lc_linecount_actuals;
1888         for (i = 0; i <linescount ; ++i) {
1889             dwarf_dealloc(dbg, linestable[i], DW_DLA_LINE);
1890         }
1891         dwarf_dealloc(dbg, linestable, DW_DLA_LIST);
1892     }
1893     line_context->lc_linebuf_actuals = 0;
1894     line_context->lc_linecount_actuals = 0;
1895     delete_line_context_itself(line_context);
1896 }
1897 
1898 /* There is an error, so count it. If we are printing
1899    errors by command line option, print the details.  */
1900 void
_dwarf_print_header_issue(Dwarf_Debug dbg,const char * specific_msg,Dwarf_Small * data_start,Dwarf_Signed value,unsigned index,unsigned tabv,unsigned linetabv,int * err_count_out)1901 _dwarf_print_header_issue(Dwarf_Debug dbg,
1902     const char *specific_msg,
1903     Dwarf_Small *data_start,
1904     Dwarf_Signed value,
1905     unsigned index,
1906     unsigned tabv,
1907     unsigned linetabv,
1908     int *err_count_out)
1909 {
1910     if (!err_count_out) {
1911         return;
1912     }
1913     /* Are we in verbose mode */
1914     if (dwarf_cmdline_options.check_verbose_mode){
1915         dwarfstring m1;
1916 
1917         dwarfstring_constructor(&m1);
1918         dwarfstring_append(&m1,
1919             "\n*** DWARF CHECK: "
1920             ".debug_line: ");
1921         dwarfstring_append(&m1,(char *)specific_msg);
1922         dwarfstring_append_printf_i(&m1,
1923             " %" DW_PR_DSd,value);
1924         if (index || tabv || linetabv) {
1925             dwarfstring_append_printf_u(&m1,
1926                 "; Mismatch index %u",index);
1927             dwarfstring_append_printf_u(&m1,
1928                 " stdval %u",tabv);
1929             dwarfstring_append_printf_u(&m1,
1930                 " linetabval %u",linetabv);
1931         }
1932         if (data_start >= dbg->de_debug_line.dss_data &&
1933             (data_start < (dbg->de_debug_line.dss_data +
1934             dbg->de_debug_line.dss_size))) {
1935             Dwarf_Unsigned off =
1936                 data_start - dbg->de_debug_line.dss_data;
1937 
1938             dwarfstring_append_printf_u(&m1,
1939                 " at offset 0x%" DW_PR_XZEROS DW_PR_DUx,off);
1940             dwarfstring_append_printf_u(&m1,
1941                 "  ( %" DW_PR_DUu " ) ",off);
1942         } else {
1943             dwarfstring_append(&m1,
1944                 " (unknown section location) ");
1945         }
1946         dwarfstring_append(&m1,"***\n");
1947         _dwarf_printf(dbg,dwarfstring_string(&m1));
1948         dwarfstring_destructor(&m1);
1949     }
1950     *err_count_out += 1;
1951 }
1952 
1953 
1954 int
_dwarf_decode_line_string_form(Dwarf_Debug dbg,Dwarf_Unsigned form,Dwarf_Unsigned offset_size,Dwarf_Small ** line_ptr,Dwarf_Small * line_ptr_end,char ** return_str,Dwarf_Error * error)1955 _dwarf_decode_line_string_form(Dwarf_Debug dbg,
1956     Dwarf_Unsigned form,
1957     Dwarf_Unsigned offset_size,
1958     Dwarf_Small **line_ptr,
1959     Dwarf_Small *line_ptr_end,
1960     char **return_str,
1961     Dwarf_Error * error)
1962 {
1963     int res = 0;
1964 
1965     switch (form) {
1966     case DW_FORM_line_strp: {
1967         Dwarf_Small *secstart = 0;
1968         Dwarf_Small *secend = 0;
1969         Dwarf_Small *strptr = 0;
1970         Dwarf_Unsigned offset = 0;
1971         Dwarf_Small *offsetptr = *line_ptr;
1972 
1973         res = _dwarf_load_section(dbg, &dbg->de_debug_line_str,error);
1974         if (res != DW_DLV_OK) {
1975             return res;
1976         }
1977 
1978         secstart = dbg->de_debug_line_str.dss_data;
1979         secend = secstart + dbg->de_debug_line_str.dss_size;
1980 
1981         READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,offsetptr, offset_size,
1982             error,line_ptr_end);
1983         *line_ptr += offset_size;
1984         strptr = secstart + offset;
1985         res = _dwarf_check_string_valid(dbg,
1986             secstart,strptr,secend,
1987             DW_DLE_LINE_STRP_OFFSET_BAD,error);
1988         if (res != DW_DLV_OK) {
1989             return res;
1990         }
1991         *return_str = (char *) strptr;
1992         return DW_DLV_OK;
1993         }
1994     case DW_FORM_string: {
1995         Dwarf_Small *secend = line_ptr_end;
1996         Dwarf_Small *strptr = *line_ptr;
1997 
1998         res = _dwarf_check_string_valid(dbg,
1999             strptr ,strptr,secend,DW_DLE_LINE_STRING_BAD,error);
2000         if (res != DW_DLV_OK) {
2001             return res;
2002         }
2003         *return_str = (char *)strptr;
2004         *line_ptr += strlen((const char *)strptr) + 1;
2005         return DW_DLV_OK;
2006         }
2007     default:
2008         _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
2009         return DW_DLV_ERROR;
2010     }
2011 }
2012 
2013 int
_dwarf_decode_line_udata_form(Dwarf_Debug dbg,Dwarf_Unsigned form,Dwarf_Small ** line_ptr,Dwarf_Unsigned * return_val,Dwarf_Small * line_end_ptr,Dwarf_Error * error)2014 _dwarf_decode_line_udata_form(Dwarf_Debug dbg,
2015     Dwarf_Unsigned form,
2016     Dwarf_Small **line_ptr,
2017     Dwarf_Unsigned *return_val,
2018     Dwarf_Small *line_end_ptr,
2019     Dwarf_Error * error)
2020 {
2021     Dwarf_Unsigned val = 0;
2022     Dwarf_Small * lp = *line_ptr;
2023 
2024     switch (form) {
2025 
2026     case DW_FORM_udata:
2027         DECODE_LEB128_UWORD_CK(lp, val,dbg,error,line_end_ptr);
2028         *return_val = val;
2029         *line_ptr = lp;
2030         return DW_DLV_OK;
2031 
2032     default:
2033         _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
2034         return DW_DLV_ERROR;
2035     }
2036 }
2037 
2038 
2039 void
_dwarf_update_chain_list(Dwarf_Chain chain_line,Dwarf_Chain * head_chain,Dwarf_Chain * curr_chain)2040 _dwarf_update_chain_list( Dwarf_Chain chain_line,
2041     Dwarf_Chain *head_chain, Dwarf_Chain *curr_chain)
2042 {
2043     if (*head_chain == NULL) {
2044         *head_chain = chain_line;
2045     } else {
2046         (*curr_chain)->ch_next = chain_line;
2047     }
2048     *curr_chain = chain_line;
2049 }
2050 
2051 void
_dwarf_free_chain_entries(Dwarf_Debug dbg,Dwarf_Chain head,int count)2052 _dwarf_free_chain_entries(Dwarf_Debug dbg,Dwarf_Chain head,int count)
2053 {
2054     int i = 0;
2055     Dwarf_Chain curr_chain = head;
2056     for (i = 0; i < count; i++) {
2057         Dwarf_Chain t = curr_chain;
2058         void *item = t->ch_item;
2059         int itype = t->ch_itemtype;
2060 
2061         if (item && itype) { /* valid DW_DLA types are never 0 */
2062             dwarf_dealloc(dbg,item,itype);
2063             t->ch_item = 0;
2064         }
2065         curr_chain = curr_chain->ch_next;
2066         dwarf_dealloc(dbg, t, DW_DLA_CHAIN);
2067     }
2068 }
2069 
2070 int
_dwarf_add_to_files_list(Dwarf_Line_Context context,Dwarf_File_Entry fe)2071 _dwarf_add_to_files_list(Dwarf_Line_Context context, Dwarf_File_Entry fe)
2072 {
2073     if (!context->lc_file_entries) {
2074         context->lc_file_entries = fe;
2075     } else {
2076         context->lc_last_entry->fi_next = fe;
2077     }
2078     context->lc_last_entry = fe;
2079     context->lc_file_entry_count++;
2080     /*  Here we attempt to write code to make it easy to interate
2081         though source file names without having to code specially
2082         for DWARF2,3,4 vs DWARF5 */
2083     if (context->lc_version_number >= DW_LINE_VERSION5 &&
2084         context->lc_version_number != EXPERIMENTAL_LINE_TABLES_VERSION) {
2085         context->lc_file_entry_baseindex = 0;
2086         context->lc_file_entry_endindex = context->lc_file_entry_count;
2087     } else {
2088         /* DWARF2,3,4 and the EXPERIMENTAL_LINE_TABLES_VERSION. */
2089         context->lc_file_entry_baseindex = 1;
2090         context->lc_file_entry_endindex = context->lc_file_entry_count+1;
2091     }
2092     return DW_DLV_OK;
2093 }
2094 
2095 
2096 int
_dwarf_line_context_constructor(Dwarf_Debug dbg,void * m)2097 _dwarf_line_context_constructor(Dwarf_Debug dbg, void *m)
2098 {
2099     Dwarf_Line_Context line_context = (Dwarf_Line_Context)m;
2100     /*  dwarf_get_alloc ensures the bytes are all zero
2101         when m is passed to us. */
2102     line_context->lc_magic = DW_CONTEXT_MAGIC;
2103     line_context->lc_dbg =  dbg;
2104     return DW_DLV_OK;
2105 }
2106 
2107 /*  This cleans up a contex record.
2108     The lines tables (actuals and logicals)
2109     are themselves items that will
2110     be dealloc'd either manually
2111     or, at closing the libdwarf dbg,
2112     automatically.  So we DO NOT
2113     touch the lines tables here
2114     See also: delete_line_context_itself()
2115 */
2116 void
_dwarf_line_context_destructor(void * m)2117 _dwarf_line_context_destructor(void *m)
2118 {
2119     Dwarf_Line_Context line_context = (Dwarf_Line_Context)m;
2120     if (line_context->lc_magic != DW_CONTEXT_MAGIC) {
2121         /* Nothing is safe, do nothing. */
2122         return;
2123     }
2124     if (line_context->lc_include_directories) {
2125         free(line_context->lc_include_directories);
2126         line_context->lc_include_directories = 0;
2127         line_context->lc_include_directories_count = 0;
2128     }
2129     if (line_context->lc_file_entries) {
2130         Dwarf_File_Entry fe = line_context->lc_file_entries;
2131         while(fe) {
2132             Dwarf_File_Entry t = fe;
2133             fe = t->fi_next;
2134             t->fi_next = 0;
2135             free(t);
2136         }
2137         line_context->lc_file_entries     = 0;
2138         line_context->lc_last_entry       = 0;
2139         line_context->lc_file_entry_count = 0;
2140         line_context->lc_file_entry_baseindex   = 0;
2141         line_context->lc_file_entry_endindex    = 0;
2142     }
2143     free(line_context->lc_directory_format_values);
2144     line_context->lc_directory_format_values = 0;
2145     free(line_context->lc_file_format_values);
2146     line_context->lc_file_format_values = 0;
2147 
2148     if (line_context->lc_subprogs) {
2149         free(line_context->lc_subprogs);
2150         line_context->lc_subprogs = 0;
2151         line_context->lc_subprogs_count = 0;
2152     }
2153     line_context->lc_magic = 0;
2154     return;
2155 }
2156