* config/tc-hppa.c (md_apply_fix): Delete old wrapper function.
[deliverable/binutils-gdb.git] / gas / config / obj-elf.c
CommitLineData
49864cfa
KR
1/* ELF object file format
2 Copyright (C) 1992, 1993 Free Software Foundation, Inc.
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2,
9 or (at your option) any later version.
10
11 GAS is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14 the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public
17 License along with GAS; see the file COPYING. If not, write
18 to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
49864cfa 20#include "as.h"
6e378515 21#include "subsegs.h"
49864cfa
KR
22#include "obstack.h"
23
c5953036
ILT
24#ifdef ECOFF_DEBUGGING
25#include "ecoff.h"
26#endif
27
604633ae
ILT
28static int obj_elf_write_symbol_p PARAMS ((symbolS *sym));
29
c5953036
ILT
30#ifdef ECOFF_DEBUGGING
31static boolean elf_get_extr PARAMS ((asymbol *, EXTR *));
32static void elf_set_index PARAMS ((asymbol *, bfd_size_type));
33#endif
34
604633ae 35static void obj_elf_line PARAMS ((int));
604633ae
ILT
36void obj_elf_version PARAMS ((int));
37static void obj_elf_size PARAMS ((int));
38static void obj_elf_type PARAMS ((int));
39static void obj_elf_ident PARAMS ((int));
40static void obj_elf_weak PARAMS ((int));
41static void obj_elf_local PARAMS ((int));
42static void obj_elf_common PARAMS ((int));
13998021
ILT
43static void obj_elf_data PARAMS ((int));
44static void obj_elf_text PARAMS ((int));
49864cfa 45
6e378515
KR
46const pseudo_typeS obj_pseudo_table[] =
47{
d7852a33 48 {"comm", obj_elf_common, 0},
6e378515 49 {"ident", obj_elf_ident, 0},
d7852a33 50 {"local", obj_elf_local, 0},
7c05f0ec 51 {"previous", obj_elf_previous, 0},
6e378515
KR
52 {"section", obj_elf_section, 0},
53 {"size", obj_elf_size, 0},
54 {"type", obj_elf_type, 0},
55 {"version", obj_elf_version, 0},
b81b8a7d 56 {"weak", obj_elf_weak, 0},
6e378515
KR
57
58/* These are used for stabs-in-elf configurations. */
6e378515 59 {"line", obj_elf_line, 0},
6e378515 60
7c05f0ec
KR
61 /* These are used for dwarf. */
62 {"2byte", cons, 2},
63 {"4byte", cons, 4},
b81b8a7d 64 {"8byte", cons, 8},
7c05f0ec 65
13998021
ILT
66 /* We need to trap the section changing calls to handle .previous. */
67 {"data", obj_elf_data, 0},
68 {"text", obj_elf_text, 0},
69
c5953036
ILT
70#ifdef ECOFF_DEBUGGING
71 /* COFF style debugging information for ECOFF. .ln is not used; .loc
72 is used instead. */
73 { "def", ecoff_directive_def, 0 },
74 { "dim", ecoff_directive_dim, 0 },
75 { "endef", ecoff_directive_endef, 0 },
76 { "file", ecoff_directive_file, 0 },
77 { "scl", ecoff_directive_scl, 0 },
78 { "tag", ecoff_directive_tag, 0 },
79 { "val", ecoff_directive_val, 0 },
80
81 /* COFF debugging requires pseudo-ops .size and .type, but ELF
82 already has meanings for those. We use .esize and .etype
83 instead. These are only generated by gcc anyhow. */
84 { "esize", ecoff_directive_size, 0 },
85 { "etype", ecoff_directive_type, 0 },
86
87 /* ECOFF specific debugging information. */
88 { "begin", ecoff_directive_begin, 0 },
89 { "bend", ecoff_directive_bend, 0 },
90 { "end", ecoff_directive_end, 0 },
91 { "ent", ecoff_directive_ent, 0 },
92 { "fmask", ecoff_directive_fmask, 0 },
93 { "frame", ecoff_directive_frame, 0 },
94 { "loc", ecoff_directive_loc, 0 },
95 { "mask", ecoff_directive_mask, 0 },
96
97 /* These are used on Irix. I don't know how to implement them. */
98 { "alias", s_ignore, 0 },
99 { "bgnb", s_ignore, 0 },
100 { "endb", s_ignore, 0 },
101 { "lab", s_ignore, 0 },
102 { "noalias", s_ignore, 0 },
103 { "verstamp", s_ignore, 0 },
104 { "vreg", s_ignore, 0 },
105#endif /* ECOFF_DEBUGGING */
106
6e378515 107 {NULL} /* end sentinel */
49864cfa
KR
108};
109
b81b8a7d 110#undef NO_RELOC
6e378515
KR
111#include "aout/aout64.h"
112
113void
114elf_file_symbol (s)
115 char *s;
116{
117 symbolS *sym;
118
119 sym = symbol_new (s, absolute_section, (valueT) 0, (struct frag *) 0);
120 sym->sy_frag = &zero_address_frag;
121 sym->bsym->flags |= BSF_FILE;
122
123 if (symbol_rootP != sym)
124 {
125 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
126 symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
127#ifdef DEBUG
128 verify_symbol_chain (symbol_rootP, symbol_lastP);
129#endif
130 }
131}
132
d7852a33 133static void
604633ae
ILT
134obj_elf_common (ignore)
135 int ignore;
d7852a33
KR
136{
137 char *name;
138 char c;
139 char *p;
140 int temp, size;
141 symbolS *symbolP;
fa20b8bf 142 int have_align;
d7852a33
KR
143
144 name = input_line_pointer;
145 c = get_symbol_end ();
146 /* just after name is now '\0' */
147 p = input_line_pointer;
148 *p = c;
149 SKIP_WHITESPACE ();
150 if (*input_line_pointer != ',')
151 {
152 as_bad ("Expected comma after symbol-name");
153 ignore_rest_of_line ();
154 return;
155 }
156 input_line_pointer++; /* skip ',' */
157 if ((temp = get_absolute_expression ()) < 0)
158 {
159 as_bad (".COMMon length (%d.) <0! Ignored.", temp);
160 ignore_rest_of_line ();
161 return;
162 }
163 size = temp;
164 *p = 0;
165 symbolP = symbol_find_or_make (name);
166 *p = c;
167 if (S_IS_DEFINED (symbolP))
168 {
169 as_bad ("Ignoring attempt to re-define symbol");
170 ignore_rest_of_line ();
171 return;
172 }
173 if (S_GET_VALUE (symbolP) != 0)
174 {
175 if (S_GET_VALUE (symbolP) != size)
176 {
177 as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
178 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
179 }
180 }
181 know (symbolP->sy_frag == &zero_address_frag);
182 if (*input_line_pointer != ',')
fa20b8bf
ILT
183 have_align = 0;
184 else
d7852a33 185 {
fa20b8bf
ILT
186 have_align = 1;
187 input_line_pointer++;
188 SKIP_WHITESPACE ();
d7852a33 189 }
fa20b8bf 190 if (! have_align || *input_line_pointer != '"')
d7852a33 191 {
fa20b8bf
ILT
192 if (! have_align)
193 temp = 0;
194 else
d7852a33 195 {
fa20b8bf
ILT
196 temp = get_absolute_expression ();
197 if (temp < 0)
198 {
199 temp = 0;
200 as_warn ("Common alignment negative; 0 assumed");
201 }
d7852a33
KR
202 }
203 if (symbolP->local)
204 {
205 segT old_sec;
206 int old_subsec;
604633ae 207 char *pfrag;
d7852a33
KR
208 int align;
209
58d4951d 210 /* allocate_bss: */
d7852a33
KR
211 old_sec = now_seg;
212 old_subsec = now_subseg;
213 align = temp;
214 record_alignment (bss_section, align);
215 subseg_set (bss_section, 0);
216 if (align)
217 frag_align (align, 0);
218 if (S_GET_SEGMENT (symbolP) == bss_section)
219 symbolP->sy_frag->fr_symbol = 0;
220 symbolP->sy_frag = frag_now;
604633ae
ILT
221 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
222 (char *) 0);
223 *pfrag = 0;
d7852a33
KR
224 S_SET_SEGMENT (symbolP, bss_section);
225 S_CLEAR_EXTERNAL (symbolP);
226 subseg_set (old_sec, old_subsec);
227 }
228 else
229 {
230 allocate_common:
604633ae 231 S_SET_VALUE (symbolP, (valueT) size);
d7852a33
KR
232 S_SET_EXTERNAL (symbolP);
233 /* should be common, but this is how gas does it for now */
234 S_SET_SEGMENT (symbolP, &bfd_und_section);
235 }
236 }
237 else
238 {
239 input_line_pointer++;
240 /* @@ Some use the dot, some don't. Can we get some consistency?? */
241 if (*input_line_pointer == '.')
242 input_line_pointer++;
243 /* @@ Some say data, some say bss. */
244 if (strncmp (input_line_pointer, "bss\"", 4)
245 && strncmp (input_line_pointer, "data\"", 5))
246 {
247 while (*--input_line_pointer != '"')
248 ;
249 input_line_pointer--;
250 goto bad_common_segment;
251 }
252 while (*input_line_pointer++ != '"')
253 ;
254 goto allocate_common;
255 }
256 demand_empty_rest_of_line ();
257 return;
258
259 {
260 bad_common_segment:
261 p = input_line_pointer;
262 while (*p && *p != '\n')
263 p++;
264 c = *p;
265 *p = '\0';
266 as_bad ("bad .common segment %s", input_line_pointer + 1);
267 *p = c;
268 input_line_pointer = p;
269 ignore_rest_of_line ();
270 return;
271 }
272}
273
274static void
604633ae
ILT
275obj_elf_local (ignore)
276 int ignore;
d7852a33
KR
277{
278 char *name;
279 int c;
280 symbolS *symbolP;
281
282 do
283 {
284 name = input_line_pointer;
285 c = get_symbol_end ();
286 symbolP = symbol_find_or_make (name);
287 *input_line_pointer = c;
288 SKIP_WHITESPACE ();
289 S_CLEAR_EXTERNAL (symbolP);
290 symbolP->local = 1;
291 if (c == ',')
292 {
293 input_line_pointer++;
294 SKIP_WHITESPACE ();
295 if (*input_line_pointer == '\n')
296 c = '\n';
297 }
298 }
299 while (c == ',');
300 demand_empty_rest_of_line ();
301}
302
b81b8a7d 303static void
604633ae
ILT
304obj_elf_weak (ignore)
305 int ignore;
b81b8a7d
KR
306{
307 char *name;
308 int c;
309 symbolS *symbolP;
310
311 do
312 {
313 name = input_line_pointer;
314 c = get_symbol_end ();
315 symbolP = symbol_find_or_make (name);
316 *input_line_pointer = c;
317 SKIP_WHITESPACE ();
318 S_SET_WEAK (symbolP);
319 symbolP->local = 1;
320 if (c == ',')
321 {
322 input_line_pointer++;
323 SKIP_WHITESPACE ();
324 if (*input_line_pointer == '\n')
325 c = '\n';
326 }
327 }
328 while (c == ',');
329 demand_empty_rest_of_line ();
330}
331
7c05f0ec
KR
332static segT previous_section;
333static int previous_subsection;
334
fa20b8bf
ILT
335/* Handle the .section pseudo-op. This code supports two different
336 syntaxes.
337
338 The first is found on Solaris, and looks like
339 .section ".sec1",#alloc,#execinstr,#write
340 Here the names after '#' are the SHF_* flags to turn on for the
341 section. I'm not sure how it determines the SHT_* type (BFD
342 doesn't really give us control over the type, anyhow).
343
344 The second format is found on UnixWare, and probably most SVR4
345 machines, and looks like
346 .section .sec1,"a",@progbits
347 The quoted string may contain any combination of a, w, x, and
348 represents the SHF_* flags to turn on for the section. The string
349 beginning with '@' can be progbits or nobits. There should be
350 other possibilities, but I don't know what they are. In any case,
351 BFD doesn't really let us set the section type. */
352
693b21e7 353void
49864cfa
KR
354obj_elf_section (xxx)
355 int xxx;
356{
357 char *string;
13998021 358 int new_sec;
fa20b8bf
ILT
359 segT sec;
360 flagword flags;
49864cfa 361
b81b8a7d 362 /* Get name of section. */
fa20b8bf 363 SKIP_WHITESPACE ();
7c05f0ec 364 if (*input_line_pointer == '"')
fa20b8bf
ILT
365 {
366 string = demand_copy_C_string (&xxx);
367 if (string == NULL)
368 {
369 ignore_rest_of_line ();
370 return;
371 }
372 }
7c05f0ec
KR
373 else
374 {
375 char *p = input_line_pointer;
376 char c;
377 while (0 == strchr ("\n\t,; ", *p))
378 p++;
fa20b8bf
ILT
379 if (p == input_line_pointer)
380 {
381 as_warn ("Missing section name");
382 ignore_rest_of_line ();
383 return;
384 }
7c05f0ec
KR
385 c = *p;
386 *p = 0;
604633ae 387 string = xmalloc ((unsigned long) (p - input_line_pointer + 1));
7c05f0ec
KR
388 strcpy (string, input_line_pointer);
389 *p = c;
390 input_line_pointer = p;
391 }
fa20b8bf
ILT
392
393 /* Switch to the section, creating it if necessary. */
394 previous_section = now_seg;
395 previous_subsection = now_subseg;
396
397 new_sec = bfd_get_section_by_name (stdoutput, string) == NULL;
398 sec = subseg_new (string, 0);
399
400 /* If this section already existed, we don't bother to change the
401 flag values. */
402 if (! new_sec)
403 {
404 while (! is_end_of_line[(unsigned char) *input_line_pointer])
405 ++input_line_pointer;
406 ++input_line_pointer;
407 return;
408 }
b81b8a7d 409
49864cfa
KR
410 SKIP_WHITESPACE ();
411 if (*input_line_pointer != ',')
49864cfa 412 {
fa20b8bf
ILT
413 /* No flags given. Guess at some useful defaults. */
414 if (strcmp (string, ".data") == 0
415 || strcmp (string, ".data1") == 0
416 || strcmp (string, ".sdata") == 0
417 || strcmp (string, ".rodata") == 0
418 || strcmp (string, ".rodata1") == 0)
419 flags = SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_RELOC | SEC_DATA;
420 else if (strcmp (string, ".text") == 0
421 || strcmp (string, ".init") == 0
422 || strcmp (string, ".fini") == 0)
423 flags = SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_RELOC | SEC_CODE;
424 else if (strcmp (string, ".bss") == 0
425 || strcmp (string, ".sbss") == 0)
426 flags = SEC_ALLOC;
427 else
428 flags = SEC_RELOC;
429 }
430 else
431 {
432 /* Skip the comma. */
433 ++input_line_pointer;
b81b8a7d 434
fa20b8bf 435 SKIP_WHITESPACE ();
b81b8a7d
KR
436 if (*input_line_pointer == '"')
437 {
fa20b8bf
ILT
438 /* Pick up a string with a combination of a, w, x. */
439 flags = SEC_READONLY | SEC_RELOC;
440 ++input_line_pointer;
441 while (*input_line_pointer != '"')
442 {
443 switch (*input_line_pointer)
444 {
445 case 'a':
446 flags |= SEC_ALLOC | SEC_LOAD;
447 break;
448 case 'w':
449 flags &=~ SEC_READONLY;
450 break;
451 case 'x':
452 flags |= SEC_CODE;
453 break;
454 default:
455 as_warn ("Bad .section directive: want a,w,x in string");
456 ignore_rest_of_line ();
457 return;
458 }
459 ++input_line_pointer;
460 }
461
462 /* Skip the closing quote. */
463 ++input_line_pointer;
464
b81b8a7d 465 SKIP_WHITESPACE ();
fa20b8bf
ILT
466 if (*input_line_pointer == ',')
467 {
468 ++input_line_pointer;
469 SKIP_WHITESPACE ();
470 if (*input_line_pointer == '@')
471 {
472 ++input_line_pointer;
473 if (strncmp (input_line_pointer, "progbits",
474 sizeof "progbits" - 1) == 0)
475 {
476 flags |= SEC_ALLOC | SEC_LOAD;
477 input_line_pointer += sizeof "progbits" - 1;
478 }
479 else if (strncmp (input_line_pointer, "nobits",
480 sizeof "nobits" - 1) == 0)
481 {
482 flags &=~ SEC_LOAD;
483 input_line_pointer += sizeof "nobits" - 1;
484 }
485 else
486 {
487 as_warn ("Unrecognized section type");
488 ignore_rest_of_line ();
489 }
490 }
491 }
b81b8a7d 492 }
fa20b8bf 493 else
49864cfa 494 {
fa20b8bf
ILT
495 flags = SEC_READONLY | SEC_RELOC;
496 do
497 {
498 SKIP_WHITESPACE ();
499 if (*input_line_pointer != '#')
500 {
501 as_warn ("Bad .section directive");
502 ignore_rest_of_line ();
503 return;
504 }
505 ++input_line_pointer;
506 if (strncmp (input_line_pointer, "write",
507 sizeof "write" - 1) == 0)
508 {
509 flags &=~ SEC_READONLY;
510 input_line_pointer += sizeof "write" - 1;
511 }
512 else if (strncmp (input_line_pointer, "alloc",
513 sizeof "alloc" - 1) == 0)
514 {
515 flags |= SEC_ALLOC | SEC_LOAD;
516 input_line_pointer += sizeof "alloc" - 1;
517 }
518 else if (strncmp (input_line_pointer, "execinstr",
519 sizeof "execinstr" - 1) == 0)
520 {
521 flags |= SEC_CODE;
522 input_line_pointer += sizeof "execinstr" - 1;
523 }
524 else
525 {
526 as_warn ("Unrecognized section attribute");
527 ignore_rest_of_line ();
528 return;
529 }
530 SKIP_WHITESPACE ();
531 }
532 while (*input_line_pointer++ == ',');
533 --input_line_pointer;
49864cfa 534 }
49864cfa 535 }
49864cfa 536
fa20b8bf 537 bfd_set_section_flags (stdoutput, sec, flags);
13998021 538
fa20b8bf 539 demand_empty_rest_of_line ();
13998021
ILT
540}
541
542/* Change to the .data section. */
543
544static void
545obj_elf_data (i)
546 int i;
547{
548 previous_section = now_seg;
549 previous_subsection = now_subseg;
550 s_data (i);
551}
552
553/* Change to the .text section. */
554
555static void
556obj_elf_text (i)
557 int i;
558{
559 previous_section = now_seg;
560 previous_subsection = now_subseg;
561 s_text (i);
49864cfa
KR
562}
563
693b21e7 564void
604633ae
ILT
565obj_elf_previous (ignore)
566 int ignore;
7c05f0ec
KR
567{
568 if (previous_section == 0)
569 {
570 as_bad (".previous without corresponding .section; ignored");
571 return;
572 }
573 subseg_set (previous_section, previous_subsection);
574 previous_section = 0;
575}
576
604633ae 577static int
6e378515
KR
578obj_elf_write_symbol_p (sym)
579 symbolS *sym;
49864cfa 580{
6e378515
KR
581 /* If this is a local symbol, are there any relocations for which
582 need this symbol? */
49864cfa 583
6e378515
KR
584 /* To find this out, we examine all relocations in all bfd sections
585 that have relocations. If there is one that references this
586 symbol, we need to keep this symbol. In this case, we return a
587 true status. In all other cases, we return a false status. */
49864cfa 588
6e378515 589 if (S_IS_LOCAL (sym))
49864cfa 590 {
6e378515
KR
591 asymbol *bsym = sym->bsym;
592 bfd *abfd = bsym->the_bfd;
593 asection *bsec;
49864cfa 594
6e378515
KR
595 for (bsec = abfd->sections; bsec; bsec = bsec->next)
596 {
597 struct reloc_cache_entry **rlocs = bsec->orelocation;
598 int rcnt = bsec->reloc_count;
49864cfa 599
6e378515
KR
600 if (rlocs)
601 {
602 int i;
49864cfa 603
6e378515
KR
604 for (i = 0; i < rcnt; i++)
605 if (rlocs[i]->sym_ptr_ptr
606 && rlocs[i]->sym_ptr_ptr[0] == bsym)
607 return 1;
608 }
609 else
610 {
611 /* No relocations for this section. Check the seg_info
612 structure to see if there are any fixups for this
613 section. */
614 segment_info_type *seginfo = seg_info (bsec);
615 fixS *fixp;
616
617 for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
618 if ((fixp->fx_addsy && fixp->fx_addsy->bsym == bsym)
619 || (fixp->fx_subsy && fixp->fx_subsy->bsym == bsym))
620 return 1;
621 }
49864cfa 622 }
49864cfa 623 }
6e378515 624 return 0;
49864cfa
KR
625}
626
6e378515
KR
627int
628obj_elf_write_symbol (sym)
629 symbolS *sym;
49864cfa 630{
6e378515 631 return /* obj_elf_write_symbol_p (sym) || */ !S_IS_LOCAL (sym);
49864cfa
KR
632}
633
49864cfa
KR
634int
635obj_elf_frob_symbol (sym, punt)
636 symbolS *sym;
637 int *punt;
638{
693b21e7
KR
639#if 0 /* ?? The return value is ignored. Only the value of *punt is
640 relevant. */
6e378515 641 return obj_elf_write_symbol_p (sym);
693b21e7 642#endif
58d4951d
ILT
643 /* FIXME: Just return 0 until is fixed. */
644 return 0;
49864cfa
KR
645}
646
6e378515 647static void
604633ae
ILT
648obj_elf_line (ignore)
649 int ignore;
6e378515
KR
650{
651 /* Assume delimiter is part of expression. BSD4.2 as fails with
652 delightful bug, so we are not being incompatible here. */
653 new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
654 demand_empty_rest_of_line ();
655}
49864cfa 656
6e378515
KR
657void
658obj_read_begin_hook ()
49864cfa 659{
c5953036
ILT
660#ifdef ECOFF_DEBUGGING
661 ecoff_read_begin_hook ();
662#endif
49864cfa
KR
663}
664
6e378515
KR
665void
666obj_symbol_new_hook (symbolP)
667 symbolS *symbolP;
49864cfa 668{
6e378515
KR
669#if 0 /* BFD already takes care of this */
670 elf32_symbol_type *esym = (elf32_symbol_type *) symbolP;
49864cfa
KR
671
672 /* There is an Elf_Internal_Sym and an Elf_External_Sym. For now,
673 just zero them out. */
674
6e378515
KR
675 bzero ((char *) &esym->internal_elf_sym, sizeof (esym->internal_elf_sym));
676 bzero ((char *) &esym->native_elf_sym, sizeof (esym->native_elf_sym));
677 bzero ((char *) &esym->tc_data, sizeof (esym->tc_data));
678#endif
c5953036
ILT
679#ifdef ECOFF_DEBUGGING
680 ecoff_symbol_new_hook (symbolP);
681#endif
49864cfa
KR
682}
683
6e378515 684void
604633ae
ILT
685obj_elf_version (ignore)
686 int ignore;
49864cfa 687{
6e378515
KR
688 char *name;
689 unsigned int c;
690 char ch;
691 char *p;
692 asection *seg = now_seg;
693 subsegT subseg = now_subseg;
694 Elf_Internal_Note i_note;
695 Elf_External_Note e_note;
696 asection *note_secp = (asection *) NULL;
697 int i, len;
698
699 SKIP_WHITESPACE ();
700 if (*input_line_pointer == '\"')
701 {
702 ++input_line_pointer; /* -> 1st char of string. */
49864cfa
KR
703 name = input_line_pointer;
704
6e378515
KR
705 while (is_a_char (c = next_char_of_string ()))
706 ;
49864cfa
KR
707 c = *input_line_pointer;
708 *input_line_pointer = '\0';
6e378515 709 *(input_line_pointer - 1) = '\0';
49864cfa
KR
710 *input_line_pointer = c;
711
4f0bccc7 712 /* create the .note section */
49864cfa 713
4f0bccc7
ILT
714 note_secp = subseg_new (".note", 0);
715 bfd_set_section_flags (stdoutput,
716 note_secp,
717 SEC_HAS_CONTENTS | SEC_READONLY);
49864cfa
KR
718
719 /* process the version string */
720
6e378515
KR
721 len = strlen (name);
722
693b21e7
KR
723 i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
724 i_note.descsz = 0; /* no description */
6e378515
KR
725 i_note.type = NT_VERSION;
726 p = frag_more (sizeof (e_note.namesz));
727 md_number_to_chars (p, (valueT) i_note.namesz, 4);
728 p = frag_more (sizeof (e_note.descsz));
729 md_number_to_chars (p, (valueT) i_note.descsz, 4);
730 p = frag_more (sizeof (e_note.type));
731 md_number_to_chars (p, (valueT) i_note.type, 4);
732
733 for (i = 0; i < len; i++)
734 {
735 ch = *(name + i);
736 {
737 FRAG_APPEND_1_CHAR (ch);
738 }
739 }
740 frag_align (2, 0);
49864cfa 741
604633ae 742 subseg_set (seg, subseg);
49864cfa 743 }
6e378515
KR
744 else
745 {
693b21e7 746 as_bad ("Expected quoted string");
49864cfa 747 }
6e378515 748 demand_empty_rest_of_line ();
49864cfa
KR
749}
750
751static void
604633ae
ILT
752obj_elf_size (ignore)
753 int ignore;
49864cfa
KR
754{
755 char *name = input_line_pointer;
756 char c = get_symbol_end ();
757 char *p;
758 expressionS exp;
49864cfa
KR
759 symbolS *sym;
760
761 p = input_line_pointer;
762 *p = c;
763 SKIP_WHITESPACE ();
764 if (*input_line_pointer != ',')
765 {
766 *p = 0;
767 as_bad ("expected comma after name `%s' in .size directive", name);
768 *p = c;
769 ignore_rest_of_line ();
770 return;
771 }
772 input_line_pointer++;
5ac34ac3
ILT
773 expression (&exp);
774 if (exp.X_op == O_absent)
49864cfa
KR
775 {
776 as_bad ("missing expression in .size directive");
5ac34ac3 777 exp.X_op = O_constant;
49864cfa
KR
778 exp.X_add_number = 0;
779 }
780 *p = 0;
781 sym = symbol_find_or_make (name);
782 *p = c;
5ac34ac3 783 if (exp.X_op == O_constant)
49864cfa
KR
784 S_SET_SIZE (sym, exp.X_add_number);
785 else
6e378515
KR
786 {
787#if 0
788 static int warned;
789 if (!warned)
790 {
791 as_tsktsk (".size expressions not yet supported, ignored");
792 warned++;
793 }
794#endif
795 }
49864cfa
KR
796 demand_empty_rest_of_line ();
797}
798
799static void
604633ae
ILT
800obj_elf_type (ignore)
801 int ignore;
49864cfa
KR
802{
803 char *name = input_line_pointer;
804 char c = get_symbol_end ();
805 char *p;
6e378515 806 int type = 0;
49864cfa
KR
807 symbolS *sym;
808
809 p = input_line_pointer;
810 *p = c;
811 SKIP_WHITESPACE ();
812 if (*input_line_pointer != ',')
813 {
814 as_bad ("expected comma after name in .type directive");
815 egress:
816 ignore_rest_of_line ();
817 return;
818 }
819 input_line_pointer++;
820 SKIP_WHITESPACE ();
b81b8a7d 821 if (*input_line_pointer != '#' && *input_line_pointer != '@')
49864cfa 822 {
b81b8a7d 823 as_bad ("expected `#' or `@' after comma in .type directive");
49864cfa
KR
824 goto egress;
825 }
826 input_line_pointer++;
827 if (!strncmp ("function", input_line_pointer, sizeof ("function") - 1))
828 {
829 type = BSF_FUNCTION;
830 input_line_pointer += sizeof ("function") - 1;
831 }
6e378515
KR
832 else if (!strncmp ("object", input_line_pointer, sizeof ("object") - 1))
833 {
834 input_line_pointer += sizeof ("object") - 1;
835 }
49864cfa
KR
836 else
837 {
838 as_bad ("unrecognized symbol type, ignored");
839 goto egress;
840 }
841 demand_empty_rest_of_line ();
842 *p = 0;
843 sym = symbol_find_or_make (name);
6e378515 844 sym->bsym->flags |= type;
49864cfa
KR
845}
846
847static void
604633ae
ILT
848obj_elf_ident (ignore)
849 int ignore;
49864cfa 850{
6e378515
KR
851 static segT comment_section;
852 segT old_section = now_seg;
853 int old_subsection = now_subseg;
49864cfa 854
6e378515
KR
855 if (!comment_section)
856 {
857 char *p;
858 comment_section = subseg_new (".comment", 0);
fa20b8bf
ILT
859 bfd_set_section_flags (stdoutput, comment_section,
860 SEC_READONLY | SEC_HAS_CONTENTS);
6e378515
KR
861 p = frag_more (1);
862 *p = 0;
863 }
864 else
865 subseg_set (comment_section, 0);
866 stringer (1);
867 subseg_set (old_section, old_subsection);
868}
869
9bd0d649
ILT
870/* The first entry in a .stabs section is special. */
871
872void
873obj_elf_init_stab_section (seg)
874 segT seg;
875{
fa20b8bf 876 char *file;
9bd0d649 877 char *p;
c5953036 878 char *stabstr_name;
9bd0d649
ILT
879 unsigned int stroff;
880
fa20b8bf
ILT
881 /* Force the section to align to a longword boundary. Without this,
882 UnixWare ar crashes. */
883 bfd_set_section_alignment (stdoutput, seg, 2);
884
9bd0d649 885 p = frag_more (12);
fa20b8bf 886 as_where (&file, (unsigned int *) NULL);
c5953036
ILT
887 stabstr_name = (char *) alloca (strlen (segment_name (seg)) + 4);
888 strcpy (stabstr_name, segment_name (seg));
889 strcat (stabstr_name, "str");
890 stroff = get_stab_string_offset (file, stabstr_name);
9bd0d649
ILT
891 know (stroff == 1);
892 md_number_to_chars (p, stroff, 4);
893 seg_info (seg)->stabu.p = p;
894}
895
896/* Fill in the counts in the first entry in a .stabs section. */
897
693b21e7
KR
898static void
899adjust_stab_sections (abfd, sec, xxx)
900 bfd *abfd;
901 asection *sec;
902 PTR xxx;
903{
904 char *name;
905 asection *strsec;
4f0bccc7 906 char *p;
693b21e7
KR
907 int strsz, nsyms;
908
909 if (strncmp (".stab", sec->name, 5))
910 return;
911 if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
912 return;
913
914 name = (char *) alloca (strlen (sec->name) + 4);
915 strcpy (name, sec->name);
916 strcat (name, "str");
917 strsec = bfd_get_section_by_name (abfd, name);
918 if (strsec)
919 strsz = bfd_section_size (abfd, strsec);
920 else
921 strsz = 0;
922 nsyms = bfd_section_size (abfd, sec) / 12 - 1;
923
4f0bccc7
ILT
924 p = seg_info (sec)->stabu.p;
925 assert (p != 0);
693b21e7 926
9bd0d649
ILT
927 bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
928 bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
693b21e7
KR
929}
930
c5953036
ILT
931#ifdef ECOFF_DEBUGGING
932
933/* This function is called by the ECOFF code. It is supposed to
934 record the external symbol information so that the backend can
935 write it out correctly. The ELF backend doesn't actually handle
936 this at the moment, so we do it ourselves. We save the information
937 in the symbol. */
938
939void
940obj_ecoff_set_ext (sym, ext)
941 symbolS *sym;
942 EXTR *ext;
943{
944 sym->bsym->udata = (PTR) ext;
945}
946
947/* This function is called by bfd_ecoff_debug_externals. It is
948 supposed to *EXT to the external symbol information, and return
949 whether the symbol should be used at all. */
950
951static boolean
952elf_get_extr (sym, ext)
953 asymbol *sym;
954 EXTR *ext;
955{
956 if (sym->udata == NULL)
957 return false;
958 *ext = *(EXTR *) sym->udata;
959 return true;
960}
961
962/* This function is called by bfd_ecoff_debug_externals. It has
963 nothing to do for ELF. */
964
965/*ARGSUSED*/
966static void
967elf_set_index (sym, indx)
968 asymbol *sym;
969 bfd_size_type indx;
970{
971}
972
973#endif /* ECOFF_DEBUGGING */
974
6e378515
KR
975void
976elf_frob_file ()
977{
693b21e7
KR
978 bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
979
6e378515 980#ifdef elf_tc_symbol
693b21e7
KR
981 {
982 int i;
6e378515 983
693b21e7 984 for (i = 0; i < stdoutput->symcount; i++)
5cf4cd1b 985 elf_tc_symbol (stdoutput, (PTR) (stdoutput->outsymbols[i]),
693b21e7
KR
986 i + 1);
987 }
6e378515 988#endif
693b21e7 989
6e378515 990#ifdef elf_tc_final_processing
5cf4cd1b 991 elf_tc_final_processing ();
6e378515
KR
992#endif
993
994 /* Finally, we must make any target-specific sections. */
995
996#ifdef elf_tc_make_sections
5cf4cd1b 997 elf_tc_make_sections (stdoutput);
6e378515 998#endif
c5953036
ILT
999
1000#ifdef ECOFF_DEBUGGING
1001 /* Generate the ECOFF debugging information. */
1002 {
1003 const struct ecoff_debug_swap *debug_swap;
1004 struct ecoff_debug_info debug;
1005 char *buf;
1006 asection *sec;
1007
1008 debug_swap
1009 = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
1010 know (debug_swap != (const struct ecoff_debug_swap *) NULL);
1011 ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
1012
1013 /* Set up the pointers in debug. */
1014#define SET(ptr, offset, type) \
1015 debug.ptr = (type) (buf + debug.symbolic_header.offset)
1016
1017 SET (line, cbLineOffset, unsigned char *);
1018 SET (external_dnr, cbDnOffset, PTR);
1019 SET (external_pdr, cbPdOffset, PTR);
1020 SET (external_sym, cbSymOffset, PTR);
1021 SET (external_opt, cbOptOffset, PTR);
1022 SET (external_aux, cbAuxOffset, union aux_ext *);
1023 SET (ss, cbSsOffset, char *);
1024 SET (external_fdr, cbFdOffset, PTR);
1025 SET (external_rfd, cbRfdOffset, PTR);
1026 /* ssext and external_ext are set up just below. */
1027
1028#undef SET
1029
1030 /* Set up the external symbols. */
1031 debug.ssext = debug.ssext_end = NULL;
1032 debug.external_ext = debug.external_ext_end = NULL;
1033 if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,
1034 elf_get_extr, elf_set_index))
1035 as_fatal ("Failed to set up debugging information: %s",
1036 bfd_errmsg (bfd_error));
1037
1038 sec = bfd_get_section_by_name (stdoutput, ".mdebug");
1039 assert (sec != NULL);
1040
1041 know (stdoutput->output_has_begun == false);
1042
1043 /* We set the size of the section, call bfd_set_section_contents
1044 to force the ELF backend to allocate a file position, and then
1045 write out the data. FIXME: Is this really the best way to do
1046 this? */
1047 sec->_raw_size = bfd_ecoff_debug_size (stdoutput, &debug, debug_swap);
1048
1049 if (! bfd_set_section_contents (stdoutput, sec, (PTR) NULL,
1050 (file_ptr) 0, (bfd_size_type) 0))
1051 as_fatal ("Can't start writing .mdebug section: %s",
1052 bfd_errmsg (bfd_error));
1053
1054 know (stdoutput->output_has_begun == true);
1055 know (sec->filepos != 0);
1056
1057 if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
1058 sec->filepos))
1059 as_fatal ("Could not write .mdebug section: %s",
1060 bfd_errmsg (bfd_error));
1061 }
1062#endif /* ECOFF_DEBUGGING */
49864cfa 1063}
This page took 0.095116 seconds and 4 git commands to generate.