rdwarf 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (163) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +4 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +28 -0
  6. data/README.md +39 -0
  7. data/Rakefile +8 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +7 -0
  10. data/ext/rdwarf/depend +5 -0
  11. data/ext/rdwarf/extconf.rb +29 -0
  12. data/ext/rdwarf/libdwarf/CHANGES +102 -0
  13. data/ext/rdwarf/libdwarf/CODINGSTYLE +71 -0
  14. data/ext/rdwarf/libdwarf/COPYING +28 -0
  15. data/ext/rdwarf/libdwarf/ChangeLog +619 -0
  16. data/ext/rdwarf/libdwarf/ChangeLog2006 +835 -0
  17. data/ext/rdwarf/libdwarf/ChangeLog2007 +217 -0
  18. data/ext/rdwarf/libdwarf/ChangeLog2008 +263 -0
  19. data/ext/rdwarf/libdwarf/ChangeLog2009 +348 -0
  20. data/ext/rdwarf/libdwarf/ChangeLog2010 +175 -0
  21. data/ext/rdwarf/libdwarf/ChangeLog2011 +297 -0
  22. data/ext/rdwarf/libdwarf/ChangeLog2012 +131 -0
  23. data/ext/rdwarf/libdwarf/ChangeLog2013 +238 -0
  24. data/ext/rdwarf/libdwarf/ChangeLog2014 +399 -0
  25. data/ext/rdwarf/libdwarf/LGPL.txt +504 -0
  26. data/ext/rdwarf/libdwarf/LIBDWARFCOPYRIGHT +40 -0
  27. data/ext/rdwarf/libdwarf/Makefile.in +220 -0
  28. data/ext/rdwarf/libdwarf/NEWS +535 -0
  29. data/ext/rdwarf/libdwarf/README +235 -0
  30. data/ext/rdwarf/libdwarf/checkexamples.c +1179 -0
  31. data/ext/rdwarf/libdwarf/cmplrs/dwarf_addr_finder.h +55 -0
  32. data/ext/rdwarf/libdwarf/common.c +62 -0
  33. data/ext/rdwarf/libdwarf/common.h +38 -0
  34. data/ext/rdwarf/libdwarf/config.h.in +146 -0
  35. data/ext/rdwarf/libdwarf/configure +5581 -0
  36. data/ext/rdwarf/libdwarf/configure.in +167 -0
  37. data/ext/rdwarf/libdwarf/dw-linetableheader.txt +39 -0
  38. data/ext/rdwarf/libdwarf/dwarf.h +1342 -0
  39. data/ext/rdwarf/libdwarf/dwarf_abbrev.c +291 -0
  40. data/ext/rdwarf/libdwarf/dwarf_abbrev.h +45 -0
  41. data/ext/rdwarf/libdwarf/dwarf_addr_finder.c +676 -0
  42. data/ext/rdwarf/libdwarf/dwarf_alloc.c +685 -0
  43. data/ext/rdwarf/libdwarf/dwarf_alloc.h +38 -0
  44. data/ext/rdwarf/libdwarf/dwarf_arange.c +595 -0
  45. data/ext/rdwarf/libdwarf/dwarf_arange.h +62 -0
  46. data/ext/rdwarf/libdwarf/dwarf_base_types.h +157 -0
  47. data/ext/rdwarf/libdwarf/dwarf_die_deliv.c +1802 -0
  48. data/ext/rdwarf/libdwarf/dwarf_die_deliv.h +46 -0
  49. data/ext/rdwarf/libdwarf/dwarf_elf_access.c +1348 -0
  50. data/ext/rdwarf/libdwarf/dwarf_elf_access.h +46 -0
  51. data/ext/rdwarf/libdwarf/dwarf_error.c +492 -0
  52. data/ext/rdwarf/libdwarf/dwarf_error.h +53 -0
  53. data/ext/rdwarf/libdwarf/dwarf_form.c +1302 -0
  54. data/ext/rdwarf/libdwarf/dwarf_frame.c +2454 -0
  55. data/ext/rdwarf/libdwarf/dwarf_frame.h +418 -0
  56. data/ext/rdwarf/libdwarf/dwarf_frame2.c +1533 -0
  57. data/ext/rdwarf/libdwarf/dwarf_frame3.c +282 -0
  58. data/ext/rdwarf/libdwarf/dwarf_funcs.c +123 -0
  59. data/ext/rdwarf/libdwarf/dwarf_funcs.h +33 -0
  60. data/ext/rdwarf/libdwarf/dwarf_gdbindex.c +520 -0
  61. data/ext/rdwarf/libdwarf/dwarf_gdbindex.h +97 -0
  62. data/ext/rdwarf/libdwarf/dwarf_global.c +612 -0
  63. data/ext/rdwarf/libdwarf/dwarf_global.h +117 -0
  64. data/ext/rdwarf/libdwarf/dwarf_harmless.c +228 -0
  65. data/ext/rdwarf/libdwarf/dwarf_harmless.h +31 -0
  66. data/ext/rdwarf/libdwarf/dwarf_incl.h +61 -0
  67. data/ext/rdwarf/libdwarf/dwarf_init_finish.c +1263 -0
  68. data/ext/rdwarf/libdwarf/dwarf_leb.c +159 -0
  69. data/ext/rdwarf/libdwarf/dwarf_line.c +1822 -0
  70. data/ext/rdwarf/libdwarf/dwarf_line.h +446 -0
  71. data/ext/rdwarf/libdwarf/dwarf_line2.c +98 -0
  72. data/ext/rdwarf/libdwarf/dwarf_line_table_reader_common.c +1583 -0
  73. data/ext/rdwarf/libdwarf/dwarf_loc.c +1525 -0
  74. data/ext/rdwarf/libdwarf/dwarf_loc.h +149 -0
  75. data/ext/rdwarf/libdwarf/dwarf_loc2.c +833 -0
  76. data/ext/rdwarf/libdwarf/dwarf_macro.c +479 -0
  77. data/ext/rdwarf/libdwarf/dwarf_macro.h +35 -0
  78. data/ext/rdwarf/libdwarf/dwarf_opaque.h +778 -0
  79. data/ext/rdwarf/libdwarf/dwarf_original_elf_init.c +219 -0
  80. data/ext/rdwarf/libdwarf/dwarf_print_lines.c +631 -0
  81. data/ext/rdwarf/libdwarf/dwarf_pubtypes.c +132 -0
  82. data/ext/rdwarf/libdwarf/dwarf_query.c +1594 -0
  83. data/ext/rdwarf/libdwarf/dwarf_ranges.c +194 -0
  84. data/ext/rdwarf/libdwarf/dwarf_reloc_arm.h +308 -0
  85. data/ext/rdwarf/libdwarf/dwarf_reloc_mips.h +117 -0
  86. data/ext/rdwarf/libdwarf/dwarf_reloc_ppc.h +242 -0
  87. data/ext/rdwarf/libdwarf/dwarf_reloc_ppc64.h +272 -0
  88. data/ext/rdwarf/libdwarf/dwarf_reloc_x86_64.h +127 -0
  89. data/ext/rdwarf/libdwarf/dwarf_sort_line.c +665 -0
  90. data/ext/rdwarf/libdwarf/dwarf_string.c +82 -0
  91. data/ext/rdwarf/libdwarf/dwarf_stubs.c +38 -0
  92. data/ext/rdwarf/libdwarf/dwarf_tied.c +423 -0
  93. data/ext/rdwarf/libdwarf/dwarf_tsearch.h +125 -0
  94. data/ext/rdwarf/libdwarf/dwarf_tsearchhash.c +675 -0
  95. data/ext/rdwarf/libdwarf/dwarf_types.c +121 -0
  96. data/ext/rdwarf/libdwarf/dwarf_types.h +32 -0
  97. data/ext/rdwarf/libdwarf/dwarf_util.c +913 -0
  98. data/ext/rdwarf/libdwarf/dwarf_util.h +324 -0
  99. data/ext/rdwarf/libdwarf/dwarf_vars.c +125 -0
  100. data/ext/rdwarf/libdwarf/dwarf_vars.h +29 -0
  101. data/ext/rdwarf/libdwarf/dwarf_weaks.c +123 -0
  102. data/ext/rdwarf/libdwarf/dwarf_weaks.h +29 -0
  103. data/ext/rdwarf/libdwarf/dwarf_xu_index.c +579 -0
  104. data/ext/rdwarf/libdwarf/dwarf_xu_index.h +68 -0
  105. data/ext/rdwarf/libdwarf/dwgetopt.c +181 -0
  106. data/ext/rdwarf/libdwarf/dwgetopt.h +51 -0
  107. data/ext/rdwarf/libdwarf/gennames.c +531 -0
  108. data/ext/rdwarf/libdwarf/install.sh +119 -0
  109. data/ext/rdwarf/libdwarf/libdwarf.h.in +3746 -0
  110. data/ext/rdwarf/libdwarf/libdwarf2.1.mm +9805 -0
  111. data/ext/rdwarf/libdwarf/libdwarf2.1.pdf +0 -0
  112. data/ext/rdwarf/libdwarf/libdwarf2p.1.mm +2807 -0
  113. data/ext/rdwarf/libdwarf/libdwarf2p.1.pdf +0 -0
  114. data/ext/rdwarf/libdwarf/libdwarfdefs.h +81 -0
  115. data/ext/rdwarf/libdwarf/malloc_check.c +327 -0
  116. data/ext/rdwarf/libdwarf/malloc_check.h +52 -0
  117. data/ext/rdwarf/libdwarf/mips_extensions.mm +1266 -0
  118. data/ext/rdwarf/libdwarf/mips_extensions.pdf +0 -0
  119. data/ext/rdwarf/libdwarf/pro_alloc.c +179 -0
  120. data/ext/rdwarf/libdwarf/pro_alloc.h +33 -0
  121. data/ext/rdwarf/libdwarf/pro_arange.c +310 -0
  122. data/ext/rdwarf/libdwarf/pro_arange.h +51 -0
  123. data/ext/rdwarf/libdwarf/pro_die.c +431 -0
  124. data/ext/rdwarf/libdwarf/pro_die.h +59 -0
  125. data/ext/rdwarf/libdwarf/pro_encode_nm.c +108 -0
  126. data/ext/rdwarf/libdwarf/pro_encode_nm.h +39 -0
  127. data/ext/rdwarf/libdwarf/pro_error.c +96 -0
  128. data/ext/rdwarf/libdwarf/pro_error.h +43 -0
  129. data/ext/rdwarf/libdwarf/pro_expr.c +575 -0
  130. data/ext/rdwarf/libdwarf/pro_expr.h +36 -0
  131. data/ext/rdwarf/libdwarf/pro_finish.c +45 -0
  132. data/ext/rdwarf/libdwarf/pro_forms.c +1271 -0
  133. data/ext/rdwarf/libdwarf/pro_frame.c +572 -0
  134. data/ext/rdwarf/libdwarf/pro_frame.h +120 -0
  135. data/ext/rdwarf/libdwarf/pro_funcs.c +50 -0
  136. data/ext/rdwarf/libdwarf/pro_incl.h +91 -0
  137. data/ext/rdwarf/libdwarf/pro_init.c +327 -0
  138. data/ext/rdwarf/libdwarf/pro_line.c +373 -0
  139. data/ext/rdwarf/libdwarf/pro_line.h +112 -0
  140. data/ext/rdwarf/libdwarf/pro_macinfo.c +457 -0
  141. data/ext/rdwarf/libdwarf/pro_macinfo.h +31 -0
  142. data/ext/rdwarf/libdwarf/pro_opaque.h +513 -0
  143. data/ext/rdwarf/libdwarf/pro_pubnames.c +60 -0
  144. data/ext/rdwarf/libdwarf/pro_reloc.c +253 -0
  145. data/ext/rdwarf/libdwarf/pro_reloc.h +38 -0
  146. data/ext/rdwarf/libdwarf/pro_reloc_stream.c +256 -0
  147. data/ext/rdwarf/libdwarf/pro_reloc_stream.h +52 -0
  148. data/ext/rdwarf/libdwarf/pro_reloc_symbolic.c +245 -0
  149. data/ext/rdwarf/libdwarf/pro_reloc_symbolic.h +45 -0
  150. data/ext/rdwarf/libdwarf/pro_section.c +2233 -0
  151. data/ext/rdwarf/libdwarf/pro_section.h +100 -0
  152. data/ext/rdwarf/libdwarf/pro_types.c +274 -0
  153. data/ext/rdwarf/libdwarf/pro_types.h +34 -0
  154. data/ext/rdwarf/libdwarf/pro_util.h +38 -0
  155. data/ext/rdwarf/libdwarf/pro_vars.c +52 -0
  156. data/ext/rdwarf/libdwarf/pro_weaks.c +51 -0
  157. data/ext/rdwarf/rdwarf.c +765 -0
  158. data/ext/rdwarf/rdwarf.h +52 -0
  159. data/ext/rdwarf/rdwarf_names_gen.rb +109 -0
  160. data/lib/rdwarf.rb +181 -0
  161. data/lib/rdwarf/version.rb +3 -0
  162. data/rdwarf.gemspec +30 -0
  163. 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
+ }