1 1.1 skrll /* Stabs in sections linking support. 2 1.1.1.11 christos Copyright (C) 1996-2026 Free Software Foundation, Inc. 3 1.1 skrll Written by Ian Lance Taylor, Cygnus Support. 4 1.1 skrll 5 1.1 skrll This file is part of BFD, the Binary File Descriptor library. 6 1.1 skrll 7 1.1 skrll This program is free software; you can redistribute it and/or modify 8 1.1 skrll it under the terms of the GNU General Public License as published by 9 1.1 skrll the Free Software Foundation; either version 3 of the License, or 10 1.1 skrll (at your option) any later version. 11 1.1 skrll 12 1.1 skrll This program is distributed in the hope that it will be useful, 13 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 skrll GNU General Public License for more details. 16 1.1 skrll 17 1.1 skrll You should have received a copy of the GNU General Public License 18 1.1 skrll along with this program; if not, write to the Free Software 19 1.1 skrll Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 1.1 skrll MA 02110-1301, USA. */ 21 1.1 skrll 22 1.1 skrll 23 1.1 skrll /* This file contains support for linking stabs in sections, as used 24 1.1 skrll on COFF and ELF. */ 25 1.1 skrll 26 1.1 skrll #include "sysdep.h" 27 1.1 skrll #include "bfd.h" 28 1.1 skrll #include "libbfd.h" 29 1.1 skrll #include "aout/stab_gnu.h" 30 1.1 skrll #include "safe-ctype.h" 31 1.1 skrll 32 1.1 skrll /* Stabs entries use a 12 byte format: 33 1.1 skrll 4 byte string table index 34 1.1 skrll 1 byte stab type 35 1.1 skrll 1 byte stab other field 36 1.1 skrll 2 byte stab desc field 37 1.1 skrll 4 byte stab value 38 1.1 skrll FIXME: This will have to change for a 64 bit object format. 39 1.1 skrll 40 1.1 skrll The stabs symbols are divided into compilation units. For the 41 1.1 skrll first entry in each unit, the type of 0, the value is the length of 42 1.1 skrll the string table for this unit, and the desc field is the number of 43 1.1 skrll stabs symbols for this unit. */ 44 1.1 skrll 45 1.1 skrll #define STRDXOFF 0 46 1.1 skrll #define TYPEOFF 4 47 1.1 skrll #define OTHEROFF 5 48 1.1 skrll #define DESCOFF 6 49 1.1 skrll #define VALOFF 8 50 1.1 skrll #define STABSIZE 12 51 1.1 skrll 52 1.1 skrll /* A linked list of totals that we have found for a particular header 53 1.1 skrll file. A total is a unique identifier for a particular BINCL...EINCL 54 1.1 skrll sequence of STABs that can be used to identify duplicate sequences. 55 1.1 skrll It consists of three fields, 'sum_chars' which is the sum of all the 56 1.1 skrll STABS characters; 'num_chars' which is the number of these charactes 57 1.1 skrll and 'symb' which is a buffer of all the symbols in the sequence. This 58 1.1 skrll buffer is only checked as a last resort. */ 59 1.1 skrll 60 1.1 skrll struct stab_link_includes_totals 61 1.1 skrll { 62 1.1 skrll struct stab_link_includes_totals *next; 63 1.1 skrll bfd_vma sum_chars; /* Accumulated sum of STABS characters. */ 64 1.1 skrll bfd_vma num_chars; /* Number of STABS characters. */ 65 1.1 skrll const char* symb; /* The STABS characters themselves. */ 66 1.1 skrll }; 67 1.1 skrll 68 1.1 skrll /* An entry in the header file hash table. */ 69 1.1 skrll 70 1.1 skrll struct stab_link_includes_entry 71 1.1 skrll { 72 1.1 skrll struct bfd_hash_entry root; 73 1.1 skrll /* List of totals we have found for this file. */ 74 1.1 skrll struct stab_link_includes_totals *totals; 75 1.1 skrll }; 76 1.1 skrll 77 1.1 skrll /* This structure is used to hold a list of N_BINCL symbols, some of 78 1.1 skrll which might be converted into N_EXCL symbols. */ 79 1.1 skrll 80 1.1 skrll struct stab_excl_list 81 1.1 skrll { 82 1.1 skrll /* The next symbol to convert. */ 83 1.1 skrll struct stab_excl_list *next; 84 1.1 skrll /* The offset to this symbol in the section contents. */ 85 1.1 skrll bfd_size_type offset; 86 1.1 skrll /* The value to use for the symbol. */ 87 1.1 skrll bfd_vma val; 88 1.1 skrll /* The type of this symbol (N_BINCL or N_EXCL). */ 89 1.1 skrll int type; 90 1.1 skrll }; 91 1.1 skrll 92 1.1 skrll /* This structure is stored with each .stab section. */ 93 1.1 skrll 94 1.1 skrll struct stab_section_info 95 1.1 skrll { 96 1.1 skrll /* This is a linked list of N_BINCL symbols which should be 97 1.1 skrll converted into N_EXCL symbols. */ 98 1.1 skrll struct stab_excl_list *excls; 99 1.1 skrll 100 1.1 skrll /* This is used to map input stab offsets within their sections 101 1.1 skrll to output stab offsets, to take into account stabs that have 102 1.1 skrll been deleted. If it is NULL, the output offsets are the same 103 1.1 skrll as the input offsets, because no stabs have been deleted from 104 1.1 skrll this section. Otherwise the i'th entry is the number of 105 1.1 skrll bytes of stabs that have been deleted prior to the i'th 106 1.1 skrll stab. */ 107 1.1 skrll bfd_size_type *cumulative_skips; 108 1.1 skrll 109 1.1 skrll /* This is an array of string indices. For each stab symbol, we 110 1.1 skrll store the string index here. If a stab symbol should not be 111 1.1 skrll included in the final output, the string index is -1. */ 112 1.1 skrll bfd_size_type stridxs[1]; 113 1.1 skrll }; 114 1.1 skrll 115 1.1.1.9 christos /* 116 1.1.1.9 christos EXTERNAL 117 1.1.1.9 christos .{* This structure is used to keep track of stabs in sections 118 1.1.1.9 christos . information while linking. *} 119 1.1.1.9 christos . 120 1.1.1.9 christos .struct stab_info 121 1.1.1.9 christos .{ 122 1.1.1.9 christos . {* A hash table used to hold stabs strings. *} 123 1.1.1.9 christos . struct bfd_strtab_hash *strings; 124 1.1.1.9 christos . {* The header file hash table. *} 125 1.1.1.9 christos . struct bfd_hash_table includes; 126 1.1.1.9 christos . {* The first .stabstr section. *} 127 1.1.1.9 christos . struct bfd_section *stabstr; 128 1.1.1.9 christos .}; 129 1.1.1.9 christos . 130 1.1.1.9 christos */ 131 1.1.1.9 christos 132 1.1 skrll /* The function to create a new entry in the header file hash table. */ 133 1.1 skrll 134 1.1 skrll static struct bfd_hash_entry * 135 1.1 skrll stab_link_includes_newfunc (struct bfd_hash_entry *entry, 136 1.1 skrll struct bfd_hash_table *table, 137 1.1 skrll const char *string) 138 1.1 skrll { 139 1.1 skrll struct stab_link_includes_entry *ret = 140 1.1 skrll (struct stab_link_includes_entry *) entry; 141 1.1 skrll 142 1.1 skrll /* Allocate the structure if it has not already been allocated by a 143 1.1 skrll subclass. */ 144 1.1 skrll if (ret == NULL) 145 1.1.1.2 christos ret = (struct stab_link_includes_entry *) 146 1.1.1.5 christos bfd_hash_allocate (table, sizeof (struct stab_link_includes_entry)); 147 1.1 skrll if (ret == NULL) 148 1.1 skrll return NULL; 149 1.1 skrll 150 1.1 skrll /* Call the allocation method of the superclass. */ 151 1.1 skrll ret = ((struct stab_link_includes_entry *) 152 1.1 skrll bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); 153 1.1 skrll if (ret) 154 1.1 skrll /* Set local fields. */ 155 1.1 skrll ret->totals = NULL; 156 1.1 skrll 157 1.1 skrll return (struct bfd_hash_entry *) ret; 158 1.1 skrll } 159 1.1.1.9 christos 160 1.1.1.9 christos /* 161 1.1.1.9 christos INTERNAL_FUNCTION 162 1.1.1.9 christos _bfd_link_section_stabs 163 1.1.1.9 christos 164 1.1.1.9 christos SYNOPSIS 165 1.1.1.9 christos bool _bfd_link_section_stabs 166 1.1.1.11 christos (bfd *, struct stab_info *, asection *, asection *, 167 1.1.1.9 christos bfd_size_type *); 168 1.1.1.9 christos 169 1.1.1.9 christos DESCRIPTION 170 1.1.1.9 christos This function is called for each input file from the add_symbols 171 1.1.1.9 christos pass of the linker. 172 1.1.1.9 christos */ 173 1.1 skrll 174 1.1.1.8 christos bool 175 1.1 skrll _bfd_link_section_stabs (bfd *abfd, 176 1.1 skrll struct stab_info *sinfo, 177 1.1 skrll asection *stabsec, 178 1.1 skrll asection *stabstrsec, 179 1.1 skrll bfd_size_type *pstring_offset) 180 1.1 skrll { 181 1.1.1.8 christos bool first; 182 1.1 skrll bfd_size_type count, amt; 183 1.1 skrll struct stab_section_info *secinfo; 184 1.1 skrll bfd_byte *stabbuf = NULL; 185 1.1 skrll bfd_byte *stabstrbuf = NULL; 186 1.1 skrll bfd_byte *sym, *symend; 187 1.1 skrll bfd_size_type stroff, next_stroff, skip; 188 1.1 skrll bfd_size_type *pstridx; 189 1.1 skrll 190 1.1 skrll if (stabsec->size == 0 191 1.1.1.9 christos || stabstrsec->size == 0 192 1.1.1.9 christos || (stabsec->flags & SEC_HAS_CONTENTS) == 0 193 1.1.1.9 christos || (stabstrsec->flags & SEC_HAS_CONTENTS) == 0) 194 1.1 skrll /* This file does not contain stabs debugging information. */ 195 1.1.1.8 christos return true; 196 1.1 skrll 197 1.1 skrll if (stabsec->size % STABSIZE != 0) 198 1.1 skrll /* Something is wrong with the format of these stab symbols. 199 1.1 skrll Don't try to optimize them. */ 200 1.1.1.8 christos return true; 201 1.1 skrll 202 1.1 skrll if ((stabstrsec->flags & SEC_RELOC) != 0) 203 1.1 skrll /* We shouldn't see relocations in the strings, and we aren't 204 1.1 skrll prepared to handle them. */ 205 1.1.1.8 christos return true; 206 1.1 skrll 207 1.1 skrll if (bfd_is_abs_section (stabsec->output_section) 208 1.1 skrll || bfd_is_abs_section (stabstrsec->output_section)) 209 1.1 skrll /* At least one of the sections is being discarded from the 210 1.1 skrll link, so we should just ignore them. */ 211 1.1.1.8 christos return true; 212 1.1 skrll 213 1.1.1.8 christos first = false; 214 1.1 skrll 215 1.1 skrll if (sinfo->stabstr == NULL) 216 1.1 skrll { 217 1.1 skrll flagword flags; 218 1.1 skrll 219 1.1 skrll /* Initialize the stabs information we need to keep track of. */ 220 1.1.1.8 christos first = true; 221 1.1 skrll sinfo->strings = _bfd_stringtab_init (); 222 1.1 skrll if (sinfo->strings == NULL) 223 1.1 skrll goto error_return; 224 1.1 skrll /* Make sure the first byte is zero. */ 225 1.1.1.8 christos (void) _bfd_stringtab_add (sinfo->strings, "", true, true); 226 1.1 skrll if (! bfd_hash_table_init (&sinfo->includes, 227 1.1 skrll stab_link_includes_newfunc, 228 1.1 skrll sizeof (struct stab_link_includes_entry))) 229 1.1 skrll goto error_return; 230 1.1 skrll flags = (SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING 231 1.1 skrll | SEC_LINKER_CREATED); 232 1.1 skrll sinfo->stabstr = bfd_make_section_anyway_with_flags (abfd, ".stabstr", 233 1.1 skrll flags); 234 1.1 skrll if (sinfo->stabstr == NULL) 235 1.1 skrll goto error_return; 236 1.1 skrll } 237 1.1 skrll 238 1.1 skrll /* Initialize the information we are going to store for this .stab 239 1.1 skrll section. */ 240 1.1 skrll count = stabsec->size / STABSIZE; 241 1.1 skrll 242 1.1 skrll amt = sizeof (struct stab_section_info); 243 1.1 skrll amt += (count - 1) * sizeof (bfd_size_type); 244 1.1.1.11 christos secinfo = bfd_alloc (abfd, amt); 245 1.1.1.11 christos if (secinfo == NULL) 246 1.1 skrll goto error_return; 247 1.1 skrll 248 1.1.1.11 christos stabsec->sec_info = secinfo; 249 1.1.1.11 christos stabsec->sec_info_type = SEC_INFO_TYPE_STABS; 250 1.1 skrll secinfo->excls = NULL; 251 1.1 skrll stabsec->rawsize = stabsec->size; 252 1.1 skrll secinfo->cumulative_skips = NULL; 253 1.1 skrll memset (secinfo->stridxs, 0, (size_t) count * sizeof (bfd_size_type)); 254 1.1 skrll 255 1.1 skrll /* Read the stabs information from abfd. */ 256 1.1 skrll if (!bfd_malloc_and_get_section (abfd, stabsec, &stabbuf) 257 1.1 skrll || !bfd_malloc_and_get_section (abfd, stabstrsec, &stabstrbuf)) 258 1.1 skrll goto error_return; 259 1.1 skrll 260 1.1 skrll /* Look through the stabs symbols, work out the new string indices, 261 1.1 skrll and identify N_BINCL symbols which can be eliminated. */ 262 1.1 skrll stroff = 0; 263 1.1 skrll /* The stabs sections can be split when 264 1.1 skrll -split-by-reloc/-split-by-file is used. We must keep track of 265 1.1 skrll each stab section's place in the single concatenated string 266 1.1 skrll table. */ 267 1.1 skrll next_stroff = pstring_offset ? *pstring_offset : 0; 268 1.1 skrll skip = 0; 269 1.1 skrll 270 1.1 skrll symend = stabbuf + stabsec->size; 271 1.1 skrll for (sym = stabbuf, pstridx = secinfo->stridxs; 272 1.1 skrll sym < symend; 273 1.1 skrll sym += STABSIZE, ++pstridx) 274 1.1 skrll { 275 1.1 skrll bfd_size_type symstroff; 276 1.1 skrll int type; 277 1.1 skrll const char *string; 278 1.1 skrll 279 1.1 skrll if (*pstridx != 0) 280 1.1 skrll /* This symbol has already been handled by an N_BINCL pass. */ 281 1.1 skrll continue; 282 1.1 skrll 283 1.1 skrll type = sym[TYPEOFF]; 284 1.1 skrll 285 1.1 skrll if (type == 0) 286 1.1 skrll { 287 1.1 skrll /* Special type 0 stabs indicate the offset to the next 288 1.1 skrll string table. We only copy the very first one. */ 289 1.1 skrll stroff = next_stroff; 290 1.1 skrll next_stroff += bfd_get_32 (abfd, sym + 8); 291 1.1 skrll if (pstring_offset) 292 1.1 skrll *pstring_offset = next_stroff; 293 1.1 skrll if (! first) 294 1.1 skrll { 295 1.1 skrll *pstridx = (bfd_size_type) -1; 296 1.1 skrll ++skip; 297 1.1 skrll continue; 298 1.1 skrll } 299 1.1.1.8 christos first = false; 300 1.1 skrll } 301 1.1 skrll 302 1.1 skrll /* Store the string in the hash table, and record the index. */ 303 1.1 skrll symstroff = stroff + bfd_get_32 (abfd, sym + STRDXOFF); 304 1.1 skrll if (symstroff >= stabstrsec->size) 305 1.1 skrll { 306 1.1.1.5 christos _bfd_error_handler 307 1.1.1.5 christos /* xgettext:c-format */ 308 1.1.1.6 christos (_("%pB(%pA+%#lx): stabs entry has invalid string index"), 309 1.1 skrll abfd, stabsec, (long) (sym - stabbuf)); 310 1.1 skrll bfd_set_error (bfd_error_bad_value); 311 1.1 skrll goto error_return; 312 1.1 skrll } 313 1.1 skrll string = (char *) stabstrbuf + symstroff; 314 1.1.1.8 christos *pstridx = _bfd_stringtab_add (sinfo->strings, string, true, true); 315 1.1 skrll 316 1.1 skrll /* An N_BINCL symbol indicates the start of the stabs entries 317 1.1 skrll for a header file. We need to scan ahead to the next N_EINCL 318 1.1 skrll symbol, ignoring nesting, adding up all the characters in the 319 1.1 skrll symbol names, not including the file numbers in types (the 320 1.1 skrll first number after an open parenthesis). */ 321 1.1 skrll if (type == (int) N_BINCL) 322 1.1 skrll { 323 1.1 skrll bfd_vma sum_chars; 324 1.1 skrll bfd_vma num_chars; 325 1.1 skrll bfd_vma buf_len = 0; 326 1.1 skrll char * symb; 327 1.1 skrll char * symb_rover; 328 1.1 skrll int nest; 329 1.1 skrll bfd_byte * incl_sym; 330 1.1 skrll struct stab_link_includes_entry * incl_entry; 331 1.1 skrll struct stab_link_includes_totals * t; 332 1.1 skrll struct stab_excl_list * ne; 333 1.1 skrll 334 1.1 skrll symb = symb_rover = NULL; 335 1.1 skrll sum_chars = num_chars = 0; 336 1.1 skrll nest = 0; 337 1.1 skrll 338 1.1 skrll for (incl_sym = sym + STABSIZE; 339 1.1 skrll incl_sym < symend; 340 1.1 skrll incl_sym += STABSIZE) 341 1.1 skrll { 342 1.1 skrll int incl_type; 343 1.1 skrll 344 1.1 skrll incl_type = incl_sym[TYPEOFF]; 345 1.1 skrll if (incl_type == 0) 346 1.1 skrll break; 347 1.1 skrll else if (incl_type == (int) N_EXCL) 348 1.1 skrll continue; 349 1.1 skrll else if (incl_type == (int) N_EINCL) 350 1.1 skrll { 351 1.1 skrll if (nest == 0) 352 1.1 skrll break; 353 1.1 skrll --nest; 354 1.1 skrll } 355 1.1 skrll else if (incl_type == (int) N_BINCL) 356 1.1 skrll ++nest; 357 1.1 skrll else if (nest == 0) 358 1.1 skrll { 359 1.1 skrll const char *str; 360 1.1 skrll 361 1.1 skrll str = ((char *) stabstrbuf 362 1.1 skrll + stroff 363 1.1 skrll + bfd_get_32 (abfd, incl_sym + STRDXOFF)); 364 1.1 skrll for (; *str != '\0'; str++) 365 1.1 skrll { 366 1.1 skrll if (num_chars >= buf_len) 367 1.1 skrll { 368 1.1 skrll buf_len += 32 * 1024; 369 1.1.1.2 christos symb = (char *) bfd_realloc_or_free (symb, buf_len); 370 1.1 skrll if (symb == NULL) 371 1.1 skrll goto error_return; 372 1.1 skrll symb_rover = symb + num_chars; 373 1.1 skrll } 374 1.1 skrll * symb_rover ++ = * str; 375 1.1 skrll sum_chars += *str; 376 1.1 skrll num_chars ++; 377 1.1 skrll if (*str == '(') 378 1.1 skrll { 379 1.1 skrll /* Skip the file number. */ 380 1.1 skrll ++str; 381 1.1 skrll while (ISDIGIT (*str)) 382 1.1 skrll ++str; 383 1.1 skrll --str; 384 1.1 skrll } 385 1.1 skrll } 386 1.1 skrll } 387 1.1 skrll } 388 1.1 skrll 389 1.1 skrll BFD_ASSERT (num_chars == (bfd_vma) (symb_rover - symb)); 390 1.1 skrll 391 1.1 skrll /* If we have already included a header file with the same 392 1.1 skrll value, then replaced this one with an N_EXCL symbol. */ 393 1.1 skrll incl_entry = (struct stab_link_includes_entry * ) 394 1.1.1.8 christos bfd_hash_lookup (&sinfo->includes, string, true, true); 395 1.1 skrll if (incl_entry == NULL) 396 1.1 skrll goto error_return; 397 1.1 skrll 398 1.1 skrll for (t = incl_entry->totals; t != NULL; t = t->next) 399 1.1 skrll if (t->sum_chars == sum_chars 400 1.1 skrll && t->num_chars == num_chars 401 1.1 skrll && memcmp (t->symb, symb, num_chars) == 0) 402 1.1 skrll break; 403 1.1 skrll 404 1.1 skrll /* Record this symbol, so that we can set the value 405 1.1 skrll correctly. */ 406 1.1 skrll amt = sizeof *ne; 407 1.1.1.2 christos ne = (struct stab_excl_list *) bfd_alloc (abfd, amt); 408 1.1 skrll if (ne == NULL) 409 1.1 skrll goto error_return; 410 1.1 skrll ne->offset = sym - stabbuf; 411 1.1 skrll ne->val = sum_chars; 412 1.1 skrll ne->type = (int) N_BINCL; 413 1.1 skrll ne->next = secinfo->excls; 414 1.1 skrll secinfo->excls = ne; 415 1.1 skrll 416 1.1 skrll if (t == NULL) 417 1.1 skrll { 418 1.1 skrll /* This is the first time we have seen this header file 419 1.1 skrll with this set of stabs strings. */ 420 1.1.1.2 christos t = (struct stab_link_includes_totals *) 421 1.1.1.5 christos bfd_hash_allocate (&sinfo->includes, sizeof *t); 422 1.1 skrll if (t == NULL) 423 1.1 skrll goto error_return; 424 1.1 skrll t->sum_chars = sum_chars; 425 1.1 skrll t->num_chars = num_chars; 426 1.1.1.5 christos /* Trim data down. */ 427 1.1.1.2 christos t->symb = symb = (char *) bfd_realloc_or_free (symb, num_chars); 428 1.1 skrll t->next = incl_entry->totals; 429 1.1 skrll incl_entry->totals = t; 430 1.1 skrll } 431 1.1 skrll else 432 1.1 skrll { 433 1.1 skrll bfd_size_type *incl_pstridx; 434 1.1 skrll 435 1.1 skrll /* We have seen this header file before. Tell the final 436 1.1 skrll pass to change the type to N_EXCL. */ 437 1.1 skrll ne->type = (int) N_EXCL; 438 1.1 skrll 439 1.1 skrll /* Free off superfluous symbols. */ 440 1.1 skrll free (symb); 441 1.1 skrll 442 1.1 skrll /* Mark the skipped symbols. */ 443 1.1 skrll 444 1.1 skrll nest = 0; 445 1.1 skrll for (incl_sym = sym + STABSIZE, incl_pstridx = pstridx + 1; 446 1.1 skrll incl_sym < symend; 447 1.1 skrll incl_sym += STABSIZE, ++incl_pstridx) 448 1.1 skrll { 449 1.1 skrll int incl_type; 450 1.1 skrll 451 1.1 skrll incl_type = incl_sym[TYPEOFF]; 452 1.1 skrll 453 1.1 skrll if (incl_type == (int) N_EINCL) 454 1.1 skrll { 455 1.1 skrll if (nest == 0) 456 1.1 skrll { 457 1.1 skrll *incl_pstridx = (bfd_size_type) -1; 458 1.1 skrll ++skip; 459 1.1 skrll break; 460 1.1 skrll } 461 1.1 skrll --nest; 462 1.1 skrll } 463 1.1 skrll else if (incl_type == (int) N_BINCL) 464 1.1 skrll ++nest; 465 1.1 skrll else if (incl_type == (int) N_EXCL) 466 1.1 skrll /* Keep existing exclusion marks. */ 467 1.1 skrll continue; 468 1.1 skrll else if (nest == 0) 469 1.1 skrll { 470 1.1 skrll *incl_pstridx = (bfd_size_type) -1; 471 1.1 skrll ++skip; 472 1.1 skrll } 473 1.1 skrll } 474 1.1 skrll } 475 1.1 skrll } 476 1.1 skrll } 477 1.1 skrll 478 1.1 skrll free (stabbuf); 479 1.1 skrll stabbuf = NULL; 480 1.1 skrll free (stabstrbuf); 481 1.1 skrll stabstrbuf = NULL; 482 1.1 skrll 483 1.1 skrll /* We need to set the section sizes such that the linker will 484 1.1 skrll compute the output section sizes correctly. We set the .stab 485 1.1 skrll size to not include the entries we don't want. We set 486 1.1 skrll SEC_EXCLUDE for the .stabstr section, so that it will be dropped 487 1.1 skrll from the link. We record the size of the strtab in the first 488 1.1 skrll .stabstr section we saw, and make sure we don't set SEC_EXCLUDE 489 1.1 skrll for that section. */ 490 1.1 skrll stabsec->size = (count - skip) * STABSIZE; 491 1.1 skrll if (stabsec->size == 0) 492 1.1 skrll stabsec->flags |= SEC_EXCLUDE | SEC_KEEP; 493 1.1 skrll stabstrsec->flags |= SEC_EXCLUDE | SEC_KEEP; 494 1.1 skrll sinfo->stabstr->size = _bfd_stringtab_size (sinfo->strings); 495 1.1 skrll 496 1.1 skrll /* Calculate the `cumulative_skips' array now that stabs have been 497 1.1 skrll deleted for this section. */ 498 1.1 skrll 499 1.1 skrll if (skip != 0) 500 1.1 skrll { 501 1.1 skrll bfd_size_type i, offset; 502 1.1 skrll bfd_size_type *pskips; 503 1.1 skrll 504 1.1 skrll amt = count * sizeof (bfd_size_type); 505 1.1.1.2 christos secinfo->cumulative_skips = (bfd_size_type *) bfd_alloc (abfd, amt); 506 1.1 skrll if (secinfo->cumulative_skips == NULL) 507 1.1 skrll goto error_return; 508 1.1 skrll 509 1.1 skrll pskips = secinfo->cumulative_skips; 510 1.1 skrll pstridx = secinfo->stridxs; 511 1.1 skrll offset = 0; 512 1.1 skrll 513 1.1 skrll for (i = 0; i < count; i++, pskips++, pstridx++) 514 1.1 skrll { 515 1.1 skrll *pskips = offset; 516 1.1 skrll if (*pstridx == (bfd_size_type) -1) 517 1.1 skrll offset += STABSIZE; 518 1.1 skrll } 519 1.1 skrll 520 1.1 skrll BFD_ASSERT (offset != 0); 521 1.1 skrll } 522 1.1 skrll 523 1.1.1.8 christos return true; 524 1.1 skrll 525 1.1 skrll error_return: 526 1.1.1.8 christos free (stabbuf); 527 1.1.1.8 christos free (stabstrbuf); 528 1.1.1.8 christos return false; 529 1.1 skrll } 530 1.1.1.9 christos 531 1.1.1.9 christos /* 532 1.1.1.9 christos INTERNAL_FUNCTION 533 1.1.1.9 christos _bfd_discard_section_stabs 534 1.1.1.9 christos 535 1.1.1.9 christos SYNOPSIS 536 1.1.1.9 christos bool _bfd_discard_section_stabs 537 1.1.1.11 christos (bfd *, asection *, bool (*) (bfd_vma, void *), void *); 538 1.1.1.9 christos 539 1.1.1.9 christos DESCRIPTION 540 1.1.1.9 christos This function is called for each input file before the stab 541 1.1.1.9 christos section is relocated. It discards stab entries for discarded 542 1.1.1.9 christos functions and variables. The function returns TRUE iff 543 1.1.1.9 christos any entries have been deleted. 544 1.1 skrll */ 545 1.1 skrll 546 1.1.1.8 christos bool 547 1.1 skrll _bfd_discard_section_stabs (bfd *abfd, 548 1.1 skrll asection *stabsec, 549 1.1.1.8 christos bool (*reloc_symbol_deleted_p) (bfd_vma, void *), 550 1.1 skrll void * cookie) 551 1.1 skrll { 552 1.1 skrll bfd_size_type count, amt; 553 1.1 skrll struct stab_section_info *secinfo; 554 1.1 skrll bfd_byte *stabbuf = NULL; 555 1.1 skrll bfd_byte *sym, *symend; 556 1.1 skrll bfd_size_type skip; 557 1.1 skrll bfd_size_type *pstridx; 558 1.1 skrll int deleting; 559 1.1 skrll 560 1.1.1.9 christos if (stabsec->size == 0 || (stabsec->flags & SEC_HAS_CONTENTS) == 0) 561 1.1 skrll /* This file does not contain stabs debugging information. */ 562 1.1.1.8 christos return false; 563 1.1 skrll 564 1.1 skrll if (stabsec->size % STABSIZE != 0) 565 1.1 skrll /* Something is wrong with the format of these stab symbols. 566 1.1 skrll Don't try to optimize them. */ 567 1.1.1.8 christos return false; 568 1.1 skrll 569 1.1 skrll if ((stabsec->output_section != NULL 570 1.1 skrll && bfd_is_abs_section (stabsec->output_section))) 571 1.1 skrll /* At least one of the sections is being discarded from the 572 1.1 skrll link, so we should just ignore them. */ 573 1.1.1.8 christos return false; 574 1.1 skrll 575 1.1.1.3 christos /* We should have initialized our data in _bfd_link_section_stabs. 576 1.1 skrll If there was some bizarre error reading the string sections, though, 577 1.1 skrll we might not have. Bail rather than asserting. */ 578 1.1.1.11 christos if (stabsec->sec_info_type != SEC_INFO_TYPE_STABS) 579 1.1.1.8 christos return false; 580 1.1 skrll 581 1.1 skrll count = stabsec->rawsize / STABSIZE; 582 1.1.1.11 christos secinfo = stabsec->sec_info; 583 1.1 skrll 584 1.1 skrll /* Read the stabs information from abfd. */ 585 1.1 skrll if (!bfd_malloc_and_get_section (abfd, stabsec, &stabbuf)) 586 1.1 skrll goto error_return; 587 1.1 skrll 588 1.1 skrll /* Look through the stabs symbols and discard any information for 589 1.1 skrll discarded functions. */ 590 1.1 skrll skip = 0; 591 1.1 skrll deleting = -1; 592 1.1 skrll 593 1.1 skrll symend = stabbuf + stabsec->rawsize; 594 1.1 skrll for (sym = stabbuf, pstridx = secinfo->stridxs; 595 1.1 skrll sym < symend; 596 1.1 skrll sym += STABSIZE, ++pstridx) 597 1.1 skrll { 598 1.1 skrll int type; 599 1.1 skrll 600 1.1 skrll if (*pstridx == (bfd_size_type) -1) 601 1.1 skrll /* This stab was deleted in a previous pass. */ 602 1.1 skrll continue; 603 1.1 skrll 604 1.1 skrll type = sym[TYPEOFF]; 605 1.1 skrll 606 1.1 skrll if (type == (int) N_FUN) 607 1.1 skrll { 608 1.1 skrll int strx = bfd_get_32 (abfd, sym + STRDXOFF); 609 1.1 skrll 610 1.1 skrll if (strx == 0) 611 1.1 skrll { 612 1.1 skrll if (deleting) 613 1.1 skrll { 614 1.1 skrll skip++; 615 1.1 skrll *pstridx = -1; 616 1.1 skrll } 617 1.1 skrll deleting = -1; 618 1.1 skrll continue; 619 1.1 skrll } 620 1.1 skrll deleting = 0; 621 1.1 skrll if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie)) 622 1.1 skrll deleting = 1; 623 1.1 skrll } 624 1.1 skrll 625 1.1 skrll if (deleting == 1) 626 1.1 skrll { 627 1.1 skrll *pstridx = -1; 628 1.1 skrll skip++; 629 1.1 skrll } 630 1.1 skrll else if (deleting == -1) 631 1.1 skrll { 632 1.1 skrll /* Outside of a function. Check for deleted variables. */ 633 1.1 skrll if (type == (int) N_STSYM || type == (int) N_LCSYM) 634 1.1 skrll if ((*reloc_symbol_deleted_p) (sym + VALOFF - stabbuf, cookie)) 635 1.1 skrll { 636 1.1 skrll *pstridx = -1; 637 1.1 skrll skip ++; 638 1.1 skrll } 639 1.1 skrll /* We should also check for N_GSYM entries which reference a 640 1.1 skrll deleted global, but those are less harmful to debuggers 641 1.1 skrll and would require parsing the stab strings. */ 642 1.1 skrll } 643 1.1 skrll } 644 1.1 skrll 645 1.1 skrll free (stabbuf); 646 1.1 skrll stabbuf = NULL; 647 1.1 skrll 648 1.1 skrll /* Shrink the stabsec as needed. */ 649 1.1 skrll stabsec->size -= skip * STABSIZE; 650 1.1 skrll if (stabsec->size == 0) 651 1.1 skrll stabsec->flags |= SEC_EXCLUDE | SEC_KEEP; 652 1.1 skrll 653 1.1 skrll /* Recalculate the `cumulative_skips' array now that stabs have been 654 1.1 skrll deleted for this section. */ 655 1.1 skrll 656 1.1 skrll if (skip != 0) 657 1.1 skrll { 658 1.1 skrll bfd_size_type i, offset; 659 1.1 skrll bfd_size_type *pskips; 660 1.1 skrll 661 1.1 skrll if (secinfo->cumulative_skips == NULL) 662 1.1 skrll { 663 1.1 skrll amt = count * sizeof (bfd_size_type); 664 1.1.1.2 christos secinfo->cumulative_skips = (bfd_size_type *) bfd_alloc (abfd, amt); 665 1.1 skrll if (secinfo->cumulative_skips == NULL) 666 1.1 skrll goto error_return; 667 1.1 skrll } 668 1.1 skrll 669 1.1 skrll pskips = secinfo->cumulative_skips; 670 1.1 skrll pstridx = secinfo->stridxs; 671 1.1 skrll offset = 0; 672 1.1 skrll 673 1.1 skrll for (i = 0; i < count; i++, pskips++, pstridx++) 674 1.1 skrll { 675 1.1 skrll *pskips = offset; 676 1.1 skrll if (*pstridx == (bfd_size_type) -1) 677 1.1 skrll offset += STABSIZE; 678 1.1 skrll } 679 1.1 skrll 680 1.1 skrll BFD_ASSERT (offset != 0); 681 1.1 skrll } 682 1.1 skrll 683 1.1 skrll return skip > 0; 684 1.1 skrll 685 1.1 skrll error_return: 686 1.1.1.8 christos free (stabbuf); 687 1.1.1.8 christos return false; 688 1.1 skrll } 689 1.1 skrll 690 1.1.1.9 christos /* 691 1.1.1.9 christos INTERNAL_FUNCTION 692 1.1.1.9 christos _bfd_write_section_stabs 693 1.1.1.9 christos 694 1.1.1.9 christos SYNOPSIS 695 1.1.1.9 christos bool _bfd_write_section_stabs 696 1.1.1.11 christos (bfd *, struct stab_info *, asection *, bfd_byte *); 697 1.1.1.9 christos 698 1.1.1.9 christos DESCRIPTION 699 1.1.1.9 christos Write out the stab section. This is called with the relocated 700 1.1.1.9 christos contents. 701 1.1.1.9 christos */ 702 1.1 skrll 703 1.1.1.8 christos bool 704 1.1 skrll _bfd_write_section_stabs (bfd *output_bfd, 705 1.1 skrll struct stab_info *sinfo, 706 1.1 skrll asection *stabsec, 707 1.1 skrll bfd_byte *contents) 708 1.1 skrll { 709 1.1.1.11 christos struct stab_section_info *secinfo = stabsec->sec_info; 710 1.1 skrll struct stab_excl_list *e; 711 1.1 skrll bfd_byte *sym, *tosym, *symend; 712 1.1 skrll bfd_size_type *pstridx; 713 1.1 skrll 714 1.1.1.11 christos if (stabsec->sec_info_type != SEC_INFO_TYPE_STABS) 715 1.1 skrll return bfd_set_section_contents (output_bfd, stabsec->output_section, 716 1.1 skrll contents, stabsec->output_offset, 717 1.1 skrll stabsec->size); 718 1.1 skrll 719 1.1 skrll /* Handle each N_BINCL entry. */ 720 1.1 skrll for (e = secinfo->excls; e != NULL; e = e->next) 721 1.1 skrll { 722 1.1 skrll bfd_byte *excl_sym; 723 1.1 skrll 724 1.1 skrll BFD_ASSERT (e->offset < stabsec->rawsize); 725 1.1 skrll excl_sym = contents + e->offset; 726 1.1 skrll bfd_put_32 (output_bfd, e->val, excl_sym + VALOFF); 727 1.1 skrll excl_sym[TYPEOFF] = e->type; 728 1.1 skrll } 729 1.1 skrll 730 1.1 skrll /* Copy over all the stabs symbols, omitting the ones we don't want, 731 1.1 skrll and correcting the string indices for those we do want. */ 732 1.1 skrll tosym = contents; 733 1.1 skrll symend = contents + stabsec->rawsize; 734 1.1 skrll for (sym = contents, pstridx = secinfo->stridxs; 735 1.1 skrll sym < symend; 736 1.1 skrll sym += STABSIZE, ++pstridx) 737 1.1 skrll { 738 1.1 skrll if (*pstridx != (bfd_size_type) -1) 739 1.1 skrll { 740 1.1 skrll if (tosym != sym) 741 1.1 skrll memcpy (tosym, sym, STABSIZE); 742 1.1 skrll bfd_put_32 (output_bfd, *pstridx, tosym + STRDXOFF); 743 1.1 skrll 744 1.1 skrll if (sym[TYPEOFF] == 0) 745 1.1 skrll { 746 1.1 skrll /* This is the header symbol for the stabs section. We 747 1.1 skrll don't really need one, since we have merged all the 748 1.1 skrll input stabs sections into one, but we generate one 749 1.1 skrll for the benefit of readers which expect to see one. */ 750 1.1 skrll BFD_ASSERT (sym == contents); 751 1.1 skrll bfd_put_32 (output_bfd, _bfd_stringtab_size (sinfo->strings), 752 1.1 skrll tosym + VALOFF); 753 1.1 skrll bfd_put_16 (output_bfd, 754 1.1 skrll stabsec->output_section->size / STABSIZE - 1, 755 1.1 skrll tosym + DESCOFF); 756 1.1 skrll } 757 1.1 skrll 758 1.1 skrll tosym += STABSIZE; 759 1.1 skrll } 760 1.1 skrll } 761 1.1 skrll 762 1.1 skrll BFD_ASSERT ((bfd_size_type) (tosym - contents) == stabsec->size); 763 1.1 skrll 764 1.1 skrll return bfd_set_section_contents (output_bfd, stabsec->output_section, 765 1.1 skrll contents, (file_ptr) stabsec->output_offset, 766 1.1 skrll stabsec->size); 767 1.1 skrll } 768 1.1 skrll 769 1.1.1.9 christos /* 770 1.1.1.9 christos INTERNAL_FUNCTION 771 1.1.1.9 christos _bfd_write_stab_strings 772 1.1.1.9 christos 773 1.1.1.9 christos SYNOPSIS 774 1.1.1.9 christos bool _bfd_write_stab_strings (bfd *, struct stab_info *); 775 1.1.1.9 christos 776 1.1.1.9 christos DESCRIPTION 777 1.1.1.9 christos Write out the .stabstr section. 778 1.1.1.9 christos */ 779 1.1 skrll 780 1.1.1.8 christos bool 781 1.1 skrll _bfd_write_stab_strings (bfd *output_bfd, struct stab_info *sinfo) 782 1.1 skrll { 783 1.1 skrll if (bfd_is_abs_section (sinfo->stabstr->output_section)) 784 1.1 skrll /* The section was discarded from the link. */ 785 1.1.1.8 christos return true; 786 1.1 skrll 787 1.1 skrll BFD_ASSERT ((sinfo->stabstr->output_offset 788 1.1 skrll + _bfd_stringtab_size (sinfo->strings)) 789 1.1 skrll <= sinfo->stabstr->output_section->size); 790 1.1 skrll 791 1.1 skrll if (bfd_seek (output_bfd, 792 1.1 skrll (file_ptr) (sinfo->stabstr->output_section->filepos 793 1.1 skrll + sinfo->stabstr->output_offset), 794 1.1 skrll SEEK_SET) != 0) 795 1.1.1.8 christos return false; 796 1.1 skrll 797 1.1 skrll if (! _bfd_stringtab_emit (output_bfd, sinfo->strings)) 798 1.1.1.8 christos return false; 799 1.1 skrll 800 1.1 skrll /* We no longer need the stabs information. */ 801 1.1 skrll _bfd_stringtab_free (sinfo->strings); 802 1.1 skrll bfd_hash_table_free (&sinfo->includes); 803 1.1 skrll 804 1.1.1.8 christos return true; 805 1.1 skrll } 806 1.1 skrll 807 1.1.1.9 christos /* 808 1.1.1.9 christos INTERNAL_FUNCTION 809 1.1.1.9 christos _bfd_stab_section_offset 810 1.1.1.9 christos 811 1.1.1.9 christos SYNOPSIS 812 1.1.1.11 christos bfd_vma _bfd_stab_section_offset (asection *, bfd_vma); 813 1.1.1.9 christos 814 1.1.1.9 christos DESCRIPTION 815 1.1.1.9 christos Adjust an address in the .stab section. Given OFFSET within 816 1.1.1.9 christos STABSEC, this returns the new offset in the adjusted stab section, 817 1.1.1.9 christos or -1 if the address refers to a stab which has been removed. 818 1.1.1.9 christos */ 819 1.1 skrll 820 1.1 skrll bfd_vma 821 1.1 skrll _bfd_stab_section_offset (asection *stabsec, 822 1.1 skrll bfd_vma offset) 823 1.1 skrll { 824 1.1.1.11 christos struct stab_section_info *secinfo = stabsec->sec_info; 825 1.1 skrll 826 1.1.1.11 christos if (stabsec->sec_info_type != SEC_INFO_TYPE_STABS) 827 1.1 skrll return offset; 828 1.1 skrll 829 1.1 skrll if (offset >= stabsec->rawsize) 830 1.1 skrll return offset - stabsec->rawsize + stabsec->size; 831 1.1 skrll 832 1.1 skrll if (secinfo->cumulative_skips) 833 1.1 skrll { 834 1.1 skrll bfd_vma i; 835 1.1 skrll 836 1.1 skrll i = offset / STABSIZE; 837 1.1 skrll 838 1.1 skrll if (secinfo->stridxs [i] == (bfd_size_type) -1) 839 1.1 skrll return (bfd_vma) -1; 840 1.1 skrll 841 1.1 skrll return offset - secinfo->cumulative_skips [i]; 842 1.1 skrll } 843 1.1 skrll 844 1.1 skrll return offset; 845 1.1 skrll } 846