xref: /titanic_41/usr/src/tools/ctf/dwarf/common/pro_macinfo.c (revision 49d3bc91e27cd871b950d56c01398fa2f2e12ab4)
1 /*
2 
3   Copyright (C) 2000 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., 59 Temple Place - Suite 330, Boston MA 02111-1307,
23   USA.
24 
25   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
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
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
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
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
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
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
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
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
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
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
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