rddbg.c revision 130561
1/* rddbg.c -- Read debugging information into a generic form. 2 Copyright 1995, 1996, 1997, 2000, 2002, 2003 3 Free Software Foundation, Inc. 4 Written by Ian Lance Taylor <ian@cygnus.com>. 5 6 This file is part of GNU Binutils. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 21 02111-1307, USA. */ 22 23/* This file reads debugging information into a generic form. This 24 file knows how to dig the debugging information out of an object 25 file. */ 26 27#include "bfd.h" 28#include "bucomm.h" 29#include "libiberty.h" 30#include "debug.h" 31#include "budbg.h" 32 33static bfd_boolean read_section_stabs_debugging_info 34 (bfd *, asymbol **, long, void *, bfd_boolean *); 35static bfd_boolean read_symbol_stabs_debugging_info 36 (bfd *, asymbol **, long, void *, bfd_boolean *); 37static bfd_boolean read_ieee_debugging_info (bfd *, void *, bfd_boolean *); 38static void save_stab (int, int, bfd_vma, const char *); 39static void stab_context (void); 40static void free_saved_stabs (void); 41 42/* Read debugging information from a BFD. Returns a generic debugging 43 pointer. */ 44 45void * 46read_debugging_info (bfd *abfd, asymbol **syms, long symcount) 47{ 48 void *dhandle; 49 bfd_boolean found; 50 51 dhandle = debug_init (); 52 if (dhandle == NULL) 53 return NULL; 54 55 if (! read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, 56 &found)) 57 return NULL; 58 59 if (bfd_get_flavour (abfd) == bfd_target_aout_flavour) 60 { 61 if (! read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, 62 &found)) 63 return NULL; 64 } 65 66 if (bfd_get_flavour (abfd) == bfd_target_ieee_flavour) 67 { 68 if (! read_ieee_debugging_info (abfd, dhandle, &found)) 69 return NULL; 70 } 71 72 /* Try reading the COFF symbols if we didn't find any stabs in COFF 73 sections. */ 74 if (! found 75 && bfd_get_flavour (abfd) == bfd_target_coff_flavour 76 && symcount > 0) 77 { 78 if (! parse_coff (abfd, syms, symcount, dhandle)) 79 return NULL; 80 found = TRUE; 81 } 82 83 if (! found) 84 { 85 non_fatal (_("%s: no recognized debugging information"), 86 bfd_get_filename (abfd)); 87 return NULL; 88 } 89 90 return dhandle; 91} 92 93/* Read stabs in sections debugging information from a BFD. */ 94 95static bfd_boolean 96read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount, 97 void *dhandle, bfd_boolean *pfound) 98{ 99 static struct 100 { 101 const char *secname; 102 const char *strsecname; 103 } names[] = { { ".stab", ".stabstr" }, 104 { "LC_SYMTAB.stabs", "LC_SYMTAB.stabstr" } }; 105 unsigned int i; 106 void *shandle; 107 108 *pfound = FALSE; 109 shandle = NULL; 110 111 for (i = 0; i < sizeof names / sizeof names[0]; i++) 112 { 113 asection *sec, *strsec; 114 115 sec = bfd_get_section_by_name (abfd, names[i].secname); 116 strsec = bfd_get_section_by_name (abfd, names[i].strsecname); 117 if (sec != NULL && strsec != NULL) 118 { 119 bfd_size_type stabsize, strsize; 120 bfd_byte *stabs, *strings; 121 bfd_byte *stab; 122 bfd_size_type stroff, next_stroff; 123 124 stabsize = bfd_section_size (abfd, sec); 125 stabs = (bfd_byte *) xmalloc (stabsize); 126 if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize)) 127 { 128 fprintf (stderr, "%s: %s: %s\n", 129 bfd_get_filename (abfd), names[i].secname, 130 bfd_errmsg (bfd_get_error ())); 131 return FALSE; 132 } 133 134 strsize = bfd_section_size (abfd, strsec); 135 strings = (bfd_byte *) xmalloc (strsize); 136 if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize)) 137 { 138 fprintf (stderr, "%s: %s: %s\n", 139 bfd_get_filename (abfd), names[i].strsecname, 140 bfd_errmsg (bfd_get_error ())); 141 return FALSE; 142 } 143 144 if (shandle == NULL) 145 { 146 shandle = start_stab (dhandle, abfd, TRUE, syms, symcount); 147 if (shandle == NULL) 148 return FALSE; 149 } 150 151 *pfound = TRUE; 152 153 stroff = 0; 154 next_stroff = 0; 155 for (stab = stabs; stab < stabs + stabsize; stab += 12) 156 { 157 unsigned int strx; 158 int type; 159 int other; 160 int desc; 161 bfd_vma value; 162 163 /* This code presumes 32 bit values. */ 164 165 strx = bfd_get_32 (abfd, stab); 166 type = bfd_get_8 (abfd, stab + 4); 167 other = bfd_get_8 (abfd, stab + 5); 168 desc = bfd_get_16 (abfd, stab + 6); 169 value = bfd_get_32 (abfd, stab + 8); 170 171 if (type == 0) 172 { 173 /* Special type 0 stabs indicate the offset to the 174 next string table. */ 175 stroff = next_stroff; 176 next_stroff += value; 177 } 178 else 179 { 180 char *f, *s; 181 182 f = NULL; 183 184 if (stroff + strx > strsize) 185 { 186 fprintf (stderr, "%s: %s: stab entry %ld is corrupt, strx = 0x%x, type = %d\n", 187 bfd_get_filename (abfd), names[i].secname, 188 (long) (stab - stabs) / 12, strx, type); 189 continue; 190 } 191 192 s = (char *) strings + stroff + strx; 193 194 while (s[strlen (s) - 1] == '\\' 195 && stab + 12 < stabs + stabsize) 196 { 197 char *p; 198 199 stab += 12; 200 p = s + strlen (s) - 1; 201 *p = '\0'; 202 s = concat (s, 203 ((char *) strings 204 + stroff 205 + bfd_get_32 (abfd, stab)), 206 (const char *) NULL); 207 208 /* We have to restore the backslash, because, if 209 the linker is hashing stabs strings, we may 210 see the same string more than once. */ 211 *p = '\\'; 212 213 if (f != NULL) 214 free (f); 215 f = s; 216 } 217 218 save_stab (type, desc, value, s); 219 220 if (! parse_stab (dhandle, shandle, type, desc, value, s)) 221 { 222 stab_context (); 223 free_saved_stabs (); 224 return FALSE; 225 } 226 227 /* Don't free f, since I think the stabs code 228 expects strings to hang around. This should be 229 straightened out. FIXME. */ 230 } 231 } 232 233 free_saved_stabs (); 234 free (stabs); 235 236 /* Don't free strings, since I think the stabs code expects 237 the strings to hang around. This should be straightened 238 out. FIXME. */ 239 } 240 } 241 242 if (shandle != NULL) 243 { 244 if (! finish_stab (dhandle, shandle)) 245 return FALSE; 246 } 247 248 return TRUE; 249} 250 251/* Read stabs in the symbol table. */ 252 253static bfd_boolean 254read_symbol_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount, 255 void *dhandle, bfd_boolean *pfound) 256{ 257 void *shandle; 258 asymbol **ps, **symend; 259 260 shandle = NULL; 261 symend = syms + symcount; 262 for (ps = syms; ps < symend; ps++) 263 { 264 symbol_info i; 265 266 bfd_get_symbol_info (abfd, *ps, &i); 267 268 if (i.type == '-') 269 { 270 const char *s; 271 char *f; 272 273 if (shandle == NULL) 274 { 275 shandle = start_stab (dhandle, abfd, FALSE, syms, symcount); 276 if (shandle == NULL) 277 return FALSE; 278 } 279 280 *pfound = TRUE; 281 282 s = i.name; 283 f = NULL; 284 while (s[strlen (s) - 1] == '\\' 285 && ps + 1 < symend) 286 { 287 char *sc, *n; 288 289 ++ps; 290 sc = xstrdup (s); 291 sc[strlen (sc) - 1] = '\0'; 292 n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL); 293 free (sc); 294 if (f != NULL) 295 free (f); 296 f = n; 297 s = n; 298 } 299 300 save_stab (i.stab_type, i.stab_desc, i.value, s); 301 302 if (! parse_stab (dhandle, shandle, i.stab_type, i.stab_desc, 303 i.value, s)) 304 { 305 stab_context (); 306 free_saved_stabs (); 307 return FALSE; 308 } 309 310 /* Don't free f, since I think the stabs code expects 311 strings to hang around. This should be straightened out. 312 FIXME. */ 313 } 314 } 315 316 free_saved_stabs (); 317 318 if (shandle != NULL) 319 { 320 if (! finish_stab (dhandle, shandle)) 321 return FALSE; 322 } 323 324 return TRUE; 325} 326 327/* Read IEEE debugging information. */ 328 329static bfd_boolean 330read_ieee_debugging_info (bfd *abfd, void *dhandle, bfd_boolean *pfound) 331{ 332 asection *dsec; 333 bfd_size_type size; 334 bfd_byte *contents; 335 336 /* The BFD backend puts the debugging information into a section 337 named .debug. */ 338 339 dsec = bfd_get_section_by_name (abfd, ".debug"); 340 if (dsec == NULL) 341 return TRUE; 342 343 size = bfd_section_size (abfd, dsec); 344 contents = (bfd_byte *) xmalloc (size); 345 if (! bfd_get_section_contents (abfd, dsec, contents, 0, size)) 346 return FALSE; 347 348 if (! parse_ieee (dhandle, abfd, contents, size)) 349 return FALSE; 350 351 free (contents); 352 353 *pfound = TRUE; 354 355 return TRUE; 356} 357 358/* Record stabs strings, so that we can give some context for errors. */ 359 360#define SAVE_STABS_COUNT (16) 361 362struct saved_stab 363{ 364 int type; 365 int desc; 366 bfd_vma value; 367 char *string; 368}; 369 370static struct saved_stab saved_stabs[SAVE_STABS_COUNT]; 371static int saved_stabs_index; 372 373/* Save a stabs string. */ 374 375static void 376save_stab (int type, int desc, bfd_vma value, const char *string) 377{ 378 if (saved_stabs[saved_stabs_index].string != NULL) 379 free (saved_stabs[saved_stabs_index].string); 380 saved_stabs[saved_stabs_index].type = type; 381 saved_stabs[saved_stabs_index].desc = desc; 382 saved_stabs[saved_stabs_index].value = value; 383 saved_stabs[saved_stabs_index].string = xstrdup (string); 384 saved_stabs_index = (saved_stabs_index + 1) % SAVE_STABS_COUNT; 385} 386 387/* Provide context for an error. */ 388 389static void 390stab_context (void) 391{ 392 int i; 393 394 fprintf (stderr, _("Last stabs entries before error:\n")); 395 fprintf (stderr, "n_type n_desc n_value string\n"); 396 397 i = saved_stabs_index; 398 do 399 { 400 struct saved_stab *stabp; 401 402 stabp = saved_stabs + i; 403 if (stabp->string != NULL) 404 { 405 const char *s; 406 407 s = bfd_get_stab_name (stabp->type); 408 if (s != NULL) 409 fprintf (stderr, "%-6s", s); 410 else if (stabp->type == 0) 411 fprintf (stderr, "HdrSym"); 412 else 413 fprintf (stderr, "%-6d", stabp->type); 414 fprintf (stderr, " %-6d ", stabp->desc); 415 fprintf_vma (stderr, stabp->value); 416 if (stabp->type != 0) 417 fprintf (stderr, " %s", stabp->string); 418 fprintf (stderr, "\n"); 419 } 420 i = (i + 1) % SAVE_STABS_COUNT; 421 } 422 while (i != saved_stabs_index); 423} 424 425/* Free the saved stab strings. */ 426 427static void 428free_saved_stabs (void) 429{ 430 int i; 431 432 for (i = 0; i < SAVE_STABS_COUNT; i++) 433 { 434 if (saved_stabs[i].string != NULL) 435 { 436 free (saved_stabs[i].string); 437 saved_stabs[i].string = NULL; 438 } 439 } 440 441 saved_stabs_index = 0; 442} 443