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