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 #ifdef HAVE_ELFACCESS_H
33 #include <elfaccess.h>
34 #endif
35 #include "pro_incl.h"
36 #include "pro_section.h"
37 #include "pro_types.h"
38
39
40 /*
41 This function adds another type name to the
42 list of type names for the given Dwarf_P_Debug.
43 It returns 0 on error, and 1 otherwise.
44 */
45 Dwarf_Unsigned
dwarf_add_typename(Dwarf_P_Debug dbg,Dwarf_P_Die die,char * type_name,Dwarf_Error * error)46 dwarf_add_typename(Dwarf_P_Debug dbg,
47 Dwarf_P_Die die,
48 char *type_name, Dwarf_Error * error)
49 {
50 return
51 _dwarf_add_simple_name_entry(dbg, die, type_name,
52 dwarf_snk_typename, error);
53 }
54
55 /*
56 The following is the generic 'add a simple name entry'
57 for any of the simple name sections.
58
59 See enum dwarf_sn_kind in pro_opaque.h
60
61 */
62 Dwarf_Unsigned
_dwarf_add_simple_name_entry(Dwarf_P_Debug dbg,Dwarf_P_Die die,char * entry_name,enum dwarf_sn_kind entrykind,Dwarf_Error * error)63 _dwarf_add_simple_name_entry(Dwarf_P_Debug dbg,
64 Dwarf_P_Die die,
65 char *entry_name,
66 enum dwarf_sn_kind entrykind,
67 Dwarf_Error * error)
68 {
69 Dwarf_P_Simple_nameentry nameentry;
70 Dwarf_P_Simple_name_header hdr;
71 char *name;
72 int uword_size;
73
74 if (dbg == NULL) {
75 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
76 return (0);
77 }
78
79 if (die == NULL) {
80 _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
81 return (0);
82 }
83
84
85 nameentry = (Dwarf_P_Simple_nameentry)
86 _dwarf_p_get_alloc(dbg,
87 sizeof(struct Dwarf_P_Simple_nameentry_s));
88 if (nameentry == NULL) {
89 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
90 return (0);
91 }
92
93 name = _dwarf_p_get_alloc(dbg, strlen(entry_name) + 1);
94 if (name == NULL) {
95 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
96 return (0);
97 }
98 strcpy(name, entry_name);
99
100 nameentry->sne_die = die;
101 nameentry->sne_name = name;
102 nameentry->sne_name_len = strlen(name);
103 uword_size = dbg->de_offset_size;
104
105 hdr = &dbg->de_simple_name_headers[entrykind];
106 if (hdr->sn_head == NULL)
107 hdr->sn_head = hdr->sn_tail = nameentry;
108 else {
109 hdr->sn_tail->sne_next = nameentry;
110 hdr->sn_tail = nameentry;
111 }
112 hdr->sn_count++;
113 hdr->sn_net_len += uword_size + nameentry->sne_name_len + 1;
114
115 return (1);
116 }
117
118
119
120 /*
121 _dwarf_transform_simplename_to_disk writes
122 ".rel.debug_pubnames",
123 ".rel.debug_funcnames", sgi extension
124 ".rel.debug_typenames", sgi extension
125 ".rel.debug_varnames", sgi extension
126 ".rel.debug_weaknames", sgi extension
127 to disk.
128 section_index indexes one of those sections.
129 entrykind is one of those 'kind's. */
130 int
_dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg,enum dwarf_sn_kind entrykind,int section_index,Dwarf_Signed * nbufs,Dwarf_Error * error)131 _dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg,
132 enum dwarf_sn_kind entrykind,
133 int section_index, /* in de_elf_sects etc */
134 Dwarf_Signed *nbufs,
135 Dwarf_Error * error)
136 {
137
138
139 /* Used to fill in 0. */
140 const Dwarf_Signed big_zero = 0;
141
142 /* Used to scan the section data buffers. */
143 Dwarf_P_Section_Data debug_sect;
144
145 Dwarf_Signed debug_info_size;
146
147 Dwarf_P_Simple_nameentry nameentry_original;
148 Dwarf_P_Simple_nameentry nameentry;
149 Dwarf_Small *stream_bytes;
150 Dwarf_Small *cur_stream_bytes_ptr;
151 Dwarf_Unsigned stream_bytes_count;
152 Dwarf_Unsigned adjusted_length; /* count excluding length field */
153
154
155 int uword_size = dbg->de_offset_size;
156 int extension_size = dbg->de_64bit_extension ? 4 : 0;
157
158 Dwarf_P_Simple_name_header hdr;
159
160
161 /* ***** BEGIN CODE ***** */
162
163 debug_info_size = 0;
164 for (debug_sect = dbg->de_debug_sects; debug_sect != NULL;
165 debug_sect = debug_sect->ds_next) {
166 /* We want the size of the .debug_info section for this CU
167 because the dwarf spec requires us to output it below so we
168 look for it specifically. */
169 if (debug_sect->ds_elf_sect_no == dbg->de_elf_sects[DEBUG_INFO]) {
170 debug_info_size += debug_sect->ds_nbytes;
171 }
172 }
173
174 hdr = &dbg->de_simple_name_headers[entrykind];
175 /* Size of the .debug_typenames (or similar) section header. */
176 stream_bytes_count = extension_size + uword_size + /* Size of
177 length field. */
178 sizeof(Dwarf_Half) + /* Size of version field. */
179 uword_size + /* Size of .debug_info offset. */
180 uword_size; /* Size of .debug_names. */
181
182
183
184 nameentry_original = hdr->sn_head;
185 nameentry = nameentry_original;
186 /* add in the content size */
187 stream_bytes_count += hdr->sn_net_len;
188
189 /* Size of the last 0 offset. */
190 stream_bytes_count += uword_size;
191
192 /* Now we know how long the entire section is */
193 GET_CHUNK(dbg, dbg->de_elf_sects[section_index],
194 stream_bytes, (unsigned long) stream_bytes_count, error);
195 if (stream_bytes == NULL) {
196 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
197 return DW_DLV_ERROR;
198 }
199 cur_stream_bytes_ptr = stream_bytes;
200
201 if (extension_size) {
202 Dwarf_Unsigned x = DISTINGUISHED_VALUE;
203
204 WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
205 (const void *) &x, sizeof(x), extension_size);
206 cur_stream_bytes_ptr += extension_size;
207
208 }
209 /* Write the adjusted length of .debug_*names section. */
210 adjusted_length = stream_bytes_count - uword_size - extension_size;
211 WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
212 (const void *) &adjusted_length,
213 sizeof(adjusted_length), uword_size);
214 cur_stream_bytes_ptr += uword_size;
215
216 /* Write the version as 2 bytes. */
217 {
218 Dwarf_Half verstamp = CURRENT_VERSION_STAMP;
219
220 WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
221 (const void *) &verstamp,
222 sizeof(verstamp), sizeof(Dwarf_Half));
223 cur_stream_bytes_ptr += sizeof(Dwarf_Half);
224 }
225
226 /* Write the offset of the compile-unit. */
227 WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
228 (const void *) &big_zero,
229 sizeof(big_zero), uword_size);
230 cur_stream_bytes_ptr += uword_size;
231
232 /* now create the relocation for the compile_unit offset */
233 {
234 int res = dbg->de_reloc_name(dbg,
235 section_index,
236 extension_size + uword_size +
237 sizeof(Dwarf_Half) /* r_offset */ ,
238 /* debug_info section name symbol */
239 dbg->de_sect_name_idx[DEBUG_INFO],
240 dwarf_drt_data_reloc,
241 uword_size);
242
243 if (res != DW_DLV_OK) {
244 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
245 return DW_DLV_ERROR;
246 }
247 }
248
249 /* Write the size of .debug_info section. */
250 WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
251 (const void *) &debug_info_size,
252 sizeof(debug_info_size), uword_size);
253 cur_stream_bytes_ptr += uword_size;
254
255
256 for (nameentry = nameentry_original;
257 nameentry != NULL; nameentry = nameentry->sne_next) {
258
259 /* Copy offset of die from start of compile-unit. */
260 WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
261 (const void *) &nameentry->sne_die->di_offset,
262 sizeof(nameentry->sne_die->di_offset),
263 uword_size);
264 cur_stream_bytes_ptr += uword_size;
265
266 /* Copy the type name. */
267 strcpy((char *) cur_stream_bytes_ptr, nameentry->sne_name);
268 cur_stream_bytes_ptr += nameentry->sne_name_len + 1;
269 }
270
271 WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
272 (const void *) &big_zero,
273 sizeof(big_zero), uword_size);
274 *nbufs = dbg->de_n_debug_sect;
275 return DW_DLV_OK;
276 }
277