obj-coff.c revision 1.10 1 1.1 christos /* coff object file format
2 1.10 christos Copyright (C) 1989-2025 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos This file is part of GAS.
5 1.1 christos
6 1.1 christos GAS is free software; you can redistribute it and/or modify
7 1.1 christos it under the terms of the GNU General Public License as published by
8 1.1 christos the Free Software Foundation; either version 3, or (at your option)
9 1.1 christos any later version.
10 1.1 christos
11 1.1 christos GAS is distributed in the hope that it will be useful,
12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.1 christos GNU General Public License for more details.
15 1.1 christos
16 1.1 christos You should have received a copy of the GNU General Public License
17 1.1 christos along with GAS; see the file COPYING. If not, write to the Free
18 1.1 christos Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19 1.1 christos 02110-1301, USA. */
20 1.1 christos
21 1.1 christos #define OBJ_HEADER "obj-coff.h"
22 1.1 christos
23 1.1 christos #include "as.h"
24 1.1 christos #include "safe-ctype.h"
25 1.1 christos #include "subsegs.h"
26 1.1 christos
27 1.1 christos #ifdef TE_PE
28 1.1 christos #include "coff/pe.h"
29 1.1 christos #endif
30 1.1 christos
31 1.1 christos #ifdef OBJ_XCOFF
32 1.1 christos #include "coff/xcoff.h"
33 1.1 christos #endif
34 1.1 christos
35 1.1 christos #define streq(a,b) (strcmp ((a), (b)) == 0)
36 1.1 christos
37 1.1 christos /* I think this is probably always correct. */
38 1.1 christos #ifndef KEEP_RELOC_INFO
39 1.1 christos #define KEEP_RELOC_INFO
40 1.1 christos #endif
41 1.1 christos
42 1.1 christos /* obj_coff_section will use this macro to set a new section's
43 1.1 christos attributes when a directive has no valid flags or the "w" flag is
44 1.1 christos used. This default should be appropriate for most. */
45 1.1 christos #ifndef TC_COFF_SECTION_DEFAULT_ATTRIBUTES
46 1.1 christos #define TC_COFF_SECTION_DEFAULT_ATTRIBUTES (SEC_LOAD | SEC_DATA)
47 1.1 christos #endif
48 1.1 christos
49 1.1 christos /* This is used to hold the symbol built by a sequence of pseudo-ops
50 1.1 christos from .def and .endef. */
51 1.1 christos static symbolS *def_symbol_in_progress;
52 1.1 christos #ifdef TE_PE
53 1.1 christos /* PE weak alternate symbols begin with this string. */
54 1.1 christos static const char weak_altprefix[] = ".weak.";
55 1.1 christos #endif /* TE_PE */
56 1.1 christos
57 1.1 christos #include "obj-coff-seh.c"
58 1.1 christos
59 1.1 christos typedef struct
60 1.1 christos {
61 1.1 christos unsigned long chunk_size;
62 1.1 christos unsigned long element_size;
63 1.1 christos unsigned long size;
64 1.1 christos char *data;
65 1.1 christos unsigned long pointer;
66 1.1 christos }
67 1.1 christos stack;
68 1.1 christos
69 1.1 christos
70 1.1 christos /* Stack stuff. */
72 1.1 christos
73 1.1 christos static stack *
74 1.1 christos stack_init (unsigned long chunk_size,
75 1.1 christos unsigned long element_size)
76 1.1 christos {
77 1.1 christos stack *st;
78 1.5 christos
79 1.5 christos st = XNEW (stack);
80 1.1 christos st->data = XNEWVEC (char, chunk_size);
81 1.1 christos if (!st->data)
82 1.1 christos {
83 1.1 christos free (st);
84 1.1 christos return NULL;
85 1.1 christos }
86 1.1 christos st->pointer = 0;
87 1.1 christos st->size = chunk_size;
88 1.1 christos st->chunk_size = chunk_size;
89 1.1 christos st->element_size = element_size;
90 1.1 christos return st;
91 1.1 christos }
92 1.1 christos
93 1.10 christos static char *
94 1.1 christos stack_push (stack *st, void *element)
95 1.1 christos {
96 1.1 christos if (st->pointer + st->element_size >= st->size)
97 1.1 christos {
98 1.5 christos st->size += st->chunk_size;
99 1.1 christos st->data = XRESIZEVEC (char, st->data, st->size);
100 1.1 christos }
101 1.1 christos memcpy (st->data + st->pointer, element, st->element_size);
102 1.1 christos st->pointer += st->element_size;
103 1.1 christos return st->data + st->pointer;
104 1.1 christos }
105 1.1 christos
106 1.1 christos static char *
107 1.1 christos stack_pop (stack *st)
108 1.1 christos {
109 1.1 christos if (st->pointer < st->element_size)
110 1.1 christos {
111 1.1 christos st->pointer = 0;
112 1.1 christos return NULL;
113 1.1 christos }
114 1.1 christos st->pointer -= st->element_size;
115 1.1 christos return st->data + st->pointer;
116 1.1 christos }
117 1.1 christos
118 1.1 christos /* Maintain a list of the tagnames of the structures. */
120 1.1 christos
121 1.1 christos static htab_t tag_hash;
122 1.1 christos
123 1.1 christos static void
124 1.8 christos tag_init (void)
125 1.1 christos {
126 1.1 christos tag_hash = str_htab_create ();
127 1.1 christos }
128 1.1 christos
129 1.1 christos static void
130 1.8 christos tag_insert (const char *name, symbolS *symbolP)
131 1.1 christos {
132 1.1 christos str_hash_insert (tag_hash, name, symbolP, 1);
133 1.1 christos }
134 1.1 christos
135 1.1 christos static symbolS *
136 1.10 christos tag_find (char *name)
137 1.1 christos {
138 1.1 christos return str_hash_find (tag_hash, name);
139 1.1 christos }
140 1.1 christos
141 1.1 christos static symbolS *
142 1.1 christos tag_find_or_make (char *name)
143 1.1 christos {
144 1.1 christos symbolS *symbolP;
145 1.1 christos
146 1.8 christos if ((symbolP = tag_find (name)) == NULL)
147 1.1 christos {
148 1.1 christos symbolP = symbol_new (name, undefined_section, &zero_address_frag, 0);
149 1.1 christos
150 1.1 christos tag_insert (S_GET_NAME (symbolP), symbolP);
151 1.1 christos symbol_table_insert (symbolP);
152 1.1 christos }
153 1.1 christos
154 1.1 christos return symbolP;
155 1.1 christos }
156 1.1 christos
157 1.1 christos /* We accept the .bss directive to set the section for backward
158 1.1 christos compatibility with earlier versions of gas. */
159 1.1 christos
160 1.1 christos static void
161 1.1 christos obj_coff_bss (int ignore ATTRIBUTE_UNUSED)
162 1.1 christos {
163 1.1 christos if (*input_line_pointer == '\n')
164 1.1 christos subseg_new (".bss", get_absolute_expression ());
165 1.1 christos else
166 1.1 christos s_lcomm (0);
167 1.1 christos }
168 1.1 christos
169 1.1 christos #ifdef TE_PE
170 1.1 christos /* Called from read.c:s_comm after we've parsed .comm symbol, size.
171 1.1 christos Parse a possible alignment value. */
172 1.1 christos
173 1.1 christos static symbolS *
174 1.1 christos obj_coff_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
175 1.1 christos {
176 1.1 christos addressT align = 0;
177 1.1 christos
178 1.1 christos if (*input_line_pointer == ',')
179 1.1 christos {
180 1.1 christos align = parse_align (0);
181 1.1 christos if (align == (addressT) -1)
182 1.1 christos return NULL;
183 1.1 christos }
184 1.1 christos
185 1.1 christos S_SET_VALUE (symbolP, size);
186 1.1 christos S_SET_EXTERNAL (symbolP);
187 1.1 christos S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
188 1.1 christos
189 1.1 christos symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
190 1.1 christos
191 1.1 christos /* There is no S_SET_ALIGN (symbolP, align) in COFF/PE.
192 1.1 christos Instead we must add a note to the .drectve section. */
193 1.1 christos if (align)
194 1.1 christos {
195 1.1 christos segT current_seg = now_seg;
196 1.1 christos subsegT current_subseg = now_subseg;
197 1.1 christos flagword oldflags;
198 1.1 christos asection *sec;
199 1.1 christos size_t pfxlen, numlen;
200 1.1 christos char *frag;
201 1.1 christos char numbuff[20];
202 1.7 christos
203 1.1 christos sec = subseg_new (".drectve", 0);
204 1.1 christos oldflags = bfd_section_flags (sec);
205 1.7 christos if (oldflags == SEC_NO_FLAGS)
206 1.1 christos {
207 1.7 christos if (!bfd_set_section_flags (sec, TC_COFF_SECTION_DEFAULT_ATTRIBUTES))
208 1.1 christos as_warn (_("error setting flags for \"%s\": %s"),
209 1.1 christos bfd_section_name (sec),
210 1.1 christos bfd_errmsg (bfd_get_error ()));
211 1.1 christos }
212 1.1 christos
213 1.1 christos /* Emit a string. Note no NUL-termination. */
214 1.1 christos pfxlen = strlen (" -aligncomm:") + 2 + strlen (S_GET_NAME (symbolP)) + 1;
215 1.1 christos numlen = snprintf (numbuff, sizeof (numbuff), "%d", (int) align);
216 1.1 christos frag = frag_more (pfxlen + numlen);
217 1.1 christos (void) sprintf (frag, " -aligncomm:\"%s\",", S_GET_NAME (symbolP));
218 1.1 christos memcpy (frag + pfxlen, numbuff, numlen);
219 1.1 christos /* Restore original subseg. */
220 1.1 christos subseg_set (current_seg, current_subseg);
221 1.1 christos }
222 1.1 christos
223 1.1 christos return symbolP;
224 1.1 christos }
225 1.1 christos
226 1.1 christos static void
227 1.1 christos obj_coff_comm (int ignore ATTRIBUTE_UNUSED)
228 1.1 christos {
229 1.1 christos s_comm_internal (ignore, obj_coff_common_parse);
230 1.1 christos }
231 1.1 christos #endif /* TE_PE */
232 1.1 christos
233 1.1 christos /* @@ Ick. */
234 1.1 christos static segT
235 1.1 christos fetch_coff_debug_section (void)
236 1.1 christos {
237 1.1 christos static segT debug_section;
238 1.1 christos
239 1.1 christos if (!debug_section)
240 1.1 christos {
241 1.9 christos const asymbol *s;
242 1.1 christos
243 1.1 christos s = bfd_make_debug_symbol (stdoutput);
244 1.1 christos gas_assert (s != 0);
245 1.1 christos debug_section = s->section;
246 1.1 christos }
247 1.1 christos return debug_section;
248 1.1 christos }
249 1.1 christos
250 1.1 christos void
251 1.1 christos SA_SET_SYM_ENDNDX (symbolS *sym, symbolS *val)
252 1.1 christos {
253 1.1 christos combined_entry_type *entry, *p;
254 1.1 christos
255 1.1 christos entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
256 1.1 christos p = coffsymbol (symbol_get_bfdsym (val))->native;
257 1.1 christos entry->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = p;
258 1.1 christos entry->fix_end = 1;
259 1.1 christos }
260 1.1 christos
261 1.1 christos static void
262 1.1 christos SA_SET_SYM_TAGNDX (symbolS *sym, symbolS *val)
263 1.1 christos {
264 1.1 christos combined_entry_type *entry, *p;
265 1.1 christos
266 1.1 christos entry = &coffsymbol (symbol_get_bfdsym (sym))->native[1];
267 1.1 christos p = coffsymbol (symbol_get_bfdsym (val))->native;
268 1.1 christos entry->u.auxent.x_sym.x_tagndx.p = p;
269 1.1 christos entry->fix_tag = 1;
270 1.1 christos }
271 1.1 christos
272 1.1 christos static int
273 1.1 christos S_GET_DATA_TYPE (symbolS *sym)
274 1.1 christos {
275 1.1 christos return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type;
276 1.1 christos }
277 1.1 christos
278 1.1 christos int
279 1.1 christos S_SET_DATA_TYPE (symbolS *sym, int val)
280 1.1 christos {
281 1.1 christos coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_type = val;
282 1.1 christos return val;
283 1.1 christos }
284 1.1 christos
285 1.1 christos int
286 1.1 christos S_GET_STORAGE_CLASS (symbolS *sym)
287 1.1 christos {
288 1.1 christos return coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass;
289 1.1 christos }
290 1.1 christos
291 1.1 christos int
292 1.1 christos S_SET_STORAGE_CLASS (symbolS *sym, int val)
293 1.1 christos {
294 1.1 christos coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_sclass = val;
295 1.1 christos return val;
296 1.1 christos }
297 1.1 christos
298 1.1 christos /* Merge a debug symbol containing debug information into a normal symbol. */
299 1.1 christos
300 1.1 christos static void
301 1.1 christos c_symbol_merge (symbolS *debug, symbolS *normal)
302 1.1 christos {
303 1.1 christos S_SET_DATA_TYPE (normal, S_GET_DATA_TYPE (debug));
304 1.1 christos S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug));
305 1.1 christos
306 1.1 christos if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal))
307 1.1 christos /* Take the most we have. */
308 1.1 christos S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug));
309 1.1 christos
310 1.1 christos if (S_GET_NUMBER_AUXILIARY (debug) > 0)
311 1.1 christos /* Move all the auxiliary information. */
312 1.1 christos memcpy (SYM_AUXINFO (normal), SYM_AUXINFO (debug),
313 1.1 christos (S_GET_NUMBER_AUXILIARY (debug)
314 1.1 christos * sizeof (*SYM_AUXINFO (debug))));
315 1.1 christos
316 1.1 christos /* Move the debug flags. */
317 1.1 christos SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug));
318 1.1 christos }
319 1.8 christos
320 1.1 christos void
321 1.1 christos c_dot_file_symbol (const char *filename)
322 1.1 christos {
323 1.1 christos symbolS *symbolP;
324 1.1 christos
325 1.8 christos /* BFD converts filename to a .file symbol with an aux entry. It
326 1.1 christos also handles chaining. */
327 1.1 christos symbolP = symbol_new (filename, bfd_abs_section_ptr, &zero_address_frag, 0);
328 1.1 christos
329 1.1 christos S_SET_STORAGE_CLASS (symbolP, C_FILE);
330 1.1 christos S_SET_NUMBER_AUXILIARY (symbolP, 1);
331 1.1 christos
332 1.1 christos symbol_get_bfdsym (symbolP)->flags = BSF_DEBUGGING;
333 1.1 christos
334 1.1 christos #ifndef NO_LISTING
335 1.1 christos {
336 1.1 christos extern int listing;
337 1.1 christos
338 1.1 christos if (listing)
339 1.1 christos listing_source_file (filename);
340 1.1 christos }
341 1.1 christos #endif
342 1.1 christos
343 1.1 christos /* Make sure that the symbol is first on the symbol chain. */
344 1.1 christos if (symbol_rootP != symbolP)
345 1.1 christos {
346 1.1 christos symbol_remove (symbolP, &symbol_rootP, &symbol_lastP);
347 1.1 christos symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
348 1.1 christos }
349 1.1 christos }
350 1.1 christos
351 1.1 christos /* Line number handling. */
352 1.1 christos
353 1.1 christos struct line_no
354 1.1 christos {
355 1.1 christos struct line_no *next;
356 1.1 christos fragS *frag;
357 1.1 christos alent l;
358 1.1 christos };
359 1.1 christos
360 1.1 christos int coff_line_base;
361 1.1 christos
362 1.1 christos /* Symbol of last function, which we should hang line#s off of. */
363 1.1 christos static symbolS *line_fsym;
364 1.1 christos
365 1.1 christos #define in_function() (line_fsym != 0)
366 1.1 christos #define clear_function() (line_fsym = 0)
367 1.1 christos #define set_function(F) (line_fsym = (F), coff_add_linesym (F))
368 1.1 christos
369 1.1 christos
370 1.1 christos void
372 1.10 christos coff_obj_symbol_new_hook (symbolS *symbolP)
373 1.1 christos {
374 1.1 christos size_t sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
375 1.10 christos combined_entry_type *s = notes_alloc (sz);
376 1.8 christos
377 1.1 christos memset (s, 0, sz);
378 1.1 christos coffsymbol (symbol_get_bfdsym (symbolP))->native = s;
379 1.1 christos coffsymbol (symbol_get_bfdsym (symbolP))->native->is_sym = true;
380 1.1 christos
381 1.1 christos S_SET_DATA_TYPE (symbolP, T_NULL);
382 1.1 christos S_SET_STORAGE_CLASS (symbolP, 0);
383 1.1 christos S_SET_NUMBER_AUXILIARY (symbolP, 0);
384 1.1 christos
385 1.1 christos if (S_IS_STRING (symbolP))
386 1.1 christos SF_SET_STRING (symbolP);
387 1.1 christos
388 1.1 christos if (S_IS_LOCAL (symbolP))
389 1.1 christos SF_SET_LOCAL (symbolP);
390 1.1 christos }
391 1.1 christos
392 1.10 christos void
393 1.10 christos coff_obj_symbol_clone_hook (symbolS *newsymP, symbolS *orgsymP)
394 1.1 christos {
395 1.10 christos size_t sz = (OBJ_COFF_MAX_AUXENTRIES + 1) * sizeof (combined_entry_type);
396 1.1 christos combined_entry_type *s = notes_alloc (sz);
397 1.1 christos
398 1.1 christos memcpy (s, coffsymbol (symbol_get_bfdsym (orgsymP))->native, sz);
399 1.1 christos coffsymbol (symbol_get_bfdsym (newsymP))->native = s;
400 1.1 christos
401 1.1 christos SF_SET (newsymP, SF_GET (orgsymP));
402 1.1 christos }
403 1.1 christos
404 1.1 christos
405 1.1 christos /* Handle .ln directives. */
407 1.1 christos
408 1.1 christos static symbolS *current_lineno_sym;
409 1.1 christos static struct line_no *line_nos;
410 1.1 christos /* FIXME: Blindly assume all .ln directives will be in the .text section. */
411 1.1 christos int coff_n_line_nos;
412 1.5 christos
413 1.1 christos static void
414 1.1 christos add_lineno (fragS * frag, addressT offset, int num)
415 1.1 christos {
416 1.1 christos struct line_no * new_line = XNEW (struct line_no);
417 1.1 christos
418 1.1 christos if (!current_lineno_sym)
419 1.1 christos abort ();
420 1.1 christos
421 1.1 christos #ifndef OBJ_XCOFF
422 1.1 christos /* The native aix assembler accepts negative line number. */
423 1.1 christos
424 1.1 christos if (num <= 0)
425 1.1 christos {
426 1.1 christos /* Zero is used as an end marker in the file. */
427 1.1 christos as_warn (_("Line numbers must be positive integers\n"));
428 1.1 christos num = 1;
429 1.1 christos }
430 1.1 christos #endif /* OBJ_XCOFF */
431 1.1 christos new_line->next = line_nos;
432 1.1 christos new_line->frag = frag;
433 1.1 christos new_line->l.line_number = num;
434 1.1 christos new_line->l.u.offset = offset;
435 1.1 christos line_nos = new_line;
436 1.1 christos coff_n_line_nos++;
437 1.1 christos }
438 1.1 christos
439 1.1 christos void
440 1.1 christos coff_add_linesym (symbolS *sym)
441 1.1 christos {
442 1.1 christos if (line_nos)
443 1.1 christos {
444 1.1 christos coffsymbol (symbol_get_bfdsym (current_lineno_sym))->lineno =
445 1.1 christos (alent *) line_nos;
446 1.1 christos coff_n_line_nos++;
447 1.1 christos line_nos = 0;
448 1.1 christos }
449 1.8 christos current_lineno_sym = sym;
450 1.1 christos }
451 1.1 christos
452 1.1 christos static void
453 1.8 christos obj_coff_ln (int ignore ATTRIBUTE_UNUSED)
454 1.1 christos {
455 1.1 christos int l;
456 1.1 christos
457 1.1 christos if (def_symbol_in_progress != NULL)
458 1.1 christos {
459 1.1 christos as_warn (_(".ln pseudo-op inside .def/.endef: ignored."));
460 1.1 christos demand_empty_rest_of_line ();
461 1.1 christos return;
462 1.8 christos }
463 1.8 christos
464 1.8 christos l = get_absolute_expression ();
465 1.10 christos
466 1.1 christos /* If there is no lineno symbol, treat a .ln directive
467 1.1 christos as if it were a (no longer existing) .appline one. */
468 1.1 christos if (current_lineno_sym == NULL)
469 1.1 christos new_logical_line (NULL, l - 1);
470 1.1 christos else
471 1.1 christos add_lineno (frag_now, frag_now_fix (), l);
472 1.1 christos
473 1.1 christos #ifndef NO_LISTING
474 1.1 christos {
475 1.8 christos extern int listing;
476 1.1 christos
477 1.1 christos if (listing)
478 1.1 christos {
479 1.1 christos l += coff_line_base - 1;
480 1.1 christos listing_source_line (l);
481 1.1 christos }
482 1.1 christos }
483 1.1 christos #endif
484 1.1 christos
485 1.1 christos demand_empty_rest_of_line ();
486 1.1 christos }
487 1.1 christos
488 1.1 christos /* .loc is essentially the same as .ln; parse it for assembler
489 1.1 christos compatibility. */
490 1.1 christos
491 1.1 christos static void
492 1.1 christos obj_coff_loc (int ignore ATTRIBUTE_UNUSED)
493 1.1 christos {
494 1.1 christos int lineno;
495 1.1 christos
496 1.1 christos /* FIXME: Why do we need this check? We need it for ECOFF, but why
497 1.1 christos do we need it for COFF? */
498 1.1 christos if (now_seg != text_section)
499 1.1 christos {
500 1.1 christos as_warn (_(".loc outside of .text"));
501 1.1 christos demand_empty_rest_of_line ();
502 1.1 christos return;
503 1.1 christos }
504 1.1 christos
505 1.1 christos if (def_symbol_in_progress != NULL)
506 1.1 christos {
507 1.1 christos as_warn (_(".loc pseudo-op inside .def/.endef: ignored."));
508 1.1 christos demand_empty_rest_of_line ();
509 1.1 christos return;
510 1.1 christos }
511 1.1 christos
512 1.1 christos /* Skip the file number. */
513 1.1 christos SKIP_WHITESPACE ();
514 1.1 christos get_absolute_expression ();
515 1.1 christos SKIP_WHITESPACE ();
516 1.1 christos
517 1.1 christos lineno = get_absolute_expression ();
518 1.1 christos
519 1.1 christos #ifndef NO_LISTING
520 1.1 christos {
521 1.1 christos extern int listing;
522 1.1 christos
523 1.1 christos if (listing)
524 1.1 christos {
525 1.1 christos lineno += coff_line_base - 1;
526 1.1 christos listing_source_line (lineno);
527 1.1 christos }
528 1.1 christos }
529 1.1 christos #endif
530 1.1 christos
531 1.1 christos demand_empty_rest_of_line ();
532 1.1 christos
533 1.1 christos add_lineno (frag_now, frag_now_fix (), lineno);
534 1.1 christos }
535 1.1 christos
536 1.1 christos /* Handle the .ident pseudo-op. */
537 1.1 christos
538 1.1 christos static void
539 1.1 christos obj_coff_ident (int ignore ATTRIBUTE_UNUSED)
540 1.1 christos {
541 1.1 christos segT current_seg = now_seg;
542 1.1 christos subsegT current_subseg = now_subseg;
543 1.1 christos
544 1.1 christos #ifdef TE_PE
545 1.1 christos {
546 1.1 christos segT sec;
547 1.1 christos
548 1.7 christos /* We could put it in .comment, but that creates an extra section
549 1.1 christos that shouldn't be loaded into memory, which requires linker
550 1.1 christos changes... For now, until proven otherwise, use .rdata. */
551 1.1 christos sec = subseg_new (".rdata$zzz", 0);
552 1.1 christos bfd_set_section_flags (sec,
553 1.1 christos ((SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA)
554 1.1 christos & bfd_applicable_section_flags (stdoutput)));
555 1.1 christos }
556 1.1 christos #else
557 1.1 christos subseg_new (".comment", 0);
558 1.1 christos #endif
559 1.1 christos
560 1.1 christos stringer (8 + 1);
561 1.1 christos subseg_set (current_seg, current_subseg);
562 1.1 christos }
563 1.1 christos
564 1.1 christos /* Handle .def directives.
565 1.1 christos
566 1.1 christos One might ask : why can't we symbol_new if the symbol does not
567 1.1 christos already exist and fill it with debug information. Because of
568 1.1 christos the C_EFCN special symbol. It would clobber the value of the
569 1.10 christos function symbol before we have a chance to notice that it is
570 1.1 christos a C_EFCN. And a second reason is that the code is more clear this
571 1.1 christos way. (at least I think it is :-). */
572 1.10 christos
573 1.1 christos #define SKIP_WHITESPACES() while (is_whitespace (*input_line_pointer)) \
574 1.1 christos input_line_pointer++;
575 1.1 christos
576 1.1 christos void
577 1.1 christos obj_coff_def (int what ATTRIBUTE_UNUSED)
578 1.1 christos {
579 1.1 christos if (def_symbol_in_progress != NULL)
580 1.1 christos {
581 1.1 christos as_warn (_(".def pseudo-op used inside of .def/.endef: ignored."));
582 1.1 christos demand_empty_rest_of_line ();
583 1.1 christos return;
584 1.10 christos }
585 1.10 christos
586 1.10 christos SKIP_WHITESPACES ();
587 1.10 christos
588 1.10 christos char *symbol_name;
589 1.5 christos char name_end = get_symbol_name (&symbol_name);
590 1.10 christos char *symbol_name_copy = NULL;
591 1.1 christos char *canon_name = symbol_name;
592 1.1 christos #ifdef tc_canonicalize_symbol_name
593 1.1 christos symbol_name_copy = xstrdup (symbol_name);
594 1.10 christos canon_name = tc_canonicalize_symbol_name (symbol_name_copy);
595 1.10 christos #endif
596 1.1 christos
597 1.1 christos /* Initialize the new symbol. */
598 1.1 christos def_symbol_in_progress = symbol_make (canon_name);
599 1.1 christos free (symbol_name_copy);
600 1.1 christos symbol_set_frag (def_symbol_in_progress, &zero_address_frag);
601 1.1 christos S_SET_VALUE (def_symbol_in_progress, 0);
602 1.3 christos
603 1.1 christos if (S_IS_STRING (def_symbol_in_progress))
604 1.1 christos SF_SET_STRING (def_symbol_in_progress);
605 1.1 christos
606 1.1 christos (void) restore_line_pointer (name_end);
607 1.1 christos
608 1.1 christos demand_empty_rest_of_line ();
609 1.1 christos }
610 1.1 christos
611 1.1 christos static void
612 1.1 christos obj_coff_endef (int ignore ATTRIBUTE_UNUSED)
613 1.1 christos {
614 1.1 christos symbolS *symbolP = NULL;
615 1.1 christos
616 1.1 christos if (def_symbol_in_progress == NULL)
617 1.1 christos {
618 1.1 christos as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored."));
619 1.1 christos demand_empty_rest_of_line ();
620 1.1 christos return;
621 1.1 christos }
622 1.1 christos
623 1.1 christos /* Set the section number according to storage class. */
624 1.1 christos switch (S_GET_STORAGE_CLASS (def_symbol_in_progress))
625 1.1 christos {
626 1.1 christos case C_STRTAG:
627 1.1 christos case C_ENTAG:
628 1.1 christos case C_UNTAG:
629 1.1 christos SF_SET_TAG (def_symbol_in_progress);
630 1.1 christos /* Fall through. */
631 1.1 christos case C_FILE:
632 1.1 christos case C_TPDEF:
633 1.1 christos SF_SET_DEBUG (def_symbol_in_progress);
634 1.1 christos S_SET_SEGMENT (def_symbol_in_progress, fetch_coff_debug_section ());
635 1.1 christos break;
636 1.1 christos
637 1.1 christos case C_EFCN:
638 1.1 christos SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */
639 1.1 christos /* Fall through. */
640 1.1 christos case C_BLOCK:
641 1.1 christos SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing. */
642 1.1 christos /* Fall through. */
643 1.1 christos case C_FCN:
644 1.1 christos {
645 1.1 christos const char *name;
646 1.1 christos
647 1.1 christos S_SET_SEGMENT (def_symbol_in_progress, text_section);
648 1.1 christos
649 1.1 christos name = S_GET_NAME (def_symbol_in_progress);
650 1.1 christos if (name[0] == '.' && name[2] == 'f' && name[3] == '\0')
651 1.1 christos {
652 1.1 christos switch (name[1])
653 1.1 christos {
654 1.1 christos case 'b':
655 1.1 christos /* .bf */
656 1.1 christos if (! in_function ())
657 1.1 christos as_warn (_("`%s' symbol without preceding function"), name);
658 1.1 christos /* Will need relocating. */
659 1.1 christos SF_SET_PROCESS (def_symbol_in_progress);
660 1.1 christos clear_function ();
661 1.1 christos break;
662 1.1 christos #ifdef TE_PE
663 1.1 christos case 'e':
664 1.1 christos /* .ef */
665 1.1 christos /* The MS compilers output the actual endline, not the
666 1.1 christos function-relative one... we want to match without
667 1.1 christos changing the assembler input. */
668 1.1 christos SA_SET_SYM_LNNO (def_symbol_in_progress,
669 1.1 christos (SA_GET_SYM_LNNO (def_symbol_in_progress)
670 1.1 christos + coff_line_base));
671 1.1 christos break;
672 1.1 christos #endif
673 1.1 christos }
674 1.1 christos }
675 1.1 christos }
676 1.1 christos break;
677 1.1 christos
678 1.1 christos #ifdef C_AUTOARG
679 1.1 christos case C_AUTOARG:
680 1.1 christos #endif /* C_AUTOARG */
681 1.1 christos case C_AUTO:
682 1.1 christos case C_REG:
683 1.1 christos case C_ARG:
684 1.1 christos case C_REGPARM:
685 1.1 christos case C_FIELD:
686 1.1 christos
687 1.1 christos /* According to the COFF documentation:
688 1.1 christos
689 1.1 christos http://osr5doc.sco.com:1996/topics/COFF_SectNumFld.html
690 1.1 christos
691 1.1 christos A special section number (-2) marks symbolic debugging symbols,
692 1.1 christos including structure/union/enumeration tag names, typedefs, and
693 1.1 christos the name of the file. A section number of -1 indicates that the
694 1.1 christos symbol has a value but is not relocatable. Examples of
695 1.1 christos absolute-valued symbols include automatic and register variables,
696 1.1 christos function arguments, and .eos symbols.
697 1.1 christos
698 1.1 christos But from Ian Lance Taylor:
699 1.1 christos
700 1.1 christos http://sources.redhat.com/ml/binutils/2000-08/msg00202.html
701 1.1 christos
702 1.1 christos the actual tools all marked them as section -1. So the GNU COFF
703 1.1 christos assembler follows historical COFF assemblers.
704 1.1 christos
705 1.1 christos However, it causes problems for djgpp
706 1.1 christos
707 1.1 christos http://sources.redhat.com/ml/binutils/2000-08/msg00210.html
708 1.1 christos
709 1.1 christos By defining STRICTCOFF, a COFF port can make the assembler to
710 1.1 christos follow the documented behavior. */
711 1.1 christos #ifdef STRICTCOFF
712 1.1 christos case C_MOS:
713 1.1 christos case C_MOE:
714 1.1 christos case C_MOU:
715 1.1 christos case C_EOS:
716 1.1 christos #endif
717 1.1 christos SF_SET_DEBUG (def_symbol_in_progress);
718 1.1 christos S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
719 1.1 christos break;
720 1.1 christos
721 1.1 christos #ifndef STRICTCOFF
722 1.1 christos case C_MOS:
723 1.1 christos case C_MOE:
724 1.1 christos case C_MOU:
725 1.1 christos case C_EOS:
726 1.1 christos S_SET_SEGMENT (def_symbol_in_progress, absolute_section);
727 1.1 christos break;
728 1.1 christos #endif
729 1.1 christos
730 1.1 christos case C_EXT:
731 1.1 christos case C_WEAKEXT:
732 1.1 christos #ifdef TE_PE
733 1.1 christos case C_NT_WEAK:
734 1.1 christos #endif
735 1.1 christos case C_STAT:
736 1.1 christos case C_LABEL:
737 1.1 christos /* Valid but set somewhere else (s_comm, s_lcomm, colon). */
738 1.1 christos break;
739 1.1 christos
740 1.1 christos default:
741 1.1 christos case C_USTATIC:
742 1.1 christos case C_EXTDEF:
743 1.1 christos case C_ULABEL:
744 1.1 christos as_warn (_("unexpected storage class %d"),
745 1.1 christos S_GET_STORAGE_CLASS (def_symbol_in_progress));
746 1.1 christos break;
747 1.1 christos }
748 1.1 christos
749 1.1 christos /* Now that we have built a debug symbol, try to find if we should
750 1.1 christos merge with an existing symbol or not. If a symbol is C_EFCN or
751 1.1 christos absolute_section or untagged SEG_DEBUG it never merges. We also
752 1.1 christos don't merge labels, which are in a different namespace, nor
753 1.1 christos symbols which have not yet been defined since they are typically
754 1.1 christos unique, nor do we merge tags with non-tags. */
755 1.1 christos
756 1.1 christos /* Two cases for functions. Either debug followed by definition or
757 1.1 christos definition followed by debug. For definition first, we will
758 1.1 christos merge the debug symbol into the definition. For debug first, the
759 1.1 christos lineno entry MUST point to the definition function or else it
760 1.1 christos will point off into space when obj_crawl_symbol_chain() merges
761 1.1 christos the debug symbol into the real symbol. Therefor, let's presume
762 1.1 christos the debug symbol is a real function reference. */
763 1.1 christos
764 1.1 christos /* FIXME-SOON If for some reason the definition label/symbol is
765 1.1 christos never seen, this will probably leave an undefined symbol at link
766 1.7 christos time. */
767 1.1 christos
768 1.1 christos if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
769 1.1 christos || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
770 1.1 christos || (streq (bfd_section_name (S_GET_SEGMENT (def_symbol_in_progress)),
771 1.1 christos "*DEBUG*")
772 1.1 christos && !SF_GET_TAG (def_symbol_in_progress))
773 1.1 christos || S_GET_SEGMENT (def_symbol_in_progress) == absolute_section
774 1.1 christos || ! symbol_constant_p (def_symbol_in_progress)
775 1.1 christos || (symbolP = symbol_find (S_GET_NAME (def_symbol_in_progress))) == NULL
776 1.1 christos || SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP))
777 1.1 christos {
778 1.1 christos /* If it already is at the end of the symbol list, do nothing */
779 1.1 christos if (def_symbol_in_progress != symbol_lastP)
780 1.1 christos {
781 1.1 christos symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
782 1.1 christos symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
783 1.1 christos &symbol_lastP);
784 1.1 christos }
785 1.1 christos }
786 1.1 christos else
787 1.1 christos {
788 1.1 christos /* This symbol already exists, merge the newly created symbol
789 1.1 christos into the old one. This is not mandatory. The linker can
790 1.1 christos handle duplicate symbols correctly. But I guess that it save
791 1.1 christos a *lot* of space if the assembly file defines a lot of
792 1.1 christos symbols. [loic] */
793 1.1 christos
794 1.1 christos /* The debug entry (def_symbol_in_progress) is merged into the
795 1.1 christos previous definition. */
796 1.1 christos
797 1.1 christos c_symbol_merge (def_symbol_in_progress, symbolP);
798 1.1 christos symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
799 1.1 christos
800 1.1 christos def_symbol_in_progress = symbolP;
801 1.1 christos
802 1.1 christos if (SF_GET_FUNCTION (def_symbol_in_progress)
803 1.1 christos || SF_GET_TAG (def_symbol_in_progress)
804 1.1 christos || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_STAT)
805 1.1 christos {
806 1.1 christos /* For functions, and tags, and static symbols, the symbol
807 1.1 christos *must* be where the debug symbol appears. Move the
808 1.1 christos existing symbol to the current place. */
809 1.1 christos /* If it already is at the end of the symbol list, do nothing. */
810 1.1 christos if (def_symbol_in_progress != symbol_lastP)
811 1.1 christos {
812 1.1 christos symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
813 1.1 christos symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
814 1.1 christos }
815 1.1 christos }
816 1.1 christos }
817 1.1 christos
818 1.1 christos if (SF_GET_TAG (def_symbol_in_progress))
819 1.1 christos {
820 1.1 christos symbolS *oldtag;
821 1.1 christos
822 1.1 christos oldtag = symbol_find (S_GET_NAME (def_symbol_in_progress));
823 1.1 christos if (oldtag == NULL || ! SF_GET_TAG (oldtag))
824 1.1 christos tag_insert (S_GET_NAME (def_symbol_in_progress),
825 1.1 christos def_symbol_in_progress);
826 1.1 christos }
827 1.1 christos
828 1.1 christos if (SF_GET_FUNCTION (def_symbol_in_progress))
829 1.1 christos {
830 1.1 christos set_function (def_symbol_in_progress);
831 1.1 christos SF_SET_PROCESS (def_symbol_in_progress);
832 1.1 christos
833 1.1 christos if (symbolP == NULL)
834 1.1 christos /* That is, if this is the first time we've seen the
835 1.1 christos function. */
836 1.1 christos symbol_table_insert (def_symbol_in_progress);
837 1.1 christos
838 1.1 christos }
839 1.1 christos
840 1.1 christos def_symbol_in_progress = NULL;
841 1.1 christos demand_empty_rest_of_line ();
842 1.1 christos }
843 1.1 christos
844 1.1 christos static void
845 1.1 christos obj_coff_dim (int ignore ATTRIBUTE_UNUSED)
846 1.1 christos {
847 1.1 christos int d_index;
848 1.1 christos
849 1.1 christos if (def_symbol_in_progress == NULL)
850 1.1 christos {
851 1.1 christos as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored."));
852 1.1 christos demand_empty_rest_of_line ();
853 1.1 christos return;
854 1.1 christos }
855 1.1 christos
856 1.1 christos S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
857 1.1 christos
858 1.1 christos for (d_index = 0; d_index < DIMNUM; d_index++)
859 1.1 christos {
860 1.1 christos SKIP_WHITESPACES ();
861 1.1 christos SA_SET_SYM_DIMEN (def_symbol_in_progress, d_index,
862 1.1 christos get_absolute_expression ());
863 1.1 christos
864 1.1 christos switch (*input_line_pointer)
865 1.1 christos {
866 1.1 christos case ',':
867 1.1 christos input_line_pointer++;
868 1.1 christos break;
869 1.1 christos
870 1.1 christos default:
871 1.1 christos as_warn (_("badly formed .dim directive ignored"));
872 1.1 christos /* Fall through. */
873 1.1 christos case '\n':
874 1.1 christos case ';':
875 1.1 christos d_index = DIMNUM;
876 1.1 christos break;
877 1.1 christos }
878 1.1 christos }
879 1.1 christos
880 1.1 christos demand_empty_rest_of_line ();
881 1.1 christos }
882 1.1 christos
883 1.1 christos static void
884 1.1 christos obj_coff_line (int ignore ATTRIBUTE_UNUSED)
885 1.1 christos {
886 1.1 christos int this_base;
887 1.1 christos
888 1.1 christos if (def_symbol_in_progress == NULL)
889 1.1 christos {
890 1.1 christos /* Probably stabs-style line? */
891 1.1 christos obj_coff_ln (0);
892 1.1 christos return;
893 1.1 christos }
894 1.1 christos
895 1.1 christos this_base = get_absolute_expression ();
896 1.1 christos if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
897 1.1 christos coff_line_base = this_base;
898 1.1 christos
899 1.1 christos S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
900 1.1 christos SA_SET_SYM_LNNO (def_symbol_in_progress, this_base);
901 1.1 christos
902 1.1 christos demand_empty_rest_of_line ();
903 1.1 christos
904 1.1 christos #ifndef NO_LISTING
905 1.1 christos if (streq (".bf", S_GET_NAME (def_symbol_in_progress)))
906 1.10 christos {
907 1.1 christos extern int listing;
908 1.1 christos
909 1.1 christos if (listing)
910 1.1 christos listing_source_line (this_base);
911 1.1 christos }
912 1.1 christos #endif
913 1.1 christos }
914 1.1 christos
915 1.1 christos static void
916 1.6 christos obj_coff_size (int ignore ATTRIBUTE_UNUSED)
917 1.1 christos {
918 1.1 christos if (def_symbol_in_progress == NULL)
919 1.1 christos {
920 1.1 christos as_warn (_(".size pseudo-op used outside of .def/.endef: ignored."));
921 1.1 christos demand_empty_rest_of_line ();
922 1.1 christos return;
923 1.1 christos }
924 1.1 christos
925 1.1 christos S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
926 1.1 christos SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ());
927 1.1 christos demand_empty_rest_of_line ();
928 1.1 christos }
929 1.1 christos
930 1.1 christos static void
931 1.6 christos obj_coff_scl (int ignore ATTRIBUTE_UNUSED)
932 1.1 christos {
933 1.1 christos if (def_symbol_in_progress == NULL)
934 1.1 christos {
935 1.1 christos as_warn (_(".scl pseudo-op used outside of .def/.endef: ignored."));
936 1.1 christos demand_empty_rest_of_line ();
937 1.1 christos return;
938 1.1 christos }
939 1.1 christos
940 1.1 christos S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ());
941 1.1 christos demand_empty_rest_of_line ();
942 1.1 christos }
943 1.1 christos
944 1.1 christos static void
945 1.1 christos obj_coff_tag (int ignore ATTRIBUTE_UNUSED)
946 1.1 christos {
947 1.1 christos char *symbol_name;
948 1.6 christos char name_end;
949 1.1 christos
950 1.1 christos if (def_symbol_in_progress == NULL)
951 1.1 christos {
952 1.1 christos as_warn (_(".tag pseudo-op used outside of .def/.endef: ignored."));
953 1.1 christos demand_empty_rest_of_line ();
954 1.3 christos return;
955 1.1 christos }
956 1.1 christos
957 1.1 christos S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1);
958 1.1 christos name_end = get_symbol_name (&symbol_name);
959 1.1 christos
960 1.1 christos #ifdef tc_canonicalize_symbol_name
961 1.1 christos symbol_name = tc_canonicalize_symbol_name (symbol_name);
962 1.1 christos #endif
963 1.1 christos
964 1.1 christos /* Assume that the symbol referred to by .tag is always defined.
965 1.1 christos This was a bad assumption. I've added find_or_make. xoxorich. */
966 1.1 christos SA_SET_SYM_TAGNDX (def_symbol_in_progress,
967 1.1 christos tag_find_or_make (symbol_name));
968 1.1 christos if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L)
969 1.3 christos as_warn (_("tag not found for .tag %s"), symbol_name);
970 1.1 christos
971 1.1 christos SF_SET_TAGGED (def_symbol_in_progress);
972 1.1 christos
973 1.1 christos (void) restore_line_pointer (name_end);
974 1.1 christos demand_empty_rest_of_line ();
975 1.1 christos }
976 1.1 christos
977 1.1 christos static void
978 1.6 christos obj_coff_type (int ignore ATTRIBUTE_UNUSED)
979 1.1 christos {
980 1.1 christos if (def_symbol_in_progress == NULL)
981 1.1 christos {
982 1.1 christos as_warn (_(".type pseudo-op used outside of .def/.endef: ignored."));
983 1.1 christos demand_empty_rest_of_line ();
984 1.1 christos return;
985 1.10 christos }
986 1.10 christos
987 1.1 christos S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ());
988 1.1 christos
989 1.1 christos if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress))
990 1.1 christos && S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF)
991 1.1 christos SF_SET_FUNCTION (def_symbol_in_progress);
992 1.1 christos
993 1.1 christos demand_empty_rest_of_line ();
994 1.1 christos }
995 1.1 christos
996 1.1 christos static void
997 1.6 christos obj_coff_val (int ignore ATTRIBUTE_UNUSED)
998 1.1 christos {
999 1.1 christos if (def_symbol_in_progress == NULL)
1000 1.1 christos {
1001 1.1 christos as_warn (_(".val pseudo-op used outside of .def/.endef: ignored."));
1002 1.1 christos demand_empty_rest_of_line ();
1003 1.1 christos return;
1004 1.3 christos }
1005 1.3 christos
1006 1.1 christos if (is_name_beginner (*input_line_pointer))
1007 1.1 christos {
1008 1.3 christos char *symbol_name;
1009 1.1 christos char name_end = get_symbol_name (&symbol_name);
1010 1.1 christos
1011 1.1 christos #ifdef tc_canonicalize_symbol_name
1012 1.1 christos symbol_name = tc_canonicalize_symbol_name (symbol_name);
1013 1.1 christos #endif
1014 1.10 christos if (streq (symbol_name, "."))
1015 1.1 christos {
1016 1.1 christos /* If the .val is != from the .def (e.g. statics). */
1017 1.1 christos symbol_set_frag (def_symbol_in_progress, frag_now);
1018 1.1 christos S_SET_VALUE (def_symbol_in_progress, frag_now_fix ());
1019 1.1 christos }
1020 1.1 christos else if (! streq (S_GET_NAME (def_symbol_in_progress), symbol_name))
1021 1.1 christos {
1022 1.1 christos expressionS exp;
1023 1.1 christos
1024 1.1 christos exp.X_op = O_symbol;
1025 1.1 christos exp.X_add_symbol = symbol_find_or_make (symbol_name);
1026 1.1 christos exp.X_op_symbol = NULL;
1027 1.1 christos exp.X_add_number = 0;
1028 1.1 christos symbol_set_value_expression (def_symbol_in_progress, &exp);
1029 1.1 christos
1030 1.1 christos /* If the segment is undefined when the forward reference is
1031 1.1 christos resolved, then copy the segment id from the forward
1032 1.1 christos symbol. */
1033 1.1 christos SF_SET_GET_SEGMENT (def_symbol_in_progress);
1034 1.1 christos
1035 1.1 christos /* FIXME: gcc can generate address expressions here in
1036 1.1 christos unusual cases (search for "obscure" in sdbout.c). We
1037 1.1 christos just ignore the offset here, thus generating incorrect
1038 1.1 christos debugging information. We ignore the rest of the line
1039 1.3 christos just below. */
1040 1.1 christos }
1041 1.1 christos /* Otherwise, it is the name of a non debug symbol and its value
1042 1.1 christos will be calculated later. */
1043 1.1 christos (void) restore_line_pointer (name_end);
1044 1.1 christos }
1045 1.1 christos else
1046 1.1 christos {
1047 1.1 christos S_SET_VALUE (def_symbol_in_progress, get_absolute_expression ());
1048 1.1 christos }
1049 1.1 christos
1050 1.1 christos demand_empty_rest_of_line ();
1051 1.1 christos }
1052 1.1 christos
1053 1.1 christos #ifdef TE_PE
1054 1.1 christos
1055 1.1 christos /* Return nonzero if name begins with weak alternate symbol prefix. */
1056 1.8 christos
1057 1.1 christos static int
1058 1.1 christos weak_is_altname (const char * name)
1059 1.1 christos {
1060 1.1 christos return startswith (name, weak_altprefix);
1061 1.1 christos }
1062 1.10 christos
1063 1.1 christos /* Return the name of the alternate symbol
1064 1.1 christos name corresponding to a weak symbol's name. */
1065 1.5 christos
1066 1.1 christos static char *
1067 1.1 christos weak_name2altname (const char * name)
1068 1.1 christos {
1069 1.1 christos return concat (weak_altprefix, name, (char *) NULL);
1070 1.1 christos }
1071 1.10 christos
1072 1.1 christos /* Return the name of the weak symbol corresponding to an
1073 1.1 christos alternate symbol. */
1074 1.1 christos
1075 1.1 christos static char *
1076 1.1 christos weak_altname2name (const char * name)
1077 1.1 christos {
1078 1.1 christos gas_assert (weak_is_altname (name));
1079 1.1 christos return xstrdup (name + 6);
1080 1.1 christos }
1081 1.1 christos
1082 1.1 christos /* Make a weak symbol name unique by
1083 1.1 christos appending the name of an external symbol. */
1084 1.1 christos
1085 1.1 christos static const char *
1086 1.1 christos weak_uniquify (const char * name)
1087 1.1 christos {
1088 1.1 christos const char * unique = "";
1089 1.1 christos
1090 1.1 christos #ifdef TE_PE
1091 1.1 christos if (an_external_name != NULL)
1092 1.10 christos unique = an_external_name;
1093 1.1 christos #endif
1094 1.1 christos gas_assert (weak_is_altname (name));
1095 1.1 christos
1096 1.1 christos return notes_concat (name, ".", unique, (char *) NULL);
1097 1.1 christos }
1098 1.1 christos
1099 1.1 christos void
1100 1.1 christos pecoff_obj_set_weak_hook (symbolS *symbolP)
1101 1.1 christos {
1102 1.1 christos symbolS *alternateP;
1103 1.1 christos
1104 1.1 christos /* See _Microsoft Portable Executable and Common Object
1105 1.1 christos File Format Specification_, section 5.5.3.
1106 1.1 christos Create a symbol representing the alternate value.
1107 1.1 christos coff_frob_symbol will set the value of this symbol from
1108 1.1 christos the value of the weak symbol itself. */
1109 1.10 christos S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
1110 1.10 christos S_SET_NUMBER_AUXILIARY (symbolP, 1);
1111 1.10 christos SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
1112 1.1 christos
1113 1.1 christos char *altname = weak_name2altname (S_GET_NAME (symbolP));
1114 1.1 christos alternateP = symbol_find_or_make (altname);
1115 1.1 christos free (altname);
1116 1.1 christos S_SET_EXTERNAL (alternateP);
1117 1.1 christos S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK);
1118 1.1 christos
1119 1.1 christos SA_SET_SYM_TAGNDX (symbolP, alternateP);
1120 1.1 christos }
1121 1.1 christos
1122 1.1 christos void
1123 1.1 christos pecoff_obj_clear_weak_hook (symbolS *symbolP)
1124 1.1 christos {
1125 1.1 christos symbolS *alternateP;
1126 1.10 christos
1127 1.10 christos S_SET_STORAGE_CLASS (symbolP, 0);
1128 1.10 christos SA_SET_SYM_FSIZE (symbolP, 0);
1129 1.1 christos
1130 1.1 christos char *altname = weak_name2altname (S_GET_NAME (symbolP));
1131 1.1 christos alternateP = symbol_find (altname);
1132 1.1 christos free (altname);
1133 1.1 christos S_CLEAR_EXTERNAL (alternateP);
1134 1.1 christos }
1135 1.1 christos
1136 1.1 christos #endif /* TE_PE */
1137 1.1 christos
1138 1.1 christos /* Handle .weak. This is a GNU extension in formats other than PE. */
1139 1.1 christos
1140 1.1 christos static void
1141 1.1 christos obj_coff_weak (int ignore ATTRIBUTE_UNUSED)
1142 1.1 christos {
1143 1.1 christos char *name;
1144 1.1 christos int c;
1145 1.3 christos symbolS *symbolP;
1146 1.1 christos
1147 1.1 christos do
1148 1.1 christos {
1149 1.1 christos c = get_symbol_name (&name);
1150 1.1 christos if (*name == 0)
1151 1.1 christos {
1152 1.1 christos as_warn (_("badly formed .weak directive ignored"));
1153 1.1 christos ignore_rest_of_line ();
1154 1.10 christos return;
1155 1.10 christos }
1156 1.1 christos c = 0;
1157 1.1 christos symbolP = symbol_find_or_make (name);
1158 1.1 christos restore_line_pointer (c);
1159 1.1 christos SKIP_WHITESPACE ();
1160 1.1 christos S_SET_WEAK (symbolP);
1161 1.1 christos
1162 1.1 christos if (c == ',')
1163 1.1 christos {
1164 1.1 christos input_line_pointer++;
1165 1.1 christos SKIP_WHITESPACE ();
1166 1.1 christos if (*input_line_pointer == '\n')
1167 1.1 christos c = '\n';
1168 1.1 christos }
1169 1.1 christos
1170 1.1 christos }
1171 1.1 christos while (c == ',');
1172 1.1 christos
1173 1.1 christos demand_empty_rest_of_line ();
1174 1.1 christos }
1175 1.1 christos
1176 1.1 christos void
1177 1.1 christos coff_obj_read_begin_hook (void)
1178 1.1 christos {
1179 1.1 christos /* These had better be the same. Usually 18 bytes. */
1180 1.1 christos know (sizeof (SYMENT) == sizeof (AUXENT));
1181 1.10 christos know (SYMESZ == AUXESZ);
1182 1.10 christos tag_init ();
1183 1.10 christos }
1184 1.10 christos
1185 1.10 christos void
1186 1.10 christos coff_assign_symbol (symbolS *symp ATTRIBUTE_UNUSED)
1187 1.10 christos {
1188 1.10 christos #ifndef TE_PE
1189 1.10 christos /* "set" symbols are local unless otherwise specified. */
1190 1.1 christos SF_SET_LOCAL (symp);
1191 1.1 christos #endif
1192 1.1 christos }
1193 1.1 christos
1194 1.1 christos #ifndef OBJ_XCOFF
1195 1.1 christos static symbolS *coff_last_bf;
1196 1.1 christos #endif
1197 1.10 christos
1198 1.1 christos void
1199 1.1 christos coff_frob_symbol (symbolS *symp, int *punt)
1200 1.1 christos {
1201 1.1 christos static symbolS *last_functionP;
1202 1.1 christos static symbolS *last_tagP;
1203 1.1 christos static stack *block_stack;
1204 1.1 christos static symbolS *set_end;
1205 1.1 christos symbolS *next_set_end = NULL;
1206 1.1 christos
1207 1.1 christos if (symp == &abs_symbol)
1208 1.1 christos {
1209 1.1 christos *punt = 1;
1210 1.1 christos return;
1211 1.1 christos }
1212 1.1 christos
1213 1.1 christos if (current_lineno_sym)
1214 1.1 christos coff_add_linesym (NULL);
1215 1.1 christos
1216 1.1 christos if (!block_stack)
1217 1.1 christos block_stack = stack_init (512, sizeof (symbolS*));
1218 1.1 christos
1219 1.1 christos #ifdef TE_PE
1220 1.1 christos if (S_GET_STORAGE_CLASS (symp) == C_NT_WEAK
1221 1.1 christos && ! S_IS_WEAK (symp)
1222 1.10 christos && weak_is_altname (S_GET_NAME (symp)))
1223 1.10 christos {
1224 1.10 christos /* This is a weak alternate symbol. All processing of
1225 1.1 christos PECOFFweak symbols is done here, through the alternate. */
1226 1.1 christos char *weakname = weak_altname2name (S_GET_NAME (symp));
1227 1.1 christos symbolS *weakp = symbol_find_noref (weakname, 1);
1228 1.1 christos free (weakname);
1229 1.1 christos gas_assert (weakp);
1230 1.1 christos gas_assert (S_GET_NUMBER_AUXILIARY (weakp) == 1);
1231 1.1 christos
1232 1.1 christos if (! S_IS_WEAK (weakp))
1233 1.1 christos {
1234 1.1 christos /* The symbol was turned from weak to strong. Discard altname. */
1235 1.1 christos *punt = 1;
1236 1.1 christos return;
1237 1.1 christos }
1238 1.1 christos else if (symbol_equated_p (weakp))
1239 1.1 christos {
1240 1.1 christos /* The weak symbol has an alternate specified; symp is unneeded. */
1241 1.1 christos S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1242 1.1 christos SA_SET_SYM_TAGNDX (weakp,
1243 1.1 christos symbol_get_value_expression (weakp)->X_add_symbol);
1244 1.1 christos
1245 1.1 christos S_CLEAR_EXTERNAL (symp);
1246 1.1 christos *punt = 1;
1247 1.1 christos return;
1248 1.1 christos }
1249 1.1 christos else
1250 1.1 christos {
1251 1.1 christos /* The weak symbol has been assigned an alternate value.
1252 1.1 christos Copy this value to symp, and set symp as weakp's alternate. */
1253 1.1 christos if (S_GET_STORAGE_CLASS (weakp) != C_NT_WEAK)
1254 1.1 christos {
1255 1.1 christos S_SET_STORAGE_CLASS (symp, S_GET_STORAGE_CLASS (weakp));
1256 1.1 christos S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
1257 1.1 christos }
1258 1.1 christos
1259 1.1 christos if (S_IS_DEFINED (weakp))
1260 1.1 christos {
1261 1.1 christos /* This is a defined weak symbol. Copy value information
1262 1.1 christos from the weak symbol itself to the alternate symbol. */
1263 1.1 christos symbol_set_value_expression (symp,
1264 1.1 christos symbol_get_value_expression (weakp));
1265 1.1 christos symbol_set_frag (symp, symbol_get_frag (weakp));
1266 1.1 christos S_SET_SEGMENT (symp, S_GET_SEGMENT (weakp));
1267 1.1 christos }
1268 1.1 christos else
1269 1.1 christos {
1270 1.1 christos /* This is an undefined weak symbol.
1271 1.1 christos Define the alternate symbol to zero. */
1272 1.1 christos S_SET_VALUE (symp, 0);
1273 1.1 christos S_SET_SEGMENT (symp, absolute_section);
1274 1.1 christos }
1275 1.1 christos
1276 1.1 christos S_SET_NAME (symp, weak_uniquify (S_GET_NAME (symp)));
1277 1.1 christos S_SET_STORAGE_CLASS (symp, C_EXT);
1278 1.1 christos
1279 1.1 christos S_SET_VALUE (weakp, 0);
1280 1.1 christos S_SET_SEGMENT (weakp, undefined_section);
1281 1.1 christos }
1282 1.1 christos }
1283 1.1 christos #else /* TE_PE */
1284 1.1 christos if (S_IS_WEAK (symp))
1285 1.1 christos S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
1286 1.1 christos #endif /* TE_PE */
1287 1.1 christos
1288 1.1 christos if (!S_IS_DEFINED (symp)
1289 1.1 christos && !S_IS_WEAK (symp)
1290 1.1 christos && S_GET_STORAGE_CLASS (symp) != C_STAT)
1291 1.1 christos S_SET_STORAGE_CLASS (symp, C_EXT);
1292 1.1 christos
1293 1.1 christos if (!SF_GET_DEBUG (symp))
1294 1.1 christos {
1295 1.1 christos symbolS * real;
1296 1.1 christos
1297 1.1 christos if (!SF_GET_LOCAL (symp)
1298 1.1 christos && !SF_GET_STATICS (symp)
1299 1.1 christos && S_GET_STORAGE_CLASS (symp) != C_LABEL
1300 1.1 christos && symbol_constant_p (symp)
1301 1.1 christos && (real = symbol_find_noref (S_GET_NAME (symp), 1))
1302 1.1 christos && S_GET_STORAGE_CLASS (real) == C_NULL
1303 1.1 christos && real != symp)
1304 1.1 christos {
1305 1.1 christos c_symbol_merge (symp, real);
1306 1.1 christos *punt = 1;
1307 1.1 christos return;
1308 1.1 christos }
1309 1.1 christos
1310 1.1 christos if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
1311 1.1 christos {
1312 1.1 christos gas_assert (S_GET_VALUE (symp) == 0);
1313 1.1 christos if (S_IS_WEAKREFD (symp))
1314 1.1 christos *punt = 1;
1315 1.1 christos else
1316 1.1 christos S_SET_EXTERNAL (symp);
1317 1.1 christos }
1318 1.1 christos else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
1319 1.1 christos {
1320 1.1 christos if (S_GET_SEGMENT (symp) == text_section
1321 1.1 christos && symp != seg_info (text_section)->sym)
1322 1.1 christos S_SET_STORAGE_CLASS (symp, C_LABEL);
1323 1.1 christos else
1324 1.1 christos S_SET_STORAGE_CLASS (symp, C_STAT);
1325 1.1 christos }
1326 1.1 christos
1327 1.1 christos if (SF_GET_PROCESS (symp))
1328 1.10 christos {
1329 1.1 christos if (S_GET_STORAGE_CLASS (symp) == C_BLOCK)
1330 1.1 christos {
1331 1.1 christos if (streq (S_GET_NAME (symp), ".bb"))
1332 1.1 christos stack_push (block_stack, &symp);
1333 1.1 christos else
1334 1.1 christos {
1335 1.1 christos symbolS *begin;
1336 1.1 christos
1337 1.1 christos begin = *(symbolS **) stack_pop (block_stack);
1338 1.1 christos if (begin == 0)
1339 1.1 christos as_warn (_("mismatched .eb"));
1340 1.1 christos else
1341 1.10 christos next_set_end = begin;
1342 1.1 christos }
1343 1.1 christos }
1344 1.1 christos
1345 1.1 christos if (SF_GET_FUNCTION (symp) && S_IS_DEFINED (symp))
1346 1.1 christos {
1347 1.1 christos union internal_auxent *auxp;
1348 1.10 christos
1349 1.10 christos if (S_GET_NUMBER_AUXILIARY (symp) < 1)
1350 1.1 christos S_SET_NUMBER_AUXILIARY (symp, 1);
1351 1.1 christos auxp = SYM_AUXENT (symp);
1352 1.3 christos memset (&auxp->x_sym.x_fcnary.x_fcn, 0,
1353 1.3 christos sizeof (auxp->x_sym.x_fcnary.x_fcn));
1354 1.1 christos }
1355 1.10 christos
1356 1.1 christos if (S_GET_STORAGE_CLASS (symp) == C_EFCN
1357 1.1 christos && S_IS_DEFINED (symp))
1358 1.10 christos {
1359 1.10 christos if (!last_functionP)
1360 1.10 christos as_fatal (_("C_EFCN symbol for %s out of scope"),
1361 1.1 christos S_GET_NAME (symp));
1362 1.1 christos SA_SET_SYM_FSIZE (last_functionP,
1363 1.1 christos (S_GET_VALUE (symp)
1364 1.1 christos - S_GET_VALUE (last_functionP)));
1365 1.1 christos }
1366 1.1 christos }
1367 1.1 christos
1368 1.1 christos if (S_IS_EXTERNAL (symp))
1369 1.1 christos S_SET_STORAGE_CLASS (symp, C_EXT);
1370 1.1 christos else if (SF_GET_LOCAL (symp))
1371 1.1 christos *punt = 1;
1372 1.1 christos
1373 1.1 christos if (SF_GET_FUNCTION (symp))
1374 1.1 christos symbol_get_bfdsym (symp)->flags |= BSF_FUNCTION;
1375 1.1 christos }
1376 1.1 christos
1377 1.1 christos /* Double check weak symbols. */
1378 1.1 christos if (S_IS_WEAK (symp) && S_IS_COMMON (symp))
1379 1.1 christos as_bad (_("Symbol `%s' can not be both weak and common"),
1380 1.1 christos S_GET_NAME (symp));
1381 1.1 christos
1382 1.1 christos if (SF_GET_TAG (symp))
1383 1.1 christos last_tagP = symp;
1384 1.1 christos else if (S_GET_STORAGE_CLASS (symp) == C_EOS)
1385 1.1 christos next_set_end = last_tagP;
1386 1.1 christos
1387 1.8 christos #ifdef OBJ_XCOFF
1388 1.1 christos /* This is pretty horrible, but we have to set *punt correctly in
1389 1.1 christos order to call SA_SET_SYM_ENDNDX correctly. */
1390 1.1 christos if (! symbol_used_in_reloc_p (symp)
1391 1.1 christos && S_GET_STORAGE_CLASS (symp) != C_DWARF
1392 1.1 christos && ((symbol_get_bfdsym (symp)->flags & BSF_SECTION_SYM) != 0
1393 1.1 christos || (! (S_IS_EXTERNAL (symp) || S_IS_WEAK (symp))
1394 1.1 christos && ! symbol_get_tc (symp)->output
1395 1.10 christos && S_GET_STORAGE_CLASS (symp) != C_FILE)))
1396 1.1 christos *punt = 1;
1397 1.1 christos #endif
1398 1.1 christos
1399 1.1 christos if (set_end != NULL
1400 1.1 christos && ! *punt
1401 1.1 christos && ((symbol_get_bfdsym (symp)->flags & BSF_NOT_AT_END) != 0
1402 1.1 christos || (S_IS_DEFINED (symp)
1403 1.1 christos && ! S_IS_COMMON (symp)
1404 1.1 christos && (! S_IS_EXTERNAL (symp) || SF_GET_FUNCTION (symp)))))
1405 1.1 christos {
1406 1.1 christos SA_SET_SYM_ENDNDX (set_end, symp);
1407 1.1 christos set_end = NULL;
1408 1.1 christos }
1409 1.1 christos
1410 1.1 christos if (next_set_end != NULL)
1411 1.1 christos {
1412 1.1 christos if (set_end != NULL)
1413 1.1 christos as_warn (_("Warning: internal error: forgetting to set endndx of %s"),
1414 1.10 christos S_GET_NAME (set_end));
1415 1.10 christos set_end = next_set_end;
1416 1.10 christos }
1417 1.10 christos
1418 1.10 christos if (SF_GET_FUNCTION (symp) && S_IS_DEFINED (symp) && !*punt)
1419 1.10 christos {
1420 1.10 christos if (last_functionP)
1421 1.1 christos SA_SET_SYM_ENDNDX (last_functionP, symp);
1422 1.1 christos last_functionP = symp;
1423 1.1 christos }
1424 1.1 christos
1425 1.1 christos #ifndef OBJ_XCOFF
1426 1.1 christos if (! *punt
1427 1.1 christos && S_GET_STORAGE_CLASS (symp) == C_FCN
1428 1.1 christos && streq (S_GET_NAME (symp), ".bf"))
1429 1.1 christos {
1430 1.1 christos if (coff_last_bf != NULL)
1431 1.1 christos SA_SET_SYM_ENDNDX (coff_last_bf, symp);
1432 1.1 christos coff_last_bf = symp;
1433 1.1 christos }
1434 1.1 christos #endif
1435 1.1 christos if (coffsymbol (symbol_get_bfdsym (symp))->lineno)
1436 1.1 christos {
1437 1.1 christos int i;
1438 1.1 christos struct line_no *lptr;
1439 1.1 christos alent *l;
1440 1.1 christos
1441 1.1 christos lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1442 1.1 christos for (i = 0; lptr; lptr = lptr->next)
1443 1.1 christos i++;
1444 1.1 christos lptr = (struct line_no *) coffsymbol (symbol_get_bfdsym (symp))->lineno;
1445 1.5 christos
1446 1.1 christos /* We need i entries for line numbers, plus 1 for the first
1447 1.1 christos entry which BFD will override, plus 1 for the last zero
1448 1.1 christos entry (a marker for BFD). */
1449 1.1 christos l = XNEWVEC (alent, (i + 2));
1450 1.1 christos coffsymbol (symbol_get_bfdsym (symp))->lineno = l;
1451 1.1 christos l[i + 1].line_number = 0;
1452 1.1 christos l[i + 1].u.sym = NULL;
1453 1.1 christos for (; i > 0; i--)
1454 1.1 christos {
1455 1.1 christos if (lptr->frag)
1456 1.1 christos lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE;
1457 1.1 christos l[i] = lptr->l;
1458 1.1 christos lptr = lptr->next;
1459 1.1 christos }
1460 1.1 christos }
1461 1.1 christos }
1462 1.1 christos
1463 1.1 christos void
1464 1.1 christos coff_adjust_section_syms (bfd *abfd ATTRIBUTE_UNUSED,
1465 1.1 christos asection *sec,
1466 1.1 christos void * x ATTRIBUTE_UNUSED)
1467 1.1 christos {
1468 1.1 christos symbolS *secsym;
1469 1.1 christos segment_info_type *seginfo = seg_info (sec);
1470 1.1 christos int nlnno, nrelocs = 0;
1471 1.1 christos
1472 1.1 christos /* RS/6000 gas creates a .debug section manually in ppc_frob_file in
1473 1.1 christos tc-ppc.c. Do not get confused by it. */
1474 1.1 christos if (seginfo == NULL)
1475 1.1 christos return;
1476 1.1 christos
1477 1.1 christos if (streq (sec->name, ".text"))
1478 1.1 christos nlnno = coff_n_line_nos;
1479 1.1 christos else
1480 1.1 christos nlnno = 0;
1481 1.1 christos {
1482 1.1 christos /* @@ Hope that none of the fixups expand to more than one reloc
1483 1.1 christos entry... */
1484 1.1 christos fixS *fixp = seginfo->fix_root;
1485 1.1 christos while (fixp)
1486 1.1 christos {
1487 1.1 christos if (! fixp->fx_done)
1488 1.7 christos nrelocs++;
1489 1.1 christos fixp = fixp->fx_next;
1490 1.1 christos }
1491 1.1 christos }
1492 1.1 christos if (bfd_section_size (sec) == 0
1493 1.1 christos && nrelocs == 0
1494 1.1 christos && nlnno == 0
1495 1.1 christos && sec != text_section
1496 1.1 christos && sec != data_section
1497 1.1 christos && sec != bss_section)
1498 1.1 christos return;
1499 1.8 christos
1500 1.8 christos secsym = section_symbol (sec);
1501 1.8 christos /* This is an estimate; we'll plug in the real value using
1502 1.8 christos SET_SECTION_RELOCS later */
1503 1.8 christos #ifdef OBJ_XCOFF
1504 1.8 christos if (S_GET_STORAGE_CLASS (secsym) == C_DWARF)
1505 1.8 christos SA_SET_SECT_NRELOC (secsym, nrelocs);
1506 1.8 christos else
1507 1.8 christos {
1508 1.1 christos SA_SET_SCN_NRELOC (secsym, nrelocs);
1509 1.1 christos SA_SET_SCN_NLINNO (secsym, nlnno);
1510 1.8 christos }
1511 1.1 christos #else
1512 1.1 christos SA_SET_SCN_NRELOC (secsym, nrelocs);
1513 1.1 christos SA_SET_SCN_NLINNO (secsym, nlnno);
1514 1.1 christos #endif
1515 1.1 christos }
1516 1.1 christos
1517 1.1 christos void
1518 1.1 christos coff_frob_file_after_relocs (void)
1519 1.1 christos {
1520 1.1 christos bfd_map_over_sections (stdoutput, coff_adjust_section_syms, NULL);
1521 1.1 christos }
1522 1.1 christos
1523 1.1 christos /* Implement the .section pseudo op:
1524 1.1 christos .section name {, "flags"}
1525 1.1 christos ^ ^
1526 1.1 christos | +--- optional flags: 'b' for bss
1527 1.1 christos | 'i' for info
1528 1.1 christos +-- section name 'l' for lib
1529 1.1 christos 'n' for noload
1530 1.1 christos 'o' for over
1531 1.1 christos 'w' for data
1532 1.1 christos 'd' (apparently m88k for data)
1533 1.1 christos 'e' for exclude
1534 1.1 christos 'x' for text
1535 1.1 christos 'r' for read-only data
1536 1.1 christos 's' for shared data (PE)
1537 1.1 christos 'y' for noread
1538 1.1 christos '0' - '9' for power-of-two alignment (GNU extension).
1539 1.1 christos But if the argument is not a quoted string, treat it as a
1540 1.1 christos subsegment number.
1541 1.1 christos
1542 1.1 christos Note the 'a' flag is silently ignored. This allows the same
1543 1.1 christos .section directive to be parsed in both ELF and COFF formats. */
1544 1.1 christos
1545 1.1 christos void
1546 1.1 christos obj_coff_section (int ignore ATTRIBUTE_UNUSED)
1547 1.1 christos {
1548 1.1 christos /* Strip out the section name. */
1549 1.1 christos char *section_name;
1550 1.1 christos char c;
1551 1.1 christos int alignment = -1;
1552 1.8 christos char *name;
1553 1.1 christos unsigned int exp;
1554 1.1 christos flagword flags, oldflags;
1555 1.1 christos asection *sec;
1556 1.1 christos bool is_bss = false;
1557 1.1 christos
1558 1.1 christos if (flag_mri)
1559 1.1 christos {
1560 1.1 christos char type;
1561 1.1 christos
1562 1.3 christos s_mri_sect (&type);
1563 1.10 christos return;
1564 1.10 christos }
1565 1.10 christos
1566 1.1 christos c = get_symbol_name (§ion_name);
1567 1.1 christos name = notes_memdup0 (section_name, input_line_pointer - section_name);
1568 1.1 christos restore_line_pointer (c);
1569 1.1 christos SKIP_WHITESPACE ();
1570 1.1 christos
1571 1.1 christos exp = 0;
1572 1.1 christos flags = SEC_NO_FLAGS;
1573 1.1 christos
1574 1.1 christos if (*input_line_pointer == ',')
1575 1.1 christos {
1576 1.1 christos ++input_line_pointer;
1577 1.1 christos SKIP_WHITESPACE ();
1578 1.10 christos if (*input_line_pointer != '"')
1579 1.1 christos exp = get_absolute_expression ();
1580 1.1 christos else
1581 1.1 christos {
1582 1.1 christos char attr;
1583 1.1 christos int readonly_removed = 0;
1584 1.10 christos int load_removed = 0;
1585 1.1 christos
1586 1.1 christos while (attr = *++input_line_pointer,
1587 1.1 christos attr != '"'
1588 1.1 christos && ! is_end_of_stmt (attr))
1589 1.1 christos {
1590 1.1 christos if (ISDIGIT (attr))
1591 1.1 christos {
1592 1.1 christos alignment = attr - '0';
1593 1.1 christos continue;
1594 1.1 christos }
1595 1.1 christos switch (attr)
1596 1.1 christos {
1597 1.1 christos case 'e':
1598 1.1 christos /* Exclude section from linking. */
1599 1.1 christos flags |= SEC_EXCLUDE;
1600 1.1 christos break;
1601 1.1 christos
1602 1.8 christos case 'b':
1603 1.1 christos /* Uninitialised data section. */
1604 1.1 christos flags |= SEC_ALLOC;
1605 1.1 christos flags &=~ SEC_LOAD;
1606 1.1 christos is_bss = true;
1607 1.1 christos break;
1608 1.1 christos
1609 1.1 christos case 'n':
1610 1.1 christos /* Section not loaded. */
1611 1.1 christos flags &=~ SEC_LOAD;
1612 1.1 christos flags |= SEC_NEVER_LOAD;
1613 1.1 christos load_removed = 1;
1614 1.1 christos break;
1615 1.1 christos
1616 1.1 christos case 's':
1617 1.1 christos /* Shared section. */
1618 1.1 christos flags |= SEC_COFF_SHARED;
1619 1.1 christos /* Fall through. */
1620 1.1 christos case 'd':
1621 1.1 christos /* Data section. */
1622 1.1 christos flags |= SEC_DATA;
1623 1.1 christos if (! load_removed)
1624 1.1 christos flags |= SEC_LOAD;
1625 1.1 christos flags &=~ SEC_READONLY;
1626 1.1 christos break;
1627 1.1 christos
1628 1.1 christos case 'w':
1629 1.1 christos /* Writable section. */
1630 1.1 christos flags &=~ SEC_READONLY;
1631 1.1 christos readonly_removed = 1;
1632 1.1 christos break;
1633 1.1 christos
1634 1.1 christos case 'a':
1635 1.1 christos /* Ignore. Here for compatibility with ELF. */
1636 1.1 christos break;
1637 1.1 christos
1638 1.1 christos case 'r': /* Read-only section. Implies a data section. */
1639 1.1 christos readonly_removed = 0;
1640 1.1 christos /* Fall through. */
1641 1.1 christos case 'x': /* Executable section. */
1642 1.1 christos /* If we are setting the 'x' attribute or if the 'r'
1643 1.1 christos attribute is being used to restore the readonly status
1644 1.1 christos of a code section (eg "wxr") then set the SEC_CODE flag,
1645 1.1 christos otherwise set the SEC_DATA flag. */
1646 1.1 christos flags |= (attr == 'x' || (flags & SEC_CODE) ? SEC_CODE : SEC_DATA);
1647 1.1 christos if (! load_removed)
1648 1.1 christos flags |= SEC_LOAD;
1649 1.1 christos /* Note - the READONLY flag is set here, even for the 'x'
1650 1.1 christos attribute in order to be compatible with the MSVC
1651 1.1 christos linker. */
1652 1.1 christos if (! readonly_removed)
1653 1.1 christos flags |= SEC_READONLY;
1654 1.1 christos break;
1655 1.1 christos
1656 1.1 christos case 'y':
1657 1.1 christos flags |= SEC_COFF_NOREAD | SEC_READONLY;
1658 1.1 christos break;
1659 1.1 christos
1660 1.1 christos case 'i': /* STYP_INFO */
1661 1.1 christos case 'l': /* STYP_LIB */
1662 1.1 christos case 'o': /* STYP_OVER */
1663 1.1 christos as_warn (_("unsupported section attribute '%c'"), attr);
1664 1.1 christos break;
1665 1.1 christos
1666 1.1 christos default:
1667 1.1 christos as_warn (_("unknown section attribute '%c'"), attr);
1668 1.1 christos break;
1669 1.1 christos }
1670 1.1 christos }
1671 1.1 christos if (attr == '"')
1672 1.10 christos ++input_line_pointer;
1673 1.3 christos }
1674 1.8 christos }
1675 1.8 christos
1676 1.8 christos sec = subseg_new (name, exp);
1677 1.1 christos
1678 1.1 christos if (is_bss)
1679 1.1 christos seg_info (sec)->bss = 1;
1680 1.7 christos
1681 1.1 christos if (alignment >= 0)
1682 1.1 christos sec->alignment_power = alignment;
1683 1.1 christos
1684 1.1 christos oldflags = bfd_section_flags (sec);
1685 1.1 christos if (oldflags == SEC_NO_FLAGS)
1686 1.1 christos {
1687 1.1 christos /* Set section flags for a new section just created by subseg_new.
1688 1.1 christos Provide a default if no flags were parsed. */
1689 1.1 christos if (flags == SEC_NO_FLAGS)
1690 1.1 christos flags = TC_COFF_SECTION_DEFAULT_ATTRIBUTES;
1691 1.1 christos
1692 1.8 christos #ifdef COFF_LONG_SECTION_NAMES
1693 1.1 christos /* Add SEC_LINK_ONCE and SEC_LINK_DUPLICATES_DISCARD to .gnu.linkonce
1694 1.1 christos sections so adjust_reloc_syms in write.c will correctly handle
1695 1.1 christos relocs which refer to non-local symbols in these sections. */
1696 1.7 christos if (startswith (name, ".gnu.linkonce"))
1697 1.1 christos flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
1698 1.7 christos #endif
1699 1.1 christos
1700 1.1 christos if (!bfd_set_section_flags (sec, flags))
1701 1.1 christos as_warn (_("error setting flags for \"%s\": %s"),
1702 1.1 christos bfd_section_name (sec),
1703 1.1 christos bfd_errmsg (bfd_get_error ()));
1704 1.1 christos }
1705 1.1 christos else if (flags != SEC_NO_FLAGS)
1706 1.1 christos {
1707 1.1 christos /* This section's attributes have already been set. Warn if the
1708 1.1 christos attributes don't match. */
1709 1.1 christos flagword matchflags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
1710 1.1 christos | SEC_DATA | SEC_COFF_SHARED | SEC_NEVER_LOAD
1711 1.1 christos | SEC_COFF_NOREAD);
1712 1.1 christos if ((flags ^ oldflags) & matchflags)
1713 1.1 christos as_warn (_("Ignoring changed section attributes for %s"), name);
1714 1.1 christos }
1715 1.1 christos
1716 1.1 christos demand_empty_rest_of_line ();
1717 1.1 christos }
1718 1.1 christos
1719 1.1 christos void
1720 1.8 christos coff_adjust_symtab (void)
1721 1.1 christos {
1722 1.1 christos if (symbol_rootP == NULL
1723 1.1 christos || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
1724 1.1 christos c_dot_file_symbol ("fake");
1725 1.1 christos }
1726 1.1 christos
1727 1.1 christos void
1728 1.1 christos coff_frob_section (segT sec)
1729 1.1 christos {
1730 1.1 christos segT strsec;
1731 1.1 christos char *p;
1732 1.1 christos fragS *fragp;
1733 1.1 christos bfd_vma n_entries;
1734 1.1 christos
1735 1.1 christos /* The COFF back end in BFD requires that all section sizes be
1736 1.7 christos rounded up to multiples of the corresponding section alignments,
1737 1.1 christos supposedly because standard COFF has no other way of encoding alignment
1738 1.1 christos for sections. If your COFF flavor has a different way of encoding
1739 1.1 christos section alignment, then skip this step, as TICOFF does. */
1740 1.1 christos bfd_vma size = bfd_section_size (sec);
1741 1.9 christos #if !defined(TICOFF)
1742 1.9 christos bfd_vma align_power = (bfd_vma) sec->alignment_power + OCTETS_PER_BYTE_POWER;
1743 1.1 christos bfd_vma mask = ((bfd_vma) 1 << align_power) - 1;
1744 1.1 christos
1745 1.1 christos if (!do_not_pad_sections_to_alignment
1746 1.1 christos && (size & mask) != 0)
1747 1.1 christos {
1748 1.7 christos bfd_vma new_size;
1749 1.1 christos fragS *last;
1750 1.1 christos
1751 1.1 christos new_size = (size + mask) & ~mask;
1752 1.1 christos bfd_set_section_size (sec, new_size);
1753 1.1 christos
1754 1.1 christos /* If the size had to be rounded up, add some padding in
1755 1.1 christos the last non-empty frag. */
1756 1.1 christos fragp = seg_info (sec)->frchainP->frch_root;
1757 1.9 christos last = seg_info (sec)->frchainP->frch_last;
1758 1.9 christos while (fragp->fr_next != last)
1759 1.9 christos fragp = fragp->fr_next;
1760 1.9 christos last->fr_address = size;
1761 1.1 christos if ((new_size - size) % fragp->fr_var == 0)
1762 1.1 christos fragp->fr_offset += (new_size - size) / fragp->fr_var;
1763 1.1 christos else
1764 1.1 christos abort ();
1765 1.1 christos }
1766 1.1 christos #endif
1767 1.1 christos
1768 1.1 christos /* If the section size is non-zero, the section symbol needs an aux
1769 1.1 christos entry associated with it, indicating the size. We don't know
1770 1.1 christos all the values yet; coff_frob_symbol will fill them in later. */
1771 1.1 christos #ifndef TICOFF
1772 1.1 christos if (size != 0
1773 1.1 christos || sec == text_section
1774 1.1 christos || sec == data_section
1775 1.1 christos || sec == bss_section)
1776 1.1 christos #endif
1777 1.1 christos {
1778 1.7 christos symbolS *secsym = section_symbol (sec);
1779 1.1 christos unsigned char sclass = C_STAT;
1780 1.1 christos
1781 1.1 christos #ifdef OBJ_XCOFF
1782 1.1 christos if (bfd_section_flags (sec) & SEC_DEBUGGING)
1783 1.1 christos sclass = C_DWARF;
1784 1.8 christos #endif
1785 1.8 christos S_SET_STORAGE_CLASS (secsym, sclass);
1786 1.8 christos S_SET_NUMBER_AUXILIARY (secsym, 1);
1787 1.1 christos SF_SET_STATICS (secsym);
1788 1.8 christos #ifdef OBJ_XCOFF
1789 1.1 christos SA_SET_SECT_SCNLEN (secsym, size);
1790 1.1 christos #else
1791 1.1 christos SA_SET_SCN_SCNLEN (secsym, size);
1792 1.1 christos #endif
1793 1.1 christos }
1794 1.1 christos /* FIXME: These should be in a "stabs.h" file, or maybe as.h. */
1795 1.1 christos #ifndef STAB_SECTION_NAME
1796 1.1 christos #define STAB_SECTION_NAME ".stab"
1797 1.1 christos #endif
1798 1.1 christos #ifndef STAB_STRING_SECTION_NAME
1799 1.1 christos #define STAB_STRING_SECTION_NAME ".stabstr"
1800 1.1 christos #endif
1801 1.1 christos if (! streq (STAB_STRING_SECTION_NAME, sec->name))
1802 1.1 christos return;
1803 1.7 christos
1804 1.1 christos strsec = sec;
1805 1.7 christos sec = subseg_get (STAB_SECTION_NAME, 0);
1806 1.1 christos /* size is already rounded up, since other section will be listed first */
1807 1.1 christos size = bfd_section_size (strsec);
1808 1.1 christos
1809 1.1 christos n_entries = bfd_section_size (sec) / 12 - 1;
1810 1.1 christos
1811 1.1 christos /* Find first non-empty frag. It should be large enough. */
1812 1.1 christos fragp = seg_info (sec)->frchainP->frch_root;
1813 1.1 christos while (fragp && fragp->fr_fix == 0)
1814 1.1 christos fragp = fragp->fr_next;
1815 1.10 christos gas_assert (fragp != 0 && fragp->fr_fix >= 12);
1816 1.10 christos
1817 1.1 christos /* Store the values. */
1818 1.1 christos p = fragp->fr_literal;
1819 1.1 christos bfd_h_put_16 (stdoutput, n_entries, p + 6);
1820 1.9 christos bfd_h_put_32 (stdoutput, size, p + 8);
1821 1.1 christos }
1822 1.5 christos
1823 1.1 christos void
1824 1.1 christos obj_coff_init_stab_section (segT stab ATTRIBUTE_UNUSED, segT stabstr)
1825 1.1 christos {
1826 1.1 christos const char *file;
1827 1.1 christos char *p;
1828 1.1 christos unsigned int stroff;
1829 1.1 christos
1830 1.10 christos /* Make space for this first symbol. */
1831 1.9 christos p = frag_more (12);
1832 1.1 christos /* Zero it out. */
1833 1.1 christos memset (p, 0, 12);
1834 1.1 christos file = as_where (NULL);
1835 1.1 christos stroff = get_stab_string_offset (file, stabstr);
1836 1.1 christos know (stroff == 1);
1837 1.1 christos md_number_to_chars (p, stroff, 4);
1838 1.1 christos }
1839 1.1 christos
1840 1.1 christos #ifdef DEBUG
1841 1.1 christos const char * s_get_name (symbolS *);
1842 1.10 christos
1843 1.1 christos const char *
1844 1.1 christos s_get_name (symbolS *s)
1845 1.1 christos {
1846 1.1 christos return s == NULL ? "(NULL)" : S_GET_NAME (s);
1847 1.1 christos }
1848 1.1 christos
1849 1.1 christos void symbol_dump (void);
1850 1.1 christos
1851 1.1 christos void
1852 1.1 christos symbol_dump (void)
1853 1.1 christos {
1854 1.1 christos symbolS *symbolP;
1855 1.1 christos
1856 1.1 christos for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
1857 1.1 christos printf (_("0x%lx: \"%s\" type = %ld, class = %d, segment = %d\n"),
1858 1.1 christos (unsigned long) symbolP,
1859 1.1 christos S_GET_NAME (symbolP),
1860 1.1 christos (long) S_GET_DATA_TYPE (symbolP),
1861 1.1 christos S_GET_STORAGE_CLASS (symbolP),
1862 1.1 christos (int) S_GET_SEGMENT (symbolP));
1863 1.10 christos }
1864 1.1 christos
1865 1.1 christos #endif /* DEBUG */
1866 1.1 christos
1867 1.1 christos static const pseudo_typeS coff_pseudo_table[] =
1868 1.1 christos {
1869 1.1 christos {"ABORT", s_abort, 0},
1870 1.1 christos /* We accept the .bss directive for backward compatibility with
1871 1.1 christos earlier versions of gas. */
1872 1.1 christos {"bss", obj_coff_bss, 0},
1873 1.1 christos #ifdef TE_PE
1874 1.1 christos /* PE provides an enhanced version of .comm with alignment. */
1875 1.1 christos {"comm", obj_coff_comm, 0},
1876 1.1 christos #endif /* TE_PE */
1877 1.1 christos {"def", obj_coff_def, 0},
1878 1.1 christos {"dim", obj_coff_dim, 0},
1879 1.1 christos {"endef", obj_coff_endef, 0},
1880 1.1 christos {"ident", obj_coff_ident, 0},
1881 1.1 christos {"line", obj_coff_line, 0},
1882 1.1 christos {"ln", obj_coff_ln, 0},
1883 1.1 christos {"scl", obj_coff_scl, 0},
1884 1.1 christos {"sect", obj_coff_section, 0},
1885 1.1 christos {"sect.s", obj_coff_section, 0},
1886 1.1 christos {"section", obj_coff_section, 0},
1887 1.1 christos {"section.s", obj_coff_section, 0},
1888 1.1 christos /* FIXME: We ignore the MRI short attribute. */
1889 1.1 christos {"size", obj_coff_size, 0},
1890 1.1 christos {"tag", obj_coff_tag, 0},
1891 1.1 christos {"type", obj_coff_type, 0},
1892 1.1 christos {"val", obj_coff_val, 0},
1893 1.10 christos {"version", s_ignore, 0},
1894 1.10 christos {"loc", obj_coff_loc, 0},
1895 1.1 christos {"optim", s_ignore, 0}, /* For sun386i cc (?) */
1896 1.1 christos {"weak", obj_coff_weak, 0},
1897 1.1 christos #if defined (TC_TIC4X) || defined (TC_TIC54X)
1898 1.1 christos /* The tic4x and tic54x use sdef instead of def. */
1899 1.1 christos {"sdef", obj_coff_def, 0},
1900 1.1 christos #endif
1901 1.1 christos #if defined(SEH_CMDS)
1902 1.1 christos SEH_CMDS
1903 1.1 christos #endif
1904 1.10 christos {NULL, NULL, 0}
1905 1.1 christos };
1906 1.1 christos
1907 1.1 christos
1909 1.1 christos void
1910 1.10 christos coff_pop_insert (void)
1911 1.10 christos {
1912 1.1 christos pop_insert (coff_pseudo_table);
1913 1.1 christos }
1914 1.1 christos
1915 1.1 christos #ifdef USE_EMULATIONS /* Support for a COFF emulation. */
1916 1.1 christos
1917 1.1 christos static int
1918 1.1 christos coff_separate_stab_sections (void)
1919 1.1 christos {
1920 1.1 christos return 1;
1921 1.1 christos }
1922 1.1 christos
1923 1.1 christos const struct format_ops coff_format_ops =
1924 1.9 christos {
1925 1.1 christos bfd_target_coff_flavour,
1926 1.10 christos 0, /* dfl_leading_underscore */
1927 1.1 christos 1, /* emit_section_symbols */
1928 1.1 christos 0, /* begin */
1929 1.1 christos 0, /* end. */
1930 1.1 christos c_dot_file_symbol,
1931 1.1 christos coff_assign_symbol,
1932 1.1 christos coff_frob_symbol,
1933 1.1 christos 0, /* frob_file */
1934 1.1 christos 0, /* frob_file_before_adjust */
1935 1.1 christos 0, /* frob_file_before_fix */
1936 1.1 christos coff_frob_file_after_relocs,
1937 1.1 christos 0, /* s_get_size */
1938 1.1 christos 0, /* s_set_size */
1939 1.1 christos 0, /* s_get_align */
1940 1.1 christos 0, /* s_set_align */
1941 1.1 christos 0, /* s_get_other */
1942 1.1 christos 0, /* s_set_other */
1943 1.1 christos 0, /* s_get_desc */
1944 1.1 christos 0, /* s_set_desc */
1945 1.1 christos 0, /* s_get_type */
1946 1.1 christos 0, /* s_set_type */
1947 1.1 christos 0, /* copy_symbol_attributes */
1948 1.1 christos 0, /* process_stab */
1949 1.1 christos coff_separate_stab_sections,
1950 1.1 christos obj_coff_init_stab_section,
1951 1.1 christos 0, /* sec_sym_ok_for_reloc */
1952 1.1 christos coff_pop_insert,
1953 1.1 christos 0, /* ecoff_set_ext */
1954 1.10 christos coff_obj_read_begin_hook,
1955 1.10 christos coff_obj_symbol_new_hook,
1956 coff_obj_symbol_clone_hook,
1957 coff_adjust_symtab
1958 };
1959
1960 #endif /* USE_EMULATIONS */
1961