rdwarf 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +28 -0
- data/README.md +39 -0
- data/Rakefile +8 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/ext/rdwarf/depend +5 -0
- data/ext/rdwarf/extconf.rb +29 -0
- data/ext/rdwarf/libdwarf/CHANGES +102 -0
- data/ext/rdwarf/libdwarf/CODINGSTYLE +71 -0
- data/ext/rdwarf/libdwarf/COPYING +28 -0
- data/ext/rdwarf/libdwarf/ChangeLog +619 -0
- data/ext/rdwarf/libdwarf/ChangeLog2006 +835 -0
- data/ext/rdwarf/libdwarf/ChangeLog2007 +217 -0
- data/ext/rdwarf/libdwarf/ChangeLog2008 +263 -0
- data/ext/rdwarf/libdwarf/ChangeLog2009 +348 -0
- data/ext/rdwarf/libdwarf/ChangeLog2010 +175 -0
- data/ext/rdwarf/libdwarf/ChangeLog2011 +297 -0
- data/ext/rdwarf/libdwarf/ChangeLog2012 +131 -0
- data/ext/rdwarf/libdwarf/ChangeLog2013 +238 -0
- data/ext/rdwarf/libdwarf/ChangeLog2014 +399 -0
- data/ext/rdwarf/libdwarf/LGPL.txt +504 -0
- data/ext/rdwarf/libdwarf/LIBDWARFCOPYRIGHT +40 -0
- data/ext/rdwarf/libdwarf/Makefile.in +220 -0
- data/ext/rdwarf/libdwarf/NEWS +535 -0
- data/ext/rdwarf/libdwarf/README +235 -0
- data/ext/rdwarf/libdwarf/checkexamples.c +1179 -0
- data/ext/rdwarf/libdwarf/cmplrs/dwarf_addr_finder.h +55 -0
- data/ext/rdwarf/libdwarf/common.c +62 -0
- data/ext/rdwarf/libdwarf/common.h +38 -0
- data/ext/rdwarf/libdwarf/config.h.in +146 -0
- data/ext/rdwarf/libdwarf/configure +5581 -0
- data/ext/rdwarf/libdwarf/configure.in +167 -0
- data/ext/rdwarf/libdwarf/dw-linetableheader.txt +39 -0
- data/ext/rdwarf/libdwarf/dwarf.h +1342 -0
- data/ext/rdwarf/libdwarf/dwarf_abbrev.c +291 -0
- data/ext/rdwarf/libdwarf/dwarf_abbrev.h +45 -0
- data/ext/rdwarf/libdwarf/dwarf_addr_finder.c +676 -0
- data/ext/rdwarf/libdwarf/dwarf_alloc.c +685 -0
- data/ext/rdwarf/libdwarf/dwarf_alloc.h +38 -0
- data/ext/rdwarf/libdwarf/dwarf_arange.c +595 -0
- data/ext/rdwarf/libdwarf/dwarf_arange.h +62 -0
- data/ext/rdwarf/libdwarf/dwarf_base_types.h +157 -0
- data/ext/rdwarf/libdwarf/dwarf_die_deliv.c +1802 -0
- data/ext/rdwarf/libdwarf/dwarf_die_deliv.h +46 -0
- data/ext/rdwarf/libdwarf/dwarf_elf_access.c +1348 -0
- data/ext/rdwarf/libdwarf/dwarf_elf_access.h +46 -0
- data/ext/rdwarf/libdwarf/dwarf_error.c +492 -0
- data/ext/rdwarf/libdwarf/dwarf_error.h +53 -0
- data/ext/rdwarf/libdwarf/dwarf_form.c +1302 -0
- data/ext/rdwarf/libdwarf/dwarf_frame.c +2454 -0
- data/ext/rdwarf/libdwarf/dwarf_frame.h +418 -0
- data/ext/rdwarf/libdwarf/dwarf_frame2.c +1533 -0
- data/ext/rdwarf/libdwarf/dwarf_frame3.c +282 -0
- data/ext/rdwarf/libdwarf/dwarf_funcs.c +123 -0
- data/ext/rdwarf/libdwarf/dwarf_funcs.h +33 -0
- data/ext/rdwarf/libdwarf/dwarf_gdbindex.c +520 -0
- data/ext/rdwarf/libdwarf/dwarf_gdbindex.h +97 -0
- data/ext/rdwarf/libdwarf/dwarf_global.c +612 -0
- data/ext/rdwarf/libdwarf/dwarf_global.h +117 -0
- data/ext/rdwarf/libdwarf/dwarf_harmless.c +228 -0
- data/ext/rdwarf/libdwarf/dwarf_harmless.h +31 -0
- data/ext/rdwarf/libdwarf/dwarf_incl.h +61 -0
- data/ext/rdwarf/libdwarf/dwarf_init_finish.c +1263 -0
- data/ext/rdwarf/libdwarf/dwarf_leb.c +159 -0
- data/ext/rdwarf/libdwarf/dwarf_line.c +1822 -0
- data/ext/rdwarf/libdwarf/dwarf_line.h +446 -0
- data/ext/rdwarf/libdwarf/dwarf_line2.c +98 -0
- data/ext/rdwarf/libdwarf/dwarf_line_table_reader_common.c +1583 -0
- data/ext/rdwarf/libdwarf/dwarf_loc.c +1525 -0
- data/ext/rdwarf/libdwarf/dwarf_loc.h +149 -0
- data/ext/rdwarf/libdwarf/dwarf_loc2.c +833 -0
- data/ext/rdwarf/libdwarf/dwarf_macro.c +479 -0
- data/ext/rdwarf/libdwarf/dwarf_macro.h +35 -0
- data/ext/rdwarf/libdwarf/dwarf_opaque.h +778 -0
- data/ext/rdwarf/libdwarf/dwarf_original_elf_init.c +219 -0
- data/ext/rdwarf/libdwarf/dwarf_print_lines.c +631 -0
- data/ext/rdwarf/libdwarf/dwarf_pubtypes.c +132 -0
- data/ext/rdwarf/libdwarf/dwarf_query.c +1594 -0
- data/ext/rdwarf/libdwarf/dwarf_ranges.c +194 -0
- data/ext/rdwarf/libdwarf/dwarf_reloc_arm.h +308 -0
- data/ext/rdwarf/libdwarf/dwarf_reloc_mips.h +117 -0
- data/ext/rdwarf/libdwarf/dwarf_reloc_ppc.h +242 -0
- data/ext/rdwarf/libdwarf/dwarf_reloc_ppc64.h +272 -0
- data/ext/rdwarf/libdwarf/dwarf_reloc_x86_64.h +127 -0
- data/ext/rdwarf/libdwarf/dwarf_sort_line.c +665 -0
- data/ext/rdwarf/libdwarf/dwarf_string.c +82 -0
- data/ext/rdwarf/libdwarf/dwarf_stubs.c +38 -0
- data/ext/rdwarf/libdwarf/dwarf_tied.c +423 -0
- data/ext/rdwarf/libdwarf/dwarf_tsearch.h +125 -0
- data/ext/rdwarf/libdwarf/dwarf_tsearchhash.c +675 -0
- data/ext/rdwarf/libdwarf/dwarf_types.c +121 -0
- data/ext/rdwarf/libdwarf/dwarf_types.h +32 -0
- data/ext/rdwarf/libdwarf/dwarf_util.c +913 -0
- data/ext/rdwarf/libdwarf/dwarf_util.h +324 -0
- data/ext/rdwarf/libdwarf/dwarf_vars.c +125 -0
- data/ext/rdwarf/libdwarf/dwarf_vars.h +29 -0
- data/ext/rdwarf/libdwarf/dwarf_weaks.c +123 -0
- data/ext/rdwarf/libdwarf/dwarf_weaks.h +29 -0
- data/ext/rdwarf/libdwarf/dwarf_xu_index.c +579 -0
- data/ext/rdwarf/libdwarf/dwarf_xu_index.h +68 -0
- data/ext/rdwarf/libdwarf/dwgetopt.c +181 -0
- data/ext/rdwarf/libdwarf/dwgetopt.h +51 -0
- data/ext/rdwarf/libdwarf/gennames.c +531 -0
- data/ext/rdwarf/libdwarf/install.sh +119 -0
- data/ext/rdwarf/libdwarf/libdwarf.h.in +3746 -0
- data/ext/rdwarf/libdwarf/libdwarf2.1.mm +9805 -0
- data/ext/rdwarf/libdwarf/libdwarf2.1.pdf +0 -0
- data/ext/rdwarf/libdwarf/libdwarf2p.1.mm +2807 -0
- data/ext/rdwarf/libdwarf/libdwarf2p.1.pdf +0 -0
- data/ext/rdwarf/libdwarf/libdwarfdefs.h +81 -0
- data/ext/rdwarf/libdwarf/malloc_check.c +327 -0
- data/ext/rdwarf/libdwarf/malloc_check.h +52 -0
- data/ext/rdwarf/libdwarf/mips_extensions.mm +1266 -0
- data/ext/rdwarf/libdwarf/mips_extensions.pdf +0 -0
- data/ext/rdwarf/libdwarf/pro_alloc.c +179 -0
- data/ext/rdwarf/libdwarf/pro_alloc.h +33 -0
- data/ext/rdwarf/libdwarf/pro_arange.c +310 -0
- data/ext/rdwarf/libdwarf/pro_arange.h +51 -0
- data/ext/rdwarf/libdwarf/pro_die.c +431 -0
- data/ext/rdwarf/libdwarf/pro_die.h +59 -0
- data/ext/rdwarf/libdwarf/pro_encode_nm.c +108 -0
- data/ext/rdwarf/libdwarf/pro_encode_nm.h +39 -0
- data/ext/rdwarf/libdwarf/pro_error.c +96 -0
- data/ext/rdwarf/libdwarf/pro_error.h +43 -0
- data/ext/rdwarf/libdwarf/pro_expr.c +575 -0
- data/ext/rdwarf/libdwarf/pro_expr.h +36 -0
- data/ext/rdwarf/libdwarf/pro_finish.c +45 -0
- data/ext/rdwarf/libdwarf/pro_forms.c +1271 -0
- data/ext/rdwarf/libdwarf/pro_frame.c +572 -0
- data/ext/rdwarf/libdwarf/pro_frame.h +120 -0
- data/ext/rdwarf/libdwarf/pro_funcs.c +50 -0
- data/ext/rdwarf/libdwarf/pro_incl.h +91 -0
- data/ext/rdwarf/libdwarf/pro_init.c +327 -0
- data/ext/rdwarf/libdwarf/pro_line.c +373 -0
- data/ext/rdwarf/libdwarf/pro_line.h +112 -0
- data/ext/rdwarf/libdwarf/pro_macinfo.c +457 -0
- data/ext/rdwarf/libdwarf/pro_macinfo.h +31 -0
- data/ext/rdwarf/libdwarf/pro_opaque.h +513 -0
- data/ext/rdwarf/libdwarf/pro_pubnames.c +60 -0
- data/ext/rdwarf/libdwarf/pro_reloc.c +253 -0
- data/ext/rdwarf/libdwarf/pro_reloc.h +38 -0
- data/ext/rdwarf/libdwarf/pro_reloc_stream.c +256 -0
- data/ext/rdwarf/libdwarf/pro_reloc_stream.h +52 -0
- data/ext/rdwarf/libdwarf/pro_reloc_symbolic.c +245 -0
- data/ext/rdwarf/libdwarf/pro_reloc_symbolic.h +45 -0
- data/ext/rdwarf/libdwarf/pro_section.c +2233 -0
- data/ext/rdwarf/libdwarf/pro_section.h +100 -0
- data/ext/rdwarf/libdwarf/pro_types.c +274 -0
- data/ext/rdwarf/libdwarf/pro_types.h +34 -0
- data/ext/rdwarf/libdwarf/pro_util.h +38 -0
- data/ext/rdwarf/libdwarf/pro_vars.c +52 -0
- data/ext/rdwarf/libdwarf/pro_weaks.c +51 -0
- data/ext/rdwarf/rdwarf.c +765 -0
- data/ext/rdwarf/rdwarf.h +52 -0
- data/ext/rdwarf/rdwarf_names_gen.rb +109 -0
- data/lib/rdwarf.rb +181 -0
- data/lib/rdwarf/version.rb +3 -0
- data/rdwarf.gemspec +30 -0
- metadata +251 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
|
|
4
|
+
Portions Copyright 2011 David Anderson. All Rights Reserved.
|
|
5
|
+
|
|
6
|
+
This program is free software; you can redistribute it and/or modify it
|
|
7
|
+
under the terms of version 2.1 of the GNU Lesser General Public License
|
|
8
|
+
as published by the Free Software Foundation.
|
|
9
|
+
|
|
10
|
+
This program is distributed in the hope that it would be useful, but
|
|
11
|
+
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
13
|
+
|
|
14
|
+
Further, this software is distributed without any warranty that it is
|
|
15
|
+
free of the rightful claim of any third person regarding infringement
|
|
16
|
+
or the like. Any license provided herein, whether implied or
|
|
17
|
+
otherwise, applies only to this software file. Patent licenses, if
|
|
18
|
+
any, provided herein do not apply to combinations of this program with
|
|
19
|
+
other software, or any other product whatsoever.
|
|
20
|
+
|
|
21
|
+
You should have received a copy of the GNU Lesser General Public
|
|
22
|
+
License along with this program; if not, write the Free Software
|
|
23
|
+
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
|
|
24
|
+
USA.
|
|
25
|
+
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
#include "config.h"
|
|
29
|
+
#include "dwarf_incl.h"
|
|
30
|
+
#include <stdio.h>
|
|
31
|
+
|
|
32
|
+
/* 10 bytes of leb, 7 bits each part of the number, gives
|
|
33
|
+
room for a 64bit number.
|
|
34
|
+
While any number of leading zeroes would be legal, so
|
|
35
|
+
no max is really truly required here, why would a
|
|
36
|
+
compiler generate leading zeros? That would
|
|
37
|
+
be strange.
|
|
38
|
+
*/
|
|
39
|
+
#define BYTESLEBMAX 10
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
/* Decode ULEB */
|
|
43
|
+
Dwarf_Unsigned
|
|
44
|
+
_dwarf_decode_u_leb128(Dwarf_Small * leb128, Dwarf_Word * leb128_length)
|
|
45
|
+
{
|
|
46
|
+
unsigned char byte;
|
|
47
|
+
Dwarf_Word word_number;
|
|
48
|
+
Dwarf_Unsigned number;
|
|
49
|
+
Dwarf_Sword shift;
|
|
50
|
+
/* The byte_length value will be a small non-negative integer. */
|
|
51
|
+
unsigned byte_length = 0;
|
|
52
|
+
|
|
53
|
+
/* The following unrolls-the-loop for the first few bytes and
|
|
54
|
+
unpacks into 32 bits to make this as fast as possible.
|
|
55
|
+
word_number is assumed big enough that the shift has a defined
|
|
56
|
+
result. */
|
|
57
|
+
if ((*leb128 & 0x80) == 0) {
|
|
58
|
+
if (leb128_length != NULL)
|
|
59
|
+
*leb128_length = 1;
|
|
60
|
+
return (*leb128);
|
|
61
|
+
} else if ((*(leb128 + 1) & 0x80) == 0) {
|
|
62
|
+
if (leb128_length != NULL)
|
|
63
|
+
*leb128_length = 2;
|
|
64
|
+
|
|
65
|
+
word_number = *leb128 & 0x7f;
|
|
66
|
+
word_number |= (*(leb128 + 1) & 0x7f) << 7;
|
|
67
|
+
return (word_number);
|
|
68
|
+
} else if ((*(leb128 + 2) & 0x80) == 0) {
|
|
69
|
+
if (leb128_length != NULL)
|
|
70
|
+
*leb128_length = 3;
|
|
71
|
+
|
|
72
|
+
word_number = *leb128 & 0x7f;
|
|
73
|
+
word_number |= (*(leb128 + 1) & 0x7f) << 7;
|
|
74
|
+
word_number |= (*(leb128 + 2) & 0x7f) << 14;
|
|
75
|
+
return (word_number);
|
|
76
|
+
} else if ((*(leb128 + 3) & 0x80) == 0) {
|
|
77
|
+
if (leb128_length != NULL)
|
|
78
|
+
*leb128_length = 4;
|
|
79
|
+
|
|
80
|
+
word_number = *leb128 & 0x7f;
|
|
81
|
+
word_number |= (*(leb128 + 1) & 0x7f) << 7;
|
|
82
|
+
word_number |= (*(leb128 + 2) & 0x7f) << 14;
|
|
83
|
+
word_number |= (*(leb128 + 3) & 0x7f) << 21;
|
|
84
|
+
return (word_number);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* The rest handles long numbers Because the 'number' may be larger
|
|
88
|
+
than the default int/unsigned, we must cast the 'byte' before
|
|
89
|
+
the shift for the shift to have a defined result. */
|
|
90
|
+
number = 0;
|
|
91
|
+
shift = 0;
|
|
92
|
+
byte_length = 1;
|
|
93
|
+
byte = *(leb128);
|
|
94
|
+
for (;;) {
|
|
95
|
+
number |= ((Dwarf_Unsigned) (byte & 0x7f)) << shift;
|
|
96
|
+
|
|
97
|
+
if ((byte & 0x80) == 0) {
|
|
98
|
+
if (leb128_length != NULL)
|
|
99
|
+
*leb128_length = byte_length;
|
|
100
|
+
return (number);
|
|
101
|
+
}
|
|
102
|
+
shift += 7;
|
|
103
|
+
|
|
104
|
+
byte_length++;
|
|
105
|
+
if (byte_length > BYTESLEBMAX) {
|
|
106
|
+
/* Erroneous input. What to do?
|
|
107
|
+
Abort? Return error? Just stop here?*/
|
|
108
|
+
*leb128_length = BYTESLEBMAX;
|
|
109
|
+
return number;
|
|
110
|
+
}
|
|
111
|
+
++leb128;
|
|
112
|
+
byte = *leb128;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
#define BITSINBYTE 8
|
|
117
|
+
|
|
118
|
+
/* decode SLEB */
|
|
119
|
+
Dwarf_Signed
|
|
120
|
+
_dwarf_decode_s_leb128(Dwarf_Small * leb128, Dwarf_Word * leb128_length)
|
|
121
|
+
{
|
|
122
|
+
Dwarf_Signed number = 0;
|
|
123
|
+
Dwarf_Bool sign = 0;
|
|
124
|
+
Dwarf_Word shift = 0;
|
|
125
|
+
unsigned char byte = *leb128;
|
|
126
|
+
/* The byte_length value will be a small non-negative integer. */
|
|
127
|
+
unsigned byte_length = 1;
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
/* byte_length being the number of bytes of data absorbed so far in
|
|
131
|
+
turning the leb into a Dwarf_Signed. */
|
|
132
|
+
|
|
133
|
+
for (;;) {
|
|
134
|
+
sign = byte & 0x40;
|
|
135
|
+
number |= ((Dwarf_Signed) ((byte & 0x7f))) << shift;
|
|
136
|
+
shift += 7;
|
|
137
|
+
|
|
138
|
+
if ((byte & 0x80) == 0) {
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
++leb128;
|
|
142
|
+
byte = *leb128;
|
|
143
|
+
byte_length++;
|
|
144
|
+
if (byte_length > BYTESLEBMAX) {
|
|
145
|
+
/* Erroneous input. What to do?
|
|
146
|
+
Abort? Return error? Just stop here?*/
|
|
147
|
+
*leb128_length = BYTESLEBMAX;
|
|
148
|
+
return number;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if ((shift < sizeof(Dwarf_Signed) * BITSINBYTE) && sign) {
|
|
153
|
+
number |= -((Dwarf_Signed) 1 << shift);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (leb128_length != NULL)
|
|
157
|
+
*leb128_length = byte_length;
|
|
158
|
+
return (number);
|
|
159
|
+
}
|
|
@@ -0,0 +1,1822 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
|
|
3
|
+
Portions Copyright (C) 2007-2015 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 "dwarf_incl.h"
|
|
31
|
+
#include <stdio.h>
|
|
32
|
+
#include <stdlib.h>
|
|
33
|
+
#include "dwarf_line.h"
|
|
34
|
+
|
|
35
|
+
/* Line Register Set initial conditions. */
|
|
36
|
+
static struct Dwarf_Line_Registers_s _dwarf_line_table_regs_default_values = {
|
|
37
|
+
/* Dwarf_Addr lr_address */ 0,
|
|
38
|
+
/* Dwarf_Word lr_file */ 1,
|
|
39
|
+
/* Dwarf_Word lr_line */ 1,
|
|
40
|
+
/* Dwarf_Word lr_column */ 0,
|
|
41
|
+
/* Dwarf_Bool lr_is_stmt */ false,
|
|
42
|
+
/* Dwarf_Bool lr_basic_block */ false,
|
|
43
|
+
/* Dwarf_Bool lr_end_sequence */ false,
|
|
44
|
+
/* Dwarf_Bool lr_prologue_end */ false,
|
|
45
|
+
/* Dwarf_Bool lr_epilogue_begin */ false,
|
|
46
|
+
/* Dwarf_Small lr_isa */ 0,
|
|
47
|
+
/* Dwarf_Unsigned lr_op_index */ 0,
|
|
48
|
+
/* Dwarf_Unsigned lr_discriminator */ 0,
|
|
49
|
+
/* Dwarf_Unsigned lr_call_context */ 0,
|
|
50
|
+
/* Dwarf_Unsigned lr_subprogram */ 0,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
void
|
|
54
|
+
_dwarf_set_line_table_regs_default_values(Dwarf_Line_Registers regs,
|
|
55
|
+
Dwarf_Bool is_stmt)
|
|
56
|
+
{
|
|
57
|
+
*regs = _dwarf_line_table_regs_default_values;
|
|
58
|
+
regs->lr_is_stmt = is_stmt;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
static int
|
|
63
|
+
is_path_separator(Dwarf_Small s)
|
|
64
|
+
{
|
|
65
|
+
if (s == '/') {
|
|
66
|
+
return 1;
|
|
67
|
+
}
|
|
68
|
+
#ifdef HAVE_WINDOWS_PATH
|
|
69
|
+
if (s == '\\') {
|
|
70
|
+
return 1;
|
|
71
|
+
}
|
|
72
|
+
#endif
|
|
73
|
+
return 0;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* Return 0 if false, 1 if true.
|
|
77
|
+
If HAVE_WINDOWS_PATH is defined we
|
|
78
|
+
attempt to handle windows full paths:
|
|
79
|
+
\\something or C:cwdpath.c
|
|
80
|
+
*/
|
|
81
|
+
static int
|
|
82
|
+
file_name_is_full_path(Dwarf_Small *fname)
|
|
83
|
+
{
|
|
84
|
+
Dwarf_Small firstc = *fname;
|
|
85
|
+
if (is_path_separator(firstc)) {
|
|
86
|
+
/* Full path. */
|
|
87
|
+
return 1;
|
|
88
|
+
}
|
|
89
|
+
if (!firstc) {
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
/* This is a windows path test, but we do have
|
|
93
|
+
a few windows paths in our regression tests...
|
|
94
|
+
This is extremely unlikely to cause UN*X/POSIX
|
|
95
|
+
users any problems. */
|
|
96
|
+
if ((firstc >= 'A' && firstc <= 'Z') ||
|
|
97
|
+
(firstc >= 'a' && firstc <= 'z')) {
|
|
98
|
+
|
|
99
|
+
Dwarf_Small secondc = fname[1];
|
|
100
|
+
if (secondc == ':') {
|
|
101
|
+
return 1;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/* End Windows style */
|
|
105
|
+
return 0;
|
|
106
|
+
}
|
|
107
|
+
#include "dwarf_line_table_reader_common.c"
|
|
108
|
+
|
|
109
|
+
static void
|
|
110
|
+
special_cat(char *dst,char *src,int srclen)
|
|
111
|
+
{
|
|
112
|
+
#if defined (HAVE_WINDOWS_PATH)
|
|
113
|
+
/* Always '/' instead of '\\', this is a Windows -> Unix
|
|
114
|
+
issue. */
|
|
115
|
+
int i1 = 0;
|
|
116
|
+
int i2 = 0;
|
|
117
|
+
|
|
118
|
+
for ( ; dst[i1] ; ++i1) {
|
|
119
|
+
}
|
|
120
|
+
for (; i2 < srclen; ++i2,++i1) {
|
|
121
|
+
dst[i1] = src[i2];
|
|
122
|
+
if (dst[i1] == '\\') {
|
|
123
|
+
dst[i1] = '/';
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
#else
|
|
127
|
+
strcat(dst, src);
|
|
128
|
+
#endif /* HAVE_WINDOWS_PATH */
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* With this routine we ensure the file full path
|
|
133
|
+
is calculated identically for
|
|
134
|
+
dwarf_srcfiles() and dwarf_filename()
|
|
135
|
+
|
|
136
|
+
We sometimes return a string pointer that points inside a dwarfsection,
|
|
137
|
+
yet sometimes we return a _dwarf_get_alloc allocated string.
|
|
138
|
+
This is safe because dwarf_dealloc (which users should
|
|
139
|
+
call eventually)will not actually deallocate
|
|
140
|
+
a string unless _dwarf_get_alloc allocated the pointed-to area.
|
|
141
|
+
|
|
142
|
+
dwarf_finish() will do the dealloc if nothing else does.
|
|
143
|
+
*/
|
|
144
|
+
static int
|
|
145
|
+
create_fullest_file_path(Dwarf_Debug dbg,
|
|
146
|
+
Dwarf_File_Entry fe,
|
|
147
|
+
Dwarf_Line_Context line_context,
|
|
148
|
+
char ** name_ptr_out,
|
|
149
|
+
Dwarf_Error *error)
|
|
150
|
+
{
|
|
151
|
+
Dwarf_Unsigned dirno = 0;
|
|
152
|
+
char *full_name = 0;
|
|
153
|
+
char *file_name = 0;
|
|
154
|
+
|
|
155
|
+
dirno = fe->fi_dir_index;
|
|
156
|
+
file_name = (char *) fe->fi_file_name;
|
|
157
|
+
if (!file_name) {
|
|
158
|
+
_dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME);
|
|
159
|
+
return (DW_DLV_ERROR);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (file_name_is_full_path((Dwarf_Small *)file_name)) {
|
|
163
|
+
#ifdef HAVE_WINDOWS_PATH
|
|
164
|
+
{ unsigned len = strlen(file_name);
|
|
165
|
+
char *tmp = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING,
|
|
166
|
+
len+1);
|
|
167
|
+
if(tmp) {
|
|
168
|
+
tmp[0] = 0;
|
|
169
|
+
special_cat(tmp,file_name,len);
|
|
170
|
+
if (strcmp(tmp,file_name)) {
|
|
171
|
+
/* We transformed the name. Use the new name. */
|
|
172
|
+
*name_ptr_out = tmp;
|
|
173
|
+
return DW_DLV_OK;
|
|
174
|
+
} else {
|
|
175
|
+
dwarf_dealloc(dbg,tmp,DW_DLA_STRING);
|
|
176
|
+
/* Just fall through. file_name ok. */
|
|
177
|
+
}
|
|
178
|
+
} /* else out of memory, just fall through to keep going. */
|
|
179
|
+
}
|
|
180
|
+
#endif
|
|
181
|
+
*name_ptr_out = file_name;
|
|
182
|
+
return DW_DLV_OK;
|
|
183
|
+
} else {
|
|
184
|
+
char *comp_dir_name = "";
|
|
185
|
+
char *inc_dir_name = "";
|
|
186
|
+
Dwarf_Unsigned incdirnamelen = 0;
|
|
187
|
+
Dwarf_Unsigned filenamelen = strlen(file_name);
|
|
188
|
+
Dwarf_Unsigned compdirnamelen = 0;
|
|
189
|
+
|
|
190
|
+
if (line_context->lc_compilation_directory) {
|
|
191
|
+
/* This is safe because dwarf_dealloc is careful to not
|
|
192
|
+
dealloc strings which dwarf_get_alloc did not
|
|
193
|
+
allocate. */
|
|
194
|
+
comp_dir_name = (char *)line_context->lc_compilation_directory;
|
|
195
|
+
compdirnamelen = strlen(comp_dir_name);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (dirno > line_context->lc_include_directories_count) {
|
|
199
|
+
_dwarf_error(dbg, error, DW_DLE_INCL_DIR_NUM_BAD);
|
|
200
|
+
return (DW_DLV_ERROR);
|
|
201
|
+
}
|
|
202
|
+
if (dirno > 0) {
|
|
203
|
+
inc_dir_name = (char *) line_context->lc_include_directories[
|
|
204
|
+
fe->fi_dir_index - 1];
|
|
205
|
+
incdirnamelen = strlen(inc_dir_name);
|
|
206
|
+
}
|
|
207
|
+
full_name = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING,
|
|
208
|
+
compdirnamelen + 1 +
|
|
209
|
+
incdirnamelen + 1 +
|
|
210
|
+
filenamelen + 1);
|
|
211
|
+
if (full_name == NULL) {
|
|
212
|
+
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
|
|
213
|
+
return (DW_DLV_ERROR);
|
|
214
|
+
}
|
|
215
|
+
if (dirno == 0) {
|
|
216
|
+
/* Just use comp dir name */
|
|
217
|
+
if (compdirnamelen > 0) {
|
|
218
|
+
special_cat(full_name,comp_dir_name,compdirnamelen);
|
|
219
|
+
strcat(full_name, "/");
|
|
220
|
+
}
|
|
221
|
+
special_cat(full_name,file_name,filenamelen);
|
|
222
|
+
*name_ptr_out = full_name;
|
|
223
|
+
return DW_DLV_OK;
|
|
224
|
+
}
|
|
225
|
+
if (incdirnamelen > 0 &&
|
|
226
|
+
file_name_is_full_path((Dwarf_Small*)inc_dir_name) ) {
|
|
227
|
+
/* Just use inc dir. */
|
|
228
|
+
special_cat(full_name,inc_dir_name,incdirnamelen);
|
|
229
|
+
strcat(full_name,"/");
|
|
230
|
+
special_cat(full_name,file_name,filenamelen);
|
|
231
|
+
*name_ptr_out = full_name;
|
|
232
|
+
return DW_DLV_OK;
|
|
233
|
+
}
|
|
234
|
+
/* Concat all three names. */
|
|
235
|
+
if (compdirnamelen > 0) {
|
|
236
|
+
special_cat(full_name,comp_dir_name,compdirnamelen);
|
|
237
|
+
strcat(full_name, "/");
|
|
238
|
+
}
|
|
239
|
+
if (incdirnamelen > 0) {
|
|
240
|
+
special_cat(full_name,inc_dir_name,incdirnamelen);
|
|
241
|
+
strcat(full_name, "/");
|
|
242
|
+
}
|
|
243
|
+
special_cat(full_name,file_name,filenamelen);
|
|
244
|
+
}
|
|
245
|
+
*name_ptr_out = full_name;
|
|
246
|
+
return DW_DLV_OK;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
/* Although source files is supposed to return the
|
|
251
|
+
source files in the compilation-unit, it does
|
|
252
|
+
not look for any in the statement program. In
|
|
253
|
+
other words, it ignores those defined using the
|
|
254
|
+
extended opcode DW_LNE_define_file. */
|
|
255
|
+
int
|
|
256
|
+
dwarf_srcfiles(Dwarf_Die die,
|
|
257
|
+
char ***srcfiles,
|
|
258
|
+
Dwarf_Signed * srcfilecount, Dwarf_Error * error)
|
|
259
|
+
{
|
|
260
|
+
/* This pointer is used to scan the portion of the .debug_line
|
|
261
|
+
section for the current cu. */
|
|
262
|
+
Dwarf_Small *line_ptr;
|
|
263
|
+
|
|
264
|
+
/* Pointer to a DW_AT_stmt_list attribute in case it exists in the
|
|
265
|
+
die. */
|
|
266
|
+
Dwarf_Attribute stmt_list_attr;
|
|
267
|
+
|
|
268
|
+
/* Pointer to DW_AT_comp_dir attribute in die. */
|
|
269
|
+
Dwarf_Attribute comp_dir_attr;
|
|
270
|
+
|
|
271
|
+
/* Pointer to name of compilation directory. */
|
|
272
|
+
Dwarf_Small *comp_dir = 0;
|
|
273
|
+
|
|
274
|
+
/* Offset into .debug_line specified by a DW_AT_stmt_list
|
|
275
|
+
attribute. */
|
|
276
|
+
Dwarf_Unsigned line_offset = 0;
|
|
277
|
+
|
|
278
|
+
/* This points to a block of char *'s, each of which points to a
|
|
279
|
+
file name. */
|
|
280
|
+
char **ret_files = 0;
|
|
281
|
+
|
|
282
|
+
/* The Dwarf_Debug this die belongs to. */
|
|
283
|
+
Dwarf_Debug dbg = 0;
|
|
284
|
+
Dwarf_CU_Context context = 0;
|
|
285
|
+
Dwarf_Line_Context line_context = 0;
|
|
286
|
+
|
|
287
|
+
/* Used to chain the file names. */
|
|
288
|
+
Dwarf_Chain curr_chain = NULL;
|
|
289
|
+
Dwarf_Chain prev_chain = NULL;
|
|
290
|
+
Dwarf_Chain head_chain = NULL;
|
|
291
|
+
|
|
292
|
+
Dwarf_Half attrform = 0;
|
|
293
|
+
int resattr = DW_DLV_ERROR;
|
|
294
|
+
int lres = DW_DLV_ERROR;
|
|
295
|
+
unsigned i = 0;
|
|
296
|
+
int res = DW_DLV_ERROR;
|
|
297
|
+
|
|
298
|
+
/* ***** BEGIN CODE ***** */
|
|
299
|
+
/* Reset error. */
|
|
300
|
+
if (error != NULL) {
|
|
301
|
+
*error = NULL;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
CHECK_DIE(die, DW_DLV_ERROR);
|
|
305
|
+
context = die->di_cu_context;
|
|
306
|
+
dbg = context->cc_dbg;
|
|
307
|
+
|
|
308
|
+
resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
|
|
309
|
+
if (resattr != DW_DLV_OK) {
|
|
310
|
+
return resattr;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (dbg->de_debug_line.dss_index == 0) {
|
|
314
|
+
_dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_NULL);
|
|
315
|
+
return (DW_DLV_ERROR);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
res = _dwarf_load_section(dbg, &dbg->de_debug_line,error);
|
|
319
|
+
if (res != DW_DLV_OK) {
|
|
320
|
+
return res;
|
|
321
|
+
}
|
|
322
|
+
if (!dbg->de_debug_line.dss_size) {
|
|
323
|
+
return (DW_DLV_NO_ENTRY);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
lres = dwarf_whatform(stmt_list_attr,&attrform,error);
|
|
328
|
+
if (lres != DW_DLV_OK) {
|
|
329
|
+
return lres;
|
|
330
|
+
}
|
|
331
|
+
if (attrform != DW_FORM_data4 && attrform != DW_FORM_data8 &&
|
|
332
|
+
attrform != DW_FORM_sec_offset &&
|
|
333
|
+
attrform != DW_FORM_GNU_ref_alt) {
|
|
334
|
+
_dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
|
|
335
|
+
return (DW_DLV_ERROR);
|
|
336
|
+
}
|
|
337
|
+
lres = dwarf_global_formref(stmt_list_attr, &line_offset, error);
|
|
338
|
+
if (lres != DW_DLV_OK) {
|
|
339
|
+
return lres;
|
|
340
|
+
}
|
|
341
|
+
if (line_offset >= dbg->de_debug_line.dss_size) {
|
|
342
|
+
_dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
|
|
343
|
+
return (DW_DLV_ERROR);
|
|
344
|
+
}
|
|
345
|
+
line_ptr = dbg->de_debug_line.dss_data + line_offset;
|
|
346
|
+
{
|
|
347
|
+
Dwarf_Unsigned fission_offset = 0;
|
|
348
|
+
Dwarf_Unsigned fission_size = 0;
|
|
349
|
+
int res = _dwarf_get_fission_addition_die(die, DW_SECT_LINE,
|
|
350
|
+
&fission_offset,&fission_size,error);
|
|
351
|
+
if(res != DW_DLV_OK) {
|
|
352
|
+
return res;
|
|
353
|
+
}
|
|
354
|
+
line_ptr += fission_offset;
|
|
355
|
+
}
|
|
356
|
+
dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
|
|
357
|
+
|
|
358
|
+
/* If die has DW_AT_comp_dir attribute, get the string that names
|
|
359
|
+
the compilation directory. */
|
|
360
|
+
resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
|
|
361
|
+
if (resattr == DW_DLV_ERROR) {
|
|
362
|
+
return resattr;
|
|
363
|
+
}
|
|
364
|
+
if (resattr == DW_DLV_OK) {
|
|
365
|
+
int cres = DW_DLV_ERROR;
|
|
366
|
+
char *cdir = 0;
|
|
367
|
+
|
|
368
|
+
cres = dwarf_formstring(comp_dir_attr, &cdir, error);
|
|
369
|
+
if (cres == DW_DLV_ERROR) {
|
|
370
|
+
return cres;
|
|
371
|
+
} else if (cres == DW_DLV_OK) {
|
|
372
|
+
comp_dir = (Dwarf_Small *) cdir;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
if (resattr == DW_DLV_OK) {
|
|
376
|
+
dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
|
|
377
|
+
}
|
|
378
|
+
line_context = (Dwarf_Line_Context)
|
|
379
|
+
_dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1);
|
|
380
|
+
if (line_context == NULL) {
|
|
381
|
+
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
|
|
382
|
+
return (DW_DLV_ERROR);
|
|
383
|
+
}
|
|
384
|
+
line_context->lc_new_style_access = false;
|
|
385
|
+
/* We are in dwarf_srcfiles() */
|
|
386
|
+
{
|
|
387
|
+
Dwarf_Small *line_ptr_out = 0;
|
|
388
|
+
int dres = _dwarf_read_line_table_header(dbg,
|
|
389
|
+
context,
|
|
390
|
+
line_ptr,
|
|
391
|
+
dbg->de_debug_line.dss_size,
|
|
392
|
+
&line_ptr_out,
|
|
393
|
+
line_context,
|
|
394
|
+
NULL, NULL,error,
|
|
395
|
+
0);
|
|
396
|
+
|
|
397
|
+
if (dres == DW_DLV_ERROR) {
|
|
398
|
+
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
|
|
399
|
+
line_context = 0;
|
|
400
|
+
return dres;
|
|
401
|
+
}
|
|
402
|
+
if (dres == DW_DLV_NO_ENTRY) {
|
|
403
|
+
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
|
|
404
|
+
line_context = 0;
|
|
405
|
+
return dres;
|
|
406
|
+
}
|
|
407
|
+
line_ptr = line_ptr_out;
|
|
408
|
+
}
|
|
409
|
+
line_context->lc_compilation_directory = comp_dir;
|
|
410
|
+
/* We are in dwarf_srcfiles() */
|
|
411
|
+
{
|
|
412
|
+
Dwarf_File_Entry fe = line_context->lc_file_entries;
|
|
413
|
+
Dwarf_File_Entry fe2 = fe;
|
|
414
|
+
for (i = 0; i < line_context->lc_file_entry_count;
|
|
415
|
+
++i,fe2 = fe->fi_next ) {
|
|
416
|
+
int sres = 0;
|
|
417
|
+
char *name_out = 0;
|
|
418
|
+
|
|
419
|
+
fe = fe2;
|
|
420
|
+
sres = create_fullest_file_path(dbg,fe,line_context,
|
|
421
|
+
&name_out,error);
|
|
422
|
+
if (sres != DW_DLV_OK) {
|
|
423
|
+
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
|
|
424
|
+
/* This can leak some strings */
|
|
425
|
+
return sres;
|
|
426
|
+
}
|
|
427
|
+
curr_chain =
|
|
428
|
+
(Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
|
|
429
|
+
if (curr_chain == NULL) {
|
|
430
|
+
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
|
|
431
|
+
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
|
|
432
|
+
return (DW_DLV_ERROR);
|
|
433
|
+
}
|
|
434
|
+
curr_chain->ch_item = name_out;
|
|
435
|
+
if (head_chain == NULL) {
|
|
436
|
+
head_chain = prev_chain = curr_chain;
|
|
437
|
+
} else {
|
|
438
|
+
prev_chain->ch_next = curr_chain;
|
|
439
|
+
prev_chain = curr_chain;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/* We are in dwarf_srcfiles() */
|
|
445
|
+
if (line_context->lc_file_entry_count == 0) {
|
|
446
|
+
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
|
|
447
|
+
*srcfiles = NULL;
|
|
448
|
+
*srcfilecount = 0;
|
|
449
|
+
return (DW_DLV_NO_ENTRY);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
ret_files = (char **)
|
|
453
|
+
_dwarf_get_alloc(dbg, DW_DLA_LIST, line_context->lc_file_entry_count);
|
|
454
|
+
if (ret_files == NULL) {
|
|
455
|
+
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
|
|
456
|
+
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
|
|
457
|
+
return (DW_DLV_ERROR);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
curr_chain = head_chain;
|
|
461
|
+
for (i = 0; i < line_context->lc_file_entry_count; i++) {
|
|
462
|
+
*(ret_files + i) = curr_chain->ch_item;
|
|
463
|
+
prev_chain = curr_chain;
|
|
464
|
+
curr_chain = curr_chain->ch_next;
|
|
465
|
+
dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
|
|
466
|
+
}
|
|
467
|
+
/* Our chain is not recorded in the line_context so
|
|
468
|
+
the line_context destructor will not destroy our list of strings
|
|
469
|
+
or our strings.
|
|
470
|
+
Our caller has to do the deallocations. */
|
|
471
|
+
|
|
472
|
+
*srcfiles = ret_files;
|
|
473
|
+
*srcfilecount = line_context->lc_file_entry_count;
|
|
474
|
+
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
|
|
475
|
+
return (DW_DLV_OK);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
/* Return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR
|
|
481
|
+
doaddrs is true iff this is being called for SGI IRIX rqs processing
|
|
482
|
+
(ie, not a normal libdwarf dwarf_srclines or two-level user call at all).
|
|
483
|
+
dolines is true iff this is called by a dwarf_srclines call.
|
|
484
|
+
|
|
485
|
+
In case of error or NO_ENTRY in this code we use the
|
|
486
|
+
dwarf_srcline_dealloc(line_context)
|
|
487
|
+
and dealloc of DW_DLA_LINE_CONTEXT
|
|
488
|
+
from the new interface for uniformity here.
|
|
489
|
+
*/
|
|
490
|
+
|
|
491
|
+
int
|
|
492
|
+
_dwarf_internal_srclines(Dwarf_Die die,
|
|
493
|
+
Dwarf_Bool is_new_interface,
|
|
494
|
+
Dwarf_Unsigned * version,
|
|
495
|
+
Dwarf_Small * table_count, /* returns 0,1, or 2 */
|
|
496
|
+
Dwarf_Line_Context *line_context_out,
|
|
497
|
+
Dwarf_Line ** linebuf,
|
|
498
|
+
Dwarf_Signed * linecount,
|
|
499
|
+
Dwarf_Line ** linebuf_actuals,
|
|
500
|
+
Dwarf_Signed * linecount_actuals,
|
|
501
|
+
Dwarf_Bool doaddrs,
|
|
502
|
+
Dwarf_Bool dolines,
|
|
503
|
+
Dwarf_Error * error)
|
|
504
|
+
{
|
|
505
|
+
/* This pointer is used to scan the portion of the .debug_line
|
|
506
|
+
section for the current cu. */
|
|
507
|
+
Dwarf_Small *line_ptr = 0;
|
|
508
|
+
|
|
509
|
+
/* This points to the last byte of the .debug_line portion for the
|
|
510
|
+
current cu. */
|
|
511
|
+
Dwarf_Small *line_ptr_end = 0;
|
|
512
|
+
|
|
513
|
+
/* For two-level line tables, this points to the first byte of the
|
|
514
|
+
actuals table (and the end of the logicals table) for the current
|
|
515
|
+
cu. */
|
|
516
|
+
Dwarf_Small *line_ptr_actuals = 0;
|
|
517
|
+
Dwarf_Small *section_start = 0;
|
|
518
|
+
|
|
519
|
+
/* Pointer to a DW_AT_stmt_list attribute in case it exists in the
|
|
520
|
+
die. */
|
|
521
|
+
Dwarf_Attribute stmt_list_attr = 0;
|
|
522
|
+
|
|
523
|
+
/* Pointer to DW_AT_comp_dir attribute in die. */
|
|
524
|
+
Dwarf_Attribute comp_dir_attr = 0;
|
|
525
|
+
|
|
526
|
+
/* Pointer to name of compilation directory. */
|
|
527
|
+
Dwarf_Small *comp_dir = NULL;
|
|
528
|
+
|
|
529
|
+
/* Offset into .debug_line specified by a DW_AT_stmt_list
|
|
530
|
+
attribute. */
|
|
531
|
+
Dwarf_Unsigned line_offset = 0;
|
|
532
|
+
|
|
533
|
+
/* Pointer to a Dwarf_Line_Context_s structure that contains the
|
|
534
|
+
context such as file names and include directories for the set
|
|
535
|
+
of lines being generated.
|
|
536
|
+
This is always recorded on an
|
|
537
|
+
DW_LNS_end_sequence operator,
|
|
538
|
+
on all special opcodes, and on DW_LNS_copy.
|
|
539
|
+
*/
|
|
540
|
+
Dwarf_Line_Context line_context = 0;
|
|
541
|
+
Dwarf_CU_Context cu_context = 0;
|
|
542
|
+
Dwarf_Unsigned fission_offset = 0;
|
|
543
|
+
|
|
544
|
+
/* The Dwarf_Debug this die belongs to. */
|
|
545
|
+
Dwarf_Debug dbg = 0;
|
|
546
|
+
int resattr = DW_DLV_ERROR;
|
|
547
|
+
int lres = DW_DLV_ERROR;
|
|
548
|
+
Dwarf_Half address_size = 0;
|
|
549
|
+
Dwarf_Small * orig_line_ptr = 0;
|
|
550
|
+
|
|
551
|
+
int res = DW_DLV_ERROR;
|
|
552
|
+
|
|
553
|
+
/* ***** BEGIN CODE ***** */
|
|
554
|
+
if (error != NULL) {
|
|
555
|
+
*error = NULL;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
CHECK_DIE(die, DW_DLV_ERROR);
|
|
559
|
+
cu_context = die->di_cu_context;
|
|
560
|
+
dbg = cu_context->cc_dbg;
|
|
561
|
+
|
|
562
|
+
res = _dwarf_load_section(dbg, &dbg->de_debug_line,error);
|
|
563
|
+
if (res != DW_DLV_OK) {
|
|
564
|
+
return res;
|
|
565
|
+
}
|
|
566
|
+
if (!dbg->de_debug_line.dss_size) {
|
|
567
|
+
return (DW_DLV_NO_ENTRY);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
address_size = _dwarf_get_address_size(dbg, die);
|
|
571
|
+
resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
|
|
572
|
+
if (resattr != DW_DLV_OK) {
|
|
573
|
+
return resattr;
|
|
574
|
+
}
|
|
575
|
+
lres = dwarf_global_formref(stmt_list_attr, &line_offset, error);
|
|
576
|
+
if (lres != DW_DLV_OK) {
|
|
577
|
+
return lres;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
if (line_offset >= dbg->de_debug_line.dss_size) {
|
|
581
|
+
_dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
|
|
582
|
+
return (DW_DLV_ERROR);
|
|
583
|
+
}
|
|
584
|
+
{
|
|
585
|
+
Dwarf_Unsigned fission_size = 0;
|
|
586
|
+
int res = _dwarf_get_fission_addition_die(die, DW_SECT_LINE,
|
|
587
|
+
&fission_offset,&fission_size,error);
|
|
588
|
+
if(res != DW_DLV_OK) {
|
|
589
|
+
return res;
|
|
590
|
+
}
|
|
591
|
+
line_ptr += fission_offset;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
section_start = dbg->de_debug_line.dss_data;
|
|
595
|
+
orig_line_ptr = section_start + line_offset + fission_offset;
|
|
596
|
+
line_ptr = orig_line_ptr;
|
|
597
|
+
dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
|
|
598
|
+
|
|
599
|
+
/* If die has DW_AT_comp_dir attribute, get the string that names
|
|
600
|
+
the compilation directory. */
|
|
601
|
+
resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
|
|
602
|
+
if (resattr == DW_DLV_ERROR) {
|
|
603
|
+
return resattr;
|
|
604
|
+
}
|
|
605
|
+
if (resattr == DW_DLV_OK) {
|
|
606
|
+
int cres = DW_DLV_ERROR;
|
|
607
|
+
char *cdir = 0;
|
|
608
|
+
|
|
609
|
+
cres = dwarf_formstring(comp_dir_attr, &cdir, error);
|
|
610
|
+
if (cres == DW_DLV_ERROR) {
|
|
611
|
+
return cres;
|
|
612
|
+
} else if (cres == DW_DLV_OK) {
|
|
613
|
+
comp_dir = (Dwarf_Small *) cdir;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
if (resattr == DW_DLV_OK) {
|
|
617
|
+
dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
|
|
618
|
+
}
|
|
619
|
+
line_context = (Dwarf_Line_Context)
|
|
620
|
+
_dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1);
|
|
621
|
+
if (line_context == NULL) {
|
|
622
|
+
_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
|
|
623
|
+
return (DW_DLV_ERROR);
|
|
624
|
+
}
|
|
625
|
+
line_context->lc_new_style_access = is_new_interface;
|
|
626
|
+
line_context->lc_compilation_directory = comp_dir;
|
|
627
|
+
/* We are in dwarf_internal_srclines() */
|
|
628
|
+
{
|
|
629
|
+
Dwarf_Small *newlinep = 0;
|
|
630
|
+
int resp = _dwarf_read_line_table_header(dbg,
|
|
631
|
+
cu_context,
|
|
632
|
+
line_ptr, dbg->de_debug_line.dss_size,
|
|
633
|
+
&newlinep,
|
|
634
|
+
line_context,
|
|
635
|
+
NULL,NULL,
|
|
636
|
+
error,
|
|
637
|
+
0);
|
|
638
|
+
|
|
639
|
+
if (resp == DW_DLV_ERROR) {
|
|
640
|
+
if(is_new_interface) {
|
|
641
|
+
dwarf_srclines_dealloc_b(line_context);
|
|
642
|
+
} else {
|
|
643
|
+
dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT);
|
|
644
|
+
}
|
|
645
|
+
return resp;
|
|
646
|
+
}
|
|
647
|
+
if (resp == DW_DLV_NO_ENTRY) {
|
|
648
|
+
if(is_new_interface) {
|
|
649
|
+
dwarf_srclines_dealloc_b(line_context);
|
|
650
|
+
} else {
|
|
651
|
+
dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT);
|
|
652
|
+
}
|
|
653
|
+
return resp;
|
|
654
|
+
}
|
|
655
|
+
line_ptr_end = line_context->lc_line_ptr_end;
|
|
656
|
+
line_ptr = newlinep;
|
|
657
|
+
if (line_context->lc_actuals_table_offset > 0) {
|
|
658
|
+
line_ptr_actuals = line_context->lc_line_prologue_start +
|
|
659
|
+
line_context->lc_actuals_table_offset;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
|
|
664
|
+
if (line_ptr_actuals == 0) {
|
|
665
|
+
/* ASSERT: lc_table_count == 1 or lc_table_count == 0 */
|
|
666
|
+
int err_count_out = 0;
|
|
667
|
+
/* Normal style (single level) line table. */
|
|
668
|
+
Dwarf_Bool is_actuals_table = false;
|
|
669
|
+
Dwarf_Bool local_is_single_table = true;
|
|
670
|
+
res = read_line_table_program(dbg,
|
|
671
|
+
line_ptr, line_ptr_end, orig_line_ptr,
|
|
672
|
+
section_start,
|
|
673
|
+
line_context,
|
|
674
|
+
address_size, doaddrs, dolines,
|
|
675
|
+
local_is_single_table,
|
|
676
|
+
is_actuals_table,
|
|
677
|
+
error,
|
|
678
|
+
&err_count_out);
|
|
679
|
+
if (res != DW_DLV_OK) {
|
|
680
|
+
if(is_new_interface) {
|
|
681
|
+
dwarf_srclines_dealloc_b(line_context);
|
|
682
|
+
} else {
|
|
683
|
+
dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT);
|
|
684
|
+
}
|
|
685
|
+
return res;
|
|
686
|
+
}
|
|
687
|
+
if (linebuf)
|
|
688
|
+
*linebuf = line_context->lc_linebuf_logicals;
|
|
689
|
+
if (linecount)
|
|
690
|
+
*linecount = line_context->lc_linecount_logicals;
|
|
691
|
+
if (linebuf_actuals) {
|
|
692
|
+
*linebuf_actuals = NULL;
|
|
693
|
+
}
|
|
694
|
+
if (linecount_actuals) {
|
|
695
|
+
*linecount_actuals = 0;
|
|
696
|
+
}
|
|
697
|
+
} else {
|
|
698
|
+
Dwarf_Bool is_actuals_table = false;
|
|
699
|
+
Dwarf_Bool local2_is_single_table = false;
|
|
700
|
+
int err_count_out = 0;
|
|
701
|
+
|
|
702
|
+
line_context->lc_is_single_table = false;
|
|
703
|
+
/* Two-level line table.
|
|
704
|
+
First read the logicals table. */
|
|
705
|
+
res = read_line_table_program(dbg,
|
|
706
|
+
line_ptr, line_ptr_actuals, orig_line_ptr,
|
|
707
|
+
section_start,
|
|
708
|
+
line_context,
|
|
709
|
+
address_size, doaddrs, dolines,
|
|
710
|
+
local2_is_single_table,
|
|
711
|
+
is_actuals_table, error,
|
|
712
|
+
&err_count_out);
|
|
713
|
+
if (res != DW_DLV_OK) {
|
|
714
|
+
if(is_new_interface) {
|
|
715
|
+
dwarf_srclines_dealloc_b(line_context);
|
|
716
|
+
} else {
|
|
717
|
+
dwarf_dealloc(dbg,line_context,DW_DLA_LINE_CONTEXT);
|
|
718
|
+
}
|
|
719
|
+
return res;
|
|
720
|
+
}
|
|
721
|
+
if (linebuf) {
|
|
722
|
+
*linebuf = line_context->lc_linebuf_logicals;
|
|
723
|
+
} else {
|
|
724
|
+
}
|
|
725
|
+
if (linecount) {
|
|
726
|
+
*linecount = line_context->lc_linecount_logicals;
|
|
727
|
+
}
|
|
728
|
+
if (is_new_interface) {
|
|
729
|
+
/* ASSERT: linebuf_actuals == NULL */
|
|
730
|
+
is_actuals_table = true;
|
|
731
|
+
/* The call requested an actuals table
|
|
732
|
+
and one is present. So now read that one. */
|
|
733
|
+
res = read_line_table_program(dbg,
|
|
734
|
+
|
|
735
|
+
line_ptr_actuals, line_ptr_end, orig_line_ptr,
|
|
736
|
+
section_start,
|
|
737
|
+
line_context,
|
|
738
|
+
address_size, doaddrs, dolines,
|
|
739
|
+
local2_is_single_table,
|
|
740
|
+
is_actuals_table, error,
|
|
741
|
+
&err_count_out);
|
|
742
|
+
if (res != DW_DLV_OK) {
|
|
743
|
+
dwarf_srclines_dealloc_b(line_context);
|
|
744
|
+
return res;
|
|
745
|
+
}
|
|
746
|
+
if (linebuf_actuals) {
|
|
747
|
+
*linebuf_actuals = line_context->lc_linebuf_actuals;
|
|
748
|
+
}
|
|
749
|
+
if (linecount_actuals != NULL) {
|
|
750
|
+
*linecount_actuals = line_context->lc_linecount_actuals;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
if (!is_new_interface &&
|
|
755
|
+
(*linecount == 0 && (linecount_actuals == NULL || *linecount_actuals == 0))) {
|
|
756
|
+
/* Here we have no actual lines of any kind. In other words,
|
|
757
|
+
it looks like a debugfission line table skeleton or
|
|
758
|
+
a caller not prepared for skeletons or two-level reading..
|
|
759
|
+
In that case there are no line entries so the context
|
|
760
|
+
had nowhere to be recorded. Hence we have to delete it
|
|
761
|
+
else we would leak the context. */
|
|
762
|
+
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
|
|
763
|
+
line_context = 0;
|
|
764
|
+
return DW_DLV_OK;
|
|
765
|
+
}
|
|
766
|
+
*table_count = line_context->lc_table_count;
|
|
767
|
+
if (version != NULL) {
|
|
768
|
+
*version = line_context->lc_version_number;
|
|
769
|
+
}
|
|
770
|
+
*line_context_out = line_context;
|
|
771
|
+
return (DW_DLV_OK);
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
int
|
|
776
|
+
dwarf_srclines(Dwarf_Die die,
|
|
777
|
+
Dwarf_Line ** linebuf,
|
|
778
|
+
Dwarf_Signed * linecount, Dwarf_Error * error)
|
|
779
|
+
{
|
|
780
|
+
Dwarf_Unsigned version = 0;
|
|
781
|
+
Dwarf_Line_Context line_context = 0;
|
|
782
|
+
Dwarf_Small table_count = 0;
|
|
783
|
+
Dwarf_Bool is_new_interface = false;
|
|
784
|
+
int res = _dwarf_internal_srclines(die,
|
|
785
|
+
is_new_interface,
|
|
786
|
+
&version,
|
|
787
|
+
&table_count,
|
|
788
|
+
&line_context,
|
|
789
|
+
linebuf,
|
|
790
|
+
linecount,
|
|
791
|
+
/* linebuf_actuals */ 0,
|
|
792
|
+
/*linecount_actuals*/0,
|
|
793
|
+
/* addrlist= */ false,
|
|
794
|
+
/* linelist= */ true,
|
|
795
|
+
error);
|
|
796
|
+
return res;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
int
|
|
800
|
+
dwarf_srclines_two_level(Dwarf_Die die,
|
|
801
|
+
Dwarf_Unsigned * version,
|
|
802
|
+
Dwarf_Line ** linebuf,
|
|
803
|
+
Dwarf_Signed * linecount,
|
|
804
|
+
Dwarf_Line ** linebuf_actuals,
|
|
805
|
+
Dwarf_Signed * linecount_actuals,
|
|
806
|
+
Dwarf_Error * error)
|
|
807
|
+
{
|
|
808
|
+
Dwarf_Line_Context line_context = 0;
|
|
809
|
+
Dwarf_Small table_count = 0;
|
|
810
|
+
Dwarf_Bool is_new_interface = false;
|
|
811
|
+
int res = _dwarf_internal_srclines(die,
|
|
812
|
+
is_new_interface,
|
|
813
|
+
version,
|
|
814
|
+
&table_count,
|
|
815
|
+
&line_context,
|
|
816
|
+
linebuf,
|
|
817
|
+
linecount,
|
|
818
|
+
linebuf_actuals,
|
|
819
|
+
linecount_actuals,
|
|
820
|
+
/* addrlist= */ false,
|
|
821
|
+
/* linelist= */ true,
|
|
822
|
+
error);
|
|
823
|
+
return res;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
/* New October 2015. */
|
|
827
|
+
int
|
|
828
|
+
dwarf_srclines_b(Dwarf_Die die,
|
|
829
|
+
Dwarf_Unsigned * version_out,
|
|
830
|
+
Dwarf_Small * table_count,
|
|
831
|
+
Dwarf_Line_Context * line_context,
|
|
832
|
+
Dwarf_Error * error)
|
|
833
|
+
{
|
|
834
|
+
Dwarf_Signed linecount_actuals = 0;
|
|
835
|
+
Dwarf_Line *linebuf = 0;
|
|
836
|
+
Dwarf_Line *linebuf_actuals = 0;
|
|
837
|
+
Dwarf_Signed linecount = 0;
|
|
838
|
+
Dwarf_Bool is_new_interface = true;
|
|
839
|
+
int res = 0;
|
|
840
|
+
Dwarf_Unsigned tcount = 0;
|
|
841
|
+
|
|
842
|
+
res = _dwarf_internal_srclines(die,
|
|
843
|
+
is_new_interface,
|
|
844
|
+
version_out,
|
|
845
|
+
table_count,
|
|
846
|
+
line_context,
|
|
847
|
+
&linebuf,
|
|
848
|
+
&linecount,
|
|
849
|
+
&linebuf_actuals,
|
|
850
|
+
&linecount_actuals,
|
|
851
|
+
/* addrlist= */ false,
|
|
852
|
+
/* linelist= */ true,
|
|
853
|
+
error);
|
|
854
|
+
if (res == DW_DLV_OK) {
|
|
855
|
+
(*line_context)->lc_new_style_access = true;
|
|
856
|
+
}
|
|
857
|
+
if(linecount_actuals ) {
|
|
858
|
+
tcount++;
|
|
859
|
+
}
|
|
860
|
+
if(linecount ) {
|
|
861
|
+
tcount++;
|
|
862
|
+
}
|
|
863
|
+
*table_count = tcount;
|
|
864
|
+
return res;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
/* New October 2015. */
|
|
869
|
+
int
|
|
870
|
+
dwarf_srclines_from_linecontext(Dwarf_Line_Context line_context,
|
|
871
|
+
Dwarf_Line** linebuf,
|
|
872
|
+
Dwarf_Signed * linecount,
|
|
873
|
+
Dwarf_Error * error)
|
|
874
|
+
{
|
|
875
|
+
if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
|
|
876
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
|
|
877
|
+
return (DW_DLV_ERROR);
|
|
878
|
+
}
|
|
879
|
+
if (!line_context->lc_new_style_access) {
|
|
880
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
|
|
881
|
+
return (DW_DLV_ERROR);
|
|
882
|
+
}
|
|
883
|
+
*linebuf = line_context->lc_linebuf_logicals;
|
|
884
|
+
*linecount = line_context->lc_linecount_logicals;
|
|
885
|
+
return DW_DLV_OK;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
/* New October 2015. */
|
|
889
|
+
int
|
|
890
|
+
dwarf_srclines_two_level_from_linecontext(Dwarf_Line_Context line_context,
|
|
891
|
+
Dwarf_Line** linebuf,
|
|
892
|
+
Dwarf_Signed * linecount,
|
|
893
|
+
Dwarf_Line** linebuf_actuals,
|
|
894
|
+
Dwarf_Signed * linecount_actuals,
|
|
895
|
+
Dwarf_Error * error)
|
|
896
|
+
{
|
|
897
|
+
if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
|
|
898
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
|
|
899
|
+
return (DW_DLV_ERROR);
|
|
900
|
+
}
|
|
901
|
+
if (!line_context->lc_new_style_access) {
|
|
902
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
|
|
903
|
+
return (DW_DLV_ERROR);
|
|
904
|
+
}
|
|
905
|
+
*linebuf = line_context->lc_linebuf_logicals;
|
|
906
|
+
*linecount = line_context->lc_linecount_logicals;
|
|
907
|
+
*linebuf_actuals = line_context->lc_linebuf_actuals;
|
|
908
|
+
*linecount_actuals = line_context->lc_linecount_actuals;
|
|
909
|
+
return DW_DLV_OK;
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
|
|
913
|
+
/* New October 2015. */
|
|
914
|
+
int
|
|
915
|
+
dwarf_srclines_table_offset(Dwarf_Line_Context line_context,
|
|
916
|
+
Dwarf_Unsigned * offset,
|
|
917
|
+
Dwarf_Error * error)
|
|
918
|
+
{
|
|
919
|
+
if (!line_context ){
|
|
920
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
|
|
921
|
+
return (DW_DLV_ERROR);
|
|
922
|
+
}
|
|
923
|
+
if( line_context->lc_magic != DW_CONTEXT_MAGIC) {
|
|
924
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
|
|
925
|
+
return (DW_DLV_ERROR);
|
|
926
|
+
}
|
|
927
|
+
*offset = line_context->lc_section_offset;
|
|
928
|
+
return DW_DLV_OK;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
/* New October 2015. */
|
|
932
|
+
/* If the CU DIE has no DW_AT_comp_dir then
|
|
933
|
+
the pointer pushed back to *compilation_directory
|
|
934
|
+
will be NULL. */
|
|
935
|
+
int dwarf_srclines_comp_dir(Dwarf_Line_Context line_context,
|
|
936
|
+
const char ** compilation_directory,
|
|
937
|
+
Dwarf_Error * error)
|
|
938
|
+
{
|
|
939
|
+
if (!line_context ){
|
|
940
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
|
|
941
|
+
return (DW_DLV_ERROR);
|
|
942
|
+
}
|
|
943
|
+
if( line_context->lc_magic != DW_CONTEXT_MAGIC) {
|
|
944
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
|
|
945
|
+
return (DW_DLV_ERROR);
|
|
946
|
+
}
|
|
947
|
+
*compilation_directory =
|
|
948
|
+
(const char *)line_context->lc_compilation_directory;
|
|
949
|
+
return DW_DLV_OK;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
|
|
953
|
+
|
|
954
|
+
|
|
955
|
+
/* New October 2015. */
|
|
956
|
+
int
|
|
957
|
+
dwarf_srclines_subprog_count(Dwarf_Line_Context line_context,
|
|
958
|
+
Dwarf_Signed * count_out,
|
|
959
|
+
Dwarf_Error * error)
|
|
960
|
+
{
|
|
961
|
+
if (!line_context ){
|
|
962
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
|
|
963
|
+
return (DW_DLV_ERROR);
|
|
964
|
+
}
|
|
965
|
+
if( line_context->lc_magic != DW_CONTEXT_MAGIC) {
|
|
966
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
|
|
967
|
+
return (DW_DLV_ERROR);
|
|
968
|
+
}
|
|
969
|
+
*count_out = line_context->lc_subprogs_count;
|
|
970
|
+
return DW_DLV_OK;
|
|
971
|
+
}
|
|
972
|
+
/* New October 2015. */
|
|
973
|
+
/* Index says which to return. Valid indexes are
|
|
974
|
+
1-lc_subprogs_count
|
|
975
|
+
*/
|
|
976
|
+
int
|
|
977
|
+
dwarf_srclines_subprog_data(Dwarf_Line_Context line_context,
|
|
978
|
+
Dwarf_Signed index,
|
|
979
|
+
const char ** name,
|
|
980
|
+
Dwarf_Unsigned *decl_file,
|
|
981
|
+
Dwarf_Unsigned *decl_line,
|
|
982
|
+
Dwarf_Error *error)
|
|
983
|
+
{
|
|
984
|
+
Dwarf_Subprog_Entry sub = 0;
|
|
985
|
+
if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
|
|
986
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
|
|
987
|
+
return (DW_DLV_ERROR);
|
|
988
|
+
}
|
|
989
|
+
if (index < 1 || index > line_context->lc_subprogs_count) {
|
|
990
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_INDEX_WRONG);
|
|
991
|
+
return (DW_DLV_ERROR);
|
|
992
|
+
}
|
|
993
|
+
sub = line_context->lc_subprogs + (index-1);
|
|
994
|
+
*name = (const char *)sub->ds_subprog_name;
|
|
995
|
+
*decl_file = sub->ds_decl_file;
|
|
996
|
+
*decl_line = sub->ds_decl_line;
|
|
997
|
+
return DW_DLV_OK;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
/* New October 2015. */
|
|
1001
|
+
int
|
|
1002
|
+
dwarf_srclines_files_count(Dwarf_Line_Context line_context,
|
|
1003
|
+
Dwarf_Signed *count_out,
|
|
1004
|
+
Dwarf_Error *error)
|
|
1005
|
+
{
|
|
1006
|
+
if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
|
|
1007
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
|
|
1008
|
+
return (DW_DLV_ERROR);
|
|
1009
|
+
}
|
|
1010
|
+
*count_out = line_context->lc_file_entry_count;
|
|
1011
|
+
return DW_DLV_OK;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
/* New October 2015. */
|
|
1015
|
+
int
|
|
1016
|
+
dwarf_srclines_files_data(Dwarf_Line_Context line_context,
|
|
1017
|
+
Dwarf_Signed index,
|
|
1018
|
+
const char ** name,
|
|
1019
|
+
Dwarf_Unsigned * directory_index,
|
|
1020
|
+
Dwarf_Unsigned * last_mod_time,
|
|
1021
|
+
Dwarf_Unsigned * file_length,
|
|
1022
|
+
Dwarf_Error * error)
|
|
1023
|
+
{
|
|
1024
|
+
Dwarf_File_Entry fi = 0;
|
|
1025
|
+
Dwarf_Signed i =0;
|
|
1026
|
+
if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
|
|
1027
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
|
|
1028
|
+
return (DW_DLV_ERROR);
|
|
1029
|
+
}
|
|
1030
|
+
if (index < 1 || index > line_context->lc_file_entry_count) {
|
|
1031
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_INDEX_WRONG);
|
|
1032
|
+
return (DW_DLV_ERROR);
|
|
1033
|
+
}
|
|
1034
|
+
fi = line_context->lc_file_entries;
|
|
1035
|
+
for ( i = 1; i < index; i++) {
|
|
1036
|
+
fi = fi->fi_next;
|
|
1037
|
+
}
|
|
1038
|
+
if(name) {
|
|
1039
|
+
*name = (const char *)fi->fi_file_name;
|
|
1040
|
+
}
|
|
1041
|
+
if (directory_index) {
|
|
1042
|
+
*directory_index = fi->fi_dir_index;
|
|
1043
|
+
}
|
|
1044
|
+
if (last_mod_time) {
|
|
1045
|
+
*last_mod_time = fi->fi_time_last_mod;
|
|
1046
|
+
}
|
|
1047
|
+
if (file_length) {
|
|
1048
|
+
*file_length = fi->fi_file_length;
|
|
1049
|
+
}
|
|
1050
|
+
return DW_DLV_OK;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
|
|
1054
|
+
/* New October 2015. */
|
|
1055
|
+
int
|
|
1056
|
+
dwarf_srclines_include_dir_count(Dwarf_Line_Context line_context,
|
|
1057
|
+
Dwarf_Signed * count,
|
|
1058
|
+
Dwarf_Error * error)
|
|
1059
|
+
{
|
|
1060
|
+
if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
|
|
1061
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
|
|
1062
|
+
return (DW_DLV_ERROR);
|
|
1063
|
+
}
|
|
1064
|
+
*count = line_context->lc_include_directories_count;
|
|
1065
|
+
return DW_DLV_OK;
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
/* New October 2015. */
|
|
1069
|
+
int
|
|
1070
|
+
dwarf_srclines_include_dir_data(Dwarf_Line_Context line_context,
|
|
1071
|
+
Dwarf_Signed index,
|
|
1072
|
+
const char ** name,
|
|
1073
|
+
Dwarf_Error * error)
|
|
1074
|
+
{
|
|
1075
|
+
if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
|
|
1076
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
|
|
1077
|
+
return (DW_DLV_ERROR);
|
|
1078
|
+
}
|
|
1079
|
+
if (index < 1 || index > line_context->lc_include_directories_count) {
|
|
1080
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_INDEX_WRONG);
|
|
1081
|
+
return (DW_DLV_ERROR);
|
|
1082
|
+
}
|
|
1083
|
+
*name = (const char *)(line_context->lc_include_directories[index-1]);
|
|
1084
|
+
return DW_DLV_OK;
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
/* New October 2015. */
|
|
1088
|
+
int
|
|
1089
|
+
dwarf_srclines_version(Dwarf_Line_Context line_context,
|
|
1090
|
+
Dwarf_Unsigned *version_out,
|
|
1091
|
+
Dwarf_Small *table_count_out,
|
|
1092
|
+
Dwarf_Error *error)
|
|
1093
|
+
{
|
|
1094
|
+
if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
|
|
1095
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_BOTCH);
|
|
1096
|
+
return (DW_DLV_ERROR);
|
|
1097
|
+
}
|
|
1098
|
+
*version_out = line_context->lc_version_number;
|
|
1099
|
+
*table_count_out = line_context->lc_table_count;
|
|
1100
|
+
return DW_DLV_OK;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
|
|
1105
|
+
/* Every line table entry (except DW_DLE_end_sequence,
|
|
1106
|
+
which is returned using dwarf_lineendsequence())
|
|
1107
|
+
potentially has the begin-statement
|
|
1108
|
+
flag marked 'on'. This returns thru *return_bool,
|
|
1109
|
+
the begin-statement flag. */
|
|
1110
|
+
|
|
1111
|
+
int
|
|
1112
|
+
dwarf_linebeginstatement(Dwarf_Line line,
|
|
1113
|
+
Dwarf_Bool * return_bool, Dwarf_Error * error)
|
|
1114
|
+
{
|
|
1115
|
+
if (line == NULL || return_bool == 0) {
|
|
1116
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
|
|
1117
|
+
return (DW_DLV_ERROR);
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
*return_bool = (line->li_addr_line.li_l_data.li_is_stmt);
|
|
1121
|
+
return DW_DLV_OK;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
/* At the end of any contiguous line-table there may be
|
|
1125
|
+
a DW_LNE_end_sequence operator.
|
|
1126
|
+
This returns non-zero thru *return_bool
|
|
1127
|
+
if and only if this 'line' entry was a DW_LNE_end_sequence.
|
|
1128
|
+
|
|
1129
|
+
Within a compilation unit or function there may be multiple
|
|
1130
|
+
line tables, each ending with a DW_LNE_end_sequence.
|
|
1131
|
+
Each table describes a contiguous region.
|
|
1132
|
+
Because compilers may split function code up in arbitrary ways
|
|
1133
|
+
compilers may need to emit multiple contigous regions (ie
|
|
1134
|
+
line tables) for a single function.
|
|
1135
|
+
See the DWARF3 spec section 6.2. */
|
|
1136
|
+
int
|
|
1137
|
+
dwarf_lineendsequence(Dwarf_Line line,
|
|
1138
|
+
Dwarf_Bool * return_bool, Dwarf_Error * error)
|
|
1139
|
+
{
|
|
1140
|
+
if (line == NULL) {
|
|
1141
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
|
|
1142
|
+
return (DW_DLV_ERROR);
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
*return_bool = (line->li_addr_line.li_l_data.li_end_sequence);
|
|
1146
|
+
return DW_DLV_OK;
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
|
|
1150
|
+
/* Each 'line' entry has a line-number.
|
|
1151
|
+
If the entry is a DW_LNE_end_sequence the line-number is
|
|
1152
|
+
meaningless (see dwarf_lineendsequence(), just above). */
|
|
1153
|
+
int
|
|
1154
|
+
dwarf_lineno(Dwarf_Line line,
|
|
1155
|
+
Dwarf_Unsigned * ret_lineno, Dwarf_Error * error)
|
|
1156
|
+
{
|
|
1157
|
+
if (line == NULL || ret_lineno == 0) {
|
|
1158
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
|
|
1159
|
+
return (DW_DLV_ERROR);
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
*ret_lineno = (line->li_addr_line.li_l_data.li_line);
|
|
1163
|
+
return DW_DLV_OK;
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
/* Each 'line' entry has a file-number, and index into the file table.
|
|
1167
|
+
If the entry is a DW_LNE_end_sequence the index is
|
|
1168
|
+
meaningless (see dwarf_lineendsequence(), just above).
|
|
1169
|
+
The file number returned is an index into the file table
|
|
1170
|
+
produced by dwarf_srcfiles(), but care is required: the
|
|
1171
|
+
li_file begins with 1 for real files, so that the li_file returned here
|
|
1172
|
+
is 1 greater than its index into the dwarf_srcfiles() output array.
|
|
1173
|
+
And entries from DW_LNE_define_file don't appear in
|
|
1174
|
+
the dwarf_srcfiles() output so file indexes from here may exceed
|
|
1175
|
+
the size of the dwarf_srcfiles() output array size.
|
|
1176
|
+
*/
|
|
1177
|
+
int
|
|
1178
|
+
dwarf_line_srcfileno(Dwarf_Line line,
|
|
1179
|
+
Dwarf_Unsigned * ret_fileno, Dwarf_Error * error)
|
|
1180
|
+
{
|
|
1181
|
+
if (line == NULL || ret_fileno == 0) {
|
|
1182
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
|
|
1183
|
+
return (DW_DLV_ERROR);
|
|
1184
|
+
}
|
|
1185
|
+
/* li_file must be <= line->li_context->lc_file_entry_count else it
|
|
1186
|
+
is trash. li_file 0 means not attributable to any source file
|
|
1187
|
+
per dwarf2/3 spec. */
|
|
1188
|
+
|
|
1189
|
+
*ret_fileno = (line->li_addr_line.li_l_data.li_file);
|
|
1190
|
+
return DW_DLV_OK;
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
/* Each 'line' entry has an is_addr_set attribute.
|
|
1194
|
+
If the entry is a DW_LNE_set_address, return TRUE through
|
|
1195
|
+
the *is_addr_set pointer. */
|
|
1196
|
+
int
|
|
1197
|
+
dwarf_line_is_addr_set(Dwarf_Line line,
|
|
1198
|
+
Dwarf_Bool *is_addr_set, Dwarf_Error * error)
|
|
1199
|
+
{
|
|
1200
|
+
if (line == NULL) {
|
|
1201
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
|
|
1202
|
+
return (DW_DLV_ERROR);
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
*is_addr_set = (line->li_addr_line.li_l_data.li_is_addr_set);
|
|
1206
|
+
return DW_DLV_OK;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
/* Each 'line' entry has a line-address.
|
|
1210
|
+
If the entry is a DW_LNE_end_sequence the adddress
|
|
1211
|
+
is one-beyond the last address this contigous region
|
|
1212
|
+
covers, so the address is not inside the region,
|
|
1213
|
+
but is just outside it. */
|
|
1214
|
+
int
|
|
1215
|
+
dwarf_lineaddr(Dwarf_Line line,
|
|
1216
|
+
Dwarf_Addr * ret_lineaddr, Dwarf_Error * error)
|
|
1217
|
+
{
|
|
1218
|
+
if (line == NULL || ret_lineaddr == 0) {
|
|
1219
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
|
|
1220
|
+
return (DW_DLV_ERROR);
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
*ret_lineaddr = (line->li_address);
|
|
1224
|
+
return DW_DLV_OK;
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
|
|
1228
|
+
/* Obsolete: do not use this function.
|
|
1229
|
+
December 2011: For reasons lost in the mists of history,
|
|
1230
|
+
this returned -1, not zero (through the pointer
|
|
1231
|
+
ret_lineoff), if the column was zero.
|
|
1232
|
+
That was always bogus, even in DWARF2.
|
|
1233
|
+
It is also bogus that the column value is signed, but
|
|
1234
|
+
it is painful to change the argument type in 2011, so leave it.
|
|
1235
|
+
*/
|
|
1236
|
+
int
|
|
1237
|
+
dwarf_lineoff(Dwarf_Line line,
|
|
1238
|
+
Dwarf_Signed * ret_lineoff, Dwarf_Error * error)
|
|
1239
|
+
{
|
|
1240
|
+
if (line == NULL || ret_lineoff == 0) {
|
|
1241
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
|
|
1242
|
+
return (DW_DLV_ERROR);
|
|
1243
|
+
}
|
|
1244
|
+
*ret_lineoff = (
|
|
1245
|
+
(line->li_addr_line.li_l_data.li_column == 0) ?
|
|
1246
|
+
-1 : line->li_addr_line.li_l_data.li_column);
|
|
1247
|
+
return DW_DLV_OK;
|
|
1248
|
+
}
|
|
1249
|
+
/* Each 'line' entry has a column-within-line (offset
|
|
1250
|
+
within the line) where the
|
|
1251
|
+
source text begins.
|
|
1252
|
+
If the entry is a DW_LNE_end_sequence the line-number is
|
|
1253
|
+
meaningless (see dwarf_lineendsequence(), just above).
|
|
1254
|
+
Lines of text begin at column 1. The value 0
|
|
1255
|
+
means the line begins at the left edge of the line.
|
|
1256
|
+
(See the DWARF3 spec, section 6.2.2).
|
|
1257
|
+
So 0 and 1 mean essentially the same thing.
|
|
1258
|
+
dwarf_lineoff_b() is new in December 2011.
|
|
1259
|
+
*/
|
|
1260
|
+
int
|
|
1261
|
+
dwarf_lineoff_b(Dwarf_Line line,
|
|
1262
|
+
Dwarf_Unsigned * ret_lineoff, Dwarf_Error * error)
|
|
1263
|
+
{
|
|
1264
|
+
if (line == NULL || ret_lineoff == 0) {
|
|
1265
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
|
|
1266
|
+
return (DW_DLV_ERROR);
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
*ret_lineoff = line->li_addr_line.li_l_data.li_column;
|
|
1270
|
+
return DW_DLV_OK;
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
|
|
1274
|
+
static int
|
|
1275
|
+
dwarf_filename(Dwarf_Line_Context context, Dwarf_Sword fileno,
|
|
1276
|
+
char **ret_filename, Dwarf_Error *error)
|
|
1277
|
+
{
|
|
1278
|
+
Dwarf_Signed i = 0;
|
|
1279
|
+
Dwarf_File_Entry file_entry = 0;
|
|
1280
|
+
Dwarf_Debug dbg = context->lc_dbg;
|
|
1281
|
+
int res = 0;
|
|
1282
|
+
|
|
1283
|
+
if (fileno > context->lc_file_entry_count) {
|
|
1284
|
+
_dwarf_error(dbg, error, DW_DLE_LINE_FILE_NUM_BAD);
|
|
1285
|
+
return (DW_DLV_ERROR);
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
if (fileno == 0) {
|
|
1289
|
+
/* No file name known: see dwarf2/3 spec. */
|
|
1290
|
+
_dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME);
|
|
1291
|
+
return (DW_DLV_ERROR);
|
|
1292
|
+
}
|
|
1293
|
+
file_entry = context->lc_file_entries;
|
|
1294
|
+
/* ASSERT: li_file > 0, dwarf correctness issue, see line table
|
|
1295
|
+
definition of dwarf2/3 spec. */
|
|
1296
|
+
|
|
1297
|
+
for (i = 1; i < fileno ; i++) {
|
|
1298
|
+
file_entry = file_entry->fi_next;
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
res = create_fullest_file_path(dbg,
|
|
1302
|
+
file_entry,context, ret_filename,error);
|
|
1303
|
+
return res;
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
int
|
|
1307
|
+
dwarf_linesrc(Dwarf_Line line, char **ret_linesrc, Dwarf_Error * error)
|
|
1308
|
+
{
|
|
1309
|
+
if (line == NULL) {
|
|
1310
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
|
|
1311
|
+
return (DW_DLV_ERROR);
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
if (line->li_context == NULL) {
|
|
1315
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL);
|
|
1316
|
+
return (DW_DLV_ERROR);
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
return dwarf_filename(line->li_context,
|
|
1320
|
+
line->li_addr_line.li_l_data.li_file, ret_linesrc, error);
|
|
1321
|
+
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
/* Every line table entry potentially has the basic-block-start
|
|
1325
|
+
flag marked 'on'. This returns thru *return_bool,
|
|
1326
|
+
the basic-block-start flag.
|
|
1327
|
+
*/
|
|
1328
|
+
int
|
|
1329
|
+
dwarf_lineblock(Dwarf_Line line,
|
|
1330
|
+
Dwarf_Bool * return_bool, Dwarf_Error * error)
|
|
1331
|
+
{
|
|
1332
|
+
if (line == NULL) {
|
|
1333
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
|
|
1334
|
+
return (DW_DLV_ERROR);
|
|
1335
|
+
}
|
|
1336
|
+
*return_bool = (line->li_addr_line.li_l_data.li_basic_block);
|
|
1337
|
+
return DW_DLV_OK;
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
/* We gather these into one call as it's likely one
|
|
1341
|
+
will want all or none of them. */
|
|
1342
|
+
int dwarf_prologue_end_etc(Dwarf_Line line,
|
|
1343
|
+
Dwarf_Bool * prologue_end,
|
|
1344
|
+
Dwarf_Bool * epilogue_begin,
|
|
1345
|
+
Dwarf_Unsigned * isa,
|
|
1346
|
+
Dwarf_Unsigned * discriminator,
|
|
1347
|
+
Dwarf_Error * error)
|
|
1348
|
+
{
|
|
1349
|
+
if (line == NULL) {
|
|
1350
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
|
|
1351
|
+
return (DW_DLV_ERROR);
|
|
1352
|
+
}
|
|
1353
|
+
*prologue_end = (line->li_addr_line.li_l_data.li_prologue_end);
|
|
1354
|
+
*epilogue_begin = (line->li_addr_line.li_l_data.li_epilogue_begin);
|
|
1355
|
+
*isa = (line->li_addr_line.li_l_data.li_isa);
|
|
1356
|
+
*discriminator = (line->li_addr_line.li_l_data.li_discriminator);
|
|
1357
|
+
return DW_DLV_OK;
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
int
|
|
1361
|
+
dwarf_linelogical(Dwarf_Line line,
|
|
1362
|
+
Dwarf_Unsigned * logical,
|
|
1363
|
+
Dwarf_Error* error)
|
|
1364
|
+
{
|
|
1365
|
+
if (line == NULL) {
|
|
1366
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
|
|
1367
|
+
return (DW_DLV_ERROR);
|
|
1368
|
+
}
|
|
1369
|
+
*logical = (line->li_addr_line.li_l_data.li_line);
|
|
1370
|
+
return DW_DLV_OK;
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
int
|
|
1374
|
+
dwarf_linecontext(Dwarf_Line line,
|
|
1375
|
+
Dwarf_Unsigned * context,
|
|
1376
|
+
Dwarf_Error* error)
|
|
1377
|
+
{
|
|
1378
|
+
if (line == NULL) {
|
|
1379
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
|
|
1380
|
+
return (DW_DLV_ERROR);
|
|
1381
|
+
}
|
|
1382
|
+
*context = (line->li_addr_line.li_l_data.li_call_context);
|
|
1383
|
+
return DW_DLV_OK;
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
int
|
|
1387
|
+
dwarf_line_subprogno(Dwarf_Line line,
|
|
1388
|
+
Dwarf_Unsigned * subprog,
|
|
1389
|
+
Dwarf_Error * error)
|
|
1390
|
+
{
|
|
1391
|
+
if (line == NULL) {
|
|
1392
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
|
|
1393
|
+
return (DW_DLV_ERROR);
|
|
1394
|
+
}
|
|
1395
|
+
*subprog = (line->li_addr_line.li_l_data.li_subprogram);
|
|
1396
|
+
return DW_DLV_OK;
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
int
|
|
1400
|
+
dwarf_line_subprog(Dwarf_Line line,
|
|
1401
|
+
char ** subprog_name,
|
|
1402
|
+
char ** decl_filename,
|
|
1403
|
+
Dwarf_Unsigned * decl_line,
|
|
1404
|
+
Dwarf_Error * error)
|
|
1405
|
+
{
|
|
1406
|
+
Dwarf_Unsigned subprog_no;
|
|
1407
|
+
Dwarf_Subprog_Entry subprog;
|
|
1408
|
+
Dwarf_Debug dbg;
|
|
1409
|
+
int res;
|
|
1410
|
+
|
|
1411
|
+
if (line == NULL) {
|
|
1412
|
+
_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
|
|
1413
|
+
return DW_DLV_ERROR;
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
if (line->li_context == NULL) {
|
|
1417
|
+
_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL);
|
|
1418
|
+
return DW_DLV_ERROR;
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
dbg = line->li_context->lc_dbg;
|
|
1422
|
+
|
|
1423
|
+
subprog_no = line->li_addr_line.li_l_data.li_subprogram;
|
|
1424
|
+
if (subprog_no == 0) {
|
|
1425
|
+
*subprog_name = NULL;
|
|
1426
|
+
*decl_filename = NULL;
|
|
1427
|
+
*decl_line = 0;
|
|
1428
|
+
return DW_DLV_OK;
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
if (subprog_no > line->li_context->lc_subprogs_count) {
|
|
1432
|
+
_dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME);
|
|
1433
|
+
return DW_DLV_ERROR;
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
subprog = &line->li_context->lc_subprogs[subprog_no - 1];
|
|
1437
|
+
|
|
1438
|
+
*subprog_name = (char *)subprog->ds_subprog_name;
|
|
1439
|
+
*decl_line = subprog->ds_decl_line;
|
|
1440
|
+
|
|
1441
|
+
res = dwarf_filename(line->li_context, subprog->ds_decl_file,
|
|
1442
|
+
decl_filename, error);
|
|
1443
|
+
if (res != DW_DLV_OK) {
|
|
1444
|
+
*decl_filename = NULL;
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
return DW_DLV_OK;
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
static void
|
|
1451
|
+
delete_line_context_itself(Dwarf_Line_Context context)
|
|
1452
|
+
{
|
|
1453
|
+
|
|
1454
|
+
|
|
1455
|
+
Dwarf_Debug dbg = 0;
|
|
1456
|
+
Dwarf_File_Entry fe = 0;
|
|
1457
|
+
|
|
1458
|
+
if(context->lc_magic != DW_CONTEXT_MAGIC) {
|
|
1459
|
+
/* Something is wrong. */
|
|
1460
|
+
return;
|
|
1461
|
+
}
|
|
1462
|
+
dbg = context->lc_dbg;
|
|
1463
|
+
fe = context->lc_file_entries;
|
|
1464
|
+
while (fe) {
|
|
1465
|
+
Dwarf_File_Entry fenext = fe->fi_next;
|
|
1466
|
+
fe->fi_next = 0;
|
|
1467
|
+
free(fe);
|
|
1468
|
+
fe = fenext;
|
|
1469
|
+
}
|
|
1470
|
+
context->lc_file_entries = 0;
|
|
1471
|
+
if (context->lc_subprogs) {
|
|
1472
|
+
free(context->lc_subprogs);
|
|
1473
|
+
context->lc_subprogs = 0;
|
|
1474
|
+
}
|
|
1475
|
+
if (context->lc_include_directories) {
|
|
1476
|
+
free(context->lc_include_directories);
|
|
1477
|
+
context->lc_include_directories = 0;
|
|
1478
|
+
}
|
|
1479
|
+
context->lc_magic = 0xdead;
|
|
1480
|
+
dwarf_dealloc(dbg, context, DW_DLA_LINE_CONTEXT);
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
/* It's impossible for callers of dwarf_srclines() to get to and
|
|
1484
|
+
free all the resources (in particular, the li_context and its
|
|
1485
|
+
lc_file_entries).
|
|
1486
|
+
So this function, new July 2005, does it.
|
|
1487
|
+
|
|
1488
|
+
As of September 2015 this will now delete either
|
|
1489
|
+
table of a two-level line table.
|
|
1490
|
+
In the two-level case one calls it once each on
|
|
1491
|
+
both the logicals and actuals tables.
|
|
1492
|
+
(in either order, the order is not critical).
|
|
1493
|
+
Once the logicals table is dealloced any
|
|
1494
|
+
use of the actuals table will surely result in chaos.
|
|
1495
|
+
Just do the two calls one after the other.
|
|
1496
|
+
|
|
1497
|
+
In the standard single-table case (DWARF 2,3,4)
|
|
1498
|
+
one calls it just once on the
|
|
1499
|
+
linebuf. Old style dealloc. Should never be used with
|
|
1500
|
+
dwarf_srclines_b(), but if it is there
|
|
1501
|
+
are no bad consequences..
|
|
1502
|
+
|
|
1503
|
+
Those using standard DWARF should use
|
|
1504
|
+
dwarf_srclines_b() and dwarf_srclines_dealloc_b()
|
|
1505
|
+
instead of dwarf_srclines and dwarf_srclines_dealloc()
|
|
1506
|
+
as that gives access to various bits of useful information.
|
|
1507
|
+
*/
|
|
1508
|
+
|
|
1509
|
+
void
|
|
1510
|
+
dwarf_srclines_dealloc(Dwarf_Debug dbg, Dwarf_Line * linebuf,
|
|
1511
|
+
Dwarf_Signed count)
|
|
1512
|
+
{
|
|
1513
|
+
Dwarf_Signed i = 0;
|
|
1514
|
+
/* alternate_data_count is a failsafe to prevent
|
|
1515
|
+
duplicate frees when there is inappropriate mixing
|
|
1516
|
+
of new interface and this old routine */
|
|
1517
|
+
Dwarf_Bool alternate_data_count = 0;
|
|
1518
|
+
|
|
1519
|
+
struct Dwarf_Line_Context_s *line_context = 0;
|
|
1520
|
+
|
|
1521
|
+
|
|
1522
|
+
if(!linebuf) {
|
|
1523
|
+
return;
|
|
1524
|
+
}
|
|
1525
|
+
if (count > 0) {
|
|
1526
|
+
/* All these entries share a single line_context, and
|
|
1527
|
+
for two-levels tables each table gets it too.
|
|
1528
|
+
Hence we will dealloc ONLY if !is_actuals_table
|
|
1529
|
+
so for single and two-level tables the space
|
|
1530
|
+
is deallocated. */
|
|
1531
|
+
line_context = linebuf[0]->li_context;
|
|
1532
|
+
if (line_context && line_context->lc_magic != DW_CONTEXT_MAGIC ) {
|
|
1533
|
+
/* Something is very wrong. */
|
|
1534
|
+
line_context = 0;
|
|
1535
|
+
} else if (line_context) {
|
|
1536
|
+
if (linebuf == line_context->lc_linebuf_logicals) {
|
|
1537
|
+
line_context->lc_linebuf_logicals = 0;
|
|
1538
|
+
line_context->lc_linecount_logicals = 0;
|
|
1539
|
+
alternate_data_count = line_context->lc_linecount_actuals;
|
|
1540
|
+
/* Ok to delete logicals */
|
|
1541
|
+
} else if (linebuf == line_context->lc_linebuf_actuals) {
|
|
1542
|
+
/* Ok to delete actuals */
|
|
1543
|
+
line_context->lc_linebuf_actuals = 0;
|
|
1544
|
+
line_context->lc_linecount_actuals = 0;
|
|
1545
|
+
alternate_data_count = line_context->lc_linecount_logicals;
|
|
1546
|
+
} else {
|
|
1547
|
+
/* Something is wrong very wrong. */
|
|
1548
|
+
return;
|
|
1549
|
+
}
|
|
1550
|
+
} else {
|
|
1551
|
+
/* Else: impossible. Unless the caller
|
|
1552
|
+
passed in a bogus linebuf. */
|
|
1553
|
+
line_context = 0;
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
/* Here we actually delete a set of lines. */
|
|
1558
|
+
for (i = 0; i < count; ++i) {
|
|
1559
|
+
dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE);
|
|
1560
|
+
}
|
|
1561
|
+
dwarf_dealloc(dbg, linebuf, DW_DLA_LIST);
|
|
1562
|
+
|
|
1563
|
+
if (line_context && !line_context->lc_new_style_access
|
|
1564
|
+
&& !alternate_data_count ) {
|
|
1565
|
+
/* There is nothing left
|
|
1566
|
+
referencing this line_context. */
|
|
1567
|
+
dwarf_dealloc(dbg, line_context, DW_DLA_LINE_CONTEXT);
|
|
1568
|
+
}
|
|
1569
|
+
return;
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
/* New October 2015.
|
|
1573
|
+
This should be used to deallocate all
|
|
1574
|
+
lines data that is
|
|
1575
|
+
set up by dwarf_srclines_b().
|
|
1576
|
+
This and dwarf_srclines_b() are now (October 2015)
|
|
1577
|
+
the preferred routine to use. */
|
|
1578
|
+
void
|
|
1579
|
+
dwarf_srclines_dealloc_b(Dwarf_Line_Context line_context)
|
|
1580
|
+
{
|
|
1581
|
+
Dwarf_Line *linestable = 0;
|
|
1582
|
+
Dwarf_Signed linescount = 0;
|
|
1583
|
+
Dwarf_Signed i = 0;
|
|
1584
|
+
Dwarf_Debug dbg = 0;
|
|
1585
|
+
|
|
1586
|
+
if(!line_context) {
|
|
1587
|
+
return;
|
|
1588
|
+
}
|
|
1589
|
+
if(line_context->lc_magic != DW_CONTEXT_MAGIC) {
|
|
1590
|
+
/* Something is wrong. */
|
|
1591
|
+
return; }
|
|
1592
|
+
dbg = line_context->lc_dbg;
|
|
1593
|
+
if (!line_context || line_context->lc_magic != DW_CONTEXT_MAGIC) {
|
|
1594
|
+
/* Something is badly wrong here.*/
|
|
1595
|
+
return;
|
|
1596
|
+
}
|
|
1597
|
+
linestable = line_context->lc_linebuf_logicals;
|
|
1598
|
+
linescount = line_context->lc_linecount_logicals;
|
|
1599
|
+
for (i = 0; i < linescount ; ++i) {
|
|
1600
|
+
dwarf_dealloc(dbg, linestable[i], DW_DLA_LINE);
|
|
1601
|
+
}
|
|
1602
|
+
dwarf_dealloc(dbg, linestable, DW_DLA_LIST);
|
|
1603
|
+
line_context->lc_linebuf_logicals = 0;
|
|
1604
|
+
line_context->lc_linecount_logicals = 0;
|
|
1605
|
+
|
|
1606
|
+
linestable = line_context->lc_linebuf_actuals;
|
|
1607
|
+
linescount = line_context->lc_linecount_actuals;
|
|
1608
|
+
for (i = 0; i <linescount ; ++i) {
|
|
1609
|
+
dwarf_dealloc(dbg, linestable[i], DW_DLA_LINE);
|
|
1610
|
+
}
|
|
1611
|
+
dwarf_dealloc(dbg, linestable, DW_DLA_LIST);
|
|
1612
|
+
line_context->lc_linebuf_actuals = 0;
|
|
1613
|
+
line_context->lc_linecount_actuals = 0;
|
|
1614
|
+
delete_line_context_itself(line_context);
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
/* There is an error, so count it. If we are printing
|
|
1618
|
+
errors by command line option, print the details. */
|
|
1619
|
+
void
|
|
1620
|
+
_dwarf_print_header_issue(Dwarf_Debug dbg,
|
|
1621
|
+
const char *specific_msg,
|
|
1622
|
+
Dwarf_Small *data_start,
|
|
1623
|
+
int *err_count_out)
|
|
1624
|
+
{
|
|
1625
|
+
if (!err_count_out) {
|
|
1626
|
+
return;
|
|
1627
|
+
}
|
|
1628
|
+
/* Are we in verbose mode */
|
|
1629
|
+
if (dwarf_cmdline_options.check_verbose_mode){
|
|
1630
|
+
dwarf_printf(dbg,
|
|
1631
|
+
"\n*** DWARF CHECK: "
|
|
1632
|
+
".debug_line: %s", specific_msg);
|
|
1633
|
+
|
|
1634
|
+
if (data_start >= dbg->de_debug_line.dss_data &&
|
|
1635
|
+
(data_start < (dbg->de_debug_line.dss_data +
|
|
1636
|
+
dbg->de_debug_line.dss_size))) {
|
|
1637
|
+
Dwarf_Unsigned off = data_start - dbg->de_debug_line.dss_data;
|
|
1638
|
+
dwarf_printf(dbg,
|
|
1639
|
+
" at offset 0x%" DW_PR_XZEROS DW_PR_DUx
|
|
1640
|
+
" ( %" DW_PR_DUu " ) ",
|
|
1641
|
+
off,off);
|
|
1642
|
+
} else {
|
|
1643
|
+
dwarf_printf(dbg,
|
|
1644
|
+
" (unknown section location) ");
|
|
1645
|
+
}
|
|
1646
|
+
dwarf_printf(dbg,"***\n");
|
|
1647
|
+
}
|
|
1648
|
+
*err_count_out += 1;
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
|
|
1652
|
+
int
|
|
1653
|
+
_dwarf_decode_line_string_form(Dwarf_Debug dbg,
|
|
1654
|
+
Dwarf_Unsigned form,
|
|
1655
|
+
Dwarf_Unsigned offset_size,
|
|
1656
|
+
Dwarf_Small **line_ptr,
|
|
1657
|
+
Dwarf_Small *line_ptr_end,
|
|
1658
|
+
char **return_str,
|
|
1659
|
+
Dwarf_Error * error)
|
|
1660
|
+
{
|
|
1661
|
+
int res = 0;
|
|
1662
|
+
|
|
1663
|
+
switch (form) {
|
|
1664
|
+
case DW_FORM_line_strp: {
|
|
1665
|
+
Dwarf_Small *secstart = 0;
|
|
1666
|
+
Dwarf_Small *secend = 0;
|
|
1667
|
+
Dwarf_Small *strptr = 0;
|
|
1668
|
+
Dwarf_Unsigned offset = 0;
|
|
1669
|
+
Dwarf_Small *offsetptr = *line_ptr;
|
|
1670
|
+
|
|
1671
|
+
res = _dwarf_load_section(dbg, &dbg->de_debug_line_str,error);
|
|
1672
|
+
if (res != DW_DLV_OK) {
|
|
1673
|
+
return res;
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
secstart = dbg->de_debug_line_str.dss_data;
|
|
1677
|
+
secend = secstart + dbg->de_debug_line_str.dss_size;
|
|
1678
|
+
|
|
1679
|
+
READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,offsetptr, offset_size);
|
|
1680
|
+
*line_ptr += offset_size;
|
|
1681
|
+
strptr = secstart + offset;
|
|
1682
|
+
res = _dwarf_check_string_valid(dbg,
|
|
1683
|
+
secstart,strptr,secend,error);
|
|
1684
|
+
if (res != DW_DLV_OK) {
|
|
1685
|
+
return res;
|
|
1686
|
+
}
|
|
1687
|
+
*return_str = (char *) strptr;
|
|
1688
|
+
return DW_DLV_OK;
|
|
1689
|
+
}
|
|
1690
|
+
case DW_FORM_string: {
|
|
1691
|
+
Dwarf_Small *secend = line_ptr_end;;
|
|
1692
|
+
Dwarf_Small *strptr = *line_ptr;
|
|
1693
|
+
res = _dwarf_check_string_valid(dbg,
|
|
1694
|
+
strptr ,strptr,secend,error);
|
|
1695
|
+
if (res != DW_DLV_OK) {
|
|
1696
|
+
return res;
|
|
1697
|
+
}
|
|
1698
|
+
*return_str = (char *)strptr;
|
|
1699
|
+
*line_ptr += strlen((const char *)strptr) + 1;
|
|
1700
|
+
return DW_DLV_OK;
|
|
1701
|
+
}
|
|
1702
|
+
default:
|
|
1703
|
+
_dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
|
|
1704
|
+
return DW_DLV_ERROR;
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
|
|
1708
|
+
int
|
|
1709
|
+
_dwarf_decode_line_udata_form(Dwarf_Debug dbg,
|
|
1710
|
+
Dwarf_Unsigned form,
|
|
1711
|
+
Dwarf_Small **line_ptr,
|
|
1712
|
+
Dwarf_Unsigned *return_val,
|
|
1713
|
+
Dwarf_Error * error)
|
|
1714
|
+
{
|
|
1715
|
+
Dwarf_Unsigned val = 0;
|
|
1716
|
+
Dwarf_Small * lp = *line_ptr;
|
|
1717
|
+
|
|
1718
|
+
switch (form) {
|
|
1719
|
+
|
|
1720
|
+
case DW_FORM_udata:
|
|
1721
|
+
DECODE_LEB128_UWORD(lp, val);
|
|
1722
|
+
*return_val = val;
|
|
1723
|
+
*line_ptr = lp;
|
|
1724
|
+
return DW_DLV_OK;
|
|
1725
|
+
|
|
1726
|
+
default:
|
|
1727
|
+
_dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
|
|
1728
|
+
return DW_DLV_ERROR;
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1732
|
+
|
|
1733
|
+
void
|
|
1734
|
+
_dwarf_update_chain_list( Dwarf_Chain chain_line,
|
|
1735
|
+
Dwarf_Chain *head_chain, Dwarf_Chain *curr_chain)
|
|
1736
|
+
{
|
|
1737
|
+
if (*head_chain == NULL) {
|
|
1738
|
+
*head_chain = chain_line;
|
|
1739
|
+
} else {
|
|
1740
|
+
(*curr_chain)->ch_next = chain_line;
|
|
1741
|
+
}
|
|
1742
|
+
*curr_chain = chain_line;
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1745
|
+
void
|
|
1746
|
+
_dwarf_free_chain_entries(Dwarf_Debug dbg,Dwarf_Chain head,int count)
|
|
1747
|
+
{
|
|
1748
|
+
int i = 0;
|
|
1749
|
+
Dwarf_Chain curr_chain = head;
|
|
1750
|
+
for (i = 0; i < count; i++) {
|
|
1751
|
+
Dwarf_Chain t = curr_chain;
|
|
1752
|
+
curr_chain = curr_chain->ch_next;
|
|
1753
|
+
dwarf_dealloc(dbg, t, DW_DLA_CHAIN);
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
|
|
1757
|
+
int
|
|
1758
|
+
_dwarf_add_to_files_list(Dwarf_Line_Context context, Dwarf_File_Entry fe)
|
|
1759
|
+
{
|
|
1760
|
+
if (!context->lc_file_entries) {
|
|
1761
|
+
context->lc_file_entries = fe;
|
|
1762
|
+
} else {
|
|
1763
|
+
context->lc_last_entry->fi_next = fe;
|
|
1764
|
+
}
|
|
1765
|
+
context->lc_last_entry = fe;
|
|
1766
|
+
context->lc_file_entry_count++;
|
|
1767
|
+
return DW_DLV_OK;
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
|
|
1771
|
+
int
|
|
1772
|
+
_dwarf_line_context_constructor(Dwarf_Debug dbg, void *m)
|
|
1773
|
+
{
|
|
1774
|
+
Dwarf_Line_Context line_context = (Dwarf_Line_Context)m;
|
|
1775
|
+
/* dwarf_get_alloc ensures the bytes are all zero
|
|
1776
|
+
when m is passed to us. */
|
|
1777
|
+
line_context->lc_magic = DW_CONTEXT_MAGIC;
|
|
1778
|
+
line_context->lc_dbg = dbg;
|
|
1779
|
+
return DW_DLV_OK;
|
|
1780
|
+
}
|
|
1781
|
+
|
|
1782
|
+
/* This cleans up a contex record.
|
|
1783
|
+
The lines tables (actuals and logicals)
|
|
1784
|
+
are themselves items that will
|
|
1785
|
+
be dealloc'd either manually
|
|
1786
|
+
or, at closing the libdwarf dbg,
|
|
1787
|
+
automatically. So we DO NOT
|
|
1788
|
+
touch the lines tables here */
|
|
1789
|
+
void
|
|
1790
|
+
_dwarf_line_context_destructor(void *m)
|
|
1791
|
+
{
|
|
1792
|
+
Dwarf_Line_Context line_context = (Dwarf_Line_Context)m;
|
|
1793
|
+
if (line_context->lc_magic != DW_CONTEXT_MAGIC) {
|
|
1794
|
+
/* Nothing is safe, do nothing. */
|
|
1795
|
+
return;
|
|
1796
|
+
}
|
|
1797
|
+
if (line_context->lc_include_directories) {
|
|
1798
|
+
free(line_context->lc_include_directories);
|
|
1799
|
+
line_context->lc_include_directories = 0;
|
|
1800
|
+
line_context->lc_include_directories_count = 0;
|
|
1801
|
+
}
|
|
1802
|
+
if (line_context->lc_file_entries) {
|
|
1803
|
+
Dwarf_File_Entry fe = line_context->lc_file_entries;
|
|
1804
|
+
while(fe) {
|
|
1805
|
+
Dwarf_File_Entry t = fe;
|
|
1806
|
+
fe = t->fi_next;
|
|
1807
|
+
t->fi_next = 0;
|
|
1808
|
+
free(t);
|
|
1809
|
+
}
|
|
1810
|
+
line_context->lc_file_entries = 0;
|
|
1811
|
+
line_context->lc_last_entry = 0;
|
|
1812
|
+
line_context->lc_file_entry_count = 0;
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
if (line_context->lc_subprogs) {
|
|
1816
|
+
free(line_context->lc_subprogs);
|
|
1817
|
+
line_context->lc_subprogs = 0;
|
|
1818
|
+
line_context->lc_subprogs_count = 0;
|
|
1819
|
+
}
|
|
1820
|
+
line_context->lc_magic = 0;
|
|
1821
|
+
return;
|
|
1822
|
+
}
|