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 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
26 Mountain View, CA 94043, or:
27
28 http://www.sgi.com
29
30 For further information regarding this notice, see:
31
32 http://oss.sgi.com/projects/GenInfo/NoticeExplan
33
34 */
35
36
37
38 #include "config.h"
39 #include "libdwarfdefs.h"
40 #include <stdio.h>
41 #include <string.h>
42 #include "pro_incl.h"
43 #include "pro_section.h"
44 #include "pro_macinfo.h"
45
46 /*
47 I don't much like the error strings this generates, since
48 like the rest of libdwarf they are simple strings with
49 no useful numbers in them. But that's not something I can
50 fix without more work than I have time for
51 right now. davea Nov 94.
52 */
53
54 /* these are gross overestimates of the number of
55 ** bytes needed to store a number in LEB form.
56 ** Just estimates, and since blocks are reasonable size,
57 ** the end-block waste is small.
58 ** Of course the waste is NOT present on disk.
59 */
60
61 #define COMMAND_LEN ENCODE_SPACE_NEEDED
62 #define LINE_LEN ENCODE_SPACE_NEEDED
63 #define BASE_MACINFO_MALLOC_LEN 2048
64
65 static int
libdwarf_compose_begin(Dwarf_P_Debug dbg,int code,size_t maxlen,int * compose_error_type)66 libdwarf_compose_begin(Dwarf_P_Debug dbg, int code,
67 size_t maxlen, int *compose_error_type)
68 {
69 unsigned char *nextchar;
70 struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
71
72 if (curblk == 0) {
73 struct dw_macinfo_block_s *newb;
74 size_t len;
75
76 /* initial allocation */
77 size_t blen = BASE_MACINFO_MALLOC_LEN;
78
79 if (blen < maxlen) {
80 blen = 2 * maxlen;
81 }
82 len = sizeof(struct dw_macinfo_block_s) + blen;
83 newb =
84 (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len);
85 if (!newb) {
86 *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL;
87 return DW_DLV_ERROR;
88 }
89 newb->mb_data =
90 (char *) newb + sizeof(struct dw_macinfo_block_s);
91 newb->mb_avail_len = blen;
92 newb->mb_used_len = 0;
93 newb->mb_macinfo_data_space_len = blen;
94 dbg->de_first_macinfo = newb;
95 dbg->de_current_macinfo = newb;
96 curblk = newb;
97 } else if (curblk->mb_avail_len < maxlen) {
98 struct dw_macinfo_block_s *newb;
99 size_t len;
100
101 /* no space left in block: allocate a new block */
102 size_t blen =
103 dbg->de_current_macinfo->mb_macinfo_data_space_len * 2;
104 if (blen < maxlen) {
105 blen = 2 * maxlen;
106 }
107 len = sizeof(struct dw_macinfo_block_s) + blen;
108 newb =
109 (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len);
110 if (!newb) {
111 *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL;
112 return DW_DLV_ERROR;
113 }
114 newb->mb_data =
115 (char *) newb + sizeof(struct dw_macinfo_block_s);
116 newb->mb_avail_len = blen;
117 newb->mb_used_len = 0;
118 newb->mb_macinfo_data_space_len = blen;
119 dbg->de_first_macinfo->mb_next = newb;
120 dbg->de_current_macinfo = newb;
121 curblk = newb;
122 }
123 /* now curblk has enough room */
124 dbg->de_compose_avail = curblk->mb_avail_len;
125 dbg->de_compose_used_len = curblk->mb_used_len;
126 nextchar =
127 (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len);
128 *nextchar = code;
129 dbg->de_compose_avail--;
130 ++dbg->de_compose_used_len;
131 return DW_DLV_OK;
132 }
133
134
135
136 static void
libdwarf_compose_add_string(Dwarf_P_Debug dbg,char * string,size_t len)137 libdwarf_compose_add_string(Dwarf_P_Debug dbg, char *string, size_t len)
138 {
139 struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
140 unsigned char *nextchar;
141
142 nextchar =
143 (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len);
144
145 len += 1; /* count the null terminator */
146
147 memcpy(nextchar, string, len);
148 dbg->de_compose_avail -= len;
149 dbg->de_compose_used_len += len;
150 return;
151
152 }
153 static int
libdwarf_compose_add_line(Dwarf_P_Debug dbg,Dwarf_Unsigned line,int * compose_error_type)154 libdwarf_compose_add_line(Dwarf_P_Debug dbg,
155 Dwarf_Unsigned line, int *compose_error_type)
156 {
157 struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
158 unsigned char *nextchar;
159 int res;
160 int nbytes;
161
162 nextchar =
163 (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len);
164
165 /* Put the created leb number directly into the macro buffer If
166 dbg->de_compose_avail is > INT_MAX this will not work as the
167 'int' will look negative to _dwarf_pro_encode_leb128_nm! */
168
169 res = _dwarf_pro_encode_leb128_nm(line, &nbytes,
170 (char *) nextchar,
171 (int) dbg->de_compose_avail);
172 if (res != DW_DLV_OK) {
173 *compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE;
174 return DW_DLV_ERROR;
175 }
176
177 dbg->de_compose_avail -= nbytes;
178 dbg->de_compose_used_len += nbytes;
179 return DW_DLV_OK;
180 }
181
182 /*
183 This function actually 'commits' the space used by the
184 preceeding calls.
185 */
186 static int
libdwarf_compose_complete(Dwarf_P_Debug dbg,int * compose_error_type)187 libdwarf_compose_complete(Dwarf_P_Debug dbg, int *compose_error_type)
188 {
189 struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
190
191 if (dbg->de_compose_used_len > curblk->mb_macinfo_data_space_len) {
192 *compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE;
193 return DW_DLV_ERROR;
194 }
195 curblk->mb_avail_len = dbg->de_compose_avail;
196 curblk->mb_used_len = dbg->de_compose_used_len;
197 return DW_DLV_OK;
198 }
199
200
201
202 int
dwarf_def_macro(Dwarf_P_Debug dbg,Dwarf_Unsigned line,char * macname,char * macvalue,Dwarf_Error * error)203 dwarf_def_macro(Dwarf_P_Debug dbg,
204 Dwarf_Unsigned line,
205 char *macname, char *macvalue, Dwarf_Error * error)
206 {
207 size_t len;
208 size_t len2;
209 size_t length_est;
210 int res;
211 int compose_error_type;
212
213 if (dbg == NULL) {
214 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
215 return (DW_DLV_ERROR);
216 }
217 if (macname == 0) {
218 _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
219 return (DW_DLV_ERROR);
220 }
221 len = strlen(macname) + 1;
222 if (len == 0) {
223 _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
224 return (DW_DLV_ERROR);
225 }
226 if (macvalue) {
227 len2 = strlen(macvalue) + 1;
228 } else {
229 len2 = 0;
230 }
231 length_est = COMMAND_LEN + LINE_LEN + len + len2 + 1; /* 1
232 for
233 space
234 character
235 we
236 add */
237 res = libdwarf_compose_begin(dbg, DW_MACINFO_define, length_est,
238 &compose_error_type);
239 if (res != DW_DLV_OK) {
240 _dwarf_p_error(NULL, error, compose_error_type);
241 return (DW_DLV_ERROR);
242 }
243 res = libdwarf_compose_add_line(dbg, line, &compose_error_type);
244 if (res != DW_DLV_OK) {
245 _dwarf_p_error(NULL, error, compose_error_type);
246 return (DW_DLV_ERROR);
247 }
248 libdwarf_compose_add_string(dbg, macname, len);
249 libdwarf_compose_add_string(dbg, " ", 1);
250 if (macvalue) {
251 libdwarf_compose_add_string(dbg, " ", 1);
252 libdwarf_compose_add_string(dbg, macvalue, len2);
253 }
254 res = libdwarf_compose_complete(dbg, &compose_error_type);
255 if (res != DW_DLV_OK) {
256 _dwarf_p_error(NULL, error, compose_error_type);
257 return (DW_DLV_ERROR);
258 }
259 return DW_DLV_OK;
260 }
261
262 int
dwarf_undef_macro(Dwarf_P_Debug dbg,Dwarf_Unsigned line,char * macname,Dwarf_Error * error)263 dwarf_undef_macro(Dwarf_P_Debug dbg,
264 Dwarf_Unsigned line,
265 char *macname, Dwarf_Error * error)
266 {
267
268 size_t len;
269 size_t length_est;
270 int res;
271 int compose_error_type;
272
273 if (dbg == NULL) {
274 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
275 return (DW_DLV_ERROR);
276 }
277 if (macname == 0) {
278 _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
279 return (DW_DLV_ERROR);
280 }
281 len = strlen(macname) + 1;
282 if (len == 0) {
283 _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
284 return (DW_DLV_ERROR);
285 }
286 length_est = COMMAND_LEN + LINE_LEN + len;
287 res = libdwarf_compose_begin(dbg, DW_MACINFO_undef, length_est,
288 &compose_error_type);
289 if (res != DW_DLV_OK) {
290 _dwarf_p_error(NULL, error, compose_error_type);
291 return (DW_DLV_ERROR);
292 }
293 res = libdwarf_compose_add_line(dbg, line, &compose_error_type);
294 if (res != DW_DLV_OK) {
295 _dwarf_p_error(NULL, error, compose_error_type);
296 return (DW_DLV_ERROR);
297 }
298 libdwarf_compose_add_string(dbg, macname, len);
299 res = libdwarf_compose_complete(dbg, &compose_error_type);
300 if (res != DW_DLV_OK) {
301 _dwarf_p_error(NULL, error, compose_error_type);
302 return (DW_DLV_ERROR);
303 }
304 return DW_DLV_OK;
305 }
306
307 int
dwarf_start_macro_file(Dwarf_P_Debug dbg,Dwarf_Unsigned fileindex,Dwarf_Unsigned linenumber,Dwarf_Error * error)308 dwarf_start_macro_file(Dwarf_P_Debug dbg,
309 Dwarf_Unsigned fileindex,
310 Dwarf_Unsigned linenumber, Dwarf_Error * error)
311 {
312 size_t length_est;
313 int res;
314 int compose_error_type;
315
316 if (dbg == NULL) {
317 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
318 return (DW_DLV_ERROR);
319 }
320 length_est = COMMAND_LEN + LINE_LEN + LINE_LEN;
321 res = libdwarf_compose_begin(dbg, DW_MACINFO_start_file, length_est,
322 &compose_error_type);
323 if (res != DW_DLV_OK) {
324 _dwarf_p_error(NULL, error, compose_error_type);
325 return (DW_DLV_ERROR);
326 }
327 res = libdwarf_compose_add_line(dbg, fileindex,
328 &compose_error_type);
329 if (res != DW_DLV_OK) {
330 _dwarf_p_error(NULL, error, compose_error_type);
331 return (DW_DLV_ERROR);
332 }
333 res = libdwarf_compose_add_line(dbg, linenumber,
334 &compose_error_type);
335 if (res != DW_DLV_OK) {
336 _dwarf_p_error(NULL, error, compose_error_type);
337 return (DW_DLV_ERROR);
338 }
339 return DW_DLV_OK;
340 }
341
342 int
dwarf_end_macro_file(Dwarf_P_Debug dbg,Dwarf_Error * error)343 dwarf_end_macro_file(Dwarf_P_Debug dbg, Dwarf_Error * error)
344 {
345 size_t length_est;
346 int res;
347 int compose_error_type;
348
349 if (dbg == NULL) {
350 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
351 return (DW_DLV_ERROR);
352 }
353 length_est = COMMAND_LEN;
354 res = libdwarf_compose_begin(dbg, DW_MACINFO_end_file, length_est,
355 &compose_error_type);
356 if (res != DW_DLV_OK) {
357 _dwarf_p_error(NULL, error, compose_error_type);
358 return (DW_DLV_ERROR);
359 }
360 res = libdwarf_compose_complete(dbg, &compose_error_type);
361 if (res != DW_DLV_OK) {
362 _dwarf_p_error(NULL, error, compose_error_type);
363 return (DW_DLV_ERROR);
364 }
365 return DW_DLV_OK;
366 }
367
368 int
dwarf_vendor_ext(Dwarf_P_Debug dbg,Dwarf_Unsigned constant,char * string,Dwarf_Error * error)369 dwarf_vendor_ext(Dwarf_P_Debug dbg,
370 Dwarf_Unsigned constant,
371 char *string, Dwarf_Error * error)
372 {
373 size_t len;
374 size_t length_est;
375 int res;
376 int compose_error_type;
377
378 if (dbg == NULL) {
379 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
380 return (DW_DLV_ERROR);
381 }
382 if (string == 0) {
383 _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
384 return (DW_DLV_ERROR);
385 }
386 len = strlen(string) + 1;
387 if (len == 0) {
388 _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
389 return (DW_DLV_ERROR);
390 }
391 length_est = COMMAND_LEN + LINE_LEN + len;
392 res = libdwarf_compose_begin(dbg, DW_MACINFO_vendor_ext, length_est,
393 &compose_error_type);
394 if (res != DW_DLV_OK) {
395 _dwarf_p_error(NULL, error, compose_error_type);
396 return (DW_DLV_ERROR);
397 }
398 res = libdwarf_compose_add_line(dbg, constant, &compose_error_type);
399 if (res != DW_DLV_OK) {
400 _dwarf_p_error(NULL, error, compose_error_type);
401 return (DW_DLV_ERROR);
402 }
403 libdwarf_compose_add_string(dbg, string, len);
404 libdwarf_compose_complete(dbg, &compose_error_type);
405 if (res != DW_DLV_OK) {
406 _dwarf_p_error(NULL, error, compose_error_type);
407 return (DW_DLV_ERROR);
408 }
409 return DW_DLV_OK;
410 }
411
412
413
414 int
_dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg,Dwarf_Error * error)415 _dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg,
416 Dwarf_Error * error)
417 {
418 /* Total num of bytes in .debug_macinfo section. */
419 Dwarf_Unsigned mac_num_bytes;
420
421 /* Points to first byte of .debug_macinfo buffer. */
422 Dwarf_Small *macinfo;
423
424 /* Fills in the .debug_macinfo buffer. */
425 Dwarf_Small *macinfo_ptr;
426
427
428 /* Used to scan the section data buffers. */
429 struct dw_macinfo_block_s *m_prev;
430 struct dw_macinfo_block_s *m_sect;
431
432
433 /* Get the size of the debug_macinfo data */
434 mac_num_bytes = 0;
435 for (m_sect = dbg->de_first_macinfo; m_sect != NULL;
436 m_sect = m_sect->mb_next) {
437 mac_num_bytes += m_sect->mb_used_len;
438 }
439 /* Tthe final entry has a type code of 0 to indicate It is final
440 for this CU Takes just 1 byte. */
441 mac_num_bytes += 1;
442
443 GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_MACINFO],
444 macinfo, (unsigned long) mac_num_bytes, error);
445 if (macinfo == NULL) {
446 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
447 return (0);
448 }
449
450 macinfo_ptr = macinfo;
451 m_prev = 0;
452 for (m_sect = dbg->de_first_macinfo; m_sect != NULL;
453 m_sect = m_sect->mb_next) {
454 memcpy(macinfo_ptr, m_sect->mb_data, m_sect->mb_used_len);
455 macinfo_ptr += m_sect->mb_used_len;
456 if (m_prev) {
457 _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev);
458 m_prev = 0;
459 }
460 m_prev = m_sect;
461 }
462 *macinfo_ptr = 0; /* the type code of 0 as last entry */
463 if (m_prev) {
464 _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev);
465 m_prev = 0;
466 }
467
468 dbg->de_first_macinfo = NULL;
469 dbg->de_current_macinfo = NULL;
470
471 return (int) dbg->de_n_debug_sect;
472 }
473