/src/binutils-gdb/bfd/syms.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Generic symbol-table support for the BFD library. |
2 | | Copyright (C) 1990-2025 Free Software Foundation, Inc. |
3 | | Written by Cygnus Support. |
4 | | |
5 | | This file is part of BFD, the Binary File Descriptor library. |
6 | | |
7 | | This program is free software; you can redistribute it and/or modify |
8 | | it under the terms of the GNU General Public License as published by |
9 | | the Free Software Foundation; either version 3 of the License, or |
10 | | (at your option) any later version. |
11 | | |
12 | | This program is distributed in the hope that it will be useful, |
13 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | GNU General Public License for more details. |
16 | | |
17 | | You should have received a copy of the GNU General Public License |
18 | | along with this program; if not, write to the Free Software |
19 | | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
20 | | MA 02110-1301, USA. */ |
21 | | |
22 | | /* |
23 | | SECTION |
24 | | Symbols |
25 | | |
26 | | BFD tries to maintain as much symbol information as it can when |
27 | | it moves information from file to file. BFD passes information |
28 | | to applications though the <<asymbol>> structure. When the |
29 | | application requests the symbol table, BFD reads the table in |
30 | | the native form and translates parts of it into the internal |
31 | | format. To maintain more than the information passed to |
32 | | applications, some targets keep some information ``behind the |
33 | | scenes'' in a structure only the particular back end knows |
34 | | about. For example, the coff back end keeps the original |
35 | | symbol table structure as well as the canonical structure when |
36 | | a BFD is read in. On output, the coff back end can reconstruct |
37 | | the output symbol table so that no information is lost, even |
38 | | information unique to coff which BFD doesn't know or |
39 | | understand. If a coff symbol table were read, but were written |
40 | | through an a.out back end, all the coff specific information |
41 | | would be lost. The symbol table of a BFD |
42 | | is not necessarily read in until a canonicalize request is |
43 | | made. Then the BFD back end fills in a table provided by the |
44 | | application with pointers to the canonical information. To |
45 | | output symbols, the application provides BFD with a table of |
46 | | pointers to pointers to <<asymbol>>s. This allows applications |
47 | | like the linker to output a symbol as it was read, since the ``behind |
48 | | the scenes'' information will be still available. |
49 | | @menu |
50 | | @* Reading Symbols:: |
51 | | @* Writing Symbols:: |
52 | | @* Mini Symbols:: |
53 | | @* typedef asymbol:: |
54 | | @* symbol handling functions:: |
55 | | @end menu |
56 | | |
57 | | INODE |
58 | | Reading Symbols, Writing Symbols, Symbols, Symbols |
59 | | SUBSECTION |
60 | | Reading symbols |
61 | | |
62 | | There are two stages to reading a symbol table from a BFD: |
63 | | allocating storage, and the actual reading process. This is an |
64 | | excerpt from an application which reads the symbol table: |
65 | | |
66 | | | long storage_needed; |
67 | | | asymbol **symbol_table; |
68 | | | long number_of_symbols; |
69 | | | long i; |
70 | | | |
71 | | | storage_needed = bfd_get_symtab_upper_bound (abfd); |
72 | | | |
73 | | | if (storage_needed < 0) |
74 | | | FAIL |
75 | | | |
76 | | | if (storage_needed == 0) |
77 | | | return; |
78 | | | |
79 | | | symbol_table = xmalloc (storage_needed); |
80 | | | ... |
81 | | | number_of_symbols = |
82 | | | bfd_canonicalize_symtab (abfd, symbol_table); |
83 | | | |
84 | | | if (number_of_symbols < 0) |
85 | | | FAIL |
86 | | | |
87 | | | for (i = 0; i < number_of_symbols; i++) |
88 | | | process_symbol (symbol_table[i]); |
89 | | |
90 | | All storage for the symbols themselves is in an objalloc |
91 | | connected to the BFD; it is freed when the BFD is closed. |
92 | | |
93 | | INODE |
94 | | Writing Symbols, Mini Symbols, Reading Symbols, Symbols |
95 | | SUBSECTION |
96 | | Writing symbols |
97 | | |
98 | | Writing of a symbol table is automatic when a BFD open for |
99 | | writing is closed. The application attaches a vector of |
100 | | pointers to pointers to symbols to the BFD being written, and |
101 | | fills in the symbol count. The close and cleanup code reads |
102 | | through the table provided and performs all the necessary |
103 | | operations. The BFD output code must always be provided with an |
104 | | ``owned'' symbol: one which has come from another BFD, or one |
105 | | which has been created using <<bfd_make_empty_symbol>>. Here is an |
106 | | example showing the creation of a symbol table with only one element: |
107 | | |
108 | | | #include "sysdep.h" |
109 | | | #include "bfd.h" |
110 | | | int main (void) |
111 | | | { |
112 | | | bfd *abfd; |
113 | | | asymbol *ptrs[2]; |
114 | | | asymbol *new; |
115 | | | |
116 | | | abfd = bfd_openw ("foo","a.out-sunos-big"); |
117 | | | bfd_set_format (abfd, bfd_object); |
118 | | | new = bfd_make_empty_symbol (abfd); |
119 | | | new->name = "dummy_symbol"; |
120 | | | new->section = bfd_make_section_old_way (abfd, ".text"); |
121 | | | new->flags = BSF_GLOBAL; |
122 | | | new->value = 0x12345; |
123 | | | |
124 | | | ptrs[0] = new; |
125 | | | ptrs[1] = 0; |
126 | | | |
127 | | | bfd_set_symtab (abfd, ptrs, 1); |
128 | | | bfd_close (abfd); |
129 | | | return 0; |
130 | | | } |
131 | | | |
132 | | | ./makesym |
133 | | | nm foo |
134 | | | 00012345 A dummy_symbol |
135 | | |
136 | | Many formats cannot represent arbitrary symbol information; for |
137 | | instance, the <<a.out>> object format does not allow an |
138 | | arbitrary number of sections. A symbol pointing to a section |
139 | | which is not one of <<.text>>, <<.data>> or <<.bss>> cannot |
140 | | be described. |
141 | | |
142 | | INODE |
143 | | Mini Symbols, typedef asymbol, Writing Symbols, Symbols |
144 | | SUBSECTION |
145 | | Mini Symbols |
146 | | |
147 | | Mini symbols provide read-only access to the symbol table. |
148 | | They use less memory space, but require more time to access. |
149 | | They can be useful for tools like nm or objdump, which may |
150 | | have to handle symbol tables of extremely large executables. |
151 | | |
152 | | The <<bfd_read_minisymbols>> function will read the symbols |
153 | | into memory in an internal form. It will return a <<void *>> |
154 | | pointer to a block of memory, a symbol count, and the size of |
155 | | each symbol. The pointer is allocated using <<malloc>>, and |
156 | | should be freed by the caller when it is no longer needed. |
157 | | |
158 | | The function <<bfd_minisymbol_to_symbol>> will take a pointer |
159 | | to a minisymbol, and a pointer to a structure returned by |
160 | | <<bfd_make_empty_symbol>>, and return a <<asymbol>> structure. |
161 | | The return value may or may not be the same as the value from |
162 | | <<bfd_make_empty_symbol>> which was passed in. |
163 | | |
164 | | */ |
165 | | |
166 | | /* |
167 | | DOCDD |
168 | | INODE |
169 | | typedef asymbol, symbol handling functions, Mini Symbols, Symbols |
170 | | |
171 | | SUBSECTION |
172 | | typedef asymbol |
173 | | |
174 | | An <<asymbol>> has the form: |
175 | | |
176 | | CODE_FRAGMENT |
177 | | .typedef struct bfd_symbol |
178 | | .{ |
179 | | . {* A pointer to the BFD which owns the symbol. This information |
180 | | . is necessary so that a back end can work out what additional |
181 | | . information (invisible to the application writer) is carried |
182 | | . with the symbol. |
183 | | . |
184 | | . This field is *almost* redundant, since you can use section->owner |
185 | | . instead, except that some symbols point to the global sections |
186 | | . bfd_{abs,com,und}_section. This could be fixed by making |
187 | | . these globals be per-bfd (or per-target-flavor). FIXME. *} |
188 | | . struct bfd *the_bfd; {* Use bfd_asymbol_bfd(sym) to access this field. *} |
189 | | . |
190 | | . {* The text of the symbol. The name is left alone, and not copied; the |
191 | | . application may not alter it. *} |
192 | | . const char *name; |
193 | | . |
194 | | . {* The value of the symbol. This really should be a union of a |
195 | | . numeric value with a pointer, since some flags indicate that |
196 | | . a pointer to another symbol is stored here. *} |
197 | | . symvalue value; |
198 | | . |
199 | | . {* Attributes of a symbol. *} |
200 | | .#define BSF_NO_FLAGS 0 |
201 | | . |
202 | | . {* The symbol has local scope; <<static>> in <<C>>. The value |
203 | | . is the offset into the section of the data. *} |
204 | | .#define BSF_LOCAL (1 << 0) |
205 | | . |
206 | | . {* The symbol has global scope; initialized data in <<C>>. The |
207 | | . value is the offset into the section of the data. *} |
208 | | .#define BSF_GLOBAL (1 << 1) |
209 | | . |
210 | | . {* The symbol has global scope and is exported. The value is |
211 | | . the offset into the section of the data. *} |
212 | | .#define BSF_EXPORT BSF_GLOBAL {* No real difference. *} |
213 | | . |
214 | | . {* A normal C symbol would be one of: |
215 | | . <<BSF_LOCAL>>, <<BSF_UNDEFINED>> or <<BSF_GLOBAL>>. *} |
216 | | . |
217 | | . {* The symbol is a debugging record. The value has an arbitrary |
218 | | . meaning, unless BSF_DEBUGGING_RELOC is also set. *} |
219 | | .#define BSF_DEBUGGING (1 << 2) |
220 | | . |
221 | | . {* The symbol denotes a function entry point. Used in ELF, |
222 | | . perhaps others someday. *} |
223 | | .#define BSF_FUNCTION (1 << 3) |
224 | | . |
225 | | . {* Used by the linker. *} |
226 | | .#define BSF_KEEP (1 << 5) |
227 | | . |
228 | | . {* An ELF common symbol. *} |
229 | | .#define BSF_ELF_COMMON (1 << 6) |
230 | | . |
231 | | . {* A weak global symbol, overridable without warnings by |
232 | | . a regular global symbol of the same name. *} |
233 | | .#define BSF_WEAK (1 << 7) |
234 | | . |
235 | | . {* This symbol was created to point to a section, e.g. ELF's |
236 | | . STT_SECTION symbols. *} |
237 | | .#define BSF_SECTION_SYM (1 << 8) |
238 | | . |
239 | | . {* The symbol used to be a common symbol, but now it is |
240 | | . allocated. *} |
241 | | .#define BSF_OLD_COMMON (1 << 9) |
242 | | . |
243 | | . {* In some files the type of a symbol sometimes alters its |
244 | | . location in an output file - ie in coff a <<ISFCN>> symbol |
245 | | . which is also <<C_EXT>> symbol appears where it was |
246 | | . declared and not at the end of a section. This bit is set |
247 | | . by the target BFD part to convey this information. *} |
248 | | .#define BSF_NOT_AT_END (1 << 10) |
249 | | . |
250 | | . {* Signal that the symbol is the label of constructor section. *} |
251 | | .#define BSF_CONSTRUCTOR (1 << 11) |
252 | | . |
253 | | . {* Signal that the symbol is a warning symbol. The name is a |
254 | | . warning. The name of the next symbol is the one to warn about; |
255 | | . if a reference is made to a symbol with the same name as the next |
256 | | . symbol, a warning is issued by the linker. *} |
257 | | .#define BSF_WARNING (1 << 12) |
258 | | . |
259 | | . {* Signal that the symbol is indirect. This symbol is an indirect |
260 | | . pointer to the symbol with the same name as the next symbol. *} |
261 | | .#define BSF_INDIRECT (1 << 13) |
262 | | . |
263 | | . {* BSF_FILE marks symbols that contain a file name. This is used |
264 | | . for ELF STT_FILE symbols. *} |
265 | | .#define BSF_FILE (1 << 14) |
266 | | . |
267 | | . {* Symbol is from dynamic linking information. *} |
268 | | .#define BSF_DYNAMIC (1 << 15) |
269 | | . |
270 | | . {* The symbol denotes a data object. Used in ELF, and perhaps |
271 | | . others someday. *} |
272 | | .#define BSF_OBJECT (1 << 16) |
273 | | . |
274 | | . {* This symbol is a debugging symbol. The value is the offset |
275 | | . into the section of the data. BSF_DEBUGGING should be set |
276 | | . as well. *} |
277 | | .#define BSF_DEBUGGING_RELOC (1 << 17) |
278 | | . |
279 | | . {* This symbol is thread local. Used in ELF. *} |
280 | | .#define BSF_THREAD_LOCAL (1 << 18) |
281 | | . |
282 | | . {* This symbol represents a complex relocation expression, |
283 | | . with the expression tree serialized in the symbol name. *} |
284 | | .#define BSF_RELC (1 << 19) |
285 | | . |
286 | | . {* This symbol represents a signed complex relocation expression, |
287 | | . with the expression tree serialized in the symbol name. *} |
288 | | .#define BSF_SRELC (1 << 20) |
289 | | . |
290 | | . {* This symbol was created by bfd_get_synthetic_symtab. *} |
291 | | .#define BSF_SYNTHETIC (1 << 21) |
292 | | . |
293 | | . {* This symbol is an indirect code object. Unrelated to BSF_INDIRECT. |
294 | | . The dynamic linker will compute the value of this symbol by |
295 | | . calling the function that it points to. BSF_FUNCTION must |
296 | | . also be also set. *} |
297 | | .#define BSF_GNU_INDIRECT_FUNCTION (1 << 22) |
298 | | . {* This symbol is a globally unique data object. The dynamic linker |
299 | | . will make sure that in the entire process there is just one symbol |
300 | | . with this name and type in use. BSF_OBJECT must also be set. *} |
301 | | .#define BSF_GNU_UNIQUE (1 << 23) |
302 | | . |
303 | | . {* This section symbol should be included in the symbol table. *} |
304 | | .#define BSF_SECTION_SYM_USED (1 << 24) |
305 | | . |
306 | | . flagword flags; |
307 | | . |
308 | | . {* A pointer to the section to which this symbol is |
309 | | . relative. This will always be non NULL, there are special |
310 | | . sections for undefined and absolute symbols. *} |
311 | | . struct bfd_section *section; |
312 | | . |
313 | | . {* Back end special data. *} |
314 | | . union |
315 | | . { |
316 | | . void *p; |
317 | | . bfd_vma i; |
318 | | . } |
319 | | . udata; |
320 | | .} |
321 | | .asymbol; |
322 | | . |
323 | | |
324 | | EXTERNAL |
325 | | .typedef enum bfd_print_symbol |
326 | | .{ |
327 | | . bfd_print_symbol_name, |
328 | | . bfd_print_symbol_more, |
329 | | . bfd_print_symbol_all |
330 | | .} bfd_print_symbol_type; |
331 | | . |
332 | | .{* Information about a symbol that nm needs. *} |
333 | | . |
334 | | .typedef struct _symbol_info |
335 | | .{ |
336 | | . symvalue value; |
337 | | . char type; |
338 | | . const char *name; {* Symbol name. *} |
339 | | . unsigned char stab_type; {* Stab type. *} |
340 | | . char stab_other; {* Stab other. *} |
341 | | . short stab_desc; {* Stab desc. *} |
342 | | . const char *stab_name; {* String for stab type. *} |
343 | | .} symbol_info; |
344 | | . |
345 | | .{* An empty string that will not match the address of any other |
346 | | . symbol name, even unnamed local symbols which will also have empty |
347 | | . string names. This can be used to flag a symbol as corrupt if its |
348 | | . name uses an out of range string table index. *} |
349 | | .extern const char bfd_symbol_error_name[]; |
350 | | */ |
351 | | |
352 | | #include "sysdep.h" |
353 | | #include "bfd.h" |
354 | | #include "libbfd.h" |
355 | | #include "safe-ctype.h" |
356 | | #include "bfdlink.h" |
357 | | #include "aout/stab_gnu.h" |
358 | | |
359 | | const char bfd_symbol_error_name[] = { 0 }; |
360 | | |
361 | | /* |
362 | | DOCDD |
363 | | INODE |
364 | | symbol handling functions, , typedef asymbol, Symbols |
365 | | SUBSECTION |
366 | | Symbol handling functions |
367 | | */ |
368 | | |
369 | | /* |
370 | | FUNCTION |
371 | | bfd_get_symtab_upper_bound |
372 | | |
373 | | DESCRIPTION |
374 | | Return the number of bytes required to store a vector of pointers |
375 | | to <<asymbols>> for all the symbols in the BFD @var{abfd}, |
376 | | including a terminal NULL pointer. If there are no symbols in |
377 | | the BFD, then return 0. If an error occurs, return -1. |
378 | | |
379 | | .#define bfd_get_symtab_upper_bound(abfd) \ |
380 | | . BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd)) |
381 | | . |
382 | | */ |
383 | | |
384 | | /* |
385 | | FUNCTION |
386 | | bfd_is_local_label |
387 | | |
388 | | SYNOPSIS |
389 | | bool bfd_is_local_label (bfd *abfd, asymbol *sym); |
390 | | |
391 | | DESCRIPTION |
392 | | Return TRUE if the given symbol @var{sym} in the BFD @var{abfd} is |
393 | | a compiler generated local label, else return FALSE. |
394 | | */ |
395 | | |
396 | | bool |
397 | | bfd_is_local_label (bfd *abfd, asymbol *sym) |
398 | 10 | { |
399 | | /* The BSF_SECTION_SYM check is needed for IA-64, where every label that |
400 | | starts with '.' is local. This would accidentally catch section names |
401 | | if we didn't reject them here. */ |
402 | 10 | if ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_FILE | BSF_SECTION_SYM)) != 0) |
403 | 0 | return false; |
404 | 10 | if (sym->name == NULL || sym->name == bfd_symbol_error_name) |
405 | 0 | return false; |
406 | 10 | return bfd_is_local_label_name (abfd, sym->name); |
407 | 10 | } |
408 | | |
409 | | /* |
410 | | FUNCTION |
411 | | bfd_is_local_label_name |
412 | | |
413 | | SYNOPSIS |
414 | | bool bfd_is_local_label_name (bfd *abfd, const char *name); |
415 | | |
416 | | DESCRIPTION |
417 | | Return TRUE if a symbol with the name @var{name} in the BFD |
418 | | @var{abfd} is a compiler generated local label, else return |
419 | | FALSE. This just checks whether the name has the form of a |
420 | | local label. |
421 | | |
422 | | .#define bfd_is_local_label_name(abfd, name) \ |
423 | | . BFD_SEND (abfd, _bfd_is_local_label_name, (abfd, name)) |
424 | | . |
425 | | */ |
426 | | |
427 | | /* |
428 | | FUNCTION |
429 | | bfd_is_target_special_symbol |
430 | | |
431 | | SYNOPSIS |
432 | | bool bfd_is_target_special_symbol (bfd *abfd, asymbol *sym); |
433 | | |
434 | | DESCRIPTION |
435 | | Return TRUE iff a symbol @var{sym} in the BFD @var{abfd} is something |
436 | | special to the particular target represented by the BFD. Such symbols |
437 | | should normally not be mentioned to the user. |
438 | | |
439 | | .#define bfd_is_target_special_symbol(abfd, sym) \ |
440 | | . BFD_SEND (abfd, _bfd_is_target_special_symbol, (abfd, sym)) |
441 | | . |
442 | | */ |
443 | | |
444 | | /* |
445 | | FUNCTION |
446 | | bfd_canonicalize_symtab |
447 | | |
448 | | DESCRIPTION |
449 | | Read the symbols from the BFD @var{abfd}, and fills in |
450 | | the vector @var{location} with pointers to the symbols and |
451 | | a trailing NULL. |
452 | | Return the actual number of symbol pointers, not |
453 | | including the NULL. |
454 | | |
455 | | .#define bfd_canonicalize_symtab(abfd, location) \ |
456 | | . BFD_SEND (abfd, _bfd_canonicalize_symtab, (abfd, location)) |
457 | | . |
458 | | */ |
459 | | |
460 | | /* |
461 | | FUNCTION |
462 | | bfd_set_symtab |
463 | | |
464 | | SYNOPSIS |
465 | | bool bfd_set_symtab |
466 | | (bfd *abfd, asymbol **location, unsigned int count); |
467 | | |
468 | | DESCRIPTION |
469 | | Arrange that when the output BFD @var{abfd} is closed, |
470 | | the table @var{location} of @var{count} pointers to symbols |
471 | | will be written. |
472 | | */ |
473 | | |
474 | | bool |
475 | | bfd_set_symtab (bfd *abfd, asymbol **location, unsigned int symcount) |
476 | 305 | { |
477 | 305 | if (abfd->format != bfd_object || bfd_read_p (abfd)) |
478 | 0 | { |
479 | 0 | bfd_set_error (bfd_error_invalid_operation); |
480 | 0 | return false; |
481 | 0 | } |
482 | | |
483 | 305 | abfd->outsymbols = location; |
484 | 305 | abfd->symcount = symcount; |
485 | 305 | return true; |
486 | 305 | } |
487 | | |
488 | | /* |
489 | | FUNCTION |
490 | | bfd_print_symbol_vandf |
491 | | |
492 | | SYNOPSIS |
493 | | void bfd_print_symbol_vandf (bfd *abfd, void *file, asymbol *symbol); |
494 | | |
495 | | DESCRIPTION |
496 | | Print the value and flags of the @var{symbol} supplied to the |
497 | | stream @var{file}. |
498 | | */ |
499 | | void |
500 | | bfd_print_symbol_vandf (bfd *abfd, void *arg, asymbol *symbol) |
501 | 0 | { |
502 | 0 | FILE *file = (FILE *) arg; |
503 | |
|
504 | 0 | flagword type = symbol->flags; |
505 | |
|
506 | 0 | if (symbol->section != NULL) |
507 | 0 | bfd_fprintf_vma (abfd, file, symbol->value + symbol->section->vma); |
508 | 0 | else |
509 | 0 | bfd_fprintf_vma (abfd, file, symbol->value); |
510 | | |
511 | | /* This presumes that a symbol can not be both BSF_DEBUGGING and |
512 | | BSF_DYNAMIC, nor more than one of BSF_FUNCTION, BSF_FILE, and |
513 | | BSF_OBJECT. */ |
514 | 0 | fprintf (file, " %c%c%c%c%c%c%c", |
515 | 0 | ((type & BSF_LOCAL) |
516 | 0 | ? (type & BSF_GLOBAL) ? '!' : 'l' |
517 | 0 | : (type & BSF_GLOBAL) ? 'g' |
518 | 0 | : (type & BSF_GNU_UNIQUE) ? 'u' : ' '), |
519 | 0 | (type & BSF_WEAK) ? 'w' : ' ', |
520 | 0 | (type & BSF_CONSTRUCTOR) ? 'C' : ' ', |
521 | 0 | (type & BSF_WARNING) ? 'W' : ' ', |
522 | 0 | (type & BSF_INDIRECT) ? 'I' : (type & BSF_GNU_INDIRECT_FUNCTION) ? 'i' : ' ', |
523 | 0 | (type & BSF_DEBUGGING) ? 'd' : (type & BSF_DYNAMIC) ? 'D' : ' ', |
524 | 0 | ((type & BSF_FUNCTION) |
525 | 0 | ? 'F' |
526 | 0 | : ((type & BSF_FILE) |
527 | 0 | ? 'f' |
528 | 0 | : ((type & BSF_OBJECT) ? 'O' : ' ')))); |
529 | 0 | } |
530 | | |
531 | | /* |
532 | | FUNCTION |
533 | | bfd_make_empty_symbol |
534 | | |
535 | | DESCRIPTION |
536 | | Create a new <<asymbol>> structure for the BFD @var{abfd} |
537 | | and return a pointer to it. |
538 | | |
539 | | This routine is necessary because each back end has private |
540 | | information surrounding the <<asymbol>>. Building your own |
541 | | <<asymbol>> and pointing to it will not create the private |
542 | | information, and will cause problems later on. |
543 | | |
544 | | .#define bfd_make_empty_symbol(abfd) \ |
545 | | . BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd)) |
546 | | . |
547 | | */ |
548 | | |
549 | | /* |
550 | | FUNCTION |
551 | | _bfd_generic_make_empty_symbol |
552 | | |
553 | | SYNOPSIS |
554 | | asymbol *_bfd_generic_make_empty_symbol (bfd *); |
555 | | |
556 | | DESCRIPTION |
557 | | Create a new <<asymbol>> structure for the BFD @var{abfd} |
558 | | and return a pointer to it. Used by core file routines, |
559 | | binary back-end and anywhere else where no private info |
560 | | is needed. |
561 | | */ |
562 | | |
563 | | asymbol * |
564 | | _bfd_generic_make_empty_symbol (bfd *abfd) |
565 | 1.74M | { |
566 | 1.74M | size_t amt = sizeof (asymbol); |
567 | 1.74M | asymbol *new_symbol = (asymbol *) bfd_zalloc (abfd, amt); |
568 | 1.74M | if (new_symbol) |
569 | 1.74M | new_symbol->the_bfd = abfd; |
570 | 1.74M | return new_symbol; |
571 | 1.74M | } |
572 | | |
573 | | /* |
574 | | FUNCTION |
575 | | bfd_make_debug_symbol |
576 | | |
577 | | DESCRIPTION |
578 | | Create a new <<asymbol>> structure for the BFD @var{abfd}, |
579 | | to be used as a debugging symbol. |
580 | | |
581 | | .#define bfd_make_debug_symbol(abfd) \ |
582 | | . BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd)) |
583 | | . |
584 | | */ |
585 | | |
586 | | struct section_to_type |
587 | | { |
588 | | const char *section; |
589 | | char type; |
590 | | }; |
591 | | |
592 | | /* Map special section names to POSIX/BSD single-character symbol types. |
593 | | This table is probably incomplete. It is sorted for convenience of |
594 | | adding entries. Since it is so short, a linear search is used. */ |
595 | | static const struct section_to_type stt[] = |
596 | | { |
597 | | {".didat", 'i'}, /* MSVC's .didat (delay import) section */ |
598 | | {".drectve", 'i'}, /* MSVC's .drective section */ |
599 | | {".edata", 'e'}, /* MSVC's .edata (export) section */ |
600 | | {".idata", 'i'}, /* MSVC's .idata (import) section */ |
601 | | {".pdata", 'p'}, /* MSVC's .pdata (stack unwind) section */ |
602 | | {0, 0} |
603 | | }; |
604 | | |
605 | | /* Return the single-character symbol type corresponding to |
606 | | section S, or '?' for an unknown COFF section. |
607 | | |
608 | | Check for leading strings which match, followed by a number, '.', |
609 | | or '$' so .idata5 matches the .idata entry. */ |
610 | | |
611 | | static char |
612 | | coff_section_type (const char *s) |
613 | 145k | { |
614 | 145k | const struct section_to_type *t; |
615 | | |
616 | 849k | for (t = &stt[0]; t->section; t++) |
617 | 715k | { |
618 | 715k | size_t len = strlen (t->section); |
619 | 715k | if (strncmp (s, t->section, len) == 0 |
620 | 715k | && memchr (".$0123456789", s[len], 13) != 0) |
621 | 11.5k | return t->type; |
622 | 715k | } |
623 | | |
624 | 133k | return '?'; |
625 | 145k | } |
626 | | |
627 | | /* Return the single-character symbol type corresponding to section |
628 | | SECTION, or '?' for an unknown section. This uses section flags to |
629 | | identify sections. |
630 | | |
631 | | FIXME These types are unhandled: e, i, p. If we handled these also, |
632 | | we could perhaps obsolete coff_section_type. */ |
633 | | |
634 | | static char |
635 | | decode_section_type (const struct bfd_section *section) |
636 | 133k | { |
637 | 133k | if (section->flags & SEC_CODE) |
638 | 61.1k | return 't'; |
639 | 72.5k | if (section->flags & SEC_DATA) |
640 | 42.4k | { |
641 | 42.4k | if (section->flags & SEC_READONLY) |
642 | 21.5k | return 'r'; |
643 | 20.8k | else if (section->flags & SEC_SMALL_DATA) |
644 | 26 | return 'g'; |
645 | 20.8k | else |
646 | 20.8k | return 'd'; |
647 | 42.4k | } |
648 | 30.0k | if ((section->flags & SEC_HAS_CONTENTS) == 0) |
649 | 19.6k | { |
650 | 19.6k | if (section->flags & SEC_SMALL_DATA) |
651 | 3 | return 's'; |
652 | 19.6k | else |
653 | 19.6k | return 'b'; |
654 | 19.6k | } |
655 | 10.4k | if (section->flags & SEC_DEBUGGING) |
656 | 9.25k | return 'N'; |
657 | 1.18k | if ((section->flags & SEC_HAS_CONTENTS) && (section->flags & SEC_READONLY)) |
658 | 632 | return 'n'; |
659 | | |
660 | 551 | return '?'; |
661 | 1.18k | } |
662 | | |
663 | | /* |
664 | | FUNCTION |
665 | | bfd_decode_symclass |
666 | | |
667 | | SYNOPSIS |
668 | | int bfd_decode_symclass (asymbol *symbol); |
669 | | |
670 | | DESCRIPTION |
671 | | Return a character corresponding to the symbol |
672 | | class of @var{symbol}, or '?' for an unknown class. |
673 | | */ |
674 | | int |
675 | | bfd_decode_symclass (asymbol *symbol) |
676 | 2.04M | { |
677 | 2.04M | char c; |
678 | | |
679 | | /* Paranoia... */ |
680 | 2.04M | if (symbol == NULL || symbol->section == NULL) |
681 | 0 | return '?'; |
682 | | |
683 | 2.04M | if (symbol->section && bfd_is_com_section (symbol->section)) |
684 | 24.4k | { |
685 | 24.4k | if (symbol->section->flags & SEC_SMALL_DATA) |
686 | 2 | return 'c'; |
687 | 24.4k | else |
688 | 24.4k | return 'C'; |
689 | 24.4k | } |
690 | 2.01M | if (bfd_is_und_section (symbol->section)) |
691 | 61.0k | { |
692 | 61.0k | if (symbol->flags & BSF_WEAK) |
693 | 3.04k | { |
694 | | /* If weak, determine if it's specifically an object |
695 | | or non-object weak. */ |
696 | 3.04k | if (symbol->flags & BSF_OBJECT) |
697 | 11 | return 'v'; |
698 | 3.03k | else |
699 | 3.03k | return 'w'; |
700 | 3.04k | } |
701 | 58.0k | else |
702 | 58.0k | return 'U'; |
703 | 61.0k | } |
704 | 1.95M | if (bfd_is_ind_section (symbol->section)) |
705 | 146 | return 'I'; |
706 | 1.95M | if (symbol->flags & BSF_GNU_INDIRECT_FUNCTION) |
707 | 77 | return 'i'; |
708 | 1.95M | if (symbol->flags & BSF_WEAK) |
709 | 7.54k | { |
710 | | /* If weak, determine if it's specifically an object |
711 | | or non-object weak. */ |
712 | 7.54k | if (symbol->flags & BSF_OBJECT) |
713 | 750 | return 'V'; |
714 | 6.79k | else |
715 | 6.79k | return 'W'; |
716 | 7.54k | } |
717 | 1.94M | if (symbol->flags & BSF_GNU_UNIQUE) |
718 | 5 | return 'u'; |
719 | 1.94M | if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL))) |
720 | 15.5k | return '?'; |
721 | | |
722 | 1.93M | if (bfd_is_abs_section (symbol->section)) |
723 | 1.78M | c = 'a'; |
724 | 145k | else if (symbol->section) |
725 | 145k | { |
726 | 145k | c = coff_section_type (symbol->section->name); |
727 | 145k | if (c == '?') |
728 | 133k | c = decode_section_type (symbol->section); |
729 | 145k | } |
730 | 0 | else |
731 | 0 | return '?'; |
732 | 1.93M | if (symbol->flags & BSF_GLOBAL) |
733 | 53.6k | c = TOUPPER (c); |
734 | 1.93M | return c; |
735 | | |
736 | | /* We don't have to handle these cases just yet, but we will soon: |
737 | | N_SETV: 'v'; |
738 | | N_SETA: 'l'; |
739 | | N_SETT: 'x'; |
740 | | N_SETD: 'z'; |
741 | | N_SETB: 's'; |
742 | | N_INDR: 'i'; |
743 | | */ |
744 | 1.93M | } |
745 | | |
746 | | /* |
747 | | FUNCTION |
748 | | bfd_is_undefined_symclass |
749 | | |
750 | | SYNOPSIS |
751 | | bool bfd_is_undefined_symclass (int symclass); |
752 | | |
753 | | DESCRIPTION |
754 | | Returns non-zero if the class symbol returned by |
755 | | bfd_decode_symclass represents an undefined symbol. |
756 | | Returns zero otherwise. |
757 | | */ |
758 | | |
759 | | bool |
760 | | bfd_is_undefined_symclass (int symclass) |
761 | 4.00M | { |
762 | 4.00M | return symclass == 'U' || symclass == 'w' || symclass == 'v'; |
763 | 4.00M | } |
764 | | |
765 | | /* |
766 | | FUNCTION |
767 | | bfd_symbol_info |
768 | | |
769 | | SYNOPSIS |
770 | | void bfd_symbol_info (asymbol *symbol, symbol_info *ret); |
771 | | |
772 | | DESCRIPTION |
773 | | Fill in the basic info about symbol that nm needs. |
774 | | Additional info may be added by the back-ends after |
775 | | calling this function. |
776 | | */ |
777 | | |
778 | | void |
779 | | bfd_symbol_info (asymbol *symbol, symbol_info *ret) |
780 | 2.00M | { |
781 | 2.00M | ret->type = bfd_decode_symclass (symbol); |
782 | | |
783 | 2.00M | if (bfd_is_undefined_symclass (ret->type)) |
784 | 44.7k | ret->value = 0; |
785 | 1.95M | else |
786 | 1.95M | ret->value = symbol->value + symbol->section->vma; |
787 | | |
788 | 2.00M | ret->name = (symbol->name != bfd_symbol_error_name |
789 | 2.00M | ? symbol->name : _("<corrupt>")); |
790 | 2.00M | } |
791 | | |
792 | | /* |
793 | | FUNCTION |
794 | | bfd_copy_private_symbol_data |
795 | | |
796 | | SYNOPSIS |
797 | | bool bfd_copy_private_symbol_data |
798 | | (bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym); |
799 | | |
800 | | DESCRIPTION |
801 | | Copy private symbol information from @var{isym} in the BFD |
802 | | @var{ibfd} to the symbol @var{osym} in the BFD @var{obfd}. |
803 | | Return <<TRUE>> on success, <<FALSE>> on error. Possible error |
804 | | returns are: |
805 | | |
806 | | o <<bfd_error_no_memory>> - |
807 | | Not enough memory exists to create private data for @var{osec}. |
808 | | |
809 | | .#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \ |
810 | | . BFD_SEND (obfd, _bfd_copy_private_symbol_data, \ |
811 | | . (ibfd, isymbol, obfd, osymbol)) |
812 | | . |
813 | | */ |
814 | | |
815 | | /* The generic version of the function which returns mini symbols. |
816 | | This is used when the backend does not provide a more efficient |
817 | | version. It just uses BFD asymbol structures as mini symbols. */ |
818 | | |
819 | | long |
820 | | _bfd_generic_read_minisymbols (bfd *abfd, |
821 | | bool dynamic, |
822 | | void **minisymsp, |
823 | | unsigned int *sizep) |
824 | 13.9k | { |
825 | 13.9k | long storage; |
826 | 13.9k | asymbol **syms = NULL; |
827 | 13.9k | long symcount; |
828 | | |
829 | 13.9k | if (dynamic) |
830 | 0 | storage = bfd_get_dynamic_symtab_upper_bound (abfd); |
831 | 13.9k | else |
832 | 13.9k | storage = bfd_get_symtab_upper_bound (abfd); |
833 | 13.9k | if (storage < 0) |
834 | 9.66k | goto error_return; |
835 | 4.31k | if (storage == 0) |
836 | 15 | return 0; |
837 | | |
838 | 4.30k | syms = (asymbol **) bfd_malloc (storage); |
839 | 4.30k | if (syms == NULL) |
840 | 0 | goto error_return; |
841 | | |
842 | 4.30k | if (dynamic) |
843 | 0 | symcount = bfd_canonicalize_dynamic_symtab (abfd, syms); |
844 | 4.30k | else |
845 | 4.30k | symcount = bfd_canonicalize_symtab (abfd, syms); |
846 | 4.30k | if (symcount < 0) |
847 | 363 | goto error_return; |
848 | | |
849 | 3.94k | if (symcount == 0) |
850 | | /* We return 0 above when storage is 0. Exit in the same state |
851 | | here, so as to not complicate callers with having to deal with |
852 | | freeing memory for zero symcount. */ |
853 | 79 | free (syms); |
854 | 3.86k | else |
855 | 3.86k | { |
856 | 3.86k | *minisymsp = syms; |
857 | 3.86k | *sizep = sizeof (asymbol *); |
858 | 3.86k | } |
859 | 3.94k | return symcount; |
860 | | |
861 | 10.0k | error_return: |
862 | 10.0k | bfd_set_error (bfd_error_no_symbols); |
863 | 10.0k | free (syms); |
864 | 10.0k | return -1; |
865 | 4.30k | } |
866 | | |
867 | | /* The generic version of the function which converts a minisymbol to |
868 | | an asymbol. We don't worry about the sym argument we are passed; |
869 | | we just return the asymbol the minisymbol points to. */ |
870 | | |
871 | | asymbol * |
872 | | _bfd_generic_minisymbol_to_symbol (bfd *abfd ATTRIBUTE_UNUSED, |
873 | | bool dynamic ATTRIBUTE_UNUSED, |
874 | | const void *minisym, |
875 | | asymbol *sym ATTRIBUTE_UNUSED) |
876 | 3.18M | { |
877 | 3.18M | return *(asymbol **) minisym; |
878 | 3.18M | } |
879 | | |
880 | | /* Look through stabs debugging information in .stab and .stabstr |
881 | | sections to find the source file and line closest to a desired |
882 | | location. This is used by COFF and ELF targets. It sets *pfound |
883 | | to TRUE if it finds some information. The *pinfo field is used to |
884 | | pass cached information in and out of this routine; this first time |
885 | | the routine is called for a BFD, *pinfo should be NULL. The value |
886 | | placed in *pinfo should be saved with the BFD, and passed back each |
887 | | time this function is called. */ |
888 | | |
889 | | /* We use a cache by default. */ |
890 | | |
891 | | #define ENABLE_CACHING |
892 | | |
893 | | /* We keep an array of indexentry structures to record where in the |
894 | | stabs section we should look to find line number information for a |
895 | | particular address. */ |
896 | | |
897 | | struct indexentry |
898 | | { |
899 | | bfd_vma val; |
900 | | bfd_byte *stab; |
901 | | bfd_byte *str; |
902 | | char *directory_name; |
903 | | char *file_name; |
904 | | char *function_name; |
905 | | int idx; |
906 | | }; |
907 | | |
908 | | /* Compare two indexentry structures. This is called via qsort. */ |
909 | | |
910 | | static int |
911 | | cmpindexentry (const void *a, const void *b) |
912 | 10.0k | { |
913 | 10.0k | const struct indexentry *contestantA = (const struct indexentry *) a; |
914 | 10.0k | const struct indexentry *contestantB = (const struct indexentry *) b; |
915 | | |
916 | 10.0k | if (contestantA->val < contestantB->val) |
917 | 2.42k | return -1; |
918 | 7.62k | if (contestantA->val > contestantB->val) |
919 | 3.51k | return 1; |
920 | 4.11k | return contestantA->idx - contestantB->idx; |
921 | 7.62k | } |
922 | | |
923 | | /* A pointer to this structure is stored in *pinfo. */ |
924 | | |
925 | | struct stab_find_info |
926 | | { |
927 | | /* The .stab section. */ |
928 | | asection *stabsec; |
929 | | /* The .stabstr section. */ |
930 | | asection *strsec; |
931 | | /* The contents of the .stab section. */ |
932 | | bfd_byte *stabs; |
933 | | /* The contents of the .stabstr section. */ |
934 | | bfd_byte *strs; |
935 | | |
936 | | /* A table that indexes stabs by memory address. */ |
937 | | struct indexentry *indextable; |
938 | | /* The number of entries in indextable. */ |
939 | | int indextablesize; |
940 | | |
941 | | #ifdef ENABLE_CACHING |
942 | | /* Cached values to restart quickly. */ |
943 | | struct indexentry *cached_indexentry; |
944 | | bfd_vma cached_offset; |
945 | | bfd_byte *cached_stab; |
946 | | char *cached_file_name; |
947 | | #endif |
948 | | |
949 | | /* Saved ptr to malloc'ed filename. */ |
950 | | char *filename; |
951 | | }; |
952 | | |
953 | | bool |
954 | | _bfd_stab_section_find_nearest_line (bfd *abfd, |
955 | | asymbol **symbols, |
956 | | asection *section, |
957 | | bfd_vma offset, |
958 | | bool *pfound, |
959 | | const char **pfilename, |
960 | | const char **pfnname, |
961 | | unsigned int *pline, |
962 | | void **pinfo) |
963 | 176k | { |
964 | 176k | struct stab_find_info *info; |
965 | 176k | bfd_size_type stabsize, strsize; |
966 | 176k | bfd_byte *stab, *str; |
967 | 176k | bfd_byte *nul_fun, *nul_str; |
968 | 176k | bfd_size_type stroff; |
969 | 176k | struct indexentry *indexentry; |
970 | 176k | char *file_name; |
971 | 176k | char *directory_name; |
972 | 176k | bool saw_line, saw_func; |
973 | | |
974 | 176k | *pfound = false; |
975 | 176k | *pfilename = bfd_get_filename (abfd); |
976 | 176k | *pfnname = NULL; |
977 | 176k | *pline = 0; |
978 | | |
979 | | /* Stabs entries use a 12 byte format: |
980 | | 4 byte string table index |
981 | | 1 byte stab type |
982 | | 1 byte stab other field |
983 | | 2 byte stab desc field |
984 | | 4 byte stab value |
985 | | FIXME: This will have to change for a 64 bit object format. |
986 | | |
987 | | The stabs symbols are divided into compilation units. For the |
988 | | first entry in each unit, the type of 0, the value is the length |
989 | | of the string table for this unit, and the desc field is the |
990 | | number of stabs symbols for this unit. */ |
991 | | |
992 | 176k | #define STRDXOFF (0) |
993 | 249k | #define TYPEOFF (4) |
994 | 176k | #define OTHEROFF (5) |
995 | 176k | #define DESCOFF (6) |
996 | 176k | #define VALOFF (8) |
997 | 187k | #define STABSIZE (12) |
998 | | |
999 | 176k | info = (struct stab_find_info *) *pinfo; |
1000 | 176k | if (info != NULL) |
1001 | 168k | { |
1002 | 168k | if (info->stabsec == NULL || info->strsec == NULL) |
1003 | 165k | { |
1004 | | /* No usable stabs debugging information. */ |
1005 | 165k | return true; |
1006 | 165k | } |
1007 | | |
1008 | 2.79k | stabsize = (info->stabsec->rawsize |
1009 | 2.79k | ? info->stabsec->rawsize |
1010 | 2.79k | : info->stabsec->size); |
1011 | 2.79k | strsize = (info->strsec->rawsize |
1012 | 2.79k | ? info->strsec->rawsize |
1013 | 2.79k | : info->strsec->size); |
1014 | 2.79k | } |
1015 | 8.58k | else |
1016 | 8.58k | { |
1017 | 8.58k | long reloc_size, reloc_count; |
1018 | 8.58k | arelent **reloc_vector; |
1019 | 8.58k | int i; |
1020 | 8.58k | char *function_name; |
1021 | 8.58k | bfd_size_type amt = sizeof *info; |
1022 | | |
1023 | 8.58k | info = (struct stab_find_info *) bfd_zalloc (abfd, amt); |
1024 | 8.58k | if (info == NULL) |
1025 | 0 | return false; |
1026 | 8.58k | *pinfo = info; |
1027 | | |
1028 | | /* FIXME: When using the linker --split-by-file or |
1029 | | --split-by-reloc options, it is possible for the .stab and |
1030 | | .stabstr sections to be split. We should handle that. */ |
1031 | | |
1032 | 8.58k | info->stabsec = bfd_get_section_by_name (abfd, ".stab"); |
1033 | 8.58k | info->strsec = bfd_get_section_by_name (abfd, ".stabstr"); |
1034 | | |
1035 | 8.58k | if (info->stabsec == NULL || info->strsec == NULL) |
1036 | 7.91k | { |
1037 | | /* Try SOM section names. */ |
1038 | 7.91k | info->stabsec = bfd_get_section_by_name (abfd, "$GDB_SYMBOLS$"); |
1039 | 7.91k | info->strsec = bfd_get_section_by_name (abfd, "$GDB_STRINGS$"); |
1040 | | |
1041 | 7.91k | if (info->stabsec == NULL || info->strsec == NULL) |
1042 | 7.91k | return true; |
1043 | 7.91k | } |
1044 | | |
1045 | 667 | if ((info->stabsec->flags & SEC_HAS_CONTENTS) == 0 |
1046 | 667 | || (info->strsec->flags & SEC_HAS_CONTENTS) == 0) |
1047 | 10 | goto out; |
1048 | | |
1049 | 657 | stabsize = (info->stabsec->rawsize |
1050 | 657 | ? info->stabsec->rawsize |
1051 | 657 | : info->stabsec->size); |
1052 | 657 | stabsize = (stabsize / STABSIZE) * STABSIZE; |
1053 | 657 | strsize = (info->strsec->rawsize |
1054 | 657 | ? info->strsec->rawsize |
1055 | 657 | : info->strsec->size); |
1056 | | |
1057 | 657 | if (stabsize == 0 || strsize == 0) |
1058 | 9 | goto out; |
1059 | | |
1060 | 648 | if (!bfd_malloc_and_get_section (abfd, info->stabsec, &info->stabs)) |
1061 | 42 | goto out; |
1062 | 606 | if (!bfd_malloc_and_get_section (abfd, info->strsec, &info->strs)) |
1063 | 3 | goto out1; |
1064 | | |
1065 | | /* Stab strings ought to be nul terminated. Ensure the last one |
1066 | | is, to prevent running off the end of the buffer. */ |
1067 | 603 | info->strs[strsize - 1] = 0; |
1068 | | |
1069 | | /* If this is a relocatable object file, we have to relocate |
1070 | | the entries in .stab. This should always be simple 32 bit |
1071 | | relocations against symbols defined in this object file, so |
1072 | | this should be no big deal. */ |
1073 | 603 | reloc_size = bfd_get_reloc_upper_bound (abfd, info->stabsec); |
1074 | 603 | if (reloc_size < 0) |
1075 | 3 | goto out2; |
1076 | 600 | reloc_vector = (arelent **) bfd_malloc (reloc_size); |
1077 | 600 | if (reloc_vector == NULL && reloc_size != 0) |
1078 | 0 | goto out2; |
1079 | 600 | reloc_count = bfd_canonicalize_reloc (abfd, info->stabsec, reloc_vector, |
1080 | 600 | symbols); |
1081 | 600 | if (reloc_count < 0) |
1082 | 189 | { |
1083 | 238 | out3: |
1084 | 238 | free (reloc_vector); |
1085 | 241 | out2: |
1086 | 241 | free (info->strs); |
1087 | 241 | info->strs = NULL; |
1088 | 244 | out1: |
1089 | 244 | free (info->stabs); |
1090 | 244 | info->stabs = NULL; |
1091 | 305 | out: |
1092 | 305 | info->stabsec = NULL; |
1093 | 305 | return false; |
1094 | 244 | } |
1095 | 411 | if (reloc_count > 0) |
1096 | 179 | { |
1097 | 179 | arelent **pr; |
1098 | | |
1099 | 1.57k | for (pr = reloc_vector; *pr != NULL; pr++) |
1100 | 1.44k | { |
1101 | 1.44k | arelent *r; |
1102 | 1.44k | unsigned long val; |
1103 | 1.44k | asymbol *sym; |
1104 | 1.44k | bfd_size_type octets; |
1105 | | |
1106 | 1.44k | r = *pr; |
1107 | | /* Ignore R_*_NONE relocs. */ |
1108 | 1.44k | if (r->howto->dst_mask == 0) |
1109 | 1.36k | continue; |
1110 | | |
1111 | 79 | octets = r->address * bfd_octets_per_byte (abfd, NULL); |
1112 | 79 | if (r->howto->rightshift != 0 |
1113 | 79 | || bfd_get_reloc_size (r->howto) != 4 |
1114 | 79 | || r->howto->bitsize != 32 |
1115 | 79 | || r->howto->pc_relative |
1116 | 79 | || r->howto->bitpos != 0 |
1117 | 79 | || r->howto->dst_mask != 0xffffffff |
1118 | 79 | || octets > stabsize - 4) |
1119 | 49 | { |
1120 | 49 | _bfd_error_handler |
1121 | 49 | (_("unsupported .stab relocation")); |
1122 | 49 | bfd_set_error (bfd_error_invalid_operation); |
1123 | 49 | goto out3; |
1124 | 49 | } |
1125 | | |
1126 | 30 | val = bfd_get_32 (abfd, info->stabs + octets); |
1127 | 30 | val &= r->howto->src_mask; |
1128 | 30 | sym = *r->sym_ptr_ptr; |
1129 | 30 | val += sym->value + sym->section->vma + r->addend; |
1130 | 30 | bfd_put_32 (abfd, (bfd_vma) val, info->stabs + octets); |
1131 | 30 | } |
1132 | 179 | } |
1133 | | |
1134 | 362 | free (reloc_vector); |
1135 | | |
1136 | | /* First time through this function, build a table matching |
1137 | | function VM addresses to stabs, then sort based on starting |
1138 | | VM address. Do this in two passes: once to count how many |
1139 | | table entries we'll need, and a second to actually build the |
1140 | | table. */ |
1141 | | |
1142 | 362 | info->indextablesize = 0; |
1143 | 362 | nul_fun = NULL; |
1144 | 69.0k | for (stab = info->stabs; stab < info->stabs + stabsize; stab += STABSIZE) |
1145 | 68.7k | { |
1146 | 68.7k | if (stab[TYPEOFF] == (bfd_byte) N_SO) |
1147 | 2.26k | { |
1148 | | /* if we did not see a function def, leave space for one. */ |
1149 | 2.26k | if (nul_fun != NULL) |
1150 | 1.80k | ++info->indextablesize; |
1151 | | |
1152 | | /* N_SO with null name indicates EOF */ |
1153 | 2.26k | if (bfd_get_32 (abfd, stab + STRDXOFF) == 0) |
1154 | 129 | nul_fun = NULL; |
1155 | 2.13k | else |
1156 | 2.13k | { |
1157 | 2.13k | nul_fun = stab; |
1158 | | |
1159 | | /* two N_SO's in a row is a filename and directory. Skip */ |
1160 | 2.13k | if (stab + STABSIZE + TYPEOFF < info->stabs + stabsize |
1161 | 2.13k | && *(stab + STABSIZE + TYPEOFF) == (bfd_byte) N_SO) |
1162 | 1.33k | stab += STABSIZE; |
1163 | 2.13k | } |
1164 | 2.26k | } |
1165 | 66.4k | else if (stab[TYPEOFF] == (bfd_byte) N_FUN |
1166 | 66.4k | && bfd_get_32 (abfd, stab + STRDXOFF) != 0) |
1167 | 889 | { |
1168 | 889 | nul_fun = NULL; |
1169 | 889 | ++info->indextablesize; |
1170 | 889 | } |
1171 | 68.7k | } |
1172 | | |
1173 | 362 | if (nul_fun != NULL) |
1174 | 206 | ++info->indextablesize; |
1175 | | |
1176 | 362 | if (info->indextablesize == 0) |
1177 | 39 | { |
1178 | 39 | free (info->strs); |
1179 | 39 | info->strs = NULL; |
1180 | 39 | free (info->stabs); |
1181 | 39 | info->stabs = NULL; |
1182 | 39 | info->stabsec = NULL; |
1183 | 39 | return true; |
1184 | 39 | } |
1185 | 323 | ++info->indextablesize; |
1186 | | |
1187 | 323 | amt = info->indextablesize; |
1188 | 323 | amt *= sizeof (struct indexentry); |
1189 | 323 | info->indextable = (struct indexentry *) bfd_malloc (amt); |
1190 | 323 | if (info->indextable == NULL) |
1191 | 0 | goto out3; |
1192 | | |
1193 | 323 | file_name = NULL; |
1194 | 323 | directory_name = NULL; |
1195 | 323 | nul_fun = NULL; |
1196 | 323 | stroff = 0; |
1197 | | |
1198 | 323 | for (i = 0, stab = info->stabs, nul_str = str = info->strs; |
1199 | 66.3k | i < info->indextablesize && stab < info->stabs + stabsize; |
1200 | 66.0k | stab += STABSIZE) |
1201 | 66.0k | { |
1202 | 66.0k | switch (stab[TYPEOFF]) |
1203 | 66.0k | { |
1204 | 34.1k | case 0: |
1205 | | /* This is the first entry in a compilation unit. */ |
1206 | 34.1k | if ((bfd_size_type) ((info->strs + strsize) - str) < stroff) |
1207 | 33.0k | break; |
1208 | 1.01k | str += stroff; |
1209 | 1.01k | stroff = bfd_get_32 (abfd, stab + VALOFF); |
1210 | 1.01k | break; |
1211 | | |
1212 | 2.26k | case N_SO: |
1213 | | /* The main file name. */ |
1214 | | |
1215 | | /* The following code creates a new indextable entry with |
1216 | | a NULL function name if there were no N_FUNs in a file. |
1217 | | Note that a N_SO without a file name is an EOF and |
1218 | | there could be 2 N_SO following it with the new filename |
1219 | | and directory. */ |
1220 | 2.26k | if (nul_fun != NULL) |
1221 | 1.80k | { |
1222 | 1.80k | info->indextable[i].val = bfd_get_32 (abfd, nul_fun + VALOFF); |
1223 | 1.80k | info->indextable[i].stab = nul_fun; |
1224 | 1.80k | info->indextable[i].str = nul_str; |
1225 | 1.80k | info->indextable[i].directory_name = directory_name; |
1226 | 1.80k | info->indextable[i].file_name = file_name; |
1227 | 1.80k | info->indextable[i].function_name = NULL; |
1228 | 1.80k | info->indextable[i].idx = i; |
1229 | 1.80k | ++i; |
1230 | 1.80k | } |
1231 | | |
1232 | 2.26k | directory_name = NULL; |
1233 | 2.26k | file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF); |
1234 | 2.26k | if (file_name == (char *) str) |
1235 | 127 | { |
1236 | 127 | file_name = NULL; |
1237 | 127 | nul_fun = NULL; |
1238 | 127 | } |
1239 | 2.13k | else |
1240 | 2.13k | { |
1241 | 2.13k | nul_fun = stab; |
1242 | 2.13k | nul_str = str; |
1243 | 2.13k | if (file_name >= (char *) info->strs + strsize |
1244 | 2.13k | || file_name < (char *) str) |
1245 | 2.08k | file_name = NULL; |
1246 | 2.13k | if (stab + STABSIZE + TYPEOFF < info->stabs + stabsize |
1247 | 2.13k | && *(stab + STABSIZE + TYPEOFF) == (bfd_byte) N_SO) |
1248 | 1.33k | { |
1249 | | /* Two consecutive N_SOs are a directory and a |
1250 | | file name. */ |
1251 | 1.33k | stab += STABSIZE; |
1252 | 1.33k | directory_name = file_name; |
1253 | 1.33k | file_name = ((char *) str |
1254 | 1.33k | + bfd_get_32 (abfd, stab + STRDXOFF)); |
1255 | 1.33k | if (file_name >= (char *) info->strs + strsize |
1256 | 1.33k | || file_name < (char *) str) |
1257 | 1.29k | file_name = NULL; |
1258 | 1.33k | } |
1259 | 2.13k | } |
1260 | 2.26k | break; |
1261 | | |
1262 | 550 | case N_SOL: |
1263 | | /* The name of an include file. */ |
1264 | 550 | file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF); |
1265 | | /* PR 17512: file: 0c680a1f. */ |
1266 | | /* PR 17512: file: 5da8aec4. */ |
1267 | 550 | if (file_name >= (char *) info->strs + strsize |
1268 | 550 | || file_name < (char *) str) |
1269 | 406 | file_name = NULL; |
1270 | 550 | break; |
1271 | | |
1272 | 998 | case N_FUN: |
1273 | | /* A function name. */ |
1274 | 998 | function_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF); |
1275 | 998 | if (function_name == (char *) str) |
1276 | 109 | continue; |
1277 | 889 | if (function_name >= (char *) info->strs + strsize |
1278 | 889 | || function_name < (char *) str) |
1279 | 559 | function_name = NULL; |
1280 | | |
1281 | 889 | nul_fun = NULL; |
1282 | 889 | info->indextable[i].val = bfd_get_32 (abfd, stab + VALOFF); |
1283 | 889 | info->indextable[i].stab = stab; |
1284 | 889 | info->indextable[i].str = str; |
1285 | 889 | info->indextable[i].directory_name = directory_name; |
1286 | 889 | info->indextable[i].file_name = file_name; |
1287 | 889 | info->indextable[i].function_name = function_name; |
1288 | 889 | info->indextable[i].idx = i; |
1289 | 889 | ++i; |
1290 | 889 | break; |
1291 | 66.0k | } |
1292 | 66.0k | } |
1293 | | |
1294 | 323 | if (nul_fun != NULL) |
1295 | 206 | { |
1296 | 206 | info->indextable[i].val = bfd_get_32 (abfd, nul_fun + VALOFF); |
1297 | 206 | info->indextable[i].stab = nul_fun; |
1298 | 206 | info->indextable[i].str = nul_str; |
1299 | 206 | info->indextable[i].directory_name = directory_name; |
1300 | 206 | info->indextable[i].file_name = file_name; |
1301 | 206 | info->indextable[i].function_name = NULL; |
1302 | 206 | info->indextable[i].idx = i; |
1303 | 206 | ++i; |
1304 | 206 | } |
1305 | | |
1306 | 323 | info->indextable[i].val = (bfd_vma) -1; |
1307 | 323 | info->indextable[i].stab = info->stabs + stabsize; |
1308 | 323 | info->indextable[i].str = str; |
1309 | 323 | info->indextable[i].directory_name = NULL; |
1310 | 323 | info->indextable[i].file_name = NULL; |
1311 | 323 | info->indextable[i].function_name = NULL; |
1312 | 323 | info->indextable[i].idx = i; |
1313 | 323 | ++i; |
1314 | | |
1315 | 323 | info->indextablesize = i; |
1316 | 323 | qsort (info->indextable, (size_t) i, sizeof (struct indexentry), |
1317 | 323 | cmpindexentry); |
1318 | 323 | } |
1319 | | |
1320 | | /* We are passed a section relative offset. The offsets in the |
1321 | | stabs information are absolute. */ |
1322 | 3.11k | offset += bfd_section_vma (section); |
1323 | | |
1324 | 3.11k | #ifdef ENABLE_CACHING |
1325 | 3.11k | if (info->cached_indexentry != NULL |
1326 | 3.11k | && offset >= info->cached_offset |
1327 | 3.11k | && offset < (info->cached_indexentry + 1)->val) |
1328 | 309 | { |
1329 | 309 | stab = info->cached_stab; |
1330 | 309 | indexentry = info->cached_indexentry; |
1331 | 309 | file_name = info->cached_file_name; |
1332 | 309 | } |
1333 | 2.80k | else |
1334 | 2.80k | #endif |
1335 | 2.80k | { |
1336 | 2.80k | long low, high; |
1337 | 2.80k | long mid = -1; |
1338 | | |
1339 | | /* Cache non-existent or invalid. Do binary search on |
1340 | | indextable. */ |
1341 | 2.80k | indexentry = NULL; |
1342 | | |
1343 | 2.80k | low = 0; |
1344 | 2.80k | high = info->indextablesize - 1; |
1345 | 7.52k | while (low != high) |
1346 | 5.88k | { |
1347 | 5.88k | mid = (high + low) / 2; |
1348 | 5.88k | if (offset >= info->indextable[mid].val |
1349 | 5.88k | && offset < info->indextable[mid + 1].val) |
1350 | 1.17k | { |
1351 | 1.17k | indexentry = &info->indextable[mid]; |
1352 | 1.17k | break; |
1353 | 1.17k | } |
1354 | | |
1355 | 4.71k | if (info->indextable[mid].val > offset) |
1356 | 4.12k | high = mid; |
1357 | 589 | else |
1358 | 589 | low = mid + 1; |
1359 | 4.71k | } |
1360 | | |
1361 | 2.80k | if (indexentry == NULL) |
1362 | 1.63k | return true; |
1363 | | |
1364 | 1.17k | stab = indexentry->stab + STABSIZE; |
1365 | 1.17k | file_name = indexentry->file_name; |
1366 | 1.17k | } |
1367 | | |
1368 | 1.48k | directory_name = indexentry->directory_name; |
1369 | 1.48k | str = indexentry->str; |
1370 | | |
1371 | 1.48k | saw_line = false; |
1372 | 1.48k | saw_func = false; |
1373 | 40.9k | for (; stab < (indexentry+1)->stab; stab += STABSIZE) |
1374 | 39.9k | { |
1375 | 39.9k | bool done; |
1376 | 39.9k | bfd_vma val; |
1377 | | |
1378 | 39.9k | done = false; |
1379 | | |
1380 | 39.9k | switch (stab[TYPEOFF]) |
1381 | 39.9k | { |
1382 | 1.04k | case N_SOL: |
1383 | | /* The name of an include file. */ |
1384 | 1.04k | val = bfd_get_32 (abfd, stab + VALOFF); |
1385 | 1.04k | if (val <= offset) |
1386 | 653 | { |
1387 | 653 | file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF); |
1388 | 653 | if (file_name >= (char *) info->strs + strsize |
1389 | 653 | || file_name < (char *) str) |
1390 | 540 | file_name = NULL; |
1391 | 653 | *pline = 0; |
1392 | 653 | } |
1393 | 1.04k | break; |
1394 | | |
1395 | 301 | case N_SLINE: |
1396 | 669 | case N_DSLINE: |
1397 | 1.04k | case N_BSLINE: |
1398 | | /* A line number. If the function was specified, then the value |
1399 | | is relative to the start of the function. Otherwise, the |
1400 | | value is an absolute address. */ |
1401 | 1.04k | val = ((indexentry->function_name ? indexentry->val : 0) |
1402 | 1.04k | + bfd_get_32 (abfd, stab + VALOFF)); |
1403 | | /* If this line starts before our desired offset, or if it's |
1404 | | the first line we've been able to find, use it. The |
1405 | | !saw_line check works around a bug in GCC 2.95.3, which emits |
1406 | | the first N_SLINE late. */ |
1407 | 1.04k | if (!saw_line || val <= offset) |
1408 | 945 | { |
1409 | 945 | *pline = bfd_get_16 (abfd, stab + DESCOFF); |
1410 | | |
1411 | 945 | #ifdef ENABLE_CACHING |
1412 | 945 | info->cached_stab = stab; |
1413 | 945 | info->cached_offset = val; |
1414 | 945 | info->cached_file_name = file_name; |
1415 | 945 | info->cached_indexentry = indexentry; |
1416 | 945 | #endif |
1417 | 945 | } |
1418 | 1.04k | if (val > offset) |
1419 | 326 | done = true; |
1420 | 1.04k | saw_line = true; |
1421 | 1.04k | break; |
1422 | | |
1423 | 125 | case N_FUN: |
1424 | 596 | case N_SO: |
1425 | 596 | if (saw_func || saw_line) |
1426 | 234 | done = true; |
1427 | 596 | saw_func = true; |
1428 | 596 | break; |
1429 | 39.9k | } |
1430 | | |
1431 | 39.9k | if (done) |
1432 | 560 | break; |
1433 | 39.9k | } |
1434 | | |
1435 | 1.48k | *pfound = true; |
1436 | | |
1437 | 1.48k | if (file_name == NULL || IS_ABSOLUTE_PATH (file_name) |
1438 | 1.48k | || directory_name == NULL) |
1439 | 1.45k | *pfilename = file_name; |
1440 | 27 | else |
1441 | 27 | { |
1442 | 27 | size_t dirlen; |
1443 | | |
1444 | 27 | dirlen = strlen (directory_name); |
1445 | 27 | if (info->filename == NULL |
1446 | 27 | || filename_ncmp (info->filename, directory_name, dirlen) != 0 |
1447 | 27 | || filename_cmp (info->filename + dirlen, file_name) != 0) |
1448 | 14 | { |
1449 | 14 | size_t len; |
1450 | | |
1451 | | /* Don't free info->filename here. objdump and other |
1452 | | apps keep a copy of a previously returned file name |
1453 | | pointer. */ |
1454 | 14 | len = strlen (file_name) + 1; |
1455 | 14 | info->filename = (char *) bfd_alloc (abfd, dirlen + len); |
1456 | 14 | if (info->filename == NULL) |
1457 | 0 | return false; |
1458 | 14 | memcpy (info->filename, directory_name, dirlen); |
1459 | 14 | memcpy (info->filename + dirlen, file_name, len); |
1460 | 14 | } |
1461 | | |
1462 | 27 | *pfilename = info->filename; |
1463 | 27 | } |
1464 | | |
1465 | 1.48k | if (indexentry->function_name != NULL) |
1466 | 221 | { |
1467 | 221 | char *s; |
1468 | | |
1469 | | /* This will typically be something like main:F(0,1), so we want |
1470 | | to clobber the colon. It's OK to change the name, since the |
1471 | | string is in our own local storage anyhow. */ |
1472 | 221 | s = strchr (indexentry->function_name, ':'); |
1473 | 221 | if (s != NULL) |
1474 | 3 | *s = '\0'; |
1475 | | |
1476 | 221 | *pfnname = indexentry->function_name; |
1477 | 221 | } |
1478 | | |
1479 | 1.48k | return true; |
1480 | 1.48k | } |
1481 | | |
1482 | | void |
1483 | | _bfd_stab_cleanup (bfd *abfd ATTRIBUTE_UNUSED, void **pinfo) |
1484 | 1.84M | { |
1485 | 1.84M | struct stab_find_info *info = (struct stab_find_info *) *pinfo; |
1486 | 1.84M | if (info == NULL) |
1487 | 1.84M | return; |
1488 | | |
1489 | 8.39k | free (info->indextable); |
1490 | 8.39k | free (info->strs); |
1491 | 8.39k | free (info->stabs); |
1492 | 8.39k | } |
1493 | | |
1494 | | long |
1495 | | _bfd_nosymbols_canonicalize_symtab (bfd *abfd ATTRIBUTE_UNUSED, |
1496 | | asymbol **location ATTRIBUTE_UNUSED) |
1497 | 44 | { |
1498 | 44 | return 0; |
1499 | 44 | } |
1500 | | |
1501 | | void |
1502 | | _bfd_nosymbols_print_symbol (bfd *abfd ATTRIBUTE_UNUSED, |
1503 | | void *afile ATTRIBUTE_UNUSED, |
1504 | | asymbol *symbol ATTRIBUTE_UNUSED, |
1505 | | bfd_print_symbol_type how ATTRIBUTE_UNUSED) |
1506 | 0 | { |
1507 | 0 | } |
1508 | | |
1509 | | void |
1510 | | _bfd_nosymbols_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED, |
1511 | | asymbol *sym ATTRIBUTE_UNUSED, |
1512 | | symbol_info *ret ATTRIBUTE_UNUSED) |
1513 | 0 | { |
1514 | 0 | } |
1515 | | |
1516 | | const char * |
1517 | | _bfd_nosymbols_get_symbol_version_string (bfd *abfd, |
1518 | | asymbol *symbol ATTRIBUTE_UNUSED, |
1519 | | bool base_p ATTRIBUTE_UNUSED, |
1520 | | bool *hidden ATTRIBUTE_UNUSED) |
1521 | 1.45M | { |
1522 | 1.45M | return (const char *) _bfd_ptr_bfd_null_error (abfd); |
1523 | 1.45M | } |
1524 | | |
1525 | | bool |
1526 | | _bfd_nosymbols_bfd_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, |
1527 | | const char *name ATTRIBUTE_UNUSED) |
1528 | 0 | { |
1529 | 0 | return false; |
1530 | 0 | } |
1531 | | |
1532 | | alent * |
1533 | | _bfd_nosymbols_get_lineno (bfd *abfd, asymbol *sym ATTRIBUTE_UNUSED) |
1534 | 0 | { |
1535 | 0 | return (alent *) _bfd_ptr_bfd_null_error (abfd); |
1536 | 0 | } |
1537 | | |
1538 | | bool |
1539 | | _bfd_nosymbols_find_nearest_line |
1540 | | (bfd *abfd, |
1541 | | asymbol **symbols ATTRIBUTE_UNUSED, |
1542 | | asection *section ATTRIBUTE_UNUSED, |
1543 | | bfd_vma offset ATTRIBUTE_UNUSED, |
1544 | | const char **filename_ptr ATTRIBUTE_UNUSED, |
1545 | | const char **functionname_ptr ATTRIBUTE_UNUSED, |
1546 | | unsigned int *line_ptr ATTRIBUTE_UNUSED, |
1547 | | unsigned int *discriminator_ptr ATTRIBUTE_UNUSED) |
1548 | 9.29k | { |
1549 | 9.29k | return _bfd_bool_bfd_false_error (abfd); |
1550 | 9.29k | } |
1551 | | |
1552 | | bool |
1553 | | _bfd_nosymbols_find_nearest_line_with_alt |
1554 | | (bfd *abfd, |
1555 | | const char *alt_filename ATTRIBUTE_UNUSED, |
1556 | | asymbol **symbols ATTRIBUTE_UNUSED, |
1557 | | asection *section ATTRIBUTE_UNUSED, |
1558 | | bfd_vma offset ATTRIBUTE_UNUSED, |
1559 | | const char **filename_ptr ATTRIBUTE_UNUSED, |
1560 | | const char **functionname_ptr ATTRIBUTE_UNUSED, |
1561 | | unsigned int *line_ptr ATTRIBUTE_UNUSED, |
1562 | | unsigned int *discriminator_ptr ATTRIBUTE_UNUSED) |
1563 | 0 | { |
1564 | 0 | return _bfd_bool_bfd_false_error (abfd); |
1565 | 0 | } |
1566 | | |
1567 | | bool |
1568 | | _bfd_nosymbols_find_line (bfd *abfd, |
1569 | | asymbol **symbols ATTRIBUTE_UNUSED, |
1570 | | asymbol *symbol ATTRIBUTE_UNUSED, |
1571 | | const char **filename_ptr ATTRIBUTE_UNUSED, |
1572 | | unsigned int *line_ptr ATTRIBUTE_UNUSED) |
1573 | 45.3k | { |
1574 | 45.3k | return _bfd_bool_bfd_false_error (abfd); |
1575 | 45.3k | } |
1576 | | |
1577 | | bool |
1578 | | _bfd_nosymbols_find_inliner_info |
1579 | | (bfd *abfd, |
1580 | | const char **filename_ptr ATTRIBUTE_UNUSED, |
1581 | | const char **functionname_ptr ATTRIBUTE_UNUSED, |
1582 | | unsigned int *line_ptr ATTRIBUTE_UNUSED) |
1583 | 0 | { |
1584 | 0 | return _bfd_bool_bfd_false_error (abfd); |
1585 | 0 | } |
1586 | | |
1587 | | asymbol * |
1588 | | _bfd_nosymbols_bfd_make_debug_symbol (bfd *abfd) |
1589 | 0 | { |
1590 | 0 | return (asymbol *) _bfd_ptr_bfd_null_error (abfd); |
1591 | 0 | } |
1592 | | |
1593 | | long |
1594 | | _bfd_nosymbols_read_minisymbols (bfd *abfd, |
1595 | | bool dynamic ATTRIBUTE_UNUSED, |
1596 | | void **minisymsp ATTRIBUTE_UNUSED, |
1597 | | unsigned int *sizep ATTRIBUTE_UNUSED) |
1598 | 0 | { |
1599 | 0 | return _bfd_long_bfd_n1_error (abfd); |
1600 | 0 | } |
1601 | | |
1602 | | asymbol * |
1603 | | _bfd_nosymbols_minisymbol_to_symbol (bfd *abfd, |
1604 | | bool dynamic ATTRIBUTE_UNUSED, |
1605 | | const void *minisym ATTRIBUTE_UNUSED, |
1606 | | asymbol *sym ATTRIBUTE_UNUSED) |
1607 | 0 | { |
1608 | 0 | return (asymbol *) _bfd_ptr_bfd_null_error (abfd); |
1609 | 0 | } |
1610 | | |
1611 | | long |
1612 | | _bfd_nodynamic_get_synthetic_symtab (bfd *abfd, |
1613 | | long symcount ATTRIBUTE_UNUSED, |
1614 | | asymbol **syms ATTRIBUTE_UNUSED, |
1615 | | long dynsymcount ATTRIBUTE_UNUSED, |
1616 | | asymbol **dynsyms ATTRIBUTE_UNUSED, |
1617 | | asymbol **ret ATTRIBUTE_UNUSED) |
1618 | 5.56k | { |
1619 | 5.56k | return _bfd_long_bfd_n1_error (abfd); |
1620 | 5.56k | } |