00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "config.h"
00043 #include "dwarf_incl.h"
00044 #include <stdio.h>
00045 #include <limits.h>
00046 #include "dwarf_macro.h"
00047
00048
00049 #define LEFTPAREN '('
00050 #define RIGHTPAREN ')'
00051 #define SPACE ' '
00052
00053
00054
00055
00056
00057
00058
00059
00060 char *
00061 dwarf_find_macro_value_start(char *str)
00062 {
00063 char *lcp;
00064 int funclike = 0;
00065
00066 for (lcp = str; *lcp; ++lcp) {
00067 switch (*lcp) {
00068 case LEFTPAREN:
00069 funclike = 1;
00070 break;
00071 case RIGHTPAREN:
00072
00073 return lcp + 2;
00074 case SPACE:
00075
00076
00077 if (!funclike) {
00078 return lcp + 1;
00079 }
00080 break;
00081 }
00082 }
00083
00084
00085 return lcp;
00086
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 static Dwarf_Signed *st_base;
00099 static long max;
00100 static long next_to_use;
00101 static int was_fault = 0;
00102
00103 #define STARTERMAX 10
00104 static void
00105 _dwarf_reset_index_stack(void)
00106 {
00107 next_to_use = 0;
00108 was_fault = 0;
00109 }
00110 static int
00111 _dwarf_mac_push_index(Dwarf_Debug dbg, Dwarf_Signed indx)
00112 {
00113 Dwarf_Signed *newbase;
00114
00115 if (next_to_use >= max) {
00116 long new_size;
00117
00118 if (max == 0) {
00119 max = STARTERMAX;
00120 }
00121 new_size = max * 2;
00122 newbase =
00123 _dwarf_get_alloc(dbg, DW_DLA_STRING,
00124 new_size * sizeof(Dwarf_Signed));
00125 if (newbase == 0) {
00126
00127 was_fault = 1;
00128 return DW_DLV_ERROR;
00129 }
00130 memcpy(newbase, st_base, next_to_use * sizeof(Dwarf_Signed));
00131 dwarf_dealloc(dbg, st_base, DW_DLA_STRING);
00132 st_base = newbase;
00133 max = new_size;
00134 }
00135 st_base[next_to_use] = indx;
00136 ++next_to_use;
00137 return DW_DLV_OK;
00138 }
00139 static Dwarf_Signed
00140 _dwarf_mac_pop_index(void)
00141 {
00142 if (was_fault) {
00143 return -1;
00144 }
00145 if (next_to_use > 0) {
00146 next_to_use--;
00147 return (*(st_base + next_to_use));
00148 }
00149 return -1;
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159 int
00160 dwarf_get_macro_details(Dwarf_Debug dbg,
00161 Dwarf_Off macro_offset,
00162 Dwarf_Unsigned maximum_count,
00163 Dwarf_Signed * entry_count,
00164 Dwarf_Macro_Details ** details,
00165 Dwarf_Error * error)
00166 {
00167 Dwarf_Small *macro_base = 0;
00168 Dwarf_Small *pnext = 0;
00169 Dwarf_Unsigned endloc = 0;
00170 unsigned char uc = 0;
00171 unsigned long depth = 0;
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 int res = 0;
00182
00183
00184 unsigned long str_space = 0;
00185 int done = 0;
00186 unsigned long space_needed = 0;
00187 unsigned long string_offset = 0;
00188 Dwarf_Small *return_data = 0;
00189 Dwarf_Small *pdata = 0;
00190 unsigned long final_count = 0;
00191 Dwarf_Signed fileindex = -1;
00192 Dwarf_Small *latest_str_loc = 0;
00193
00194 unsigned long count = 0;
00195 unsigned long max_count = (unsigned long) maximum_count;
00196
00197 _dwarf_reset_index_stack();
00198 if (dbg == NULL) {
00199 _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
00200 return (DW_DLV_ERROR);
00201 }
00202
00203 res =
00204 _dwarf_load_section(dbg,
00205 dbg->de_debug_macinfo_index,
00206 &dbg->de_debug_macinfo,
00207 error);
00208 if (res != DW_DLV_OK) {
00209 return res;
00210 }
00211
00212 macro_base = dbg->de_debug_macinfo;
00213 if (macro_base == NULL) {
00214 return (DW_DLV_NO_ENTRY);
00215 }
00216 if (macro_offset >= dbg->de_debug_macinfo_size) {
00217 return (DW_DLV_NO_ENTRY);
00218 }
00219
00220 pnext = macro_base + macro_offset;
00221 if (maximum_count == 0) {
00222 max_count = ULONG_MAX;
00223 }
00224
00225
00226
00227
00228 endloc = (pnext - macro_base);
00229 if (endloc >= dbg->de_debug_macinfo_size) {
00230 if (endloc == dbg->de_debug_macinfo_size) {
00231
00232 return DW_DLV_NO_ENTRY;
00233 }
00234 _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
00235 return (DW_DLV_ERROR);
00236 }
00237 for (count = 0; !done && count < max_count; ++count) {
00238 unsigned long slen;
00239 Dwarf_Word len;
00240
00241 uc = *pnext;
00242 ++pnext;
00243 switch (uc) {
00244 case DW_MACINFO_define:
00245 case DW_MACINFO_undef:
00246
00247 case DW_MACINFO_vendor_ext:
00248
00249 (void) _dwarf_decode_u_leb128(pnext, &len);
00250
00251 pnext += len;
00252 if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
00253 _dwarf_error(dbg, error,
00254 DW_DLE_DEBUG_MACRO_INCONSISTENT);
00255 return (DW_DLV_ERROR);
00256 }
00257 slen = strlen((char *) pnext) + 1;
00258 pnext += slen;
00259 if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
00260 _dwarf_error(dbg, error,
00261 DW_DLE_DEBUG_MACRO_INCONSISTENT);
00262 return (DW_DLV_ERROR);
00263 }
00264 str_space += slen;
00265 break;
00266 case DW_MACINFO_start_file:
00267
00268 (void) _dwarf_decode_u_leb128(pnext, &len);
00269 pnext += len;
00270 if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
00271 _dwarf_error(dbg, error,
00272 DW_DLE_DEBUG_MACRO_INCONSISTENT);
00273 return (DW_DLV_ERROR);
00274 }
00275 (void) _dwarf_decode_u_leb128(pnext, &len);
00276 pnext += len;
00277 if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
00278 _dwarf_error(dbg, error,
00279 DW_DLE_DEBUG_MACRO_INCONSISTENT);
00280 return (DW_DLV_ERROR);
00281 }
00282 ++depth;
00283 break;
00284
00285 case DW_MACINFO_end_file:
00286 if (--depth == 0) {
00287
00288
00289
00290 }
00291 break;
00292 case 0:
00293
00294 done = 1;
00295 break;
00296 default:
00297 _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT);
00298 return (DW_DLV_ERROR);
00299
00300 }
00301
00302 endloc = (pnext - macro_base);
00303 if (endloc == dbg->de_debug_macinfo_size) {
00304 done = 1;
00305 } else if (endloc > dbg->de_debug_macinfo_size) {
00306 _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
00307 return (DW_DLV_ERROR);
00308 }
00309 }
00310 if (count == 0) {
00311 _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INTERNAL_ERR);
00312 return (DW_DLV_ERROR);
00313 }
00314
00315
00316
00317
00318 string_offset = count * sizeof(Dwarf_Macro_Details);
00319
00320
00321 space_needed = string_offset + str_space + 2;
00322 return_data = pdata =
00323 _dwarf_get_alloc(dbg, DW_DLA_STRING, space_needed);
00324 latest_str_loc = pdata + string_offset;
00325 if (pdata == 0) {
00326 _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_MALLOC_SPACE);
00327 return (DW_DLV_ERROR);
00328 }
00329 pnext = macro_base + macro_offset;
00330
00331 done = 0;
00332
00333
00334
00335 for (final_count = 0; !done && final_count < count; ++final_count) {
00336 unsigned long slen;
00337 Dwarf_Word len;
00338 Dwarf_Unsigned v1;
00339 Dwarf_Macro_Details *pdmd = (Dwarf_Macro_Details *) (pdata +
00340 final_count
00341 *
00342 sizeof
00343 (Dwarf_Macro_Details));
00344
00345 endloc = (pnext - macro_base);
00346 if (endloc > dbg->de_debug_macinfo_size) {
00347 _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
00348 return (DW_DLV_ERROR);
00349 }
00350 uc = *pnext;
00351 pdmd->dmd_offset = (pnext - macro_base);
00352 pdmd->dmd_type = uc;
00353 pdmd->dmd_fileindex = fileindex;
00354 pdmd->dmd_lineno = 0;
00355 pdmd->dmd_macro = 0;
00356 ++pnext;
00357 switch (uc) {
00358 case DW_MACINFO_define:
00359 case DW_MACINFO_undef:
00360
00361 case DW_MACINFO_vendor_ext:
00362
00363 v1 = _dwarf_decode_u_leb128(pnext, &len);
00364 pdmd->dmd_lineno = v1;
00365
00366 pnext += len;
00367 if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
00368 _dwarf_error(dbg, error,
00369 DW_DLE_DEBUG_MACRO_INCONSISTENT);
00370 return (DW_DLV_ERROR);
00371 }
00372 slen = strlen((char *) pnext) + 1;
00373 strcpy((char *) latest_str_loc, (char *) pnext);
00374 pdmd->dmd_macro = (char *) latest_str_loc;
00375 latest_str_loc += slen;
00376 pnext += slen;
00377 if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
00378 _dwarf_error(dbg, error,
00379 DW_DLE_DEBUG_MACRO_INCONSISTENT);
00380 return (DW_DLV_ERROR);
00381 }
00382 str_space += slen;
00383 break;
00384 case DW_MACINFO_start_file:
00385
00386 v1 = _dwarf_decode_u_leb128(pnext, &len);
00387 pdmd->dmd_lineno = v1;
00388 pnext += len;
00389 if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
00390 _dwarf_error(dbg, error,
00391 DW_DLE_DEBUG_MACRO_INCONSISTENT);
00392 return (DW_DLV_ERROR);
00393 }
00394 v1 = _dwarf_decode_u_leb128(pnext, &len);
00395 pdmd->dmd_fileindex = v1;
00396 (void) _dwarf_mac_push_index(dbg, fileindex);
00397
00398
00399 fileindex = v1;
00400 pnext += len;
00401 if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
00402 _dwarf_error(dbg, error,
00403 DW_DLE_DEBUG_MACRO_INCONSISTENT);
00404 return (DW_DLV_ERROR);
00405 }
00406 break;
00407
00408 case DW_MACINFO_end_file:
00409 fileindex = _dwarf_mac_pop_index();
00410 break;
00411 case 0:
00412
00413 done = 1;
00414 break;
00415 default:
00416
00417 _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT);
00418 return (DW_DLV_ERROR);
00419
00420 }
00421 }
00422 *entry_count = count;
00423 *details = (Dwarf_Macro_Details *) return_data;
00424
00425 return DW_DLV_OK;
00426 }