Commit | Line | Data |
---|---|---|
6724ff46 RP |
1 | /* Generic symbol-table support for the BFD library. |
2 | Copyright (C) 1990-1991 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
20 | ||
0cda46cf SC |
21 | /* |
22 | SECTION | |
23 | Symbols | |
24 | ||
25 | DESCRIPTION | |
26 | BFD trys 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 | applicationrequests 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 infomation passed to | |
32 | applications some targets keep some information 'behind the | |
33 | sceans', 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 was read, but was written | |
40 | through an a.out back end, all the coff specific information | |
41 | would be lost. (.. until BFD 2 :). 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 read, since the 'behind | |
48 | the sceens' information will be still available. | |
6724ff46 RP |
49 | @menu |
50 | * Reading Symbols:: | |
51 | * Writing Symbols:: | |
52 | * typedef asymbol:: | |
53 | * symbol handling functions:: | |
54 | @end menu | |
55 | ||
56 | @node Reading Symbols, Writing Symbols, Symbols, Symbols | |
0cda46cf SC |
57 | SUBSECTION |
58 | Reading Symbols | |
59 | ||
60 | DESCRIPTION | |
61 | There are two stages to reading a symbol table from a BFD; | |
62 | allocating storage, and the actual reading process. This is an | |
63 | excerpt from an appliction which reads the symbol table: | |
64 | ||
65 | EXAMPLE | |
6724ff46 | 66 | |
6724ff46 RP |
67 | unsigned int storage_needed; |
68 | asymbol **symbol_table; | |
69 | unsigned int number_of_symbols; | |
70 | unsigned int i; | |
71 | ||
72 | storage_needed = get_symtab_upper_bound (abfd); | |
73 | ||
74 | if (storage_needed == 0) { | |
75 | return ; | |
76 | } | |
7d68537f | 77 | symbol_table = (asymbol **) bfd_xmalloc (storage_needed); |
6724ff46 RP |
78 | ... |
79 | number_of_symbols = | |
80 | bfd_canonicalize_symtab (abfd, symbol_table); | |
81 | ||
82 | for (i = 0; i < number_of_symbols; i++) { | |
83 | process_symbol (symbol_table[i]); | |
84 | } | |
6724ff46 | 85 | |
0cda46cf SC |
86 | DESCRIPTION |
87 | ||
88 | All storage for the symbols themselves is in an obstack | |
89 | connected to the BFD, and is freed when the BFD is closed. | |
90 | ||
6724ff46 RP |
91 | |
92 | @node Writing Symbols, typedef asymbol, Reading Symbols, Symbols | |
0cda46cf SC |
93 | SUBSECTION |
94 | Writing Symbols | |
95 | ||
96 | DESCRIPTION | |
97 | Writing of a symbol table is automatic when a BFD open for | |
98 | writing is closed. The application attaches a vector of | |
99 | pointers to pointers to symbols to the BFD being written, and | |
100 | fills in the symbol count. The close and cleanup code reads | |
101 | through the table provided and performs all the necessary | |
102 | operations. The outputing code must always be provided with an | |
103 | 'owned' symbol; one which has come from another BFD, or one | |
104 | which has been created using <<bfd_make_empty_symbol>>. An | |
105 | example showing the creation of a symbol table with only one element: | |
106 | ||
107 | EXAMPLE | |
6724ff46 RP |
108 | #include "bfd.h" |
109 | main() | |
110 | { | |
111 | bfd *abfd; | |
112 | asymbol *ptrs[2]; | |
113 | asymbol *new; | |
114 | ||
115 | abfd = bfd_openw("foo","a.out-sunos-big"); | |
116 | bfd_set_format(abfd, bfd_object); | |
117 | new = bfd_make_empty_symbol(abfd); | |
118 | new->name = "dummy_symbol"; | |
119 | new->section = (asection *)0; | |
120 | new->flags = BSF_ABSOLUTE | BSF_GLOBAL; | |
121 | new->value = 0x12345; | |
122 | ||
123 | ptrs[0] = new; | |
124 | ptrs[1] = (asymbol *)0; | |
125 | ||
126 | bfd_set_symtab(abfd, ptrs, 1); | |
127 | bfd_close(abfd); | |
128 | } | |
129 | ||
130 | ./makesym | |
131 | nm foo | |
132 | 00012345 A dummy_symbol | |
133 | ||
134 | ||
0cda46cf SC |
135 | DESCRIPTION |
136 | Many formats cannot represent arbitary symbol information; for | |
137 | instance the <<a.out>> object format does not allow an | |
138 | arbitary number of sections. A symbol pointing to a section | |
139 | which is not one of <<.text>>, <<.data>> or <<.bss>> cannot | |
140 | be described. | |
6724ff46 | 141 | |
6724ff46 RP |
142 | */ |
143 | ||
144 | ||
145 | /*doc* | |
146 | @node typedef asymbol, symbol handling functions, Writing Symbols, Symbols | |
147 | ||
148 | */ | |
0cda46cf SC |
149 | /* |
150 | TYPEDEF | |
151 | typedef asymbol | |
6724ff46 | 152 | |
0cda46cf SC |
153 | DESCRIPTION |
154 | An <<asymbol>> has the form: | |
6724ff46 | 155 | |
0cda46cf SC |
156 | .typedef struct symbol_cache_entry |
157 | .{ | |
158 | A pointer to the BFD which owns the symbol. This information | |
159 | is necessary so that a back end can work out what additional | |
160 | (invisible to the application writer) information is carried | |
161 | with the symbol. | |
6724ff46 | 162 | |
0cda46cf | 163 | . struct _bfd *the_bfd; |
6724ff46 RP |
164 | |
165 | The text of the symbol. The name is left alone, and not copied - the | |
166 | application may not alter it. | |
167 | ||
0cda46cf | 168 | . CONST char *name; |
6724ff46 RP |
169 | |
170 | The value of the symbol. | |
171 | ||
0cda46cf | 172 | . symvalue value; |
6724ff46 RP |
173 | |
174 | Attributes of a symbol: | |
175 | ||
0cda46cf | 176 | .#define BSF_NO_FLAGS 0x00 |
6724ff46 | 177 | |
0cda46cf | 178 | The symbol has local scope; <<static>> in <<C>>. The value is |
6724ff46 RP |
179 | the offset into the section of the data. |
180 | ||
0cda46cf | 181 | .#define BSF_LOCAL 0x01 |
6724ff46 | 182 | |
0cda46cf | 183 | The symbol has global scope; initialized data in <<C>>. The value |
6724ff46 RP |
184 | is the offset into the section of the data. |
185 | ||
0cda46cf | 186 | .#define BSF_GLOBAL 0x02 |
6724ff46 RP |
187 | |
188 | Obsolete | |
189 | ||
0cda46cf | 190 | .#define BSF_IMPORT 0x04 |
6724ff46 RP |
191 | |
192 | The symbol has global scope, and is exported. The value is the offset | |
193 | into the section of the data. | |
194 | ||
0cda46cf | 195 | .#define BSF_EXPORT 0x08 |
6724ff46 | 196 | |
0cda46cf | 197 | The symbol is undefined. <<extern>> in <<C>>. The value has no meaning. |
6724ff46 | 198 | |
0cda46cf | 199 | .#define BSF_UNDEFINED 0x10 |
6724ff46 | 200 | |
0cda46cf | 201 | The symbol is common, initialized to zero; default in <<C>>. The |
6724ff46 RP |
202 | value is the size of the object in bytes. |
203 | ||
0cda46cf | 204 | .#define BSF_FORT_COMM 0x20 |
6724ff46 | 205 | |
0cda46cf SC |
206 | A normal <<C>> symbol would be one of: |
207 | <<BSF_LOCAL>>, <<BSF_FORT_COMM>>, <<BSF_UNDEFINED>> or <<BSF_EXPORT|BSD_GLOBAL>> | |
6724ff46 RP |
208 | |
209 | The symbol is a debugging record. The value has an arbitary meaning. | |
210 | ||
0cda46cf | 211 | .#define BSF_DEBUGGING 0x40 |
6724ff46 RP |
212 | |
213 | The symbol has no section attached, any value is the actual value and | |
214 | is not a relative offset to a section. | |
215 | ||
0cda46cf | 216 | .#define BSF_ABSOLUTE 0x80 |
6724ff46 RP |
217 | |
218 | Used by the linker | |
219 | ||
0cda46cf SC |
220 | .#define BSF_KEEP 0x10000 |
221 | .#define BSF_KEEP_G 0x80000 | |
6724ff46 RP |
222 | |
223 | Unused | |
224 | ||
0cda46cf SC |
225 | .#define BSF_WEAK 0x100000 |
226 | .#define BSF_CTOR 0x200000 | |
227 | .#define BSF_FAKE 0x400000 | |
6724ff46 RP |
228 | |
229 | The symbol used to be a common symbol, but now it is allocated. | |
230 | ||
0cda46cf | 231 | .#define BSF_OLD_COMMON 0x800000 |
6724ff46 RP |
232 | |
233 | The default value for common data. | |
234 | ||
0cda46cf | 235 | .#define BFD_FORT_COMM_DEFAULT_VALUE 0 |
6724ff46 RP |
236 | |
237 | In some files the type of a symbol sometimes alters its location | |
0cda46cf | 238 | in an output file - ie in coff a <<ISFCN>> symbol which is also <<C_EXT>> |
6724ff46 RP |
239 | symbol appears where it was declared and not at the end of a section. |
240 | This bit is set by the target BFD part to convey this information. | |
241 | ||
0cda46cf | 242 | .#define BSF_NOT_AT_END 0x40000 |
6724ff46 RP |
243 | |
244 | Signal that the symbol is the label of constructor section. | |
245 | ||
0cda46cf | 246 | .#define BSF_CONSTRUCTOR 0x1000000 |
6724ff46 RP |
247 | |
248 | Signal that the symbol is a warning symbol. If the symbol is a warning | |
249 | symbol, then the value field (I know this is tacky) will point to the | |
250 | asymbol which when referenced will cause the warning. | |
251 | ||
0cda46cf | 252 | .#define BSF_WARNING 0x2000000 |
6724ff46 RP |
253 | |
254 | Signal that the symbol is indirect. The value of the symbol is a | |
255 | pointer to an undefined asymbol which contains the name to use | |
256 | instead. | |
257 | ||
0cda46cf | 258 | .#define BSF_INDIRECT 0x4000000 |
6724ff46 | 259 | |
0cda46cf | 260 | . flagword flags; |
6724ff46 | 261 | |
7d68537f | 262 | A pointer to the section to which this symbol is relative, or 0 if the |
6724ff46 RP |
263 | symbol is absolute or undefined. Note that it is not sufficient to set |
264 | this location to 0 to mark a symbol as absolute - the flag | |
0cda46cf | 265 | <<BSF_ABSOLUTE>> must be set also. |
6724ff46 | 266 | |
0cda46cf | 267 | . struct sec *section; |
6724ff46 RP |
268 | |
269 | Back end special data. This is being phased out in favour of making | |
270 | this a union. | |
271 | ||
0cda46cf SC |
272 | . PTR udata; |
273 | .} asymbol; | |
6724ff46 RP |
274 | |
275 | */ | |
276 | ||
6724ff46 | 277 | #include "bfd.h" |
7d68537f | 278 | #include "sysdep.h" |
6724ff46 | 279 | #include "libbfd.h" |
7d68537f | 280 | #include "stab.gnu.h" |
6724ff46 | 281 | |
0cda46cf | 282 | /* |
7d68537f | 283 | @node symbol handling functions, , typedef asymbol, Symbols |
0cda46cf SC |
284 | SUBSECTION |
285 | Symbol Handling Functions | |
6724ff46 RP |
286 | |
287 | */ | |
288 | ||
0cda46cf SC |
289 | /* |
290 | FUNCTION | |
291 | get_symtab_upper_bound | |
292 | ||
293 | DESCRIPTION | |
294 | Returns the number of bytes required in a vector of pointers | |
295 | to <<asymbols>> for all the symbols in the supplied BFD, | |
296 | including a terminal NULL pointer. If there are no symbols in | |
297 | the BFD, then 0 is returned. | |
298 | ||
299 | .#define get_symtab_upper_bound(abfd) \ | |
300 | . BFD_SEND (abfd, _get_symtab_upper_bound, (abfd)) | |
6724ff46 RP |
301 | |
302 | */ | |
303 | ||
0cda46cf SC |
304 | /* |
305 | FUNCTION | |
306 | bfd_canonicalize_symtab | |
307 | ||
308 | DESCRIPTION | |
309 | Supplied a BFD and a pointer to an uninitialized vector of | |
310 | pointers. This reads in the symbols from the BFD, and fills in | |
311 | the table with pointers to the symbols, and a trailing NULL. | |
312 | The routine returns the actual number of symbol pointers not | |
313 | including the NULL. | |
6724ff46 | 314 | |
6724ff46 | 315 | |
0cda46cf SC |
316 | .#define bfd_canonicalize_symtab(abfd, location) \ |
317 | . BFD_SEND (abfd, _bfd_canonicalize_symtab,\ | |
318 | . (abfd, location)) | |
319 | ||
6724ff46 RP |
320 | */ |
321 | ||
322 | ||
0cda46cf SC |
323 | /* |
324 | FUNCTION | |
325 | bfd_set_symtab | |
326 | ||
327 | DESCRIPTION | |
328 | Provided a table of pointers to symbols and a count, writes to | |
329 | the output BFD the symbols when closed. | |
6724ff46 | 330 | |
0cda46cf SC |
331 | SYNOPSIS |
332 | boolean bfd_set_symtab (bfd *, asymbol **, unsigned int ); | |
6724ff46 RP |
333 | */ |
334 | ||
335 | boolean | |
336 | bfd_set_symtab (abfd, location, symcount) | |
337 | bfd *abfd; | |
338 | asymbol **location; | |
339 | unsigned int symcount; | |
340 | { | |
341 | if ((abfd->format != bfd_object) || (bfd_read_p (abfd))) { | |
342 | bfd_error = invalid_operation; | |
343 | return false; | |
344 | } | |
345 | ||
346 | bfd_get_outsymbols (abfd) = location; | |
347 | bfd_get_symcount (abfd) = symcount; | |
348 | return true; | |
349 | } | |
350 | ||
0cda46cf SC |
351 | /* |
352 | FUNCTION | |
353 | bfd_print_symbol_vandf | |
6724ff46 | 354 | |
0cda46cf SC |
355 | DESCRIPTION |
356 | Prints the value and flags of the symbol supplied to the stream file. | |
357 | ||
358 | SYNOPSIS | |
359 | void bfd_print_symbol_vandf(PTR file, asymbol *symbol); | |
6724ff46 RP |
360 | */ |
361 | void | |
362 | DEFUN(bfd_print_symbol_vandf,(file, symbol), | |
363 | PTR file AND | |
364 | asymbol *symbol) | |
365 | { | |
366 | flagword type = symbol->flags; | |
367 | if (symbol->section != (asection *)NULL) | |
368 | { | |
369 | fprintf_vma(file, symbol->value+symbol->section->vma); | |
370 | } | |
371 | else | |
372 | { | |
373 | fprintf_vma(file, symbol->value); | |
374 | } | |
375 | fprintf(file," %c%c%c%c%c%c%c%c%c%c", | |
376 | (type & BSF_LOCAL) ? 'l':' ', | |
377 | (type & BSF_GLOBAL) ? 'g' : ' ', | |
378 | (type & BSF_IMPORT) ? 'i' : ' ', | |
379 | (type & BSF_EXPORT) ? 'e' : ' ', | |
380 | (type & BSF_UNDEFINED) ? 'u' : ' ', | |
381 | (type & BSF_FORT_COMM) ? 'c' : ' ', | |
382 | (type & BSF_CONSTRUCTOR) ? 'C' : ' ', | |
383 | (type & BSF_WARNING) ? 'W' : ' ', | |
384 | (type & BSF_INDIRECT) ? 'I' : ' ', | |
385 | (type & BSF_DEBUGGING) ? 'd' :' '); | |
386 | ||
387 | } | |
388 | ||
389 | ||
0cda46cf SC |
390 | /* |
391 | FUNCTION | |
392 | bfd_make_empty_symbol | |
393 | ||
394 | DESCRIPTION | |
395 | This function creates a new <<asymbol>> structure for the BFD, | |
396 | and returns a pointer to it. | |
6724ff46 | 397 | |
0cda46cf SC |
398 | This routine is necessary, since each back end has private |
399 | information surrounding the <<asymbol>>. Building your own | |
400 | <<asymbol>> and pointing to it will not create the private | |
401 | information, and will cause problems later on. | |
402 | ||
403 | .#define bfd_make_empty_symbol(abfd) \ | |
404 | . BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd)) | |
6724ff46 | 405 | */ |
7d68537f | 406 | |
0cda46cf SC |
407 | /* |
408 | FUNCTION | |
409 | bfd_decode_symclass | |
410 | ||
411 | DESCRIPTION | |
412 | Return a lower-case character corresponding to the symbol | |
413 | class of symbol. | |
7d68537f | 414 | |
0cda46cf SC |
415 | SYNOPSIS |
416 | int bfd_decode_symclass(asymbol *symbol); | |
7d68537f FF |
417 | */ |
418 | int | |
419 | DEFUN(bfd_decode_symclass,(symbol), | |
420 | asymbol *symbol) | |
421 | { | |
422 | flagword flags = symbol->flags; | |
423 | ||
7d68537f FF |
424 | if (flags & BSF_FORT_COMM) return 'C'; |
425 | if (flags & BSF_UNDEFINED) return 'U'; | |
37217060 PB |
426 | if (flags & BSF_ABSOLUTE) |
427 | return (flags & BSF_GLOBAL) ? 'A' : 'a'; | |
7d68537f FF |
428 | |
429 | if ( flags & (BSF_GLOBAL|BSF_LOCAL) ) { | |
430 | if (symbol->section == (asection *)NULL) | |
431 | return '*'; | |
432 | else if ( !strcmp(symbol->section->name, ".text") ) | |
433 | return (flags & BSF_GLOBAL) ? 'T' : 't'; | |
434 | else if ( !strcmp(symbol->section->name, ".data") ) | |
435 | return (flags & BSF_GLOBAL) ? 'D' : 'd'; | |
436 | else if ( !strcmp(symbol->section->name, ".bss") ) | |
437 | return (flags & BSF_GLOBAL) ? 'B' : 'b'; | |
438 | else | |
439 | return (flags & BSF_GLOBAL) ? 'O' : 'o'; | |
440 | } | |
441 | ||
442 | /* We don't have to handle these cases just yet, but we will soon: | |
443 | N_SETV: 'v'; | |
444 | N_SETA: 'l'; | |
445 | N_SETT: 'x'; | |
446 | N_SETD: 'z'; | |
447 | N_SETB: 's'; | |
448 | N_INDR: 'i'; | |
449 | */ | |
450 | ||
451 | return '?'; | |
452 | } |