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