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,52 @@
1
+ /*
2
+
3
+ Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
4
+
5
+ This program is free software; you can redistribute it and/or modify it
6
+ under the terms of version 2.1 of the GNU Lesser General Public License
7
+ as published by the Free Software Foundation.
8
+
9
+ This program is distributed in the hope that it would be useful, but
10
+ WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
+
13
+ Further, this software is distributed without any warranty that it is
14
+ free of the rightful claim of any third person regarding infringement
15
+ or the like. Any license provided herein, whether implied or
16
+ otherwise, applies only to this software file. Patent licenses, if
17
+ any, provided herein do not apply to combinations of this program with
18
+ other software, or any other product whatsoever.
19
+
20
+ You should have received a copy of the GNU Lesser General Public
21
+ License along with this program; if not, write the Free Software
22
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
23
+ USA.
24
+
25
+ */
26
+
27
+
28
+
29
+
30
+ int _dwarf_pro_reloc_name_stream64(Dwarf_P_Debug dbg,
31
+ int base_sec_index,
32
+ Dwarf_Unsigned offset,/* r_offset of reloc */
33
+ Dwarf_Unsigned symidx,
34
+ enum Dwarf_Rel_Type,
35
+ int reltarget_length);
36
+ int _dwarf_pro_reloc_name_stream32(Dwarf_P_Debug dbg,
37
+ int base_sec_index,
38
+ Dwarf_Unsigned offset,/* r_offset of reloc */
39
+ Dwarf_Unsigned symidx,
40
+ enum Dwarf_Rel_Type,
41
+ int reltarget_length);
42
+
43
+ int _dwarf_pro_reloc_length_stream(Dwarf_P_Debug dbg,
44
+ int base_sec_index,
45
+ Dwarf_Unsigned offset, /* r_offset of reloc */
46
+ Dwarf_Unsigned start_symidx,
47
+ Dwarf_Unsigned end_symidx,
48
+ enum Dwarf_Rel_Type,
49
+ int reltarget_length);
50
+
51
+ int _dwarf_stream_relocs_to_disk(Dwarf_P_Debug dbg,
52
+ Dwarf_Signed * new_sec_count);
@@ -0,0 +1,245 @@
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 "libdwarfdefs.h"
30
+ #include <stdio.h>
31
+ #include <string.h>
32
+ /*#include <elfaccess.h> */
33
+ #include "pro_incl.h"
34
+ #include "pro_section.h"
35
+ #include "pro_reloc.h"
36
+ #include "pro_reloc_symbolic.h"
37
+
38
+ /* Return DW_DLV_ERROR on malloc error.
39
+ Return DW_DLV_OK otherwise */
40
+
41
+ int
42
+ _dwarf_pro_reloc_name_symbolic(Dwarf_P_Debug dbg,
43
+ int base_sec_index,
44
+ Dwarf_Unsigned offset, /* r_offset of reloc */
45
+ Dwarf_Unsigned symidx,
46
+ enum Dwarf_Rel_Type type,
47
+ int reltarget_length)
48
+ {
49
+ /* get a slot, fill in the slot entry */
50
+ void *relrec_to_fill = 0;
51
+ int res = 0;
52
+ struct Dwarf_Relocation_Data_s *slotp;
53
+
54
+ res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
55
+ &relrec_to_fill);
56
+ if (res != DW_DLV_OK)
57
+ return res;
58
+ slotp = (struct Dwarf_Relocation_Data_s *) relrec_to_fill;
59
+ slotp->drd_type = type;
60
+ slotp->drd_length = reltarget_length;
61
+ slotp->drd_offset = offset;
62
+ slotp->drd_symbol_index = symidx;
63
+ return DW_DLV_OK;
64
+ }
65
+
66
+
67
+
68
+ /* Return DW_DLV_ERROR on malloc error.
69
+ Return DW_DLV_OK otherwise */
70
+ int
71
+ _dwarf_pro_reloc_length_symbolic(Dwarf_P_Debug dbg,
72
+ int base_sec_index,
73
+ Dwarf_Unsigned offset, /* r_offset of reloc */
74
+ Dwarf_Unsigned start_symidx,
75
+ Dwarf_Unsigned end_symidx,
76
+ enum Dwarf_Rel_Type type,
77
+ int reltarget_length)
78
+ {
79
+ /* get a slot, fill in the slot entry */
80
+ void *relrec_to_fill = 0;
81
+ int res = 0;
82
+ struct Dwarf_Relocation_Data_s *slotp1 = 0;
83
+ struct Dwarf_Relocation_Data_s *slotp2 = 0;
84
+
85
+ res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
86
+ &relrec_to_fill);
87
+ if (res != DW_DLV_OK)
88
+ return res;
89
+ slotp1 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill;
90
+ res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
91
+ &relrec_to_fill);
92
+ if (res != DW_DLV_OK)
93
+ return res;
94
+ slotp2 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill;
95
+
96
+ /* ASSERT: type == dwarf_drt_first_of_length_type_pair */
97
+ slotp1->drd_type = type;
98
+ slotp1->drd_length = reltarget_length;
99
+ slotp1->drd_offset = offset;
100
+ slotp1->drd_symbol_index = start_symidx;
101
+
102
+ slotp2->drd_type = dwarf_drt_second_of_length_pair;
103
+ slotp2->drd_length = reltarget_length;
104
+ slotp2->drd_offset = offset;
105
+ slotp2->drd_symbol_index = end_symidx;
106
+ return DW_DLV_OK;
107
+ }
108
+
109
+ /* Reset whatever fields of Dwarf_P_Per_Reloc_Sect_s
110
+ we must to allow adding a fresh new single
111
+ block easily (block consolidation use only). */
112
+ static void
113
+ _dwarf_reset_reloc_sect_info(struct Dwarf_P_Per_Reloc_Sect_s *pblk,
114
+ unsigned long ct)
115
+ {
116
+
117
+
118
+ /* Do not zero pr_sect_num_of_reloc_sect */
119
+ pblk->pr_reloc_total_count = 0;
120
+ pblk->pr_first_block = 0;
121
+ pblk->pr_last_block = 0;
122
+ pblk->pr_block_count = 0;
123
+ pblk->pr_slots_per_block_to_alloc = ct;
124
+ }
125
+
126
+ /* Ensure each stream is a single buffer and
127
+ add that single buffer to the set of stream buffers.
128
+
129
+ By creating a new buffer and copying if necessary.
130
+ (If > 1 block, reduce to 1 block)
131
+
132
+ Free the input set of buffers if we consolidate.
133
+
134
+ We pass back *new_sec_count as zero because we
135
+ are not creating normal sections for a .o, but
136
+ symbolic relocations, separately counted.
137
+
138
+ Return -1 on error (malloc failure)
139
+
140
+ Return DW_DLV_OK on success. Any other return indicates
141
+ malloc failed. */
142
+ int
143
+ _dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg,
144
+ Dwarf_Signed * new_sec_count)
145
+ {
146
+ /* unsigned long total_size =0; */
147
+ Dwarf_Small *data = 0;
148
+ int sec_index = 0;
149
+ int res = 0;
150
+ unsigned long i = 0;
151
+ Dwarf_Error error = 0;
152
+ Dwarf_Signed sec_count = 0;
153
+ Dwarf_P_Per_Reloc_Sect p_reloc = &dbg->de_reloc_sect[0];
154
+
155
+ for (i = 0; i < NUM_DEBUG_SECTIONS; ++i, ++p_reloc) {
156
+ unsigned long ct = p_reloc->pr_reloc_total_count;
157
+ struct Dwarf_P_Relocation_Block_s *p_blk;
158
+ struct Dwarf_P_Relocation_Block_s *p_blk_last;
159
+ int err;
160
+ if (ct == 0) {
161
+ continue;
162
+ }
163
+
164
+ /* len = dbg->de_relocation_record_size; */
165
+ ++sec_count;
166
+
167
+ /* total_size = ct *len; */
168
+ sec_index = p_reloc->pr_sect_num_of_reloc_sect;
169
+ if (sec_index == 0) {
170
+ /* Call de_callback_func
171
+ getting section number of reloc section. */
172
+ int rel_section_index = 0;
173
+ Dwarf_Unsigned name_idx = 0;
174
+
175
+ /* This is a bit of a fake, as we do not really have true
176
+ elf sections at all. Just the data such might contain.
177
+ But this lets the caller eventually link things
178
+ together: without this call we would not know what rel
179
+ data goes with what section when we are asked for the
180
+ real arrays. */
181
+
182
+ if (dbg->de_callback_func) {
183
+ rel_section_index =
184
+ dbg->de_callback_func(_dwarf_rel_section_names[i],
185
+ dbg->de_relocation_record_size,
186
+ /* type */ SHT_REL,
187
+ /* flags */ 0,
188
+ /* link to symtab, which we cannot
189
+ know */ SHN_UNDEF,
190
+ /* sec rels apply to */
191
+ dbg->de_elf_sects[i],
192
+ &name_idx,
193
+ dbg->de_user_data,&err);
194
+ }
195
+ if (rel_section_index == -1) {
196
+ {
197
+ _dwarf_p_error(dbg, &error, DW_DLE_ELF_SECT_ERR);
198
+ return (DW_DLV_ERROR);
199
+ }
200
+ }
201
+ p_reloc->pr_sect_num_of_reloc_sect = rel_section_index;
202
+ sec_index = rel_section_index;
203
+ }
204
+
205
+ p_blk = p_reloc->pr_first_block;
206
+
207
+ if (p_reloc->pr_block_count > 1) {
208
+ struct Dwarf_P_Relocation_Block_s *new_blk;
209
+
210
+ /* HACK , not normal interfaces, trashing p_reloc current
211
+ contents! */
212
+ _dwarf_reset_reloc_sect_info(p_reloc, ct);
213
+
214
+ /* Creating new single block for all 'ct' entries */
215
+ res = _dwarf_pro_pre_alloc_n_reloc_slots(dbg, (int) i, ct);
216
+ if (res != DW_DLV_OK) {
217
+ return res;
218
+ }
219
+ new_blk = p_reloc->pr_first_block;
220
+
221
+ data = (Dwarf_Small *) new_blk->rb_data;
222
+
223
+ /* The following loop does the consolidation to a single
224
+ block and frees the input block(s). */
225
+ do {
226
+ unsigned long len =
227
+ p_blk->rb_where_to_add_next - p_blk->rb_data;
228
+ memcpy(data, p_blk->rb_data, len);
229
+ data += len;
230
+ p_blk_last = p_blk;
231
+ p_blk = p_blk->rb_next;
232
+ _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last);
233
+ } while (p_blk);
234
+ /* ASSERT: sum of len copied == total_size */
235
+ new_blk->rb_next_slot_to_use = ct;
236
+ new_blk->rb_where_to_add_next = (char *) data;
237
+ p_reloc->pr_reloc_total_count = ct;
238
+
239
+ /* Have now created a single block, but no change in slots
240
+ used (pr_reloc_total_count) */
241
+ }
242
+ }
243
+ *new_sec_count = 0;
244
+ return DW_DLV_OK;
245
+ }
@@ -0,0 +1,45 @@
1
+ /*
2
+
3
+ Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
4
+
5
+ This program is free software; you can redistribute it and/or modify it
6
+ under the terms of version 2.1 of the GNU Lesser General Public License
7
+ as published by the Free Software Foundation.
8
+
9
+ This program is distributed in the hope that it would be useful, but
10
+ WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
+
13
+ Further, this software is distributed without any warranty that it is
14
+ free of the rightful claim of any third person regarding infringement
15
+ or the like. Any license provided herein, whether implied or
16
+ otherwise, applies only to this software file. Patent licenses, if
17
+ any, provided herein do not apply to combinations of this program with
18
+ other software, or any other product whatsoever.
19
+
20
+ You should have received a copy of the GNU Lesser General Public
21
+ License along with this program; if not, write the Free Software
22
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
23
+ USA.
24
+
25
+ */
26
+
27
+
28
+ int _dwarf_pro_reloc_name_symbolic(Dwarf_P_Debug dbg,
29
+ int base_sec_index,
30
+ Dwarf_Unsigned offset,/* r_offset of reloc */
31
+ Dwarf_Unsigned symidx,
32
+ enum Dwarf_Rel_Type,
33
+ int reltarget_length);
34
+
35
+ int
36
+ _dwarf_pro_reloc_length_symbolic(Dwarf_P_Debug dbg,
37
+ int base_sec_index,
38
+ Dwarf_Unsigned offset, /* r_offset of reloc */
39
+ Dwarf_Unsigned start_symidx,
40
+ Dwarf_Unsigned end_symidx,
41
+ enum Dwarf_Rel_Type,
42
+ int reltarget_length);
43
+
44
+ int _dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg,
45
+ Dwarf_Signed * new_sec_count);
@@ -0,0 +1,2233 @@
1
+ /*
2
+ Copyright (C) 2000,2004,2006 Silicon Graphics, Inc. All Rights Reserved.
3
+ Portions Copyright (C) 2007-2012 David Anderson. All Rights Reserved.
4
+ Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
5
+ Portions Copyright 2012 SN Systems Ltd. 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 "libdwarfdefs.h"
31
+ #include <stdio.h>
32
+ #include <string.h>
33
+ #ifdef HAVE_ELFACCESS_H
34
+ #include <elfaccess.h>
35
+ #endif
36
+ #include "pro_incl.h"
37
+ #include "pro_section.h"
38
+ #include "pro_line.h"
39
+ #include "pro_frame.h"
40
+ #include "pro_die.h"
41
+ #include "pro_macinfo.h"
42
+ #include "pro_types.h"
43
+
44
+ #ifndef SHF_MIPS_NOSTRIP
45
+ /* if this is not defined, we probably don't need it: just use 0 */
46
+ #define SHF_MIPS_NOSTRIP 0
47
+ #endif
48
+ #ifndef R_MIPS_NONE
49
+ #define R_MIPS_NONE 0
50
+ #endif
51
+
52
+ #ifndef TRUE
53
+ #define TRUE 1
54
+ #endif
55
+ #ifndef FALSE
56
+ #define FALSE 0
57
+ #endif
58
+
59
+ /* Must match up with pro_section.h defines of DEBUG_INFO etc
60
+ and sectnames (below). REL_SEC_PREFIX is either ".rel" or ".rela"
61
+ see pro_incl.h
62
+ */
63
+ const char *_dwarf_rel_section_names[] = {
64
+ REL_SEC_PREFIX ".debug_info",
65
+ REL_SEC_PREFIX ".debug_line",
66
+ REL_SEC_PREFIX ".debug_abbrev", /* no relocations on this, really */
67
+ REL_SEC_PREFIX ".debug_frame",
68
+ REL_SEC_PREFIX ".debug_aranges",
69
+ REL_SEC_PREFIX ".debug_pubnames",
70
+ REL_SEC_PREFIX ".debug_str",
71
+ REL_SEC_PREFIX ".debug_funcnames", /* sgi extension */
72
+ REL_SEC_PREFIX ".debug_typenames", /* sgi extension */
73
+ REL_SEC_PREFIX ".debug_varnames", /* sgi extension */
74
+ REL_SEC_PREFIX ".debug_weaknames", /* sgi extension */
75
+ REL_SEC_PREFIX ".debug_macinfo",
76
+ REL_SEC_PREFIX ".debug_loc",
77
+ REL_SEC_PREFIX ".debug_ranges",
78
+ REL_SEC_PREFIX ".debug_types", /* new in DWARF4 */
79
+ REL_SEC_PREFIX ".debug_pubtypes", /* new in DWARF3 */
80
+ };
81
+
82
+ /* names of sections. Ensure that it matches the defines
83
+ in pro_section.h, in the same order
84
+ Must match also _dwarf_rel_section_names above
85
+ */
86
+ const char *_dwarf_sectnames[] = {
87
+ ".debug_info",
88
+ ".debug_line",
89
+ ".debug_abbrev",
90
+ ".debug_frame",
91
+ ".debug_aranges",
92
+ ".debug_pubnames",
93
+ ".debug_str",
94
+ ".debug_funcnames", /* sgi extension */
95
+ ".debug_typenames", /* sgi extension */
96
+ ".debug_varnames", /* sgi extension */
97
+ ".debug_weaknames", /* sgi extension */
98
+ ".debug_macinfo",
99
+ ".debug_loc",
100
+ ".debug_ranges",
101
+ ".debug_types", /* new in DWARF4 */
102
+ ".debug_pubtypes", /* new in DWARF3 */
103
+ };
104
+
105
+
106
+
107
+
108
+ static const Dwarf_Ubyte std_opcode_len[] = { 0, /* DW_LNS_copy */
109
+ 1, /* DW_LNS_advance_pc */
110
+ 1, /* DW_LNS_advance_line */
111
+ 1, /* DW_LNS_set_file */
112
+ 1, /* DW_LNS_set_column */
113
+ 0, /* DW_LNS_negate_stmt */
114
+ 0, /* DW_LNS_set_basic_block */
115
+ 0, /* DW_LNS_const_add_pc */
116
+ 1, /* DW_LNS_fixed_advance_pc */
117
+ /* The following for DWARF3 and DWARF4, though GNU
118
+ uses these in DWARF2 as well. */
119
+ 0, /* DW_LNS_set_prologue_end */
120
+ 0, /* DW_LNS_set_epilogue_begin */
121
+ 1, /* DW_LNS_set_isa */
122
+ };
123
+
124
+ /* struct to hold relocation entries. Its mantained as a linked
125
+ list of relocation structs, and will then be written at as a
126
+ whole into the relocation section. Whether its 32 bit or
127
+ 64 bit will be obtained from Dwarf_Debug pointer.
128
+ */
129
+
130
+ typedef struct Dwarf_P_Rel_s *Dwarf_P_Rel;
131
+ struct Dwarf_P_Rel_s {
132
+ Dwarf_P_Rel dr_next;
133
+ void *dr_rel_datap;
134
+ };
135
+ typedef struct Dwarf_P_Rel_Head_s *Dwarf_P_Rel_Head;
136
+ struct Dwarf_P_Rel_Head_s {
137
+ struct Dwarf_P_Rel_s *drh_head;
138
+ struct Dwarf_P_Rel_s *drh_tail;
139
+ };
140
+
141
+ static int _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg,
142
+ Dwarf_Error * error);
143
+ static int _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg,
144
+ Dwarf_Error * error);
145
+ static int _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg,
146
+ Dwarf_Error * error);
147
+ static Dwarf_P_Abbrev _dwarf_pro_getabbrev(Dwarf_P_Die, Dwarf_P_Abbrev);
148
+ static int _dwarf_pro_match_attr
149
+ (Dwarf_P_Attribute, Dwarf_P_Abbrev, int no_attr);
150
+
151
+ /* these macros used as return value for below functions */
152
+ #define OPC_INCS_ZERO -1
153
+ #define OPC_OUT_OF_RANGE -2
154
+ #define LINE_OUT_OF_RANGE -3
155
+ static int _dwarf_pro_get_opc(Dwarf_P_Debug dbg,Dwarf_Unsigned addr_adv, int line_adv);
156
+
157
+
158
+ /* BEGIN_LEN_SIZE is the size of the 'length' field in total.
159
+ Which may be 4,8, or 12 bytes!
160
+ 4 is standard DWARF2.
161
+ 8 is non-standard MIPS-IRIX 64-bit.
162
+ 12 is standard DWARF3 for 64 bit offsets.
163
+ Used in various routines: local variable names
164
+ must match the names here.
165
+ */
166
+ #define BEGIN_LEN_SIZE (uwordb_size + extension_size)
167
+
168
+ /* Return TRUE if we need the section, FALSE otherwise
169
+
170
+ If any of the 'line-data-related' calls were made
171
+ including file or directory entries,
172
+ produce .debug_line .
173
+
174
+ */
175
+ static int
176
+ dwarf_need_debug_line_section(Dwarf_P_Debug dbg)
177
+ {
178
+ if (dbg->de_lines == NULL && dbg->de_file_entries == NULL
179
+ && dbg->de_inc_dirs == NULL) {
180
+ return FALSE;
181
+ }
182
+ return TRUE;
183
+ }
184
+
185
+ /* Convert debug information to a format such that
186
+ it can be written on disk.
187
+ Called exactly once per execution.
188
+ */
189
+ Dwarf_Signed
190
+ dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error)
191
+ {
192
+ /* Section data in written out in a number of buffers. Each
193
+ _generate_*() function returns a cumulative count of buffers for
194
+ all the sections.
195
+ dwarf_get_section_bytes() returns pointers to these
196
+ buffers one at a time. */
197
+ int nbufs = 0;
198
+ int sect = 0;
199
+ int err = 0;
200
+ Dwarf_Unsigned du = 0;
201
+
202
+ if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) {
203
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_NOCOUNT);
204
+ }
205
+
206
+ /* Create dwarf section headers */
207
+ for (sect = 0; sect < NUM_DEBUG_SECTIONS; sect++) {
208
+ long flags = 0;
209
+
210
+ switch (sect) {
211
+
212
+ case DEBUG_INFO:
213
+ if (dbg->de_dies == NULL) {
214
+ continue;
215
+ }
216
+ break;
217
+
218
+ case DEBUG_LINE:
219
+ if (dwarf_need_debug_line_section(dbg) == FALSE) {
220
+ continue;
221
+ }
222
+ break;
223
+
224
+ case DEBUG_ABBREV:
225
+ if (dbg->de_dies == NULL) {
226
+ continue;
227
+ }
228
+ break;
229
+
230
+ case DEBUG_FRAME:
231
+ if (dbg->de_frame_cies == NULL) {
232
+ continue;
233
+ }
234
+ flags = SHF_MIPS_NOSTRIP;
235
+ break;
236
+
237
+ case DEBUG_ARANGES:
238
+ if (dbg->de_arange == NULL) {
239
+ continue;
240
+ }
241
+ break;
242
+
243
+ case DEBUG_PUBNAMES:
244
+ if (dbg->de_simple_name_headers[dwarf_snk_pubname].
245
+ sn_head == NULL) {
246
+ continue;
247
+ }
248
+ break;
249
+ case DEBUG_PUBTYPES:
250
+ if (dbg->de_simple_name_headers[dwarf_snk_pubtype].
251
+ sn_head == NULL) {
252
+ continue;
253
+ }
254
+ break;
255
+
256
+ case DEBUG_STR:
257
+ if (dbg->de_strings == NULL) {
258
+ continue;
259
+ }
260
+ break;
261
+
262
+ case DEBUG_FUNCNAMES:
263
+ if (dbg->de_simple_name_headers[dwarf_snk_funcname].
264
+ sn_head == NULL) {
265
+ continue;
266
+ }
267
+ break;
268
+
269
+ case DEBUG_TYPENAMES:
270
+ if (dbg->de_simple_name_headers[dwarf_snk_typename].
271
+ sn_head == NULL) {
272
+ continue;
273
+ }
274
+ break;
275
+
276
+ case DEBUG_VARNAMES:
277
+ if (dbg->de_simple_name_headers[dwarf_snk_varname].
278
+ sn_head == NULL) {
279
+ continue;
280
+ }
281
+ break;
282
+
283
+ case DEBUG_WEAKNAMES:
284
+ if (dbg->de_simple_name_headers[dwarf_snk_weakname].
285
+ sn_head == NULL) {
286
+ continue;
287
+ }
288
+ break;
289
+
290
+ case DEBUG_MACINFO:
291
+ if (dbg->de_first_macinfo == NULL) {
292
+ continue;
293
+ }
294
+ break;
295
+ case DEBUG_LOC:
296
+ /* Not handled yet. */
297
+ continue;
298
+ case DEBUG_RANGES:
299
+ /* Not handled yet. */
300
+ continue;
301
+ case DEBUG_TYPES:
302
+ /* Not handled yet. */
303
+ continue;
304
+ default:
305
+ /* logic error: missing a case */
306
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_NOCOUNT);
307
+ }
308
+ {
309
+ int new_base_elf_sect = 0;
310
+
311
+ if (dbg->de_callback_func) {
312
+ new_base_elf_sect =
313
+ dbg->de_callback_func(_dwarf_sectnames[sect],
314
+ /* rec size */ 1,
315
+ SECTION_TYPE,
316
+ flags, SHN_UNDEF, 0, &du,
317
+ dbg->de_user_data, &err);
318
+ }
319
+ if (new_base_elf_sect == -1) {
320
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR,
321
+ DW_DLV_NOCOUNT);
322
+ }
323
+ dbg->de_elf_sects[sect] = new_base_elf_sect;
324
+
325
+ dbg->de_sect_name_idx[sect] = du;
326
+ }
327
+ }
328
+
329
+ nbufs = 0;
330
+
331
+ /* Changing the order in which the sections are generated may cause
332
+ problems because of relocations. */
333
+
334
+ if (dwarf_need_debug_line_section(dbg) == TRUE) {
335
+ nbufs = _dwarf_pro_generate_debugline(dbg, error);
336
+ if (nbufs < 0) {
337
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGLINE_ERROR,
338
+ DW_DLV_NOCOUNT);
339
+ }
340
+ }
341
+
342
+ if (dbg->de_frame_cies) {
343
+ nbufs = _dwarf_pro_generate_debugframe(dbg, error);
344
+ if (nbufs < 0) {
345
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGFRAME_ERROR,
346
+ DW_DLV_NOCOUNT);
347
+ }
348
+ }
349
+ if (dbg->de_first_macinfo) {
350
+ nbufs = _dwarf_pro_transform_macro_info_to_disk(dbg, error);
351
+ if (nbufs < 0) {
352
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGMACINFO_ERROR,
353
+ DW_DLV_NOCOUNT);
354
+ }
355
+ }
356
+
357
+ if (dbg->de_dies) {
358
+ nbufs = _dwarf_pro_generate_debuginfo(dbg, error);
359
+ if (nbufs < 0) {
360
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
361
+ DW_DLV_NOCOUNT);
362
+ }
363
+ }
364
+
365
+ if (dbg->de_arange) {
366
+ nbufs = _dwarf_transform_arange_to_disk(dbg, error);
367
+ if (nbufs < 0) {
368
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_ARANGE_ERROR,
369
+ DW_DLV_NOCOUNT);
370
+ }
371
+ }
372
+
373
+ if (dbg->de_simple_name_headers[dwarf_snk_pubname].sn_head) {
374
+ nbufs = _dwarf_transform_simplename_to_disk(dbg,
375
+ dwarf_snk_pubname,
376
+ DEBUG_PUBNAMES,
377
+ error);
378
+ if (nbufs < 0) {
379
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_PUBNAMES_ERROR,
380
+ DW_DLV_NOCOUNT);
381
+ }
382
+ }
383
+ if (dbg->de_simple_name_headers[dwarf_snk_pubtype].sn_head) {
384
+ nbufs = _dwarf_transform_simplename_to_disk(dbg,
385
+ dwarf_snk_pubtype,
386
+ DEBUG_PUBTYPES,
387
+ error);
388
+ if (nbufs < 0) {
389
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGPUBTYPES_ERROR,
390
+ DW_DLV_NOCOUNT);
391
+ }
392
+ }
393
+
394
+ if (dbg->de_simple_name_headers[dwarf_snk_funcname].sn_head) {
395
+ nbufs = _dwarf_transform_simplename_to_disk(dbg,
396
+ dwarf_snk_funcname,
397
+ DEBUG_FUNCNAMES,
398
+ error);
399
+ if (nbufs < 0) {
400
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_FUNCNAMES_ERROR,
401
+ DW_DLV_NOCOUNT);
402
+ }
403
+ }
404
+
405
+ if (dbg->de_simple_name_headers[dwarf_snk_typename].sn_head) {
406
+ nbufs = _dwarf_transform_simplename_to_disk(dbg,
407
+ dwarf_snk_typename,
408
+ DEBUG_TYPENAMES,
409
+ error);
410
+ if (nbufs < 0) {
411
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_TYPENAMES_ERROR,
412
+ DW_DLV_NOCOUNT);
413
+ }
414
+ }
415
+
416
+ if (dbg->de_simple_name_headers[dwarf_snk_varname].sn_head) {
417
+ nbufs = _dwarf_transform_simplename_to_disk(dbg,
418
+ dwarf_snk_varname,
419
+ DEBUG_VARNAMES,
420
+ error);
421
+
422
+ if (nbufs < 0) {
423
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_VARNAMES_ERROR,
424
+ DW_DLV_NOCOUNT);
425
+ }
426
+ }
427
+
428
+ if (dbg->de_simple_name_headers[dwarf_snk_weakname].sn_head) {
429
+ nbufs = _dwarf_transform_simplename_to_disk(dbg,
430
+ dwarf_snk_weakname, DEBUG_WEAKNAMES, error);
431
+ if (nbufs < 0) {
432
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_WEAKNAMES_ERROR,
433
+ DW_DLV_NOCOUNT);
434
+ }
435
+ }
436
+
437
+ {
438
+ Dwarf_Signed new_chunks = 0;
439
+ int res = 0;
440
+
441
+ res = dbg->de_transform_relocs_to_disk(dbg, &new_chunks);
442
+ if (res != DW_DLV_OK) {
443
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_RELOCS_ERROR,
444
+ DW_DLV_NOCOUNT);
445
+ }
446
+ nbufs += new_chunks;
447
+ }
448
+ return nbufs;
449
+ }
450
+
451
+ static unsigned
452
+ write_fixed_size(Dwarf_Unsigned val,
453
+ Dwarf_P_Debug dbg,
454
+ int elfsectno,
455
+ Dwarf_Unsigned size,
456
+ Dwarf_Error* error)
457
+ {
458
+ unsigned char *data = 0;
459
+ GET_CHUNK(dbg, elfsectno, data, size, error);
460
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &val,
461
+ sizeof(val), size);
462
+ return size;
463
+ }
464
+
465
+ static unsigned
466
+ write_ubyte(unsigned val,
467
+ Dwarf_P_Debug dbg,
468
+ int elfsectno,
469
+ Dwarf_Error* error)
470
+ {
471
+ Dwarf_Ubyte db = val;
472
+ unsigned char *data = 0;
473
+ unsigned len = sizeof(Dwarf_Ubyte);
474
+ GET_CHUNK(dbg, elfsectno, data,
475
+ len, error);
476
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
477
+ sizeof(db), len);
478
+ return 1;
479
+ }
480
+ static unsigned
481
+ pretend_write_uval(Dwarf_Unsigned val,
482
+ Dwarf_P_Debug dbg,
483
+ int elfsectno,
484
+ Dwarf_Error* error)
485
+ {
486
+ char buff1[ENCODE_SPACE_NEEDED];
487
+ int nbytes = 0;
488
+ _dwarf_pro_encode_leb128_nm(val,
489
+ &nbytes, buff1,
490
+ sizeof(buff1));
491
+ return nbytes;
492
+ }
493
+
494
+ static unsigned
495
+ write_sval(Dwarf_Signed val,
496
+ Dwarf_P_Debug dbg,
497
+ int elfsectno,
498
+ Dwarf_Error* error)
499
+ {
500
+ char buff1[ENCODE_SPACE_NEEDED];
501
+ unsigned char *data = 0;
502
+ int nbytes = 0;
503
+ int res = _dwarf_pro_encode_signed_leb128_nm(val,
504
+ &nbytes, buff1,
505
+ sizeof(buff1));
506
+ if (res != DW_DLV_OK) {
507
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
508
+ }
509
+ GET_CHUNK(dbg, elfsectno, data, nbytes, error);
510
+ memcpy((void *) data, (const void *) buff1, nbytes);
511
+ return nbytes;
512
+ }
513
+
514
+ static unsigned
515
+ write_uval(Dwarf_Unsigned val,
516
+ Dwarf_P_Debug dbg,
517
+ int elfsectno,
518
+ Dwarf_Error* error)
519
+ {
520
+ char buff1[ENCODE_SPACE_NEEDED];
521
+ unsigned char *data = 0;
522
+ int nbytes = 0;
523
+ int res = _dwarf_pro_encode_leb128_nm(val,
524
+ &nbytes, buff1,
525
+ sizeof(buff1));
526
+ if (res != DW_DLV_OK) {
527
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
528
+ }
529
+ GET_CHUNK(dbg, elfsectno, data, nbytes, error);
530
+ memcpy((void *) data, (const void *) buff1, nbytes);
531
+ return nbytes;
532
+ }
533
+ static unsigned
534
+ write_opcode_uval(int opcode,
535
+ Dwarf_P_Debug dbg,
536
+ int elfsectno,
537
+ Dwarf_Unsigned val,
538
+ Dwarf_Error* error)
539
+ {
540
+ unsigned totallen = write_ubyte(opcode,dbg,elfsectno,error);
541
+ totallen += write_uval(val,dbg,elfsectno,error);
542
+ return totallen;
543
+ }
544
+
545
+ /* Generate debug_line section */
546
+ static int
547
+ _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error)
548
+ {
549
+ Dwarf_P_Inc_Dir curdir = 0;
550
+ Dwarf_P_F_Entry curentry = 0;
551
+ Dwarf_P_Line curline = 0;
552
+ Dwarf_P_Line prevline = 0;
553
+
554
+ /* all data named cur* are used to loop thru linked lists */
555
+
556
+ int sum_bytes = 0;
557
+ int prolog_size = 0;
558
+ unsigned char *data = 0; /* holds disk form data */
559
+ int elfsectno = 0;
560
+ unsigned char *start_line_sec = 0; /* pointer to the buffer at
561
+ section start */
562
+ /* temps for memcpy */
563
+ Dwarf_Unsigned du = 0;
564
+ Dwarf_Ubyte db = 0;
565
+ Dwarf_Half dh = 0;
566
+ int res = 0;
567
+ int uwordb_size = dbg->de_offset_size;
568
+ int extension_size = dbg->de_64bit_extension ? 4 : 0;
569
+ int upointer_size = dbg->de_pointer_size;
570
+
571
+ sum_bytes = 0;
572
+
573
+ elfsectno = dbg->de_elf_sects[DEBUG_LINE];
574
+
575
+ /* include directories */
576
+ curdir = dbg->de_inc_dirs;
577
+ while (curdir) {
578
+ prolog_size += strlen(curdir->did_name) + 1;
579
+ curdir = curdir->did_next;
580
+ }
581
+ prolog_size++; /* last null following last directory
582
+ entry. */
583
+
584
+ /* file entries */
585
+ curentry = dbg->de_file_entries;
586
+ while (curentry) {
587
+ prolog_size +=
588
+ strlen(curentry->dfe_name) + 1 + curentry->dfe_nbytes;
589
+ curentry = curentry->dfe_next;
590
+ }
591
+ prolog_size++; /* last null byte */
592
+
593
+
594
+ prolog_size += BEGIN_LEN_SIZE + sizeof_uhalf(dbg) + /* version # */
595
+ uwordb_size + /* header length */
596
+ sizeof_ubyte(dbg) + /* min_instr length */
597
+ sizeof_ubyte(dbg) + /* default is_stmt */
598
+ sizeof_ubyte(dbg) + /* linebase */
599
+ sizeof_ubyte(dbg) + /* linerange */
600
+ sizeof_ubyte(dbg); /* opcode base */
601
+
602
+ /* length of table specifying # of opnds */
603
+ prolog_size += dbg->de_line_inits.pi_opcode_base-1;
604
+ if (dbg->de_line_inits.pi_version == DW_LINE_VERSION4) {
605
+ /* For maximum_operations_per_instruction. */
606
+ prolog_size += sizeof_ubyte(dbg);
607
+ }
608
+
609
+ GET_CHUNK(dbg, elfsectno, data, prolog_size, error);
610
+ start_line_sec = data;
611
+
612
+ /* copy over the data */
613
+ /* total_length */
614
+ du = 0;
615
+ if (extension_size) {
616
+ Dwarf_Word x = DISTINGUISHED_VALUE;
617
+
618
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &x,
619
+ sizeof(x), extension_size);
620
+ data += extension_size;
621
+ }
622
+
623
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
624
+ sizeof(du), uwordb_size);
625
+ data += uwordb_size;
626
+
627
+ dh = dbg->de_line_inits.pi_version;
628
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dh,
629
+ sizeof(dh), sizeof(Dwarf_Half));
630
+ data += sizeof(Dwarf_Half);
631
+
632
+ /* header length */
633
+ du = prolog_size - (BEGIN_LEN_SIZE + sizeof(Dwarf_Half) +
634
+ uwordb_size);
635
+ {
636
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
637
+ sizeof(du), uwordb_size);
638
+ data += uwordb_size;
639
+ }
640
+ db = dbg->de_line_inits.pi_minimum_instruction_length;
641
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
642
+ sizeof(db), sizeof(Dwarf_Ubyte));
643
+ data += sizeof(Dwarf_Ubyte);
644
+
645
+ if (dbg->de_line_inits.pi_version == DW_LINE_VERSION4) {
646
+ db = dbg->de_line_inits.pi_maximum_operations_per_instruction;
647
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
648
+ sizeof(db), sizeof(Dwarf_Ubyte));
649
+ data += sizeof(Dwarf_Ubyte);
650
+ }
651
+
652
+ db = dbg->de_line_inits.pi_default_is_stmt;
653
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
654
+ sizeof(db), sizeof(Dwarf_Ubyte));
655
+ data += sizeof(Dwarf_Ubyte);
656
+ db = dbg->de_line_inits.pi_line_base;
657
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
658
+ sizeof(db), sizeof(Dwarf_Ubyte));
659
+ data += sizeof(Dwarf_Ubyte);
660
+ db = dbg->de_line_inits.pi_line_range;
661
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
662
+ sizeof(db), sizeof(Dwarf_Ubyte));
663
+ data += sizeof(Dwarf_Ubyte);
664
+ db = dbg->de_line_inits.pi_opcode_base;
665
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
666
+ sizeof(db), sizeof(Dwarf_Ubyte));
667
+ data += sizeof(Dwarf_Ubyte);
668
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) std_opcode_len,
669
+ dbg->de_line_inits.pi_opcode_base-1,
670
+ dbg->de_line_inits.pi_opcode_base-1);
671
+ data += dbg->de_line_inits.pi_opcode_base-1;
672
+
673
+ /* copy over include directories */
674
+ curdir = dbg->de_inc_dirs;
675
+ while (curdir) {
676
+ strcpy((char *) data, curdir->did_name);
677
+ data += strlen(curdir->did_name) + 1;
678
+ curdir = curdir->did_next;
679
+ }
680
+ *data = '\0'; /* last null */
681
+ data++;
682
+
683
+ /* copy file entries */
684
+ curentry = dbg->de_file_entries;
685
+ while (curentry) {
686
+ strcpy((char *) data, curentry->dfe_name);
687
+ data += strlen(curentry->dfe_name) + 1;
688
+ /* copies of leb numbers, no endian issues */
689
+ memcpy((void *) data,
690
+ (const void *) curentry->dfe_args, curentry->dfe_nbytes);
691
+ data += curentry->dfe_nbytes;
692
+ curentry = curentry->dfe_next;
693
+ }
694
+ *data = '\0';
695
+ data++;
696
+
697
+ sum_bytes += prolog_size;
698
+
699
+ curline = dbg->de_lines;
700
+ prevline = (Dwarf_P_Line)
701
+ _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
702
+ if (prevline == NULL) {
703
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, -1);
704
+ }
705
+ _dwarf_pro_reg_init(dbg,prevline);
706
+ /* generate opcodes for line numbers */
707
+ while (curline) {
708
+ int opc = 0;
709
+ int no_lns_copy = 0; /* if lns copy opcode does not need to be
710
+ generated, if special opcode or end
711
+ sequence */
712
+ Dwarf_Unsigned addr_adv = 0;
713
+ int line_adv = 0; /* supposed to be a reasonably small
714
+ number, so the size should not be a
715
+ problem. ? */
716
+
717
+ no_lns_copy = 0;
718
+ if (curline->dpl_opc != 0) {
719
+ int inst_bytes = 0; /* no of bytes in extended opcode */
720
+ unsigned writelen = 0;
721
+
722
+ switch (curline->dpl_opc) {
723
+ case DW_LNE_end_sequence:
724
+ /* Advance pc to end of text section. */
725
+ addr_adv = curline->dpl_address - prevline->dpl_address;
726
+ if (addr_adv > 0) {
727
+ writelen = write_opcode_uval(DW_LNS_advance_pc,dbg,
728
+ elfsectno,
729
+ addr_adv/
730
+ dbg->de_line_inits.pi_minimum_instruction_length,
731
+ error);
732
+ sum_bytes += writelen;
733
+ prevline->dpl_address = curline->dpl_address;
734
+ }
735
+
736
+ /* first null byte */
737
+ db = 0;
738
+ writelen = write_ubyte(db,dbg,elfsectno,error);
739
+ sum_bytes += writelen;
740
+
741
+ /* write length of extended opcode */
742
+ inst_bytes = sizeof(Dwarf_Ubyte);
743
+ writelen = write_uval(inst_bytes,dbg,elfsectno,error);
744
+ sum_bytes += writelen;
745
+
746
+ /* write extended opcode */
747
+ writelen = write_ubyte(DW_LNE_end_sequence,dbg,elfsectno,error);
748
+ sum_bytes += writelen;
749
+
750
+ /* reset value to original values */
751
+ _dwarf_pro_reg_init(dbg,prevline);
752
+ no_lns_copy = 1;
753
+ /* this is set only for end_sequence, so that a
754
+ dw_lns_copy is not generated */
755
+ break;
756
+
757
+ case DW_LNE_set_address:
758
+
759
+ /* first null byte */
760
+ db = 0;
761
+ writelen = write_ubyte(db,dbg,elfsectno,error);
762
+ sum_bytes += writelen;
763
+
764
+ /* write length of extended opcode */
765
+ inst_bytes = sizeof(Dwarf_Ubyte) + upointer_size;
766
+ writelen = write_uval(inst_bytes,dbg,elfsectno,error);
767
+ sum_bytes += writelen;
768
+
769
+ /* write extended opcode */
770
+ writelen = write_ubyte(DW_LNE_set_address,dbg,elfsectno,error);
771
+ sum_bytes += writelen;
772
+
773
+ /* reloc for address */
774
+ res = dbg->de_reloc_name(dbg, DEBUG_LINE,
775
+ sum_bytes, /* r_offset */
776
+ curline->dpl_r_symidx,
777
+ dwarf_drt_data_reloc,
778
+ uwordb_size);
779
+ if (res != DW_DLV_OK) {
780
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
781
+ }
782
+
783
+ /* write offset (address) */
784
+ du = curline->dpl_address;
785
+ writelen = write_fixed_size(du,dbg,elfsectno,
786
+ upointer_size,error);
787
+ sum_bytes += writelen;
788
+ prevline->dpl_address = curline->dpl_address;
789
+ no_lns_copy = 1;
790
+ break;
791
+ case DW_LNE_define_file:
792
+ /* Not supported, all add-file entries
793
+ are added via dbg -> de_file_entries,
794
+ which adds to the line table header. */
795
+ no_lns_copy = 1;
796
+ break;
797
+ case DW_LNE_set_discriminator: {/* DWARF4 */
798
+ unsigned val_len = 0;
799
+ /* first null byte */
800
+ db = 0;
801
+ writelen = write_ubyte(db,dbg,elfsectno,error);
802
+ sum_bytes += writelen;
803
+
804
+ /* Write len of opcode + value here. */
805
+ val_len = pretend_write_uval(curline->dpl_discriminator,
806
+ dbg, elfsectno,error) + 1;
807
+ writelen = write_uval(val_len +1,dbg,elfsectno,error);
808
+ sum_bytes += writelen;
809
+
810
+ /* Write opcode */
811
+ writelen = write_ubyte(DW_LNE_set_discriminator,
812
+ dbg,elfsectno,error);
813
+ sum_bytes += writelen;
814
+
815
+ /* Write the value itself. */
816
+ writelen = write_uval(curline->dpl_discriminator,
817
+ dbg,elfsectno,error);
818
+ sum_bytes += writelen;
819
+ no_lns_copy = 1;
820
+ }
821
+ break;
822
+ }
823
+ } else {
824
+ unsigned writelen = 0;
825
+ if (dbg->de_line_inits.pi_opcode_base >12) {
826
+ /* We have the newer standard opcodes
827
+ DW_LNS_set_prologue_end, DW_LNS_set_epilogue_end,
828
+ DW_LNS_set_isa, we do not write them if not
829
+ in the table. DWARF3 and DWARF4 */
830
+ /* Should we check if a change? These reset automatically
831
+ in the line processing/reading engine,
832
+ so I think no check of prevline is wanted. */
833
+ if (curline->dpl_epilogue_begin) {
834
+ writelen = write_ubyte(DW_LNS_set_epilogue_begin,dbg,
835
+ elfsectno, error);
836
+ sum_bytes += writelen;
837
+ }
838
+ if (curline->dpl_prologue_end) {
839
+ writelen = write_ubyte(DW_LNS_set_prologue_end,dbg,
840
+ elfsectno, error);
841
+ sum_bytes += writelen;
842
+ }
843
+ if (curline->dpl_isa != prevline->dpl_isa) {
844
+ writelen = write_opcode_uval(DW_LNS_set_isa,dbg,
845
+ elfsectno,
846
+ curline->dpl_isa ,error);
847
+ sum_bytes += writelen;
848
+ }
849
+ }
850
+ if (curline->dpl_file != prevline->dpl_file) {
851
+ db = DW_LNS_set_file;
852
+ writelen = write_opcode_uval(db,dbg,
853
+ elfsectno,
854
+ curline->dpl_file ,error);
855
+ sum_bytes += writelen;
856
+
857
+ prevline->dpl_file = curline->dpl_file;
858
+ }
859
+ if (curline->dpl_column != prevline->dpl_column) {
860
+ db = DW_LNS_set_column;
861
+ writelen = write_opcode_uval(db,dbg,
862
+ elfsectno,
863
+ curline->dpl_column ,error);
864
+ sum_bytes += writelen;
865
+ prevline->dpl_column = curline->dpl_column;
866
+ }
867
+ if (curline->dpl_is_stmt != prevline->dpl_is_stmt) {
868
+ writelen = write_ubyte(DW_LNS_negate_stmt,dbg,elfsectno,error);
869
+ sum_bytes += writelen;
870
+ prevline->dpl_is_stmt = curline->dpl_is_stmt;
871
+ }
872
+ if (curline->dpl_basic_block == true &&
873
+ prevline->dpl_basic_block == false) {
874
+ writelen = write_ubyte(DW_LNS_set_basic_block,dbg,
875
+ elfsectno,error);
876
+ sum_bytes += writelen;
877
+ prevline->dpl_basic_block = curline->dpl_basic_block;
878
+ }
879
+ if (curline->dpl_discriminator) {
880
+ /* This is dwarf4, but because it is an extended op
881
+ not a standard op,
882
+ we allow it without testing version.
883
+ GNU seems to set this from time to time. */
884
+ unsigned val_len = 0;
885
+ /* first null byte */
886
+ db = 0;
887
+ writelen = write_ubyte(db,dbg,elfsectno,error);
888
+ sum_bytes += writelen;
889
+
890
+ /* Write len of opcode + value here. */
891
+ val_len = pretend_write_uval(curline->dpl_discriminator,
892
+ dbg, elfsectno,error) + 1;
893
+ writelen = write_uval(val_len +1,dbg,elfsectno,error);
894
+ sum_bytes += writelen;
895
+
896
+ /* Write opcode */
897
+ writelen = write_ubyte(DW_LNE_set_discriminator,
898
+ dbg,elfsectno,error);
899
+ sum_bytes += writelen;
900
+
901
+ /* Write the value itself. */
902
+ writelen = write_uval(curline->dpl_discriminator,
903
+ dbg,elfsectno,error);
904
+ sum_bytes += writelen;
905
+ }
906
+
907
+ addr_adv = curline->dpl_address - prevline->dpl_address;
908
+
909
+ line_adv = (int) (curline->dpl_line - prevline->dpl_line);
910
+ if ((addr_adv % MIN_INST_LENGTH) != 0) {
911
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_ADDRESS, -1);
912
+ }
913
+ opc = _dwarf_pro_get_opc(dbg,addr_adv, line_adv);
914
+ if (opc > 0) {
915
+ /* Use special opcode. */
916
+ no_lns_copy = 1;
917
+ writelen = write_ubyte(opc,dbg,elfsectno,error);
918
+ sum_bytes += writelen;
919
+ prevline->dpl_basic_block = false;
920
+ prevline->dpl_address = curline->dpl_address;
921
+ prevline->dpl_line = curline->dpl_line;
922
+ } else {
923
+ /* opc says use standard opcodes. */
924
+ if (addr_adv > 0) {
925
+ db = DW_LNS_advance_pc;
926
+ writelen = write_opcode_uval(db,dbg,
927
+ elfsectno,
928
+ addr_adv/
929
+ dbg->de_line_inits.pi_minimum_instruction_length,
930
+ error);
931
+ sum_bytes += writelen;
932
+ prevline->dpl_basic_block = false;
933
+ prevline->dpl_address = curline->dpl_address;
934
+ }
935
+ if (line_adv != 0) {
936
+ db = DW_LNS_advance_line;
937
+ writelen = write_ubyte(db,dbg,
938
+ elfsectno,
939
+ error);
940
+ sum_bytes += writelen;
941
+ writelen = write_sval(line_adv,dbg,
942
+ elfsectno,
943
+ error);
944
+ sum_bytes += writelen;
945
+ prevline->dpl_basic_block = false;
946
+ prevline->dpl_line = curline->dpl_line;
947
+ }
948
+ }
949
+ } /* ends else for opc <= 0 */
950
+ if (no_lns_copy == 0) { /* if not a special or dw_lne_end_seq
951
+ generate a matrix line */
952
+ unsigned writelen = 0;
953
+ writelen = write_ubyte(DW_LNS_copy,dbg,elfsectno,error);
954
+ sum_bytes += writelen;
955
+ prevline->dpl_basic_block = false;
956
+ }
957
+ curline = curline->dpl_next;
958
+ }
959
+
960
+ /* write total length field */
961
+ du = sum_bytes - BEGIN_LEN_SIZE;
962
+ {
963
+ start_line_sec += extension_size;
964
+ WRITE_UNALIGNED(dbg, (void *) start_line_sec,
965
+ (const void *) &du, sizeof(du), uwordb_size);
966
+ }
967
+
968
+ return (int) dbg->de_n_debug_sect;
969
+ }
970
+
971
+ /*
972
+ Generate debug_frame section */
973
+ static int
974
+ _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error)
975
+ {
976
+ int elfsectno = 0;
977
+ int i = 0;
978
+ int firsttime = 1;
979
+ Dwarf_P_Cie curcie = 0;
980
+ Dwarf_P_Fde curfde = 0;
981
+ unsigned char *data = 0;
982
+ Dwarf_sfixed dsw = 0;
983
+ Dwarf_Unsigned du = 0;
984
+ Dwarf_Ubyte db = 0;
985
+ long *cie_offs = 0; /* Holds byte offsets for links to fde's */
986
+ unsigned long cie_length = 0;
987
+ int cie_no = 0;
988
+ int uwordb_size = dbg->de_offset_size;
989
+ int extension_size = dbg->de_64bit_extension ? 4 : 0;
990
+ int upointer_size = dbg->de_pointer_size;
991
+ Dwarf_Unsigned cur_off = 0; /* current offset of written data, held
992
+ for relocation info */
993
+
994
+ elfsectno = dbg->de_elf_sects[DEBUG_FRAME];
995
+
996
+ curcie = dbg->de_frame_cies;
997
+ cie_length = 0;
998
+ cur_off = 0;
999
+ cie_offs = (long *)
1000
+ _dwarf_p_get_alloc(dbg, sizeof(long) * dbg->de_n_cie);
1001
+ if (cie_offs == NULL) {
1002
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
1003
+ }
1004
+ /* Generate cie number as we go along. This writes
1005
+ all CIEs first before any FDEs, which is rather
1006
+ different from the order a compiler might like (which
1007
+ might be each CIE followed by its FDEs then the next CIE, and
1008
+ so on). */
1009
+ cie_no = 1;
1010
+ while (curcie) {
1011
+ char *code_al = 0;
1012
+ int c_bytes = 0;
1013
+ char *data_al = 0;
1014
+ int d_bytes = 0;
1015
+ int pad = 0; /* Pad for padding to align cies and fdes */
1016
+ int res = 0;
1017
+ char buff1[ENCODE_SPACE_NEEDED];
1018
+ char buff2[ENCODE_SPACE_NEEDED];
1019
+ char buff3[ENCODE_SPACE_NEEDED];
1020
+ char *augmentation = 0;
1021
+ char *augmented_al = 0;
1022
+ long augmented_fields_length = 0;
1023
+ int a_bytes = 0;
1024
+
1025
+ res = _dwarf_pro_encode_leb128_nm(curcie->cie_code_align,
1026
+ &c_bytes,
1027
+ buff1, sizeof(buff1));
1028
+ if (res != DW_DLV_OK) {
1029
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
1030
+ }
1031
+ /* Before April 1999, the following was using an unsigned
1032
+ encode. That worked ok even though the decoder used the
1033
+ correct signed leb read, but doing the encode correctly
1034
+ (according to the dwarf spec) saves space in the output file
1035
+ and is completely compatible.
1036
+
1037
+ Note the actual stored amount on MIPS was 10 bytes (!) to
1038
+ store the value -4. (hex)fc ffffffff ffffffff 01 The
1039
+ libdwarf consumer consumed all 10 bytes too!
1040
+
1041
+ old version res =
1042
+ _dwarf_pro_encode_leb128_nm(curcie->cie_data_align,
1043
+
1044
+ below is corrected signed version. */
1045
+ res = _dwarf_pro_encode_signed_leb128_nm(curcie->cie_data_align,
1046
+ &d_bytes,
1047
+ buff2, sizeof(buff2));
1048
+ if (res != DW_DLV_OK) {
1049
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
1050
+ }
1051
+ code_al = buff1;
1052
+ data_al = buff2;
1053
+
1054
+ /* get the correct offset */
1055
+ if (firsttime) {
1056
+ cie_offs[cie_no - 1] = 0;
1057
+ firsttime = 0;
1058
+ } else {
1059
+ cie_offs[cie_no - 1] = cie_offs[cie_no - 2] +
1060
+ (long) cie_length + BEGIN_LEN_SIZE;
1061
+ }
1062
+ cie_no++;
1063
+ augmentation = curcie->cie_aug;
1064
+ if (dbg->de_irix_exc_augmentation &&
1065
+ (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0)) {
1066
+ /* IRIX specific. */
1067
+ augmented_fields_length = 0;
1068
+ res = _dwarf_pro_encode_leb128_nm(augmented_fields_length,
1069
+ &a_bytes, buff3,
1070
+ sizeof(buff3));
1071
+ augmented_al = buff3;
1072
+ if (res != DW_DLV_OK) {
1073
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
1074
+ }
1075
+ cie_length = uwordb_size + /* cie_id */
1076
+ sizeof(Dwarf_Ubyte) + /* cie version */
1077
+ strlen(curcie->cie_aug) + 1 + /* augmentation */
1078
+ c_bytes + /* code alignment factor */
1079
+ d_bytes + /* data alignment factor */
1080
+ sizeof(Dwarf_Ubyte) + /* return reg address */
1081
+ a_bytes + /* augmentation length */
1082
+ curcie->cie_inst_bytes;
1083
+ } else {
1084
+ cie_length = uwordb_size + /* cie_id */
1085
+ sizeof(Dwarf_Ubyte) + /* cie version */
1086
+ strlen(curcie->cie_aug) + 1 + /* augmentation */
1087
+ c_bytes + d_bytes + sizeof(Dwarf_Ubyte) +
1088
+ /* return reg address */ curcie->cie_inst_bytes;
1089
+ }
1090
+ pad = (int) PADDING(cie_length, upointer_size);
1091
+ cie_length += pad;
1092
+ GET_CHUNK(dbg, elfsectno, data, cie_length +
1093
+ BEGIN_LEN_SIZE, error);
1094
+ if (extension_size) {
1095
+ Dwarf_Unsigned x = DISTINGUISHED_VALUE;
1096
+
1097
+ WRITE_UNALIGNED(dbg, (void *) data,
1098
+ (const void *) &x,
1099
+ sizeof(x), extension_size);
1100
+ data += extension_size;
1101
+
1102
+ }
1103
+ du = cie_length;
1104
+ /* total length of cie */
1105
+ WRITE_UNALIGNED(dbg, (void *) data,
1106
+ (const void *) &du, sizeof(du), uwordb_size);
1107
+ data += uwordb_size;
1108
+
1109
+ /* cie-id is a special value. */
1110
+ du = DW_CIE_ID;
1111
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
1112
+ sizeof(du), uwordb_size);
1113
+ data += uwordb_size;
1114
+
1115
+ db = curcie->cie_version;
1116
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1117
+ sizeof(db), sizeof(Dwarf_Ubyte));
1118
+ data += sizeof(Dwarf_Ubyte);
1119
+ strcpy((char *) data, curcie->cie_aug);
1120
+ data += strlen(curcie->cie_aug) + 1;
1121
+ memcpy((void *) data, (const void *) code_al, c_bytes);
1122
+ data += c_bytes;
1123
+ memcpy((void *) data, (const void *) data_al, d_bytes);
1124
+ data += d_bytes;
1125
+ db = curcie->cie_ret_reg;
1126
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1127
+ sizeof(db), sizeof(Dwarf_Ubyte));
1128
+ data += sizeof(Dwarf_Ubyte);
1129
+
1130
+ if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) {
1131
+ memcpy((void *) data, (const void *) augmented_al, a_bytes);
1132
+ data += a_bytes;
1133
+ }
1134
+ memcpy((void *) data, (const void *) curcie->cie_inst,
1135
+ curcie->cie_inst_bytes);
1136
+ data += curcie->cie_inst_bytes;
1137
+ for (i = 0; i < pad; i++) {
1138
+ *data = DW_CFA_nop;
1139
+ data++;
1140
+ }
1141
+ curcie = curcie->cie_next;
1142
+ }
1143
+ /* calculate current offset */
1144
+ cur_off = cie_offs[cie_no - 2] + cie_length + BEGIN_LEN_SIZE;
1145
+
1146
+ /* write out fde's */
1147
+ curfde = dbg->de_frame_fdes;
1148
+ while (curfde) {
1149
+ Dwarf_P_Frame_Pgm curinst = 0;
1150
+ long fde_length = 0;
1151
+ int pad2 = 0;
1152
+ Dwarf_P_Cie cie_ptr = 0;
1153
+ Dwarf_Word cie_index = 0;
1154
+ /* index is a global in string.h, so don't name anything index. */
1155
+ Dwarf_Word indx = 0;
1156
+ int oet_length = 0;
1157
+ int afl_length = 0;
1158
+ int res = 0;
1159
+ int v0_augmentation = 0;
1160
+ char afl_buff[ENCODE_SPACE_NEEDED];
1161
+
1162
+ /* Find the CIE associated with this fde. */
1163
+ cie_ptr = dbg->de_frame_cies;
1164
+ cie_index = curfde->fde_cie;
1165
+ indx = 1; /* The cie_index of the first cie is 1, not 0. */
1166
+ while (cie_ptr && indx < cie_index) {
1167
+ cie_ptr = cie_ptr->cie_next;
1168
+ indx++;
1169
+ }
1170
+ if (cie_ptr == NULL) {
1171
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_NULL, -1);
1172
+ }
1173
+
1174
+ if (strcmp(cie_ptr->cie_aug, DW_CIE_AUGMENTER_STRING_V0) == 0) {
1175
+ v0_augmentation = 1;
1176
+ oet_length = sizeof(Dwarf_sfixed);
1177
+ /* encode the length of augmented fields. */
1178
+ res = _dwarf_pro_encode_leb128_nm(oet_length,
1179
+ &afl_length, afl_buff,
1180
+ sizeof(afl_buff));
1181
+ if (res != DW_DLV_OK) {
1182
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
1183
+ }
1184
+
1185
+ fde_length = curfde->fde_n_bytes +
1186
+ BEGIN_LEN_SIZE + /* cie pointer */
1187
+ upointer_size + /* initial loc */
1188
+ upointer_size + /* address range */
1189
+ afl_length + /* augmented field length */
1190
+ oet_length; /* exception_table offset */
1191
+ } else {
1192
+ fde_length = curfde->fde_n_bytes + BEGIN_LEN_SIZE + /* cie
1193
+ pointer */
1194
+ upointer_size + /* initial loc */
1195
+ upointer_size; /* address range */
1196
+ }
1197
+
1198
+ if (curfde->fde_die) {
1199
+ /* IRIX/MIPS extension:
1200
+ Using fde offset, generate DW_AT_MIPS_fde attribute for the
1201
+ die corresponding to this fde. */
1202
+ if (_dwarf_pro_add_AT_fde(dbg, curfde->fde_die, cur_off,
1203
+ error) < 0) {
1204
+ return -1;
1205
+ }
1206
+ }
1207
+
1208
+ /* store relocation for cie pointer */
1209
+ res = dbg->de_reloc_name(dbg, DEBUG_FRAME, cur_off +
1210
+ BEGIN_LEN_SIZE /* r_offset */,
1211
+ dbg->de_sect_name_idx[DEBUG_FRAME],
1212
+ dwarf_drt_data_reloc, uwordb_size);
1213
+ if (res != DW_DLV_OK) {
1214
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
1215
+ }
1216
+
1217
+ /* store relocation information for initial location */
1218
+ res = dbg->de_reloc_name(dbg, DEBUG_FRAME,
1219
+ cur_off + BEGIN_LEN_SIZE +
1220
+ upointer_size /* r_offset */,
1221
+ curfde->fde_r_symidx,
1222
+ dwarf_drt_data_reloc, upointer_size);
1223
+ if (res != DW_DLV_OK) {
1224
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
1225
+ }
1226
+ /* Store the relocation information for the
1227
+ offset_into_exception_info field, if the offset is valid (0
1228
+ is a valid offset). */
1229
+ if (v0_augmentation &&
1230
+ curfde->fde_offset_into_exception_tables >= 0) {
1231
+
1232
+ res = dbg->de_reloc_name(dbg, DEBUG_FRAME,
1233
+ /* r_offset, where in cie this field starts */
1234
+ cur_off + BEGIN_LEN_SIZE +
1235
+ uwordb_size + 2 * upointer_size +
1236
+ afl_length,
1237
+ curfde->fde_exception_table_symbol,
1238
+ dwarf_drt_segment_rel,
1239
+ sizeof(Dwarf_sfixed));
1240
+ if (res != DW_DLV_OK) {
1241
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
1242
+ }
1243
+ }
1244
+
1245
+ /* adjust for padding */
1246
+ pad2 = (int) PADDING(fde_length, upointer_size);
1247
+ fde_length += pad2;
1248
+
1249
+
1250
+ /* write out fde */
1251
+ GET_CHUNK(dbg, elfsectno, data, fde_length + BEGIN_LEN_SIZE,
1252
+ error);
1253
+ du = fde_length;
1254
+ {
1255
+ if (extension_size) {
1256
+ Dwarf_Word x = DISTINGUISHED_VALUE;
1257
+
1258
+ WRITE_UNALIGNED(dbg, (void *) data,
1259
+ (const void *) &x,
1260
+ sizeof(x), extension_size);
1261
+ data += extension_size;
1262
+ }
1263
+ /* length */
1264
+ WRITE_UNALIGNED(dbg, (void *) data,
1265
+ (const void *) &du,
1266
+ sizeof(du), uwordb_size);
1267
+ data += uwordb_size;
1268
+
1269
+ /* offset to cie */
1270
+ du = cie_offs[curfde->fde_cie - 1];
1271
+ WRITE_UNALIGNED(dbg, (void *) data,
1272
+ (const void *) &du,
1273
+ sizeof(du), uwordb_size);
1274
+ data += uwordb_size;
1275
+
1276
+ du = curfde->fde_initloc;
1277
+ WRITE_UNALIGNED(dbg, (void *) data,
1278
+ (const void *) &du,
1279
+ sizeof(du), upointer_size);
1280
+ data += upointer_size;
1281
+
1282
+ if (dbg->de_reloc_pair &&
1283
+ curfde->fde_end_symbol != 0 &&
1284
+ curfde->fde_addr_range == 0) {
1285
+ /* symbolic reloc, need reloc for length What if we
1286
+ really know the length? If so, should use the other
1287
+ part of 'if'. */
1288
+ Dwarf_Unsigned val;
1289
+
1290
+ res = dbg->de_reloc_pair(dbg,
1291
+ /* DEBUG_ARANGES, */ DEBUG_FRAME,
1292
+ cur_off + 2 * uwordb_size + upointer_size,
1293
+ /* r_offset */ curfde->fde_r_symidx,
1294
+ curfde->fde_end_symbol,
1295
+ dwarf_drt_first_of_length_pair,
1296
+ upointer_size);
1297
+ if (res != DW_DLV_OK) {
1298
+ {
1299
+ _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1300
+ return (0);
1301
+ }
1302
+ }
1303
+
1304
+ /* arrange pre-calc so assem text can do .word end -
1305
+ begin + val (gets val from stream) */
1306
+ val = curfde->fde_end_symbol_offset -
1307
+ curfde->fde_initloc;
1308
+ WRITE_UNALIGNED(dbg, data,
1309
+ (const void *) &val,
1310
+ sizeof(val), upointer_size);
1311
+ data += upointer_size;
1312
+ } else {
1313
+
1314
+ du = curfde->fde_addr_range;
1315
+ WRITE_UNALIGNED(dbg, (void *) data,
1316
+ (const void *) &du,
1317
+ sizeof(du), upointer_size);
1318
+ data += upointer_size;
1319
+ }
1320
+ }
1321
+
1322
+ if (v0_augmentation) {
1323
+ /* write the encoded augmented field length. */
1324
+ memcpy((void *) data, (const void *) afl_buff, afl_length);
1325
+ data += afl_length;
1326
+ /* write the offset_into_exception_tables field. */
1327
+ dsw =
1328
+ (Dwarf_sfixed) curfde->fde_offset_into_exception_tables;
1329
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dsw,
1330
+ sizeof(dsw), sizeof(Dwarf_sfixed));
1331
+ data += sizeof(Dwarf_sfixed);
1332
+ }
1333
+
1334
+ curinst = curfde->fde_inst;
1335
+ if (curfde->fde_block) {
1336
+ unsigned long size = curfde->fde_inst_block_size;
1337
+ memcpy((void *) data, (const void *) curfde->fde_block, size);
1338
+ data += size;
1339
+ } else {
1340
+ while (curinst) {
1341
+ db = curinst->dfp_opcode;
1342
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1343
+ sizeof(db), sizeof(Dwarf_Ubyte));
1344
+ data += sizeof(Dwarf_Ubyte);
1345
+ memcpy((void *) data,
1346
+ (const void *) curinst->dfp_args,
1347
+ curinst->dfp_nbytes);
1348
+ data += curinst->dfp_nbytes;
1349
+ curinst = curinst->dfp_next;
1350
+ }
1351
+ }
1352
+ /* padding */
1353
+ for (i = 0; i < pad2; i++) {
1354
+ *data = DW_CFA_nop;
1355
+ data++;
1356
+ }
1357
+ cur_off += fde_length + uwordb_size;
1358
+ curfde = curfde->fde_next;
1359
+ }
1360
+
1361
+
1362
+ return (int) dbg->de_n_debug_sect;
1363
+ }
1364
+
1365
+ /*
1366
+ These functions remember all the markers we see along
1367
+ with the right offset in the .debug_info section so that
1368
+ we can dump them all back to the user with the section info.
1369
+ */
1370
+
1371
+ static int
1372
+ marker_init(Dwarf_P_Debug dbg,
1373
+ unsigned count)
1374
+ {
1375
+ dbg->de_marker_n_alloc = count;
1376
+ dbg->de_markers = NULL;
1377
+ if (count > 0) {
1378
+ dbg->de_markers = _dwarf_p_get_alloc(dbg,
1379
+ sizeof(struct Dwarf_P_Marker_s) * dbg->de_marker_n_alloc);
1380
+ if (dbg->de_markers == NULL) {
1381
+ dbg->de_marker_n_alloc = 0;
1382
+ return -1;
1383
+ }
1384
+ }
1385
+ return 0;
1386
+ }
1387
+
1388
+ static int
1389
+ marker_add(Dwarf_P_Debug dbg,
1390
+ Dwarf_Unsigned offset,
1391
+ Dwarf_Unsigned marker)
1392
+ {
1393
+ if (dbg->de_marker_n_alloc >= (dbg->de_marker_n_used + 1)) {
1394
+ unsigned n = dbg->de_marker_n_used++;
1395
+ dbg->de_markers[n].ma_offset = offset;
1396
+ dbg->de_markers[n].ma_marker = marker;
1397
+ return 0;
1398
+ }
1399
+
1400
+ return -1;
1401
+ }
1402
+
1403
+ Dwarf_Signed
1404
+ dwarf_get_die_markers(Dwarf_P_Debug dbg,
1405
+ Dwarf_P_Marker * marker_list, /* pointer to a pointer */
1406
+ Dwarf_Unsigned * marker_count,
1407
+ Dwarf_Error * error)
1408
+ {
1409
+ if (marker_list == NULL || marker_count == NULL) {
1410
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_BADADDR);
1411
+ }
1412
+ if (dbg->de_marker_n_used != dbg->de_marker_n_alloc) {
1413
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_BADADDR);
1414
+ }
1415
+
1416
+ *marker_list = dbg->de_markers;
1417
+ *marker_count = dbg->de_marker_n_used;
1418
+ return DW_DLV_OK;
1419
+ }
1420
+
1421
+ /* These functions provide the offsets of DW_FORM_string
1422
+ attributes in the section section_index. These information
1423
+ will enable a producer app that is generating assembly
1424
+ text output to easily emit those attributes in ascii form
1425
+ without having to decode the byte stream. */
1426
+ static int
1427
+ string_attr_init (Dwarf_P_Debug dbg,
1428
+ Dwarf_Signed section_index,
1429
+ unsigned count)
1430
+ {
1431
+ Dwarf_P_Per_Sect_String_Attrs sect_sa =
1432
+ &dbg->de_sect_string_attr[section_index];
1433
+
1434
+ sect_sa->sect_sa_n_alloc = count;
1435
+ sect_sa->sect_sa_list = NULL;
1436
+ if (count > 0) {
1437
+ sect_sa->sect_sa_section_number = section_index;
1438
+ sect_sa->sect_sa_list = _dwarf_p_get_alloc(dbg,
1439
+ sizeof(struct Dwarf_P_String_Attr_s) * sect_sa->sect_sa_n_alloc);
1440
+ if (sect_sa->sect_sa_list == NULL) {
1441
+ sect_sa->sect_sa_n_alloc = 0;
1442
+ return -1;
1443
+ }
1444
+ }
1445
+ return 0;
1446
+ }
1447
+
1448
+ static int
1449
+ string_attr_add (Dwarf_P_Debug dbg,
1450
+ Dwarf_Signed section_index,
1451
+ Dwarf_Unsigned offset,
1452
+ Dwarf_P_Attribute attr)
1453
+ {
1454
+ Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index];
1455
+ if (sect_sa->sect_sa_n_alloc >= (sect_sa->sect_sa_n_used + 1)) {
1456
+ unsigned n = sect_sa->sect_sa_n_used++;
1457
+ sect_sa->sect_sa_list[n].sa_offset = offset;
1458
+ sect_sa->sect_sa_list[n].sa_nbytes = attr->ar_nbytes;
1459
+ return 0;
1460
+ }
1461
+
1462
+ return -1;
1463
+ }
1464
+
1465
+ int
1466
+ dwarf_get_string_attributes_count(Dwarf_P_Debug dbg,
1467
+ Dwarf_Unsigned *
1468
+ count_of_sa_sections,
1469
+ int *drd_buffer_version,
1470
+ Dwarf_Error *error)
1471
+ {
1472
+ int i = 0;
1473
+ unsigned int count = 0;
1474
+
1475
+ for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) {
1476
+ if (dbg->de_sect_string_attr[i].sect_sa_n_used > 0) {
1477
+ ++count;
1478
+ }
1479
+ }
1480
+ *count_of_sa_sections = (Dwarf_Unsigned) count;
1481
+ *drd_buffer_version = DWARF_DRD_BUFFER_VERSION;
1482
+
1483
+ return DW_DLV_OK;
1484
+ }
1485
+
1486
+ int
1487
+ dwarf_get_string_attributes_info(Dwarf_P_Debug dbg,
1488
+ Dwarf_Signed *elf_section_index,
1489
+ Dwarf_Unsigned *sect_sa_buffer_count,
1490
+ Dwarf_P_String_Attr *sect_sa_buffer,
1491
+ Dwarf_Error *error)
1492
+ {
1493
+ int i = 0;
1494
+ int next = dbg->de_sect_sa_next_to_return;
1495
+
1496
+ for (i = next; i < NUM_DEBUG_SECTIONS; ++i) {
1497
+ Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[i];
1498
+ if (sect_sa->sect_sa_n_used > 0) {
1499
+ dbg->de_sect_sa_next_to_return = i + 1;
1500
+ *elf_section_index = sect_sa->sect_sa_section_number;
1501
+ *sect_sa_buffer_count = sect_sa->sect_sa_n_used;
1502
+ *sect_sa_buffer = sect_sa->sect_sa_list;
1503
+ return DW_DLV_OK;
1504
+ }
1505
+ }
1506
+ return DW_DLV_NO_ENTRY;
1507
+ }
1508
+
1509
+
1510
+ static int
1511
+ has_sibling_die_already(Dwarf_P_Die d)
1512
+ {
1513
+ Dwarf_P_Attribute a = 0;
1514
+ for(a = d->di_attrs; a ; a = a->ar_next) {
1515
+ if(a->ar_attribute == DW_AT_sibling) {
1516
+ return 1;
1517
+ }
1518
+ }
1519
+ return 0;
1520
+ }
1521
+
1522
+ /* Generate debug_info and debug_abbrev sections */
1523
+
1524
+ static int
1525
+ _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Error * error)
1526
+ {
1527
+ int elfsectno_of_debug_info = 0;
1528
+ int abbrevsectno = 0;
1529
+ unsigned char *data = 0;
1530
+ int cu_header_size = 0;
1531
+ Dwarf_P_Abbrev curabbrev = 0;
1532
+ Dwarf_P_Abbrev abbrev_head = 0;
1533
+ Dwarf_P_Abbrev abbrev_tail = 0;
1534
+ Dwarf_P_Die curdie = 0;
1535
+ Dwarf_P_Die first_child = 0;
1536
+ Dwarf_Word dw = 0;
1537
+ Dwarf_Unsigned du = 0;
1538
+ Dwarf_Half dh = 0;
1539
+ Dwarf_Ubyte db = 0;
1540
+ Dwarf_Half version = 0; /* Need 2 byte quantity. */
1541
+ Dwarf_Unsigned die_off = 0; /* Offset of die in debug_info. */
1542
+ int n_abbrevs = 0;
1543
+ int res = 0;
1544
+ unsigned marker_count = 0;
1545
+ unsigned string_attr_count = 0;
1546
+ unsigned string_attr_offset = 0;
1547
+
1548
+ Dwarf_Small *start_info_sec = 0;
1549
+
1550
+ int uwordb_size = dbg->de_offset_size;
1551
+ int extension_size = dbg->de_64bit_extension ? 4 : 0;
1552
+
1553
+ abbrev_head = abbrev_tail = NULL;
1554
+ elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO];
1555
+
1556
+ /* write cu header */
1557
+ cu_header_size = BEGIN_LEN_SIZE +
1558
+ sizeof(Dwarf_Half) + /* version stamp */
1559
+ uwordb_size + /* offset into abbrev table */
1560
+ sizeof(Dwarf_Ubyte); /* size of target address */
1561
+ GET_CHUNK(dbg, elfsectno_of_debug_info, data, cu_header_size,
1562
+ error);
1563
+ start_info_sec = data;
1564
+ if (extension_size) {
1565
+ du = DISTINGUISHED_VALUE;
1566
+ WRITE_UNALIGNED(dbg, (void *) data,
1567
+ (const void *) &du, sizeof(du), extension_size);
1568
+ data += extension_size;
1569
+ }
1570
+ du = 0; /* length of debug_info, not counting
1571
+ this field itself (unknown at this point). */
1572
+ WRITE_UNALIGNED(dbg, (void *) data,
1573
+ (const void *) &du, sizeof(du), uwordb_size);
1574
+ data += uwordb_size;
1575
+
1576
+ version = CURRENT_VERSION_STAMP;
1577
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &version,
1578
+ sizeof(version), sizeof(Dwarf_Half));
1579
+ data += sizeof(Dwarf_Half);
1580
+
1581
+ du = 0;/* offset into abbrev table, not yet known. */
1582
+ WRITE_UNALIGNED(dbg, (void *) data,
1583
+ (const void *) &du, sizeof(du), uwordb_size);
1584
+ data += uwordb_size;
1585
+
1586
+
1587
+ db = dbg->de_pointer_size;
1588
+
1589
+ WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1590
+ sizeof(db), 1);
1591
+
1592
+ /* We have filled the chunk we got with GET_CHUNK. At this point we
1593
+ no longer dare use "data" or "start_info_sec" as a pointer any
1594
+ longer except to refer to that first small chunk for the cu
1595
+ header. */
1596
+
1597
+ curdie = dbg->de_dies;
1598
+
1599
+ /* Create AT_macro_info if appropriate */
1600
+ if (dbg->de_first_macinfo != NULL) {
1601
+ if (_dwarf_pro_add_AT_macro_info(dbg, curdie, 0, error) < 0)
1602
+ return -1;
1603
+ }
1604
+
1605
+ /* Create AT_stmt_list attribute if necessary */
1606
+ if (dwarf_need_debug_line_section(dbg) == TRUE)
1607
+ if (_dwarf_pro_add_AT_stmt_list(dbg, curdie, error) < 0)
1608
+ return -1;
1609
+
1610
+ die_off = cu_header_size;
1611
+
1612
+ /* Relocation for abbrev offset in cu header store relocation
1613
+ record in linked list */
1614
+ res = dbg->de_reloc_name(dbg, DEBUG_INFO, BEGIN_LEN_SIZE +
1615
+ sizeof(Dwarf_Half),
1616
+ /* r_offset */
1617
+ dbg->de_sect_name_idx[DEBUG_ABBREV],
1618
+ dwarf_drt_data_reloc, uwordb_size);
1619
+ if (res != DW_DLV_OK) {
1620
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
1621
+ }
1622
+
1623
+ /* Pass 0: only top level dies, add at_sibling attribute to those
1624
+ dies with children, but if and only if
1625
+ there is no sibling attribute already. */
1626
+ first_child = curdie->di_child;
1627
+ while (first_child && first_child->di_right) {
1628
+ if (first_child->di_child) {
1629
+ if (!has_sibling_die_already(first_child)) {
1630
+ dwarf_add_AT_reference(dbg,
1631
+ first_child,
1632
+ DW_AT_sibling,
1633
+ first_child->di_right, error);
1634
+ }
1635
+ }
1636
+ first_child = first_child->di_right;
1637
+ }
1638
+
1639
+ /* Pass 1: create abbrev info, get die offsets, calc relocations */
1640
+ marker_count = 0;
1641
+ string_attr_count = 0;
1642
+ while (curdie != NULL) {
1643
+ int nbytes = 0;
1644
+ Dwarf_P_Attribute curattr = 0;
1645
+ Dwarf_P_Attribute new_first_attr = 0;
1646
+ Dwarf_P_Attribute new_last_attr = 0;
1647
+ char *space = 0;
1648
+ int cres = 0;
1649
+ char buff1[ENCODE_SPACE_NEEDED];
1650
+ int i = 0;
1651
+
1652
+ curdie->di_offset = die_off;
1653
+
1654
+ if (curdie->di_marker != 0)
1655
+ marker_count++;
1656
+
1657
+ curabbrev = _dwarf_pro_getabbrev(curdie, abbrev_head);
1658
+ if (curabbrev == NULL) {
1659
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1660
+ }
1661
+ if (abbrev_head == NULL) {
1662
+ n_abbrevs = 1;
1663
+ curabbrev->abb_idx = n_abbrevs;
1664
+ abbrev_tail = abbrev_head = curabbrev;
1665
+ } else {
1666
+ /* Check if it is a new abbreviation, if yes, add to tail */
1667
+ if (curabbrev->abb_idx == 0) {
1668
+ n_abbrevs++;
1669
+ curabbrev->abb_idx = n_abbrevs;
1670
+ abbrev_tail->abb_next = curabbrev;
1671
+ abbrev_tail = curabbrev;
1672
+ }
1673
+ }
1674
+ cres = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx,
1675
+ &nbytes,
1676
+ buff1, sizeof(buff1));
1677
+ if (cres != DW_DLV_OK) {
1678
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1679
+ }
1680
+ space = _dwarf_p_get_alloc(dbg, nbytes);
1681
+ if (space == NULL) {
1682
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1683
+ }
1684
+ memcpy(space, buff1, nbytes);
1685
+ curdie->di_abbrev = space;
1686
+ curdie->di_abbrev_nbytes = nbytes;
1687
+ die_off += nbytes;
1688
+
1689
+ /* Resorting the attributes!! */
1690
+ new_first_attr = new_last_attr = NULL;
1691
+ curattr = curdie->di_attrs;
1692
+ for (i = 0; i < (int)curabbrev->abb_n_attr; i++) {
1693
+ Dwarf_P_Attribute cur = 0;
1694
+ Dwarf_P_Attribute lastattr = 0;
1695
+
1696
+ /* The following should always find an attribute!
1697
+ It starts from the beginning of the remaining list
1698
+ of attributes on the DIE.*/
1699
+ for (cur = lastattr = curattr;
1700
+ cur && (curabbrev->abb_attrs[i] != cur->ar_attribute);
1701
+ lastattr = cur, cur = cur->ar_next)
1702
+ {
1703
+ }
1704
+
1705
+ if (!cur) {
1706
+ /* This will trip with an error if, somehow, one has
1707
+ managed to erroneously have multiple of
1708
+ a given attribute number in a single DIE. */
1709
+ DWARF_P_DBG_ERROR(dbg,DW_DLE_ABBREV_ALLOC, -1);
1710
+ }
1711
+
1712
+ /* Remove the attribute from the old list, we
1713
+ will place it on the new list. */
1714
+ if (cur == curattr) {
1715
+ curattr = cur->ar_next;
1716
+ } else {
1717
+ lastattr->ar_next = cur->ar_next;
1718
+ }
1719
+
1720
+ cur->ar_next = NULL;
1721
+
1722
+ /* Add the attribute'cur' to the new list. */
1723
+ if (new_first_attr == NULL) {
1724
+ new_first_attr = new_last_attr = cur;
1725
+ } else {
1726
+ new_last_attr->ar_next = cur;
1727
+ new_last_attr = cur;
1728
+ }
1729
+ }
1730
+
1731
+ /* Now we attach the attributes list to the die. */
1732
+ curdie->di_attrs = new_first_attr;
1733
+ curattr = curdie->di_attrs;
1734
+
1735
+ while (curattr) {
1736
+ if (curattr->ar_rel_type != R_MIPS_NONE) {
1737
+ int rres=0;
1738
+ switch (curattr->ar_attribute) {
1739
+ case DW_AT_stmt_list:
1740
+ curattr->ar_rel_symidx =
1741
+ dbg->de_sect_name_idx[DEBUG_LINE];
1742
+ break;
1743
+ case DW_AT_MIPS_fde:
1744
+ curattr->ar_rel_symidx =
1745
+ dbg->de_sect_name_idx[DEBUG_FRAME];
1746
+ break;
1747
+ case DW_AT_macro_info:
1748
+ curattr->ar_rel_symidx =
1749
+ dbg->de_sect_name_idx[DEBUG_MACINFO];
1750
+ break;
1751
+ default:
1752
+ break;
1753
+ }
1754
+ rres = dbg->de_reloc_name(dbg, DEBUG_INFO,
1755
+ die_off + curattr->ar_rel_offset,/* r_offset */
1756
+ curattr->ar_rel_symidx,
1757
+ dwarf_drt_data_reloc,
1758
+ curattr->ar_reloc_len);
1759
+
1760
+ if (rres != DW_DLV_OK) {
1761
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
1762
+ }
1763
+
1764
+ }
1765
+ if (curattr->ar_attribute_form == DW_FORM_string) {
1766
+ string_attr_count++;
1767
+ }
1768
+ die_off += curattr->ar_nbytes;
1769
+ curattr = curattr->ar_next;
1770
+ }
1771
+
1772
+ /* depth first search */
1773
+ if (curdie->di_child)
1774
+ curdie = curdie->di_child;
1775
+ else {
1776
+ while (curdie != NULL && curdie->di_right == NULL) {
1777
+ curdie = curdie->di_parent;
1778
+ die_off++; /* since we are writing a null die at
1779
+ the end of each sibling chain */
1780
+ }
1781
+ if (curdie != NULL)
1782
+ curdie = curdie->di_right;
1783
+ }
1784
+
1785
+ } /* end while (curdie != NULL) */
1786
+
1787
+ res = marker_init(dbg, marker_count);
1788
+ if (res == -1) {
1789
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
1790
+ }
1791
+ res = string_attr_init(dbg, DEBUG_INFO, string_attr_count);
1792
+ if (res == -1) {
1793
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
1794
+ }
1795
+
1796
+ /* Pass 2: Write out the die information Here 'data' is a
1797
+ temporary, one block for each GET_CHUNK. 'data' is overused. */
1798
+ curdie = dbg->de_dies;
1799
+ while (curdie != NULL) {
1800
+ Dwarf_P_Attribute curattr;
1801
+
1802
+ if (curdie->di_marker != 0) {
1803
+ res = marker_add(dbg, curdie->di_offset, curdie->di_marker);
1804
+ if (res == -1) {
1805
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
1806
+ }
1807
+ }
1808
+
1809
+ /* Index to abbreviation table */
1810
+ GET_CHUNK(dbg, elfsectno_of_debug_info,
1811
+ data, curdie->di_abbrev_nbytes, error);
1812
+
1813
+ memcpy((void *) data,
1814
+ (const void *) curdie->di_abbrev,
1815
+ curdie->di_abbrev_nbytes);
1816
+
1817
+ /* Attribute values - need to fill in all form attributes */
1818
+ curattr = curdie->di_attrs;
1819
+ string_attr_offset = curdie->di_offset + curdie->di_abbrev_nbytes;
1820
+
1821
+ while (curattr) {
1822
+ GET_CHUNK(dbg, elfsectno_of_debug_info, data,
1823
+ (unsigned long) curattr->ar_nbytes, error);
1824
+ switch (curattr->ar_attribute_form) {
1825
+ case DW_FORM_ref1:
1826
+ {
1827
+ if (curattr->ar_ref_die->di_offset >
1828
+ (unsigned) 0xff) {
1829
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1);
1830
+ }
1831
+ db = curattr->ar_ref_die->di_offset;
1832
+ WRITE_UNALIGNED(dbg, (void *) data,
1833
+ (const void *) &db,
1834
+ sizeof(db), sizeof(Dwarf_Ubyte));
1835
+ break;
1836
+ }
1837
+ case DW_FORM_ref2:
1838
+ {
1839
+ if (curattr->ar_ref_die->di_offset >
1840
+ (unsigned) 0xffff) {
1841
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1);
1842
+ }
1843
+ dh = curattr->ar_ref_die->di_offset;
1844
+ WRITE_UNALIGNED(dbg, (void *) data,
1845
+ (const void *) &dh,
1846
+ sizeof(dh), sizeof(Dwarf_Half));
1847
+ break;
1848
+ }
1849
+ case DW_FORM_ref_addr:
1850
+ {
1851
+ /* curattr->ar_ref_die == NULL!
1852
+
1853
+ DW_FORM_ref_addr doesn't take a CU-offset.
1854
+ This is different than other refs.
1855
+ This value will be set by the user of the
1856
+ producer library using a relocation.
1857
+ No need to set a value here. */
1858
+ break;
1859
+
1860
+ }
1861
+ case DW_FORM_ref4:
1862
+ {
1863
+ if (curattr->ar_ref_die->di_offset >
1864
+ (unsigned) 0xffffffff) {
1865
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1);
1866
+ }
1867
+ dw = (Dwarf_Word) curattr->ar_ref_die->di_offset;
1868
+ WRITE_UNALIGNED(dbg, (void *) data,
1869
+ (const void *) &dw,
1870
+ sizeof(dw), sizeof(Dwarf_ufixed));
1871
+ break;
1872
+ }
1873
+ case DW_FORM_ref8:
1874
+ du = curattr->ar_ref_die->di_offset;
1875
+ WRITE_UNALIGNED(dbg, (void *) data,
1876
+ (const void *) &du,
1877
+ sizeof(du), sizeof(Dwarf_Unsigned));
1878
+ break;
1879
+ case DW_FORM_ref_udata:
1880
+ { /* unsigned leb128 offset */
1881
+
1882
+ int nbytes;
1883
+ char buff1[ENCODE_SPACE_NEEDED];
1884
+
1885
+ res =
1886
+ _dwarf_pro_encode_leb128_nm(curattr->
1887
+ ar_ref_die->
1888
+ di_offset, &nbytes,
1889
+ buff1,
1890
+ sizeof(buff1));
1891
+ if (res != DW_DLV_OK) {
1892
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1893
+ }
1894
+
1895
+ memcpy(data, buff1, nbytes);
1896
+ break;
1897
+ }
1898
+ default:
1899
+ memcpy((void *) data,
1900
+ (const void *) curattr->ar_data,
1901
+ curattr->ar_nbytes);
1902
+ break;
1903
+ }
1904
+ if (curattr->ar_attribute_form == DW_FORM_string) {
1905
+ string_attr_add(dbg, DEBUG_INFO, string_attr_offset, curattr);
1906
+ }
1907
+ string_attr_offset += curattr->ar_nbytes;
1908
+ curattr = curattr->ar_next;
1909
+ }
1910
+
1911
+ /* depth first search */
1912
+ if (curdie->di_child)
1913
+ curdie = curdie->di_child;
1914
+ else {
1915
+ while (curdie != NULL && curdie->di_right == NULL) {
1916
+ GET_CHUNK(dbg, elfsectno_of_debug_info, data, 1, error);
1917
+ *data = '\0';
1918
+ curdie = curdie->di_parent;
1919
+ }
1920
+ if (curdie != NULL)
1921
+ curdie = curdie->di_right;
1922
+ }
1923
+ } /* end while (curdir != NULL) */
1924
+
1925
+ /* Write out debug_info size */
1926
+ /* Do not include length field or extension bytes */
1927
+ du = die_off - BEGIN_LEN_SIZE;
1928
+ WRITE_UNALIGNED(dbg, (void *) (start_info_sec + extension_size),
1929
+ (const void *) &du, sizeof(du), uwordb_size);
1930
+
1931
+
1932
+ data = 0; /* Emphasise not usable now */
1933
+
1934
+ /* Write out debug_abbrev section */
1935
+ abbrevsectno = dbg->de_elf_sects[DEBUG_ABBREV];
1936
+
1937
+ curabbrev = abbrev_head;
1938
+ while (curabbrev) {
1939
+ int idx = 0;
1940
+
1941
+ write_uval(curabbrev->abb_idx,dbg,abbrevsectno,error);
1942
+ write_uval(curabbrev->abb_tag,dbg,abbrevsectno,error);
1943
+
1944
+ db = curabbrev->abb_children;
1945
+ write_ubyte(db,dbg,abbrevsectno,error);
1946
+
1947
+ /* add attributes and forms */
1948
+ for (idx = 0; idx < curabbrev->abb_n_attr; idx++) {
1949
+ write_uval(curabbrev->abb_attrs[idx],
1950
+ dbg,abbrevsectno,error);
1951
+
1952
+ write_uval(curabbrev->abb_forms[idx],
1953
+ dbg,abbrevsectno,error);
1954
+ }
1955
+ /* Two zeros, for last entry, see dwarf2 sec 7.5.3 */
1956
+ GET_CHUNK(dbg, abbrevsectno, data, 2, error);
1957
+ *data = 0;
1958
+ data++;
1959
+ *data = 0;
1960
+
1961
+ curabbrev = curabbrev->abb_next;
1962
+ }
1963
+
1964
+ /* one zero, for end of cu, see dwarf2 sec 7.5.3 */
1965
+ GET_CHUNK(dbg, abbrevsectno, data, 1, error);
1966
+ *data = 0;
1967
+ return (int) dbg->de_n_debug_sect;
1968
+ }
1969
+
1970
+
1971
+ /* Get a buffer of section data.
1972
+ section_idx is the elf-section number that this data applies to.
1973
+ length shows length of returned data */
1974
+
1975
+ /*ARGSUSED*/ /* pretend all args used */
1976
+ Dwarf_Ptr
1977
+ dwarf_get_section_bytes(Dwarf_P_Debug dbg,
1978
+ Dwarf_Signed dwarf_section,
1979
+ Dwarf_Signed * section_idx,
1980
+ Dwarf_Unsigned * length, Dwarf_Error * error)
1981
+ {
1982
+ Dwarf_Ptr buf = 0;
1983
+
1984
+ if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) {
1985
+ DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, NULL);
1986
+ }
1987
+
1988
+ if (dbg->de_debug_sects == 0) {
1989
+ /* no more data !! */
1990
+ return NULL;
1991
+ }
1992
+ if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) {
1993
+ /* no data ever entered !! */
1994
+ return NULL;
1995
+ }
1996
+ *section_idx = dbg->de_debug_sects->ds_elf_sect_no;
1997
+ *length = dbg->de_debug_sects->ds_nbytes;
1998
+
1999
+ buf = (Dwarf_Ptr *) dbg->de_debug_sects->ds_data;
2000
+
2001
+ dbg->de_debug_sects = dbg->de_debug_sects->ds_next;
2002
+
2003
+ /* We may want to call the section stuff more than once: see
2004
+ dwarf_reset_section_bytes() do not do: dbg->de_n_debug_sect--; */
2005
+
2006
+ return buf;
2007
+ }
2008
+
2009
+ /* No errors possible. */
2010
+ void
2011
+ dwarf_reset_section_bytes(Dwarf_P_Debug dbg)
2012
+ {
2013
+ dbg->de_debug_sects = dbg->de_first_debug_sect;
2014
+ /* No need to reset; commented out decrement. dbg->de_n_debug_sect
2015
+ = ???; */
2016
+ dbg->de_reloc_next_to_return = 0;
2017
+ dbg->de_sect_sa_next_to_return = 0;
2018
+ }
2019
+
2020
+ /* Storage handler. Gets either a new chunk of memory, or
2021
+ a pointer in existing memory, from the linked list attached
2022
+ to dbg at de_debug_sects, depending on size of nbytes
2023
+
2024
+ Assume dbg not null, checked in top level routine
2025
+
2026
+ Returns a pointer to the allocated buffer space for the
2027
+ lib to fill in, predincrements next-to-use count so the
2028
+ space requested is already counted 'used'
2029
+ when this returns (ie, reserved).
2030
+
2031
+ */
2032
+ Dwarf_Small *
2033
+ _dwarf_pro_buffer(Dwarf_P_Debug dbg,
2034
+ int elfsectno, unsigned long nbytes)
2035
+ {
2036
+ Dwarf_P_Section_Data cursect = 0;
2037
+
2038
+ cursect = dbg->de_current_active_section;
2039
+ /* By using MAGIC_SECT_NO we allow the following MAGIC_SECT_NO must
2040
+ not match any legit section number. test to have just two
2041
+ clauses (no NULL pointer test) See dwarf_producer_init(). */
2042
+ if ((cursect->ds_elf_sect_no != elfsectno) ||
2043
+ ((cursect->ds_nbytes + nbytes) > cursect->ds_orig_alloc)
2044
+ ) {
2045
+
2046
+ /* Either the elf section has changed or there is not enough
2047
+ space in the current section.
2048
+
2049
+ Create a new Dwarf_P_Section_Data_s for the chunk. and have
2050
+ space 'on the end' for the buffer itself so we just do one
2051
+ malloc (not two). */
2052
+ unsigned long space = nbytes;
2053
+
2054
+ if (nbytes < CHUNK_SIZE)
2055
+ space = CHUNK_SIZE;
2056
+
2057
+ cursect = (Dwarf_P_Section_Data)
2058
+ _dwarf_p_get_alloc(dbg,
2059
+ sizeof(struct Dwarf_P_Section_Data_s)
2060
+ + space);
2061
+ if (cursect == NULL) {
2062
+ return (NULL);
2063
+ }
2064
+
2065
+ /* _dwarf_p_get_alloc zeroes the space... */
2066
+
2067
+ cursect->ds_data = (char *) cursect +
2068
+ sizeof(struct Dwarf_P_Section_Data_s);
2069
+ cursect->ds_orig_alloc = space;
2070
+ cursect->ds_elf_sect_no = elfsectno;
2071
+ cursect->ds_nbytes = nbytes; /* reserve this number of bytes
2072
+ of space for caller to fill in */
2073
+ /* Now link on the end of the list, and mark this one as the
2074
+ current one */
2075
+
2076
+ if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) {
2077
+ /* The only entry is the special one for 'no entry' so
2078
+ delete that phony one while adding this initial real
2079
+ one. */
2080
+ dbg->de_debug_sects = cursect;
2081
+ dbg->de_current_active_section = cursect;
2082
+ dbg->de_first_debug_sect = cursect;
2083
+ } else {
2084
+ dbg->de_current_active_section->ds_next = cursect;
2085
+ dbg->de_current_active_section = cursect;
2086
+ }
2087
+ dbg->de_n_debug_sect++;
2088
+
2089
+ return ((Dwarf_Small *) cursect->ds_data);
2090
+ }
2091
+
2092
+ /* There is enough space in the current buffer */
2093
+ {
2094
+ Dwarf_Small *space_for_caller = (Dwarf_Small *)
2095
+ (cursect->ds_data + cursect->ds_nbytes);
2096
+
2097
+ cursect->ds_nbytes += nbytes;
2098
+ return space_for_caller;
2099
+ }
2100
+ }
2101
+
2102
+
2103
+ /* Given address advance and line advance, it gives
2104
+ either special opcode, or a number < 0 */
2105
+ static int
2106
+ _dwarf_pro_get_opc(Dwarf_P_Debug dbg,Dwarf_Unsigned addr_adv, int line_adv)
2107
+ {
2108
+ int line_base = dbg->de_line_inits.pi_line_base;
2109
+ int line_range = dbg->de_line_inits.pi_line_range;
2110
+ Dwarf_Unsigned factored_adv = 0;
2111
+
2112
+ factored_adv = addr_adv / dbg->de_line_inits.pi_minimum_instruction_length;
2113
+ if (line_adv == 0 && factored_adv == 0) {
2114
+ return OPC_INCS_ZERO;
2115
+ }
2116
+ if (line_adv >= line_base && line_adv < line_base + line_range) {
2117
+ int opc = (line_adv - line_base) + (factored_adv * line_range) +
2118
+ dbg->de_line_inits.pi_opcode_base;
2119
+ if (opc > 255) {
2120
+ return OPC_OUT_OF_RANGE;
2121
+ }
2122
+ return opc;
2123
+ }
2124
+ return LINE_OUT_OF_RANGE;
2125
+ }
2126
+
2127
+ /* Handles abbreviations. It takes a die, searches through
2128
+ current list of abbreviations for matching one. If it
2129
+ finds one, it returns a pointer to the abbrev, and if it does not,
2130
+ it returns a new abbrev. It is up to the user of this function to
2131
+ link it up to the abbreviation head. If it is a new abbrev
2132
+ abb_idx has 0. */
2133
+ static Dwarf_P_Abbrev
2134
+ _dwarf_pro_getabbrev(Dwarf_P_Die die, Dwarf_P_Abbrev head)
2135
+ {
2136
+ Dwarf_P_Abbrev curabbrev;
2137
+ Dwarf_P_Attribute curattr;
2138
+ int res1;
2139
+ int nattrs;
2140
+ int match;
2141
+ Dwarf_ufixed *forms = 0;
2142
+ Dwarf_ufixed *attrs = 0;
2143
+
2144
+ curabbrev = head;
2145
+ while (curabbrev) {
2146
+ if ((die->di_tag == curabbrev->abb_tag) &&
2147
+ ((die->di_child != NULL &&
2148
+ curabbrev->abb_children == DW_CHILDREN_yes) ||
2149
+ (die->di_child == NULL &&
2150
+ curabbrev->abb_children == DW_CHILDREN_no)) &&
2151
+ (die->di_n_attr == curabbrev->abb_n_attr)) {
2152
+
2153
+ /* There is a chance of a match. */
2154
+ curattr = die->di_attrs;
2155
+ match = 1; /* Assume match found. */
2156
+ while (match && curattr) {
2157
+ res1 = _dwarf_pro_match_attr(curattr,
2158
+ curabbrev,
2159
+ (int) curabbrev->abb_n_attr);
2160
+ if (res1 == 0) {
2161
+ match = 0;
2162
+ }
2163
+ curattr = curattr->ar_next;
2164
+ }
2165
+ if (match == 1) {
2166
+ return curabbrev;
2167
+ }
2168
+ }
2169
+ curabbrev = curabbrev->abb_next;
2170
+ }
2171
+
2172
+ /* no match, create new abbreviation */
2173
+ if (die->di_n_attr != 0) {
2174
+ forms = (Dwarf_ufixed *)
2175
+ _dwarf_p_get_alloc(die->di_dbg,
2176
+ sizeof(Dwarf_ufixed) * die->di_n_attr);
2177
+ if (forms == NULL) {
2178
+ return NULL;
2179
+ }
2180
+ attrs = (Dwarf_ufixed *)
2181
+ _dwarf_p_get_alloc(die->di_dbg,
2182
+ sizeof(Dwarf_ufixed) * die->di_n_attr);
2183
+ if (attrs == NULL)
2184
+ return NULL;
2185
+ }
2186
+ nattrs = 0;
2187
+ curattr = die->di_attrs;
2188
+ while (curattr) {
2189
+ attrs[nattrs] = curattr->ar_attribute;
2190
+ forms[nattrs] = curattr->ar_attribute_form;
2191
+ nattrs++;
2192
+ curattr = curattr->ar_next;
2193
+ }
2194
+
2195
+ curabbrev = (Dwarf_P_Abbrev)
2196
+ _dwarf_p_get_alloc(die->di_dbg, sizeof(struct Dwarf_P_Abbrev_s));
2197
+ if (curabbrev == NULL) {
2198
+ return NULL;
2199
+ }
2200
+
2201
+ if (die->di_child == NULL) {
2202
+ curabbrev->abb_children = DW_CHILDREN_no;
2203
+ } else {
2204
+ curabbrev->abb_children = DW_CHILDREN_yes;
2205
+ }
2206
+ curabbrev->abb_tag = die->di_tag;
2207
+ curabbrev->abb_attrs = attrs;
2208
+ curabbrev->abb_forms = forms;
2209
+ curabbrev->abb_n_attr = die->di_n_attr;
2210
+ curabbrev->abb_idx = 0;
2211
+ curabbrev->abb_next = NULL;
2212
+
2213
+ return curabbrev;
2214
+ }
2215
+
2216
+ /* Tries to see if given attribute and form combination
2217
+ exists in the given abbreviation */
2218
+ static int
2219
+ _dwarf_pro_match_attr(Dwarf_P_Attribute attr,
2220
+ Dwarf_P_Abbrev abbrev, int no_attr)
2221
+ {
2222
+ int i;
2223
+ int found = 0;
2224
+
2225
+ for (i = 0; i < no_attr; i++) {
2226
+ if (attr->ar_attribute == abbrev->abb_attrs[i] &&
2227
+ attr->ar_attribute_form == abbrev->abb_forms[i]) {
2228
+ found = 1;
2229
+ break;
2230
+ }
2231
+ }
2232
+ return found;
2233
+ }