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