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