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