tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_macinfo.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     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
       
    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 }