tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_macro.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2 
       
     3   Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
       
     4   Portions Copyright (C) 2007 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   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
       
    27   Mountain View, CA 94043, or:
       
    28 
       
    29   http://www.sgi.com
       
    30 
       
    31   For further information regarding this notice, see:
       
    32 
       
    33   http://oss.sgi.com/projects/GenInfo/NoticeExplan
       
    34 
       
    35 */
       
    36 /* The address of the Free Software Foundation is
       
    37    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
       
    38    Boston, MA 02110-1301, USA.
       
    39    SGI has moved from the Crittenden Lane address.
       
    40 */
       
    41 
       
    42 
       
    43 
       
    44 
       
    45 #include "config.h"
       
    46 #include "dwarf_incl.h"
       
    47 #include <stdio.h>
       
    48 #include <limits.h>
       
    49 #ifdef HAVE_STDLIB_H
       
    50 #include <stdlib.h>
       
    51 #endif /* HAVE_STDLIB_H */
       
    52 #include "dwarf_macro.h"
       
    53 
       
    54 
       
    55 #define LEFTPAREN '('
       
    56 #define RIGHTPAREN ')'
       
    57 #define SPACE ' '
       
    58 
       
    59 /*
       
    60 	Given the dwarf macro string, return a pointer to
       
    61 	the value.  Returns pointer to 0 byte at end of string
       
    62 	if no value found (meaning the value is the empty string).
       
    63 
       
    64 	Only understands well-formed dwarf macinfo strings.
       
    65 */
       
    66 char *
       
    67 dwarf_find_macro_value_start(char *str)
       
    68 {
       
    69     char *lcp;
       
    70     int funclike = 0;
       
    71 
       
    72     for (lcp = str; *lcp; ++lcp) {
       
    73 	switch (*lcp) {
       
    74 	case LEFTPAREN:
       
    75 	    funclike = 1;
       
    76 	    break;
       
    77 	case RIGHTPAREN:
       
    78 	    /* lcp+1 must be a space, and following char is the value */
       
    79 	    return lcp + 2;
       
    80 	case SPACE:
       
    81 	    /* we allow extraneous spaces inside macro parameter **
       
    82 	       list, just in case... This is not really needed. */
       
    83 	    if (!funclike) {
       
    84 		return lcp + 1;
       
    85 	    }
       
    86 	    break;
       
    87 	}
       
    88     }
       
    89     /* never found value: returns pointer to the 0 byte at end of
       
    90        string */
       
    91     return lcp;
       
    92 
       
    93 }
       
    94 
       
    95 
       
    96 /*
       
    97    Try to keep fileindex correct in every Macro_Details
       
    98    record by tracking file starts and ends.
       
    99    Uses high water mark: space reused, not freed.
       
   100    Presumption is that this makes sense for most uses.
       
   101    STARTERMAX is set so that the array need not be expanded for
       
   102    most files: it is the initial include file depth.
       
   103 */
       
   104 struct macro_stack_s {
       
   105     Dwarf_Signed *st_base;
       
   106     long max;
       
   107     long next_to_use;
       
   108     int was_fault;
       
   109 };
       
   110 
       
   111 static void _dwarf_reset_index_macro_stack(struct macro_stack_s *ms);
       
   112 static void
       
   113 free_macro_stack(Dwarf_Debug dbg, struct macro_stack_s *ms)
       
   114 {
       
   115     dwarf_dealloc(dbg,ms->st_base,DW_DLA_STRING);
       
   116     _dwarf_reset_index_macro_stack(ms);
       
   117 }
       
   118 
       
   119 #define STARTERMAX 10
       
   120 static void
       
   121 _dwarf_reset_index_macro_stack(struct macro_stack_s *ms)
       
   122 {
       
   123     ms->st_base = 0;
       
   124     ms->max = 0;
       
   125     ms->next_to_use = 0;
       
   126     ms->was_fault = 0;
       
   127 }
       
   128 static int
       
   129 _dwarf_macro_stack_push_index(Dwarf_Debug dbg, Dwarf_Signed indx,
       
   130 			      struct macro_stack_s *ms)
       
   131 {
       
   132     Dwarf_Signed *newbase;
       
   133 
       
   134     if (ms->next_to_use >= ms->max) {
       
   135 	long new_size;
       
   136 
       
   137 	if (ms->max == 0) {
       
   138 	    ms->max = STARTERMAX;
       
   139 	}
       
   140 	new_size = ms->max * 2;
       
   141 	newbase =
       
   142 	    _dwarf_get_alloc(dbg, DW_DLA_STRING,
       
   143 			     new_size * sizeof(Dwarf_Signed));
       
   144 	if (newbase == 0) {
       
   145 	    /* just leave the old array in place */
       
   146 	    ms->was_fault = 1;
       
   147 	    return DW_DLV_ERROR;
       
   148 	}
       
   149         if(ms->st_base) {
       
   150 	    memcpy(newbase, ms->st_base,
       
   151 	       ms->next_to_use * sizeof(Dwarf_Signed));
       
   152 	    dwarf_dealloc(dbg, ms->st_base, DW_DLA_STRING);
       
   153         }
       
   154 	ms->st_base = newbase;
       
   155 	ms->max = new_size;
       
   156     }
       
   157     ms->st_base[ms->next_to_use] = indx;
       
   158     ++ms->next_to_use;
       
   159     return DW_DLV_OK;
       
   160 }
       
   161 
       
   162 static Dwarf_Signed
       
   163 _dwarf_macro_stack_pop_index(struct macro_stack_s *ms)
       
   164 {
       
   165     if (ms->was_fault) {
       
   166 	return -1;
       
   167     }
       
   168     if (ms->next_to_use > 0) {
       
   169 	ms->next_to_use--;
       
   170 	return (ms->st_base[ms->next_to_use]);
       
   171     } else {
       
   172         ms->was_fault = 1;
       
   173     }
       
   174     return -1;
       
   175 }
       
   176 
       
   177 /* starting at macro_offset in .debug_macinfo,
       
   178 	if maximum_count is 0, treat as if it is infinite.
       
   179 	get macro data up thru
       
   180 	maximum_count entries or the end of a compilation
       
   181 	unit's entries (whichever comes first). 
       
   182 */
       
   183 
       
   184 int
       
   185 dwarf_get_macro_details(Dwarf_Debug dbg,
       
   186 			Dwarf_Off macro_offset,
       
   187 			Dwarf_Unsigned maximum_count,
       
   188 			Dwarf_Signed * entry_count,
       
   189 			Dwarf_Macro_Details ** details,
       
   190 			Dwarf_Error * error)
       
   191 {
       
   192     Dwarf_Small *macro_base = 0;
       
   193     Dwarf_Small *pnext = 0;
       
   194     Dwarf_Unsigned endloc = 0;
       
   195     unsigned char uc = 0;
       
   196     unsigned long depth = 0;	/* By section 6.3.2 Dwarf3 draft 8/9,
       
   197 				   the base file should appear as
       
   198 				   DW_MACINFO_start_file. See
       
   199 				   http://gcc.gnu.org/ml/gcc-bugs/2005-02/msg03442.html
       
   200 				   on "[Bug debug/20253] New: [3.4/4.0 regression]:
       
   201 				   Macro debug info broken due to lexer change" for how
       
   202 				   gcc is broken in some versions. We no longer use
       
   203 				   depth as a stopping point, it's not needed as a
       
   204 				   stopping point anyway.  */
       
   205 
       
   206 
       
   207     int res = 0;
       
   208 
       
   209     /* count space used by strings */
       
   210     unsigned long str_space = 0;
       
   211     int done = 0;
       
   212     unsigned long space_needed = 0;
       
   213     unsigned long string_offset = 0;
       
   214     Dwarf_Small *return_data = 0;
       
   215     Dwarf_Small *pdata = 0;
       
   216     unsigned long final_count = 0;
       
   217     Dwarf_Signed fileindex = -1;
       
   218     Dwarf_Small *latest_str_loc = 0;
       
   219     struct macro_stack_s msdata;
       
   220 
       
   221     unsigned long count = 0;
       
   222     unsigned long max_count = (unsigned long) maximum_count;
       
   223 
       
   224     _dwarf_reset_index_macro_stack(&msdata);
       
   225     if (dbg == NULL) {
       
   226 	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
       
   227 	free_macro_stack(dbg,&msdata);
       
   228 	return (DW_DLV_ERROR);
       
   229     }
       
   230 
       
   231     res =
       
   232 	_dwarf_load_section(dbg,
       
   233 			    dbg->de_debug_macinfo_index,
       
   234 			    &dbg->de_debug_macinfo, error);
       
   235     if (res != DW_DLV_OK) {
       
   236 	free_macro_stack(dbg,&msdata);
       
   237 	return res;
       
   238     }
       
   239 
       
   240     macro_base = dbg->de_debug_macinfo;
       
   241     if (macro_base == NULL) {
       
   242 	free_macro_stack(dbg,&msdata);
       
   243 	return (DW_DLV_NO_ENTRY);
       
   244     }
       
   245     if (macro_offset >= dbg->de_debug_macinfo_size) {
       
   246 	free_macro_stack(dbg,&msdata);
       
   247 	return (DW_DLV_NO_ENTRY);
       
   248     }
       
   249 
       
   250     pnext = macro_base + macro_offset;
       
   251     if (maximum_count == 0) {
       
   252 	max_count = ULONG_MAX;
       
   253     }
       
   254 
       
   255 
       
   256     /* how many entries and how much space will they take? */
       
   257 
       
   258     endloc = (pnext - macro_base);
       
   259     if (endloc >= dbg->de_debug_macinfo_size) {
       
   260 	if (endloc == dbg->de_debug_macinfo_size) {
       
   261 	    /* normal: found last entry */
       
   262 	    free_macro_stack(dbg,&msdata);
       
   263 	    return DW_DLV_NO_ENTRY;
       
   264 	}
       
   265 	_dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
       
   266 	free_macro_stack(dbg,&msdata);
       
   267 	return (DW_DLV_ERROR);
       
   268     }
       
   269     for (count = 0; !done && count < max_count; ++count) {
       
   270 	unsigned long slen;
       
   271 	Dwarf_Word len;
       
   272 
       
   273 	uc = *pnext;
       
   274 	++pnext;		/* get past the type code */
       
   275 	switch (uc) {
       
   276 	case DW_MACINFO_define:
       
   277 	case DW_MACINFO_undef:
       
   278 	    /* line, string */
       
   279 	case DW_MACINFO_vendor_ext:
       
   280 	    /* number, string */
       
   281 	    (void) _dwarf_decode_u_leb128(pnext, &len);
       
   282 
       
   283 	    pnext += len;
       
   284 	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
       
   285 		free_macro_stack(dbg,&msdata);
       
   286 		_dwarf_error(dbg, error,
       
   287 			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
       
   288 		return (DW_DLV_ERROR);
       
   289 	    }
       
   290 	    slen = strlen((char *) pnext) + 1;
       
   291 	    pnext += slen;
       
   292 	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
       
   293 		free_macro_stack(dbg,&msdata);
       
   294 		_dwarf_error(dbg, error,
       
   295 			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
       
   296 		return (DW_DLV_ERROR);
       
   297 	    }
       
   298 	    str_space += slen;
       
   299 	    break;
       
   300 	case DW_MACINFO_start_file:
       
   301 	    /* line, file index */
       
   302 	    (void) _dwarf_decode_u_leb128(pnext, &len);
       
   303 	    pnext += len;
       
   304 	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
       
   305 		free_macro_stack(dbg,&msdata);
       
   306 		_dwarf_error(dbg, error,
       
   307 			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
       
   308 		return (DW_DLV_ERROR);
       
   309 	    }
       
   310 	    (void) _dwarf_decode_u_leb128(pnext, &len);
       
   311 	    pnext += len;
       
   312 	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
       
   313 		free_macro_stack(dbg,&msdata);
       
   314 		_dwarf_error(dbg, error,
       
   315 			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
       
   316 		return (DW_DLV_ERROR);
       
   317 	    }
       
   318 	    ++depth;
       
   319 	    break;
       
   320 
       
   321 	case DW_MACINFO_end_file:
       
   322 	    if (--depth == 0) {
       
   323 		/* done = 1; no, do not stop here, at least one gcc had 
       
   324 		   the wrong depth settings in the gcc 3.4 timeframe. */
       
   325 	    }
       
   326 	    break;		/* no string or number here */
       
   327 	case 0:
       
   328 	    /* end of cu's entries */
       
   329 	    done = 1;
       
   330 	    break;
       
   331 	default:
       
   332 	    free_macro_stack(dbg,&msdata);
       
   333 	    _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT);
       
   334 	    return (DW_DLV_ERROR);
       
   335 	    /* bogus macinfo! */
       
   336 	}
       
   337 
       
   338 	endloc = (pnext - macro_base);
       
   339 	if (endloc == dbg->de_debug_macinfo_size) {
       
   340 	    done = 1;
       
   341 	} else if (endloc > dbg->de_debug_macinfo_size) {
       
   342 	    _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
       
   343 	    free_macro_stack(dbg,&msdata);
       
   344 	    return (DW_DLV_ERROR);
       
   345 	}
       
   346     }
       
   347     if (count == 0) {
       
   348 	free_macro_stack(dbg,&msdata);
       
   349 	_dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INTERNAL_ERR);
       
   350 	return (DW_DLV_ERROR);
       
   351     }
       
   352 
       
   353     /* we have 'count' array entries to allocate and str_space bytes of 
       
   354        string space to provide for. */
       
   355 
       
   356     string_offset = count * sizeof(Dwarf_Macro_Details);
       
   357 
       
   358     /* extra 2 not really needed */
       
   359     space_needed = string_offset + str_space + 2;
       
   360     return_data = pdata =
       
   361 	_dwarf_get_alloc(dbg, DW_DLA_STRING, space_needed);
       
   362     latest_str_loc = pdata + string_offset;
       
   363     if (pdata == 0) {
       
   364 	free_macro_stack(dbg,&msdata);
       
   365 	_dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_MALLOC_SPACE);
       
   366 	return (DW_DLV_ERROR);
       
   367     }
       
   368     pnext = macro_base + macro_offset;
       
   369 
       
   370     done = 0;
       
   371 
       
   372     /* A series ends with a type code of 0. */
       
   373 
       
   374     for (final_count = 0; !done && final_count < count; ++final_count) {
       
   375 	unsigned long slen;
       
   376 	Dwarf_Word len;
       
   377 	Dwarf_Unsigned v1;
       
   378 	Dwarf_Macro_Details *pdmd = (Dwarf_Macro_Details *) (pdata +
       
   379 		(final_count * sizeof (Dwarf_Macro_Details)));
       
   380 
       
   381 	endloc = (pnext - macro_base);
       
   382 	if (endloc > dbg->de_debug_macinfo_size) {
       
   383 	    free_macro_stack(dbg,&msdata);
       
   384 	    _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
       
   385 	    return (DW_DLV_ERROR);
       
   386 	}
       
   387 	uc = *pnext;
       
   388 	pdmd->dmd_offset = (pnext - macro_base);
       
   389 	pdmd->dmd_type = uc;
       
   390 	pdmd->dmd_fileindex = fileindex;
       
   391 	pdmd->dmd_lineno = 0;
       
   392 	pdmd->dmd_macro = 0;
       
   393 	++pnext;		/* get past the type code */
       
   394 	switch (uc) {
       
   395 	case DW_MACINFO_define:
       
   396 	case DW_MACINFO_undef:
       
   397 	    /* line, string */
       
   398 	case DW_MACINFO_vendor_ext:
       
   399 	    /* number, string */
       
   400 	    v1 = _dwarf_decode_u_leb128(pnext, &len);
       
   401 	    pdmd->dmd_lineno = v1;
       
   402 
       
   403 	    pnext += len;
       
   404 	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
       
   405 		free_macro_stack(dbg,&msdata);
       
   406                 dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
       
   407 		_dwarf_error(dbg, error,
       
   408 			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
       
   409 		return (DW_DLV_ERROR);
       
   410 	    }
       
   411 	    slen = strlen((char *) pnext) + 1;
       
   412 	    strcpy((char *) latest_str_loc, (char *) pnext);
       
   413 	    pdmd->dmd_macro = (char *) latest_str_loc;
       
   414 	    latest_str_loc += slen;
       
   415 	    pnext += slen;
       
   416 	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
       
   417 		free_macro_stack(dbg,&msdata);
       
   418                 dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
       
   419 		_dwarf_error(dbg, error,
       
   420 			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
       
   421 		return (DW_DLV_ERROR);
       
   422 	    }
       
   423 	    break;
       
   424 	case DW_MACINFO_start_file:
       
   425 	    /* Line, file index */
       
   426 	    v1 = _dwarf_decode_u_leb128(pnext, &len);
       
   427 	    pdmd->dmd_lineno = v1;
       
   428 	    pnext += len;
       
   429 	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
       
   430 		free_macro_stack(dbg,&msdata);
       
   431                 dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
       
   432 		_dwarf_error(dbg, error,
       
   433 			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
       
   434 		return (DW_DLV_ERROR);
       
   435 	    }
       
   436 	    v1 = _dwarf_decode_u_leb128(pnext, &len);
       
   437 	    pdmd->dmd_fileindex = v1;
       
   438 	    (void) _dwarf_macro_stack_push_index(dbg, fileindex,
       
   439 						 &msdata);
       
   440 	    /* We ignore the error, we just let fileindex ** be -1 when 
       
   441 	       we pop this one. */
       
   442 	    fileindex = v1;
       
   443 	    pnext += len;
       
   444 	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
       
   445 		free_macro_stack(dbg,&msdata);
       
   446                 dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
       
   447 		_dwarf_error(dbg, error,
       
   448 			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
       
   449 		return (DW_DLV_ERROR);
       
   450 	    }
       
   451 	    break;
       
   452 
       
   453 	case DW_MACINFO_end_file:
       
   454 	    fileindex = _dwarf_macro_stack_pop_index(&msdata);
       
   455 	    break;		/* no string or number here */
       
   456 	case 0:
       
   457 	    /* Type code of 0 means the end of cu's entries. */
       
   458 	    done = 1;
       
   459 	    break;
       
   460 	default:
       
   461 	    /* Bogus macinfo! */
       
   462             dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
       
   463 	    free_macro_stack(dbg,&msdata);
       
   464 	    _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT);
       
   465 	    return (DW_DLV_ERROR);
       
   466 	}
       
   467     }
       
   468     *entry_count = count;
       
   469     *details = (Dwarf_Macro_Details *) return_data;
       
   470 
       
   471     free_macro_stack(dbg,&msdata);
       
   472     return DW_DLV_OK;
       
   473 }