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