obj-elf.c revision 1.9 1 1.1 christos /* ELF object file format
2 1.9 christos Copyright (C) 1992-2024 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos This file is part of GAS, the GNU Assembler.
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
8 1.1 christos published by the Free Software Foundation; either version 3,
9 1.1 christos or (at your option) any later version.
10 1.1 christos
11 1.1 christos GAS is distributed in the hope that it will be useful, but
12 1.1 christos WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14 1.1 christos the 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-elf.h"
22 1.1 christos #include "as.h"
23 1.1 christos #include "safe-ctype.h"
24 1.1 christos #include "subsegs.h"
25 1.1 christos #include "obstack.h"
26 1.1 christos #include "dwarf2dbg.h"
27 1.9 christos #include "ginsn.h"
28 1.1 christos
29 1.1 christos #ifndef ECOFF_DEBUGGING
30 1.1 christos #define ECOFF_DEBUGGING 0
31 1.1 christos #else
32 1.1 christos #define NEED_ECOFF_DEBUG
33 1.1 christos #endif
34 1.1 christos
35 1.1 christos #ifdef NEED_ECOFF_DEBUG
36 1.1 christos #include "ecoff.h"
37 1.7 christos #include "bfd/ecoff-bfd.h"
38 1.1 christos #endif
39 1.1 christos
40 1.1 christos #ifdef TC_ALPHA
41 1.1 christos #include "elf/alpha.h"
42 1.1 christos #endif
43 1.1 christos
44 1.1 christos #ifdef TC_MIPS
45 1.1 christos #include "elf/mips.h"
46 1.1 christos #endif
47 1.1 christos
48 1.1 christos #ifdef TC_PPC
49 1.1 christos #include "elf/ppc.h"
50 1.1 christos #endif
51 1.1 christos
52 1.1 christos #ifdef TC_I386
53 1.1 christos #include "elf/x86-64.h"
54 1.1 christos #endif
55 1.1 christos
56 1.1 christos #ifdef TC_MEP
57 1.1 christos #include "elf/mep.h"
58 1.1 christos #endif
59 1.1 christos
60 1.3 christos #ifdef TC_NIOS2
61 1.3 christos #include "elf/nios2.h"
62 1.3 christos #endif
63 1.3 christos
64 1.6 christos #ifdef TC_PRU
65 1.6 christos #include "elf/pru.h"
66 1.6 christos #endif
67 1.6 christos
68 1.1 christos static void obj_elf_line (int);
69 1.1 christos static void obj_elf_size (int);
70 1.1 christos static void obj_elf_type (int);
71 1.1 christos static void obj_elf_ident (int);
72 1.1 christos static void obj_elf_weak (int);
73 1.1 christos static void obj_elf_local (int);
74 1.1 christos static void obj_elf_visibility (int);
75 1.1 christos static void obj_elf_symver (int);
76 1.1 christos static void obj_elf_subsection (int);
77 1.1 christos static void obj_elf_popsection (int);
78 1.3 christos static void obj_elf_gnu_attribute (int);
79 1.1 christos static void obj_elf_tls_common (int);
80 1.1 christos static void obj_elf_lcomm (int);
81 1.1 christos static void obj_elf_struct (int);
82 1.8 christos static void obj_elf_attach_to_group (int);
83 1.1 christos
84 1.1 christos static const pseudo_typeS elf_pseudo_table[] =
85 1.1 christos {
86 1.8 christos {"attach_to_group", obj_elf_attach_to_group, 0},
87 1.1 christos {"comm", obj_elf_common, 0},
88 1.1 christos {"common", obj_elf_common, 1},
89 1.1 christos {"ident", obj_elf_ident, 0},
90 1.1 christos {"lcomm", obj_elf_lcomm, 0},
91 1.1 christos {"local", obj_elf_local, 0},
92 1.1 christos {"previous", obj_elf_previous, 0},
93 1.1 christos {"section", obj_elf_section, 0},
94 1.1 christos {"section.s", obj_elf_section, 0},
95 1.1 christos {"sect", obj_elf_section, 0},
96 1.1 christos {"sect.s", obj_elf_section, 0},
97 1.1 christos {"pushsection", obj_elf_section, 1},
98 1.1 christos {"popsection", obj_elf_popsection, 0},
99 1.1 christos {"size", obj_elf_size, 0},
100 1.1 christos {"type", obj_elf_type, 0},
101 1.1 christos {"version", obj_elf_version, 0},
102 1.1 christos {"weak", obj_elf_weak, 0},
103 1.1 christos
104 1.1 christos /* These define symbol visibility. */
105 1.1 christos {"internal", obj_elf_visibility, STV_INTERNAL},
106 1.1 christos {"hidden", obj_elf_visibility, STV_HIDDEN},
107 1.1 christos {"protected", obj_elf_visibility, STV_PROTECTED},
108 1.1 christos
109 1.1 christos /* These are used for stabs-in-elf configurations. */
110 1.1 christos {"line", obj_elf_line, 0},
111 1.1 christos
112 1.1 christos /* This is a GNU extension to handle symbol versions. */
113 1.1 christos {"symver", obj_elf_symver, 0},
114 1.1 christos
115 1.1 christos /* A GNU extension to change subsection only. */
116 1.1 christos {"subsection", obj_elf_subsection, 0},
117 1.1 christos
118 1.1 christos /* These are GNU extensions to aid in garbage collecting C++ vtables. */
119 1.6 christos {"vtable_inherit", obj_elf_vtable_inherit, 0},
120 1.6 christos {"vtable_entry", obj_elf_vtable_entry, 0},
121 1.1 christos
122 1.3 christos /* A GNU extension for object attributes. */
123 1.3 christos {"gnu_attribute", obj_elf_gnu_attribute, 0},
124 1.3 christos
125 1.1 christos /* These are used for dwarf2. */
126 1.6 christos { "file", dwarf2_directive_file, 0 },
127 1.1 christos { "loc", dwarf2_directive_loc, 0 },
128 1.1 christos { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 },
129 1.1 christos
130 1.1 christos /* We need to trap the section changing calls to handle .previous. */
131 1.1 christos {"data", obj_elf_data, 0},
132 1.1 christos {"offset", obj_elf_struct, 0},
133 1.1 christos {"struct", obj_elf_struct, 0},
134 1.1 christos {"text", obj_elf_text, 0},
135 1.8 christos {"bss", obj_elf_bss, 0},
136 1.1 christos
137 1.1 christos {"tls_common", obj_elf_tls_common, 0},
138 1.1 christos
139 1.1 christos /* End sentinel. */
140 1.1 christos {NULL, NULL, 0},
141 1.1 christos };
142 1.1 christos
143 1.1 christos static const pseudo_typeS ecoff_debug_pseudo_table[] =
144 1.1 christos {
145 1.1 christos #ifdef NEED_ECOFF_DEBUG
146 1.1 christos /* COFF style debugging information for ECOFF. .ln is not used; .loc
147 1.1 christos is used instead. */
148 1.1 christos { "def", ecoff_directive_def, 0 },
149 1.1 christos { "dim", ecoff_directive_dim, 0 },
150 1.1 christos { "endef", ecoff_directive_endef, 0 },
151 1.1 christos { "file", ecoff_directive_file, 0 },
152 1.1 christos { "scl", ecoff_directive_scl, 0 },
153 1.1 christos { "tag", ecoff_directive_tag, 0 },
154 1.1 christos { "val", ecoff_directive_val, 0 },
155 1.1 christos
156 1.1 christos /* COFF debugging requires pseudo-ops .size and .type, but ELF
157 1.1 christos already has meanings for those. We use .esize and .etype
158 1.1 christos instead. These are only generated by gcc anyhow. */
159 1.1 christos { "esize", ecoff_directive_size, 0 },
160 1.1 christos { "etype", ecoff_directive_type, 0 },
161 1.1 christos
162 1.1 christos /* ECOFF specific debugging information. */
163 1.6 christos { "aent", ecoff_directive_ent, 1 },
164 1.1 christos { "begin", ecoff_directive_begin, 0 },
165 1.1 christos { "bend", ecoff_directive_bend, 0 },
166 1.1 christos { "end", ecoff_directive_end, 0 },
167 1.1 christos { "ent", ecoff_directive_ent, 0 },
168 1.1 christos { "fmask", ecoff_directive_fmask, 0 },
169 1.1 christos { "frame", ecoff_directive_frame, 0 },
170 1.1 christos { "loc", ecoff_directive_loc, 0 },
171 1.1 christos { "mask", ecoff_directive_mask, 0 },
172 1.1 christos
173 1.1 christos /* Other ECOFF directives. */
174 1.1 christos { "extern", ecoff_directive_extern, 0 },
175 1.1 christos
176 1.1 christos /* These are used on Irix. I don't know how to implement them. */
177 1.1 christos { "alias", s_ignore, 0 },
178 1.1 christos { "bgnb", s_ignore, 0 },
179 1.1 christos { "endb", s_ignore, 0 },
180 1.1 christos { "lab", s_ignore, 0 },
181 1.1 christos { "noalias", s_ignore, 0 },
182 1.1 christos { "verstamp", s_ignore, 0 },
183 1.1 christos { "vreg", s_ignore, 0 },
184 1.1 christos #endif
185 1.1 christos
186 1.1 christos {NULL, NULL, 0} /* end sentinel */
187 1.1 christos };
188 1.1 christos
189 1.1 christos #undef NO_RELOC
190 1.1 christos #include "aout/aout64.h"
191 1.1 christos
192 1.1 christos asection *elf_com_section_ptr;
193 1.1 christos
194 1.1 christos void
195 1.1 christos elf_pop_insert (void)
196 1.1 christos {
197 1.1 christos pop_insert (elf_pseudo_table);
198 1.1 christos if (ECOFF_DEBUGGING)
199 1.1 christos pop_insert (ecoff_debug_pseudo_table);
200 1.1 christos }
201 1.1 christos
202 1.1 christos static bfd_vma
203 1.1 christos elf_s_get_size (symbolS *sym)
204 1.1 christos {
205 1.1 christos return S_GET_SIZE (sym);
206 1.1 christos }
207 1.1 christos
208 1.1 christos static void
209 1.1 christos elf_s_set_size (symbolS *sym, bfd_vma sz)
210 1.1 christos {
211 1.1 christos S_SET_SIZE (sym, sz);
212 1.1 christos }
213 1.1 christos
214 1.1 christos static bfd_vma
215 1.1 christos elf_s_get_align (symbolS *sym)
216 1.1 christos {
217 1.1 christos return S_GET_ALIGN (sym);
218 1.1 christos }
219 1.1 christos
220 1.1 christos static void
221 1.1 christos elf_s_set_align (symbolS *sym, bfd_vma align)
222 1.1 christos {
223 1.1 christos S_SET_ALIGN (sym, align);
224 1.1 christos }
225 1.1 christos
226 1.1 christos int
227 1.1 christos elf_s_get_other (symbolS *sym)
228 1.1 christos {
229 1.1 christos return elf_symbol (symbol_get_bfdsym (sym))->internal_elf_sym.st_other;
230 1.1 christos }
231 1.1 christos
232 1.1 christos static void
233 1.1 christos elf_s_set_other (symbolS *sym, int other)
234 1.1 christos {
235 1.1 christos S_SET_OTHER (sym, other);
236 1.1 christos }
237 1.1 christos
238 1.1 christos static int
239 1.1 christos elf_sec_sym_ok_for_reloc (asection *sec)
240 1.1 christos {
241 1.1 christos return obj_sec_sym_ok_for_reloc (sec);
242 1.1 christos }
243 1.1 christos
244 1.1 christos void
245 1.8 christos elf_file_symbol (const char *s)
246 1.1 christos {
247 1.7 christos asymbol *bsym;
248 1.8 christos symbolS *sym = symbol_new (s, absolute_section, &zero_address_frag, 0);
249 1.8 christos size_t name_length = strlen (s);
250 1.7 christos
251 1.8 christos if (name_length > strlen (S_GET_NAME (sym)))
252 1.8 christos {
253 1.8 christos obstack_grow (¬es, s, name_length + 1);
254 1.8 christos S_SET_NAME (sym, (const char *) obstack_finish (¬es));
255 1.8 christos }
256 1.8 christos else
257 1.8 christos strcpy ((char *) S_GET_NAME (sym), s);
258 1.1 christos
259 1.8 christos symbol_get_bfdsym (sym)->flags |= BSF_FILE;
260 1.1 christos
261 1.8 christos if (symbol_rootP != sym
262 1.8 christos && ((bsym = symbol_get_bfdsym (symbol_rootP)) == NULL
263 1.8 christos || (bsym->flags & BSF_FILE) == 0))
264 1.8 christos {
265 1.8 christos symbol_remove (sym, &symbol_rootP, &symbol_lastP);
266 1.8 christos symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
267 1.8 christos }
268 1.5 christos
269 1.1 christos #ifdef DEBUG
270 1.8 christos verify_symbol_chain (symbol_rootP, symbol_lastP);
271 1.1 christos #endif
272 1.1 christos
273 1.1 christos #ifdef NEED_ECOFF_DEBUG
274 1.8 christos ecoff_new_file (s);
275 1.1 christos #endif
276 1.1 christos }
277 1.1 christos
278 1.1 christos /* Called from read.c:s_comm after we've parsed .comm symbol, size.
279 1.1 christos Parse a possible alignment value. */
280 1.1 christos
281 1.1 christos symbolS *
282 1.1 christos elf_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
283 1.1 christos {
284 1.1 christos addressT align = 0;
285 1.1 christos int is_local = symbol_get_obj (symbolP)->local;
286 1.1 christos
287 1.1 christos if (*input_line_pointer == ',')
288 1.1 christos {
289 1.1 christos char *save = input_line_pointer;
290 1.1 christos
291 1.1 christos input_line_pointer++;
292 1.1 christos SKIP_WHITESPACE ();
293 1.1 christos
294 1.1 christos if (*input_line_pointer == '"')
295 1.1 christos {
296 1.1 christos /* For sparc. Accept .common symbol, length, "bss" */
297 1.1 christos input_line_pointer++;
298 1.1 christos /* Some use the dot, some don't. */
299 1.1 christos if (*input_line_pointer == '.')
300 1.1 christos input_line_pointer++;
301 1.1 christos /* Some say data, some say bss. */
302 1.8 christos if (startswith (input_line_pointer, "bss\""))
303 1.1 christos input_line_pointer += 4;
304 1.8 christos else if (startswith (input_line_pointer, "data\""))
305 1.1 christos input_line_pointer += 5;
306 1.1 christos else
307 1.1 christos {
308 1.1 christos char *p = input_line_pointer;
309 1.1 christos char c;
310 1.1 christos
311 1.1 christos while (*--p != '"')
312 1.1 christos ;
313 1.1 christos while (!is_end_of_line[(unsigned char) *input_line_pointer])
314 1.1 christos if (*input_line_pointer++ == '"')
315 1.1 christos break;
316 1.1 christos c = *input_line_pointer;
317 1.1 christos *input_line_pointer = '\0';
318 1.1 christos as_bad (_("bad .common segment %s"), p);
319 1.1 christos *input_line_pointer = c;
320 1.1 christos ignore_rest_of_line ();
321 1.1 christos return NULL;
322 1.1 christos }
323 1.1 christos /* ??? Don't ask me why these are always global. */
324 1.1 christos is_local = 0;
325 1.1 christos }
326 1.1 christos else
327 1.1 christos {
328 1.1 christos input_line_pointer = save;
329 1.1 christos align = parse_align (is_local);
330 1.1 christos if (align == (addressT) -1)
331 1.1 christos return NULL;
332 1.1 christos }
333 1.1 christos }
334 1.1 christos
335 1.1 christos if (is_local)
336 1.1 christos {
337 1.1 christos bss_alloc (symbolP, size, align);
338 1.1 christos S_CLEAR_EXTERNAL (symbolP);
339 1.1 christos }
340 1.1 christos else
341 1.1 christos {
342 1.1 christos S_SET_VALUE (symbolP, size);
343 1.1 christos S_SET_ALIGN (symbolP, align);
344 1.1 christos S_SET_EXTERNAL (symbolP);
345 1.1 christos S_SET_SEGMENT (symbolP, elf_com_section_ptr);
346 1.1 christos }
347 1.1 christos
348 1.1 christos symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
349 1.1 christos
350 1.1 christos return symbolP;
351 1.1 christos }
352 1.1 christos
353 1.1 christos void
354 1.1 christos obj_elf_common (int is_common)
355 1.1 christos {
356 1.1 christos if (flag_mri && is_common)
357 1.1 christos s_mri_common (0);
358 1.1 christos else
359 1.1 christos s_comm_internal (0, elf_common_parse);
360 1.1 christos }
361 1.1 christos
362 1.1 christos static void
363 1.1 christos obj_elf_tls_common (int ignore ATTRIBUTE_UNUSED)
364 1.1 christos {
365 1.1 christos symbolS *symbolP = s_comm_internal (0, elf_common_parse);
366 1.1 christos
367 1.1 christos if (symbolP)
368 1.1 christos symbol_get_bfdsym (symbolP)->flags |= BSF_THREAD_LOCAL;
369 1.1 christos }
370 1.1 christos
371 1.1 christos static void
372 1.1 christos obj_elf_lcomm (int ignore ATTRIBUTE_UNUSED)
373 1.1 christos {
374 1.1 christos symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
375 1.1 christos
376 1.1 christos if (symbolP)
377 1.1 christos symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
378 1.1 christos }
379 1.1 christos
380 1.1 christos static symbolS *
381 1.1 christos get_sym_from_input_line_and_check (void)
382 1.1 christos {
383 1.1 christos char *name;
384 1.1 christos char c;
385 1.1 christos symbolS *sym;
386 1.1 christos
387 1.3 christos c = get_symbol_name (& name);
388 1.1 christos sym = symbol_find_or_make (name);
389 1.1 christos *input_line_pointer = c;
390 1.3 christos SKIP_WHITESPACE_AFTER_NAME ();
391 1.1 christos
392 1.1 christos /* There is no symbol name if input_line_pointer has not moved. */
393 1.1 christos if (name == input_line_pointer)
394 1.1 christos as_bad (_("Missing symbol name in directive"));
395 1.1 christos return sym;
396 1.1 christos }
397 1.1 christos
398 1.1 christos static void
399 1.1 christos obj_elf_local (int ignore ATTRIBUTE_UNUSED)
400 1.1 christos {
401 1.1 christos int c;
402 1.1 christos symbolS *symbolP;
403 1.1 christos
404 1.1 christos do
405 1.1 christos {
406 1.1 christos symbolP = get_sym_from_input_line_and_check ();
407 1.1 christos c = *input_line_pointer;
408 1.1 christos S_CLEAR_EXTERNAL (symbolP);
409 1.1 christos symbol_get_obj (symbolP)->local = 1;
410 1.1 christos if (c == ',')
411 1.1 christos {
412 1.1 christos input_line_pointer++;
413 1.1 christos SKIP_WHITESPACE ();
414 1.1 christos if (*input_line_pointer == '\n')
415 1.1 christos c = '\n';
416 1.1 christos }
417 1.1 christos }
418 1.1 christos while (c == ',');
419 1.1 christos demand_empty_rest_of_line ();
420 1.1 christos }
421 1.1 christos
422 1.1 christos static void
423 1.1 christos obj_elf_weak (int ignore ATTRIBUTE_UNUSED)
424 1.1 christos {
425 1.1 christos int c;
426 1.1 christos symbolS *symbolP;
427 1.1 christos
428 1.1 christos do
429 1.1 christos {
430 1.1 christos symbolP = get_sym_from_input_line_and_check ();
431 1.1 christos c = *input_line_pointer;
432 1.1 christos S_SET_WEAK (symbolP);
433 1.1 christos if (c == ',')
434 1.1 christos {
435 1.1 christos input_line_pointer++;
436 1.1 christos SKIP_WHITESPACE ();
437 1.1 christos if (*input_line_pointer == '\n')
438 1.1 christos c = '\n';
439 1.1 christos }
440 1.1 christos }
441 1.1 christos while (c == ',');
442 1.1 christos demand_empty_rest_of_line ();
443 1.1 christos }
444 1.1 christos
445 1.1 christos static void
446 1.1 christos obj_elf_visibility (int visibility)
447 1.1 christos {
448 1.1 christos int c;
449 1.1 christos symbolS *symbolP;
450 1.1 christos asymbol *bfdsym;
451 1.1 christos elf_symbol_type *elfsym;
452 1.1 christos
453 1.1 christos do
454 1.1 christos {
455 1.1 christos symbolP = get_sym_from_input_line_and_check ();
456 1.1 christos
457 1.1 christos bfdsym = symbol_get_bfdsym (symbolP);
458 1.8 christos elfsym = elf_symbol_from (bfdsym);
459 1.1 christos
460 1.1 christos gas_assert (elfsym);
461 1.1 christos
462 1.1 christos elfsym->internal_elf_sym.st_other &= ~3;
463 1.1 christos elfsym->internal_elf_sym.st_other |= visibility;
464 1.1 christos
465 1.1 christos c = *input_line_pointer;
466 1.1 christos if (c == ',')
467 1.1 christos {
468 1.1 christos input_line_pointer ++;
469 1.1 christos
470 1.1 christos SKIP_WHITESPACE ();
471 1.1 christos
472 1.1 christos if (*input_line_pointer == '\n')
473 1.1 christos c = '\n';
474 1.1 christos }
475 1.1 christos }
476 1.1 christos while (c == ',');
477 1.1 christos
478 1.1 christos demand_empty_rest_of_line ();
479 1.1 christos }
480 1.1 christos
481 1.1 christos static segT previous_section;
482 1.1 christos static int previous_subsection;
483 1.1 christos
484 1.1 christos struct section_stack
485 1.1 christos {
486 1.1 christos struct section_stack *next;
487 1.1 christos segT seg, prev_seg;
488 1.1 christos int subseg, prev_subseg;
489 1.1 christos };
490 1.1 christos
491 1.1 christos static struct section_stack *section_stack;
492 1.1 christos
493 1.8 christos /* ELF section flags for unique sections. */
494 1.8 christos #define SEC_ASSEMBLER_SHF_MASK SHF_GNU_RETAIN
495 1.8 christos
496 1.8 christos /* Return TRUE iff SEC matches the section info INF. */
497 1.6 christos
498 1.8 christos static bool
499 1.8 christos get_section_by_match (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
500 1.1 christos {
501 1.8 christos struct elf_section_match *match = (struct elf_section_match *) inf;
502 1.6 christos const char *gname = match->group_name;
503 1.1 christos const char *group_name = elf_group_name (sec);
504 1.8 christos const char *linked_to_symbol_name
505 1.8 christos = sec->map_head.linked_to_symbol_name;
506 1.8 christos unsigned int sh_info = elf_section_data (sec)->this_hdr.sh_info;
507 1.8 christos bfd_vma sh_flags = (elf_section_data (sec)->this_hdr.sh_flags
508 1.8 christos & SEC_ASSEMBLER_SHF_MASK);
509 1.8 christos
510 1.8 christos return (sh_info == match->sh_info
511 1.8 christos && sh_flags == match->sh_flags
512 1.8 christos && ((bfd_section_flags (sec) & SEC_ASSEMBLER_SECTION_ID)
513 1.8 christos == (match->flags & SEC_ASSEMBLER_SECTION_ID))
514 1.8 christos && sec->section_id == match->section_id
515 1.6 christos && (group_name == gname
516 1.6 christos || (group_name != NULL
517 1.6 christos && gname != NULL
518 1.8 christos && strcmp (group_name, gname) == 0))
519 1.8 christos && (linked_to_symbol_name == match->linked_to_symbol_name
520 1.8 christos || (linked_to_symbol_name != NULL
521 1.8 christos && match->linked_to_symbol_name != NULL
522 1.8 christos && strcmp (linked_to_symbol_name,
523 1.8 christos match->linked_to_symbol_name) == 0)));
524 1.1 christos }
525 1.1 christos
526 1.1 christos /* Handle the .section pseudo-op. This code supports two different
527 1.1 christos syntaxes.
528 1.1 christos
529 1.1 christos The first is found on Solaris, and looks like
530 1.1 christos .section ".sec1",#alloc,#execinstr,#write
531 1.1 christos Here the names after '#' are the SHF_* flags to turn on for the
532 1.1 christos section. I'm not sure how it determines the SHT_* type (BFD
533 1.1 christos doesn't really give us control over the type, anyhow).
534 1.1 christos
535 1.1 christos The second format is found on UnixWare, and probably most SVR4
536 1.1 christos machines, and looks like
537 1.1 christos .section .sec1,"a",@progbits
538 1.1 christos The quoted string may contain any combination of a, w, x, and
539 1.1 christos represents the SHF_* flags to turn on for the section. The string
540 1.1 christos beginning with '@' can be progbits or nobits. There should be
541 1.1 christos other possibilities, but I don't know what they are. In any case,
542 1.1 christos BFD doesn't really let us set the section type. */
543 1.1 christos
544 1.9 christos static void
545 1.9 christos change_section (const char *name,
546 1.9 christos unsigned int type,
547 1.9 christos bfd_vma attr,
548 1.9 christos int entsize,
549 1.9 christos struct elf_section_match *match_p,
550 1.9 christos bool linkonce,
551 1.9 christos bool push,
552 1.9 christos subsegT new_subsection)
553 1.1 christos {
554 1.1 christos asection *old_sec;
555 1.1 christos segT sec;
556 1.1 christos flagword flags;
557 1.1 christos const struct elf_backend_data *bed;
558 1.1 christos const struct bfd_elf_special_section *ssect;
559 1.8 christos
560 1.8 christos if (match_p == NULL)
561 1.8 christos {
562 1.8 christos static struct elf_section_match unused_match;
563 1.8 christos match_p = &unused_match;
564 1.8 christos }
565 1.1 christos
566 1.1 christos #ifdef md_flush_pending_output
567 1.1 christos md_flush_pending_output ();
568 1.1 christos #endif
569 1.1 christos
570 1.1 christos /* Switch to the section, creating it if necessary. */
571 1.1 christos if (push)
572 1.1 christos {
573 1.1 christos struct section_stack *elt;
574 1.5 christos elt = XNEW (struct section_stack);
575 1.1 christos elt->next = section_stack;
576 1.1 christos elt->seg = now_seg;
577 1.1 christos elt->prev_seg = previous_section;
578 1.1 christos elt->subseg = now_subseg;
579 1.1 christos elt->prev_subseg = previous_subsection;
580 1.1 christos section_stack = elt;
581 1.1 christos }
582 1.1 christos
583 1.8 christos obj_elf_section_change_hook ();
584 1.8 christos
585 1.8 christos old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section_by_match,
586 1.8 christos (void *) match_p);
587 1.1 christos if (old_sec)
588 1.1 christos {
589 1.1 christos sec = old_sec;
590 1.9 christos subseg_set (sec, new_subsection);
591 1.1 christos }
592 1.1 christos else
593 1.9 christos sec = subseg_force_new (name, new_subsection);
594 1.1 christos
595 1.1 christos bed = get_elf_backend_data (stdoutput);
596 1.1 christos ssect = (*bed->get_sec_type_attr) (stdoutput, sec);
597 1.1 christos
598 1.1 christos if (ssect != NULL)
599 1.1 christos {
600 1.8 christos bool override = false;
601 1.1 christos
602 1.1 christos if (type == SHT_NULL)
603 1.1 christos type = ssect->type;
604 1.1 christos else if (type != ssect->type)
605 1.1 christos {
606 1.1 christos if (old_sec == NULL
607 1.1 christos /* Some older versions of gcc will emit
608 1.1 christos
609 1.1 christos .section .init_array,"aw",@progbits
610 1.1 christos
611 1.1 christos for __attribute__ ((section (".init_array"))).
612 1.1 christos "@progbits" is incorrect. Also for x86-64 large bss
613 1.1 christos sections, some older versions of gcc will emit
614 1.1 christos
615 1.1 christos .section .lbss,"aw",@progbits
616 1.1 christos
617 1.1 christos "@progbits" is incorrect. */
618 1.1 christos #ifdef TC_I386
619 1.1 christos && (bed->s->arch_size != 64
620 1.1 christos || !(ssect->attr & SHF_X86_64_LARGE))
621 1.1 christos #endif
622 1.1 christos && ssect->type != SHT_INIT_ARRAY
623 1.1 christos && ssect->type != SHT_FINI_ARRAY
624 1.1 christos && ssect->type != SHT_PREINIT_ARRAY)
625 1.1 christos {
626 1.1 christos /* We allow to specify any type for a .note section. */
627 1.5 christos if (ssect->type != SHT_NOTE
628 1.5 christos /* Processor and application defined types are allowed too. */
629 1.5 christos && type < SHT_LOPROC)
630 1.1 christos as_warn (_("setting incorrect section type for %s"),
631 1.1 christos name);
632 1.1 christos }
633 1.1 christos else
634 1.1 christos {
635 1.1 christos as_warn (_("ignoring incorrect section type for %s"),
636 1.1 christos name);
637 1.1 christos type = ssect->type;
638 1.1 christos }
639 1.1 christos }
640 1.1 christos
641 1.8 christos if (old_sec == NULL && ((attr & ~(SHF_LINK_ORDER
642 1.8 christos | SHF_MASKOS
643 1.8 christos | SHF_MASKPROC))
644 1.5 christos & ~ssect->attr) != 0)
645 1.1 christos {
646 1.8 christos /* Strip SHF_GNU_RETAIN. */
647 1.8 christos bfd_vma generic_attr = attr;
648 1.8 christos if (elf_tdata (stdoutput)->has_gnu_osabi)
649 1.8 christos generic_attr &= ~SHF_GNU_RETAIN;
650 1.8 christos
651 1.1 christos /* As a GNU extension, we permit a .note section to be
652 1.1 christos allocatable. If the linker sees an allocatable .note
653 1.1 christos section, it will create a PT_NOTE segment in the output
654 1.1 christos file. We also allow "x" for .note.GNU-stack. */
655 1.1 christos if (ssect->type == SHT_NOTE
656 1.8 christos && (generic_attr == SHF_ALLOC
657 1.8 christos || generic_attr == SHF_EXECINSTR))
658 1.1 christos ;
659 1.1 christos /* Allow different SHF_MERGE and SHF_STRINGS if we have
660 1.1 christos something like .rodata.str. */
661 1.1 christos else if (ssect->suffix_length == -2
662 1.1 christos && name[ssect->prefix_length] == '.'
663 1.8 christos && (generic_attr
664 1.1 christos & ~ssect->attr
665 1.1 christos & ~SHF_MERGE
666 1.1 christos & ~SHF_STRINGS) == 0)
667 1.1 christos ;
668 1.1 christos /* .interp, .strtab and .symtab can have SHF_ALLOC. */
669 1.8 christos else if (generic_attr == SHF_ALLOC
670 1.1 christos && (strcmp (name, ".interp") == 0
671 1.1 christos || strcmp (name, ".strtab") == 0
672 1.1 christos || strcmp (name, ".symtab") == 0))
673 1.8 christos override = true;
674 1.1 christos /* .note.GNU-stack can have SHF_EXECINSTR. */
675 1.8 christos else if (generic_attr == SHF_EXECINSTR
676 1.1 christos && strcmp (name, ".note.GNU-stack") == 0)
677 1.8 christos override = true;
678 1.1 christos #ifdef TC_ALPHA
679 1.1 christos /* A section on Alpha may have SHF_ALPHA_GPREL. */
680 1.8 christos else if ((generic_attr & ~ssect->attr) == SHF_ALPHA_GPREL)
681 1.8 christos override = true;
682 1.1 christos #endif
683 1.3 christos #ifdef TC_RX
684 1.8 christos else if (generic_attr == (SHF_EXECINSTR | SHF_WRITE | SHF_ALLOC)
685 1.3 christos && (ssect->type == SHT_INIT_ARRAY
686 1.3 christos || ssect->type == SHT_FINI_ARRAY
687 1.3 christos || ssect->type == SHT_PREINIT_ARRAY))
688 1.3 christos /* RX init/fini arrays can and should have the "awx" attributes set. */
689 1.3 christos ;
690 1.3 christos #endif
691 1.1 christos else
692 1.1 christos {
693 1.8 christos if (match_p->group_name == NULL)
694 1.1 christos as_warn (_("setting incorrect section attributes for %s"),
695 1.1 christos name);
696 1.8 christos override = true;
697 1.1 christos }
698 1.1 christos }
699 1.5 christos
700 1.1 christos if (!override && old_sec == NULL)
701 1.1 christos attr |= ssect->attr;
702 1.1 christos }
703 1.1 christos
704 1.1 christos /* Convert ELF type and flags to BFD flags. */
705 1.1 christos flags = (SEC_RELOC
706 1.1 christos | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
707 1.1 christos | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
708 1.1 christos | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
709 1.1 christos | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0)
710 1.1 christos | ((attr & SHF_MERGE) ? SEC_MERGE : 0)
711 1.1 christos | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0)
712 1.1 christos | ((attr & SHF_EXCLUDE) ? SEC_EXCLUDE: 0)
713 1.1 christos | ((attr & SHF_TLS) ? SEC_THREAD_LOCAL : 0));
714 1.1 christos #ifdef md_elf_section_flags
715 1.1 christos flags = md_elf_section_flags (flags, attr, type);
716 1.1 christos #endif
717 1.1 christos
718 1.1 christos if (linkonce)
719 1.1 christos flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
720 1.1 christos
721 1.8 christos /* PR 28054: Set the SEC_ELF_OCTETS flag for debugging sections.
722 1.8 christos Based on the code in bfd/elf.c:_bfd_elf_make_section_from_shdr().
723 1.8 christos
724 1.8 christos FIXME: We do not set the SEC_DEBUGGING flag because that causes
725 1.8 christos problems for the FT32 and MSP430 targets. Investigate and fix. */
726 1.8 christos if ((flags & SEC_ALLOC) == 0 && name [0] == '.')
727 1.8 christos {
728 1.8 christos if ( startswith (name, ".debug")
729 1.8 christos || startswith (name, ".zdebug")
730 1.8 christos || startswith (name, ".gnu.debuglto_.debug_")
731 1.8 christos || startswith (name, ".gnu.linkonce.wi.")
732 1.8 christos || startswith (name, GNU_BUILD_ATTRS_SECTION_NAME)
733 1.8 christos || startswith (name, ".note.gnu"))
734 1.8 christos flags |= SEC_ELF_OCTETS;
735 1.8 christos }
736 1.8 christos
737 1.1 christos if (old_sec == NULL)
738 1.1 christos {
739 1.1 christos symbolS *secsym;
740 1.1 christos
741 1.1 christos if (type == SHT_NULL)
742 1.1 christos type = bfd_elf_get_default_section_type (flags);
743 1.1 christos elf_section_type (sec) = type;
744 1.1 christos elf_section_flags (sec) = attr;
745 1.8 christos elf_section_data (sec)->this_hdr.sh_info = match_p->sh_info;
746 1.1 christos
747 1.1 christos /* Prevent SEC_HAS_CONTENTS from being inadvertently set. */
748 1.1 christos if (type == SHT_NOBITS)
749 1.1 christos seg_info (sec)->bss = 1;
750 1.1 christos
751 1.8 christos /* Set the section ID and flags. */
752 1.8 christos sec->section_id = match_p->section_id;
753 1.8 christos flags |= match_p->flags;
754 1.8 christos
755 1.8 christos /* Set the linked-to symbol name. */
756 1.8 christos sec->map_head.linked_to_symbol_name
757 1.8 christos = match_p->linked_to_symbol_name;
758 1.8 christos
759 1.7 christos bfd_set_section_flags (sec, flags);
760 1.1 christos if (flags & SEC_MERGE)
761 1.1 christos sec->entsize = entsize;
762 1.8 christos elf_group_name (sec) = match_p->group_name;
763 1.1 christos
764 1.1 christos /* Add a symbol for this section to the symbol table. */
765 1.1 christos secsym = symbol_find (name);
766 1.1 christos if (secsym != NULL)
767 1.8 christos {
768 1.8 christos /* We could be repurposing an undefined symbol here: make sure we
769 1.8 christos reset sy_value to look like other section symbols in order to avoid
770 1.8 christos trying to incorrectly resolve this section symbol later on. */
771 1.8 christos static const expressionS exp = { .X_op = O_constant };
772 1.8 christos symbol_set_value_expression (secsym, &exp);
773 1.8 christos symbol_set_bfdsym (secsym, sec->symbol);
774 1.8 christos }
775 1.1 christos else
776 1.1 christos symbol_table_insert (section_symbol (sec));
777 1.1 christos }
778 1.1 christos else
779 1.1 christos {
780 1.1 christos if (type != SHT_NULL
781 1.1 christos && (unsigned) type != elf_section_type (old_sec))
782 1.8 christos {
783 1.8 christos if (ssect != NULL)
784 1.8 christos /* This is a special section with known type. User
785 1.8 christos assembly might get the section type wrong; Even high
786 1.8 christos profile projects like glibc have done so in the past.
787 1.8 christos So don't error in this case. */
788 1.8 christos as_warn (_("ignoring changed section type for %s"), name);
789 1.8 christos else
790 1.8 christos /* Do error when assembly isn't self-consistent. */
791 1.8 christos as_bad (_("changed section type for %s"), name);
792 1.8 christos }
793 1.1 christos
794 1.1 christos if (attr != 0)
795 1.1 christos {
796 1.1 christos /* If section attributes are specified the second time we see a
797 1.1 christos particular section, then check that they are the same as we
798 1.1 christos saw the first time. */
799 1.1 christos if (((old_sec->flags ^ flags)
800 1.1 christos & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
801 1.1 christos | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS
802 1.1 christos | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
803 1.1 christos | SEC_THREAD_LOCAL)))
804 1.8 christos {
805 1.8 christos if (ssect != NULL)
806 1.8 christos as_warn (_("ignoring changed section attributes for %s"), name);
807 1.8 christos else
808 1.8 christos as_bad (_("changed section attributes for %s"), name);
809 1.8 christos }
810 1.5 christos else
811 1.5 christos /* FIXME: Maybe we should consider removing a previously set
812 1.8 christos processor or application specific attribute as suspicious? */
813 1.5 christos elf_section_flags (sec) = attr;
814 1.5 christos
815 1.1 christos if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
816 1.8 christos as_bad (_("changed section entity size for %s"), name);
817 1.1 christos }
818 1.1 christos }
819 1.1 christos
820 1.1 christos #ifdef md_elf_section_change_hook
821 1.1 christos md_elf_section_change_hook ();
822 1.1 christos #endif
823 1.1 christos }
824 1.1 christos
825 1.9 christos void
826 1.9 christos obj_elf_change_section (const char *name,
827 1.9 christos unsigned int type,
828 1.9 christos bfd_vma attr,
829 1.9 christos int entsize,
830 1.9 christos struct elf_section_match *match_p,
831 1.9 christos bool linkonce)
832 1.9 christos {
833 1.9 christos change_section (name, type, attr, entsize, match_p, linkonce, false, 0);
834 1.9 christos }
835 1.9 christos
836 1.1 christos static bfd_vma
837 1.7 christos obj_elf_parse_section_letters (char *str, size_t len,
838 1.9 christos bool *is_clone, int *inherit, bfd_vma *gnu_attr)
839 1.1 christos {
840 1.1 christos bfd_vma attr = 0;
841 1.9 christos
842 1.8 christos *is_clone = false;
843 1.9 christos *inherit = 0;
844 1.1 christos
845 1.1 christos while (len > 0)
846 1.1 christos {
847 1.1 christos switch (*str)
848 1.1 christos {
849 1.1 christos case 'a':
850 1.1 christos attr |= SHF_ALLOC;
851 1.8 christos /* Compatibility. */
852 1.8 christos if (len > 1 && str[1] == 'm')
853 1.8 christos {
854 1.8 christos attr |= SHF_MERGE;
855 1.8 christos str++, len--;
856 1.8 christos if (len > 1 && str[1] == 's')
857 1.8 christos {
858 1.8 christos attr |= SHF_STRINGS;
859 1.8 christos str++, len--;
860 1.8 christos }
861 1.8 christos }
862 1.1 christos break;
863 1.1 christos case 'e':
864 1.1 christos attr |= SHF_EXCLUDE;
865 1.1 christos break;
866 1.8 christos case 'o':
867 1.8 christos attr |= SHF_LINK_ORDER;
868 1.8 christos break;
869 1.1 christos case 'w':
870 1.1 christos attr |= SHF_WRITE;
871 1.1 christos break;
872 1.1 christos case 'x':
873 1.1 christos attr |= SHF_EXECINSTR;
874 1.1 christos break;
875 1.1 christos case 'M':
876 1.1 christos attr |= SHF_MERGE;
877 1.1 christos break;
878 1.1 christos case 'S':
879 1.1 christos attr |= SHF_STRINGS;
880 1.1 christos break;
881 1.1 christos case 'G':
882 1.1 christos attr |= SHF_GROUP;
883 1.1 christos break;
884 1.1 christos case 'T':
885 1.1 christos attr |= SHF_TLS;
886 1.1 christos break;
887 1.6 christos case 'd':
888 1.7 christos *gnu_attr |= SHF_GNU_MBIND;
889 1.6 christos break;
890 1.8 christos case 'R':
891 1.8 christos *gnu_attr |= SHF_GNU_RETAIN;
892 1.8 christos break;
893 1.1 christos case '?':
894 1.8 christos *is_clone = true;
895 1.1 christos break;
896 1.1 christos default:
897 1.1 christos {
898 1.5 christos const char *bad_msg = _("unrecognized .section attribute:"
899 1.8 christos " want a,e,o,w,x,M,S,G,T or number");
900 1.1 christos #ifdef md_elf_section_letter
901 1.1 christos bfd_vma md_attr = md_elf_section_letter (*str, &bad_msg);
902 1.1 christos if (md_attr != (bfd_vma) -1)
903 1.1 christos attr |= md_attr;
904 1.1 christos else
905 1.1 christos #endif
906 1.5 christos if (ISDIGIT (*str))
907 1.5 christos {
908 1.5 christos char * end;
909 1.8 christos struct elf_backend_data *bed;
910 1.8 christos bfd_vma numeric_flags = strtoul (str, &end, 0);
911 1.8 christos
912 1.8 christos attr |= numeric_flags;
913 1.8 christos
914 1.8 christos bed = (struct elf_backend_data *)
915 1.8 christos get_elf_backend_data (stdoutput);
916 1.8 christos
917 1.8 christos if (bed->elf_osabi == ELFOSABI_NONE
918 1.8 christos || bed->elf_osabi == ELFOSABI_STANDALONE
919 1.8 christos || bed->elf_osabi == ELFOSABI_GNU
920 1.8 christos || bed->elf_osabi == ELFOSABI_FREEBSD)
921 1.8 christos {
922 1.8 christos /* Add flags in the SHF_MASKOS range to gnu_attr for
923 1.8 christos OSABIs that support those flags.
924 1.8 christos Also adding the flags for ELFOSABI_{NONE,STANDALONE}
925 1.8 christos allows them to be validated later in obj_elf_section.
926 1.8 christos We can't just always set these bits in gnu_attr for
927 1.8 christos all OSABIs, since Binutils does not recognize all
928 1.8 christos SHF_MASKOS bits for non-GNU OSABIs. It's therefore
929 1.8 christos possible that numeric flags are being used to set bits
930 1.8 christos in the SHF_MASKOS range for those targets, and we
931 1.8 christos don't want assembly to fail in those situations. */
932 1.8 christos *gnu_attr |= (numeric_flags & SHF_MASKOS);
933 1.8 christos }
934 1.5 christos
935 1.5 christos /* Update str and len, allowing for the fact that
936 1.5 christos we will execute str++ and len-- below. */
937 1.5 christos end --;
938 1.5 christos len -= (end - str);
939 1.5 christos str = end;
940 1.5 christos }
941 1.9 christos else if (!attr && !*gnu_attr && (*str == '+' || *str == '-'))
942 1.9 christos *inherit = *str == '+' ? 1 : -1;
943 1.5 christos else
944 1.5 christos as_fatal ("%s", bad_msg);
945 1.1 christos }
946 1.1 christos break;
947 1.1 christos }
948 1.1 christos str++, len--;
949 1.1 christos }
950 1.1 christos
951 1.1 christos return attr;
952 1.1 christos }
953 1.1 christos
954 1.1 christos static int
955 1.8 christos obj_elf_section_type (char *str, size_t len, bool warn)
956 1.1 christos {
957 1.8 christos if (len == 8 && startswith (str, "progbits"))
958 1.1 christos return SHT_PROGBITS;
959 1.8 christos if (len == 6 && startswith (str, "nobits"))
960 1.1 christos return SHT_NOBITS;
961 1.8 christos if (len == 4 && startswith (str, "note"))
962 1.1 christos return SHT_NOTE;
963 1.8 christos if (len == 10 && startswith (str, "init_array"))
964 1.1 christos return SHT_INIT_ARRAY;
965 1.8 christos if (len == 10 && startswith (str, "fini_array"))
966 1.1 christos return SHT_FINI_ARRAY;
967 1.8 christos if (len == 13 && startswith (str, "preinit_array"))
968 1.1 christos return SHT_PREINIT_ARRAY;
969 1.1 christos
970 1.1 christos #ifdef md_elf_section_type
971 1.1 christos {
972 1.1 christos int md_type = md_elf_section_type (str, len);
973 1.1 christos if (md_type >= 0)
974 1.1 christos return md_type;
975 1.1 christos }
976 1.1 christos #endif
977 1.1 christos
978 1.5 christos if (ISDIGIT (*str))
979 1.5 christos {
980 1.5 christos char * end;
981 1.5 christos int type = strtoul (str, & end, 0);
982 1.5 christos
983 1.5 christos if (warn && (size_t) (end - str) != len)
984 1.5 christos as_warn (_("extraneous characters at end of numeric section type"));
985 1.5 christos
986 1.5 christos return type;
987 1.5 christos }
988 1.5 christos
989 1.1 christos if (warn)
990 1.1 christos as_warn (_("unrecognized section type"));
991 1.1 christos return 0;
992 1.1 christos }
993 1.1 christos
994 1.9 christos #ifdef TC_SPARC
995 1.1 christos static bfd_vma
996 1.1 christos obj_elf_section_word (char *str, size_t len, int *type)
997 1.1 christos {
998 1.1 christos int ret;
999 1.1 christos
1000 1.8 christos if (len == 5 && startswith (str, "write"))
1001 1.1 christos return SHF_WRITE;
1002 1.8 christos if (len == 5 && startswith (str, "alloc"))
1003 1.1 christos return SHF_ALLOC;
1004 1.8 christos if (len == 9 && startswith (str, "execinstr"))
1005 1.1 christos return SHF_EXECINSTR;
1006 1.8 christos if (len == 7 && startswith (str, "exclude"))
1007 1.1 christos return SHF_EXCLUDE;
1008 1.8 christos if (len == 3 && startswith (str, "tls"))
1009 1.1 christos return SHF_TLS;
1010 1.1 christos
1011 1.8 christos ret = obj_elf_section_type (str, len, false);
1012 1.1 christos if (ret != 0)
1013 1.1 christos *type = ret;
1014 1.1 christos else
1015 1.1 christos as_warn (_("unrecognized section attribute"));
1016 1.1 christos
1017 1.1 christos return 0;
1018 1.1 christos }
1019 1.9 christos #endif
1020 1.1 christos
1021 1.1 christos /* Get name of section. */
1022 1.5 christos const char *
1023 1.1 christos obj_elf_section_name (void)
1024 1.1 christos {
1025 1.1 christos char *name;
1026 1.1 christos
1027 1.1 christos SKIP_WHITESPACE ();
1028 1.1 christos if (*input_line_pointer == '"')
1029 1.1 christos {
1030 1.1 christos int dummy;
1031 1.1 christos
1032 1.1 christos name = demand_copy_C_string (&dummy);
1033 1.1 christos if (name == NULL)
1034 1.1 christos {
1035 1.1 christos ignore_rest_of_line ();
1036 1.1 christos return NULL;
1037 1.1 christos }
1038 1.1 christos }
1039 1.1 christos else
1040 1.1 christos {
1041 1.1 christos char *end = input_line_pointer;
1042 1.1 christos
1043 1.1 christos while (0 == strchr ("\n\t,; ", *end))
1044 1.1 christos end++;
1045 1.1 christos if (end == input_line_pointer)
1046 1.1 christos {
1047 1.1 christos as_bad (_("missing name"));
1048 1.1 christos ignore_rest_of_line ();
1049 1.1 christos return NULL;
1050 1.1 christos }
1051 1.1 christos
1052 1.8 christos obstack_grow0 (¬es, input_line_pointer, end - input_line_pointer);
1053 1.8 christos name = obstack_base (¬es);
1054 1.3 christos
1055 1.3 christos while (flag_sectname_subst)
1056 1.3 christos {
1057 1.3 christos char *subst = strchr (name, '%');
1058 1.3 christos if (subst && subst[1] == 'S')
1059 1.3 christos {
1060 1.8 christos size_t head = subst - name;
1061 1.8 christos size_t tail = strlen (subst + 2) + 1;
1062 1.8 christos size_t slen = strlen (now_seg->name);
1063 1.8 christos
1064 1.8 christos if (slen > 2)
1065 1.8 christos {
1066 1.8 christos obstack_blank (¬es, slen - 2);
1067 1.8 christos name = obstack_base (¬es);
1068 1.8 christos }
1069 1.8 christos memmove (name + head + slen, name + head + 2, tail);
1070 1.8 christos memcpy (name + head, now_seg->name, slen);
1071 1.3 christos }
1072 1.3 christos else
1073 1.3 christos break;
1074 1.3 christos }
1075 1.3 christos
1076 1.8 christos obstack_finish (¬es);
1077 1.8 christos
1078 1.1 christos #ifdef tc_canonicalize_section_name
1079 1.1 christos name = tc_canonicalize_section_name (name);
1080 1.1 christos #endif
1081 1.1 christos input_line_pointer = end;
1082 1.1 christos }
1083 1.1 christos SKIP_WHITESPACE ();
1084 1.1 christos return name;
1085 1.1 christos }
1086 1.1 christos
1087 1.8 christos static void
1088 1.8 christos obj_elf_attach_to_group (int dummy ATTRIBUTE_UNUSED)
1089 1.8 christos {
1090 1.8 christos const char * gname = obj_elf_section_name ();
1091 1.8 christos
1092 1.8 christos if (gname == NULL)
1093 1.8 christos {
1094 1.8 christos as_warn (_("group name not parseable"));
1095 1.8 christos return;
1096 1.8 christos }
1097 1.8 christos
1098 1.8 christos if (elf_group_name (now_seg))
1099 1.8 christos {
1100 1.9 christos if (strcmp (elf_group_name (now_seg), gname) != 0)
1101 1.9 christos as_warn (_("section %s already has a group (%s)"),
1102 1.9 christos bfd_section_name (now_seg), elf_group_name (now_seg));
1103 1.8 christos return;
1104 1.8 christos }
1105 1.8 christos
1106 1.8 christos elf_group_name (now_seg) = gname;
1107 1.8 christos elf_section_flags (now_seg) |= SHF_GROUP;
1108 1.8 christos }
1109 1.8 christos
1110 1.1 christos void
1111 1.1 christos obj_elf_section (int push)
1112 1.1 christos {
1113 1.8 christos const char *name;
1114 1.5 christos char *beg;
1115 1.1 christos int type, dummy;
1116 1.1 christos bfd_vma attr;
1117 1.7 christos bfd_vma gnu_attr;
1118 1.1 christos int entsize;
1119 1.9 christos bool linkonce;
1120 1.9 christos subsegT new_subsection = 0;
1121 1.8 christos struct elf_section_match match;
1122 1.8 christos unsigned long linked_to_section_index = -1UL;
1123 1.1 christos
1124 1.1 christos if (flag_mri)
1125 1.1 christos {
1126 1.1 christos char mri_type;
1127 1.1 christos
1128 1.1 christos #ifdef md_flush_pending_output
1129 1.1 christos md_flush_pending_output ();
1130 1.1 christos #endif
1131 1.1 christos
1132 1.8 christos obj_elf_section_change_hook ();
1133 1.1 christos
1134 1.1 christos s_mri_sect (&mri_type);
1135 1.1 christos
1136 1.1 christos #ifdef md_elf_section_change_hook
1137 1.1 christos md_elf_section_change_hook ();
1138 1.1 christos #endif
1139 1.1 christos
1140 1.1 christos return;
1141 1.1 christos }
1142 1.1 christos
1143 1.1 christos name = obj_elf_section_name ();
1144 1.1 christos if (name == NULL)
1145 1.1 christos return;
1146 1.7 christos
1147 1.8 christos memset (&match, 0, sizeof (match));
1148 1.8 christos
1149 1.7 christos symbolS * sym;
1150 1.7 christos if ((sym = symbol_find (name)) != NULL
1151 1.7 christos && ! symbol_section_p (sym)
1152 1.7 christos && S_IS_DEFINED (sym)
1153 1.7 christos && ! S_IS_VOLATILE (sym)
1154 1.7 christos && ! S_CAN_BE_REDEFINED (sym))
1155 1.7 christos {
1156 1.7 christos as_bad (_("section name '%s' already defined as another symbol"), name);
1157 1.7 christos ignore_rest_of_line ();
1158 1.7 christos return;
1159 1.7 christos }
1160 1.1 christos type = SHT_NULL;
1161 1.1 christos attr = 0;
1162 1.7 christos gnu_attr = 0;
1163 1.1 christos entsize = 0;
1164 1.1 christos linkonce = 0;
1165 1.1 christos
1166 1.1 christos if (*input_line_pointer == ',')
1167 1.1 christos {
1168 1.1 christos /* Skip the comma. */
1169 1.1 christos ++input_line_pointer;
1170 1.1 christos SKIP_WHITESPACE ();
1171 1.1 christos
1172 1.1 christos if (push && ISDIGIT (*input_line_pointer))
1173 1.1 christos {
1174 1.1 christos /* .pushsection has an optional subsection. */
1175 1.1 christos new_subsection = (subsegT) get_absolute_expression ();
1176 1.1 christos
1177 1.1 christos SKIP_WHITESPACE ();
1178 1.1 christos
1179 1.1 christos /* Stop if we don't see a comma. */
1180 1.1 christos if (*input_line_pointer != ',')
1181 1.1 christos goto done;
1182 1.1 christos
1183 1.1 christos /* Skip the comma. */
1184 1.1 christos ++input_line_pointer;
1185 1.1 christos SKIP_WHITESPACE ();
1186 1.1 christos }
1187 1.1 christos
1188 1.1 christos if (*input_line_pointer == '"')
1189 1.1 christos {
1190 1.8 christos bool is_clone;
1191 1.9 christos int inherit;
1192 1.1 christos
1193 1.1 christos beg = demand_copy_C_string (&dummy);
1194 1.1 christos if (beg == NULL)
1195 1.1 christos {
1196 1.1 christos ignore_rest_of_line ();
1197 1.1 christos return;
1198 1.1 christos }
1199 1.9 christos attr = obj_elf_parse_section_letters (beg, strlen (beg), &is_clone,
1200 1.9 christos &inherit, &gnu_attr);
1201 1.9 christos
1202 1.9 christos if (inherit > 0)
1203 1.9 christos attr |= elf_section_flags (now_seg);
1204 1.9 christos else if (inherit < 0)
1205 1.9 christos attr = elf_section_flags (now_seg) & ~attr;
1206 1.9 christos if (inherit)
1207 1.9 christos type = elf_section_type (now_seg);
1208 1.1 christos
1209 1.1 christos SKIP_WHITESPACE ();
1210 1.1 christos if (*input_line_pointer == ',')
1211 1.1 christos {
1212 1.1 christos char c;
1213 1.1 christos char *save = input_line_pointer;
1214 1.1 christos
1215 1.1 christos ++input_line_pointer;
1216 1.1 christos SKIP_WHITESPACE ();
1217 1.1 christos c = *input_line_pointer;
1218 1.1 christos if (c == '"')
1219 1.1 christos {
1220 1.1 christos beg = demand_copy_C_string (&dummy);
1221 1.1 christos if (beg == NULL)
1222 1.1 christos {
1223 1.1 christos ignore_rest_of_line ();
1224 1.1 christos return;
1225 1.1 christos }
1226 1.8 christos type = obj_elf_section_type (beg, strlen (beg), true);
1227 1.1 christos }
1228 1.1 christos else if (c == '@' || c == '%')
1229 1.1 christos {
1230 1.3 christos ++input_line_pointer;
1231 1.5 christos
1232 1.5 christos if (ISDIGIT (* input_line_pointer))
1233 1.7 christos type = strtoul (input_line_pointer, &input_line_pointer, 0);
1234 1.5 christos else
1235 1.5 christos {
1236 1.5 christos c = get_symbol_name (& beg);
1237 1.5 christos (void) restore_line_pointer (c);
1238 1.7 christos type = obj_elf_section_type (beg,
1239 1.7 christos input_line_pointer - beg,
1240 1.8 christos true);
1241 1.5 christos }
1242 1.1 christos }
1243 1.1 christos else
1244 1.1 christos input_line_pointer = save;
1245 1.1 christos }
1246 1.1 christos
1247 1.1 christos SKIP_WHITESPACE ();
1248 1.1 christos if ((attr & SHF_MERGE) != 0 && *input_line_pointer == ',')
1249 1.1 christos {
1250 1.1 christos ++input_line_pointer;
1251 1.1 christos SKIP_WHITESPACE ();
1252 1.9 christos if (inherit && *input_line_pointer == ','
1253 1.9 christos && (bfd_section_flags (now_seg) & SEC_MERGE) != 0)
1254 1.9 christos goto fetch_entsize;
1255 1.1 christos entsize = get_absolute_expression ();
1256 1.1 christos SKIP_WHITESPACE ();
1257 1.1 christos if (entsize < 0)
1258 1.1 christos {
1259 1.1 christos as_warn (_("invalid merge entity size"));
1260 1.1 christos attr &= ~SHF_MERGE;
1261 1.1 christos entsize = 0;
1262 1.1 christos }
1263 1.1 christos }
1264 1.9 christos else if ((attr & SHF_MERGE) != 0 && inherit
1265 1.9 christos && (bfd_section_flags (now_seg) & SEC_MERGE) != 0)
1266 1.9 christos {
1267 1.9 christos fetch_entsize:
1268 1.9 christos entsize = now_seg->entsize;
1269 1.9 christos }
1270 1.1 christos else if ((attr & SHF_MERGE) != 0)
1271 1.1 christos {
1272 1.1 christos as_warn (_("entity size for SHF_MERGE not specified"));
1273 1.1 christos attr &= ~SHF_MERGE;
1274 1.1 christos }
1275 1.1 christos
1276 1.8 christos if ((attr & SHF_LINK_ORDER) != 0 && *input_line_pointer == ',')
1277 1.8 christos {
1278 1.8 christos ++input_line_pointer;
1279 1.8 christos SKIP_WHITESPACE ();
1280 1.8 christos /* Check for a numeric section index, rather than a symbol name. */
1281 1.8 christos if (ISDIGIT (* input_line_pointer))
1282 1.8 christos {
1283 1.8 christos linked_to_section_index = strtoul (input_line_pointer, & input_line_pointer, 0);
1284 1.8 christos }
1285 1.9 christos else if (inherit && *input_line_pointer == ','
1286 1.9 christos && (elf_section_flags (now_seg) & SHF_LINK_ORDER) != 0)
1287 1.9 christos goto fetch_linked_to;
1288 1.8 christos else
1289 1.8 christos {
1290 1.8 christos char c;
1291 1.8 christos unsigned int length;
1292 1.8 christos
1293 1.8 christos c = get_symbol_name (& beg);
1294 1.8 christos (void) restore_line_pointer (c);
1295 1.8 christos length = input_line_pointer - beg;
1296 1.8 christos if (length)
1297 1.8 christos match.linked_to_symbol_name = xmemdup0 (beg, length);
1298 1.8 christos }
1299 1.8 christos }
1300 1.9 christos else if ((attr & SHF_LINK_ORDER) != 0 && inherit
1301 1.9 christos && (elf_section_flags (now_seg) & SHF_LINK_ORDER) != 0)
1302 1.9 christos {
1303 1.9 christos fetch_linked_to:
1304 1.9 christos if (now_seg->map_head.linked_to_symbol_name)
1305 1.9 christos match.linked_to_symbol_name =
1306 1.9 christos now_seg->map_head.linked_to_symbol_name;
1307 1.9 christos else
1308 1.9 christos linked_to_section_index =
1309 1.9 christos elf_section_data (now_seg)->this_hdr.sh_link;
1310 1.9 christos }
1311 1.8 christos
1312 1.1 christos if ((attr & SHF_GROUP) != 0 && is_clone)
1313 1.1 christos {
1314 1.1 christos as_warn (_("? section flag ignored with G present"));
1315 1.8 christos is_clone = false;
1316 1.1 christos }
1317 1.8 christos
1318 1.1 christos if ((attr & SHF_GROUP) != 0 && *input_line_pointer == ',')
1319 1.1 christos {
1320 1.1 christos ++input_line_pointer;
1321 1.9 christos SKIP_WHITESPACE ();
1322 1.9 christos if (inherit && *input_line_pointer == ','
1323 1.9 christos && (elf_section_flags (now_seg) & SHF_GROUP) != 0)
1324 1.9 christos goto fetch_group;
1325 1.8 christos match.group_name = obj_elf_section_name ();
1326 1.8 christos if (match.group_name == NULL)
1327 1.1 christos attr &= ~SHF_GROUP;
1328 1.1 christos else if (*input_line_pointer == ',')
1329 1.1 christos {
1330 1.1 christos ++input_line_pointer;
1331 1.1 christos SKIP_WHITESPACE ();
1332 1.8 christos if (startswith (input_line_pointer, "comdat"))
1333 1.1 christos {
1334 1.1 christos input_line_pointer += 6;
1335 1.1 christos linkonce = 1;
1336 1.1 christos }
1337 1.1 christos }
1338 1.8 christos else if (startswith (name, ".gnu.linkonce"))
1339 1.1 christos linkonce = 1;
1340 1.1 christos }
1341 1.9 christos else if ((attr & SHF_GROUP) != 0 && inherit
1342 1.9 christos && (elf_section_flags (now_seg) & SHF_GROUP) != 0)
1343 1.9 christos {
1344 1.9 christos fetch_group:
1345 1.9 christos match.group_name = elf_group_name (now_seg);
1346 1.9 christos linkonce =
1347 1.9 christos (bfd_section_flags (now_seg) & SEC_LINK_ONCE) != 0;
1348 1.9 christos }
1349 1.1 christos else if ((attr & SHF_GROUP) != 0)
1350 1.1 christos {
1351 1.1 christos as_warn (_("group name for SHF_GROUP not specified"));
1352 1.1 christos attr &= ~SHF_GROUP;
1353 1.1 christos }
1354 1.1 christos
1355 1.1 christos if (is_clone)
1356 1.1 christos {
1357 1.1 christos const char *now_group = elf_group_name (now_seg);
1358 1.1 christos if (now_group != NULL)
1359 1.1 christos {
1360 1.8 christos match.group_name = now_group;
1361 1.1 christos linkonce = (now_seg->flags & SEC_LINK_ONCE) != 0;
1362 1.1 christos }
1363 1.1 christos }
1364 1.6 christos
1365 1.7 christos if ((gnu_attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',')
1366 1.6 christos {
1367 1.8 christos char *save = input_line_pointer;
1368 1.6 christos ++input_line_pointer;
1369 1.6 christos SKIP_WHITESPACE ();
1370 1.6 christos if (ISDIGIT (* input_line_pointer))
1371 1.6 christos {
1372 1.6 christos char *t = input_line_pointer;
1373 1.8 christos match.sh_info = strtoul (input_line_pointer,
1374 1.8 christos &input_line_pointer, 0);
1375 1.8 christos if (match.sh_info == (unsigned int) -1)
1376 1.6 christos {
1377 1.6 christos as_warn (_("unsupported mbind section info: %s"), t);
1378 1.8 christos match.sh_info = 0;
1379 1.6 christos }
1380 1.6 christos }
1381 1.8 christos else
1382 1.8 christos input_line_pointer = save;
1383 1.8 christos }
1384 1.8 christos
1385 1.8 christos if ((gnu_attr & SHF_GNU_RETAIN) != 0)
1386 1.8 christos match.sh_flags |= SHF_GNU_RETAIN;
1387 1.8 christos
1388 1.8 christos if (*input_line_pointer == ',')
1389 1.8 christos {
1390 1.8 christos char *save = input_line_pointer;
1391 1.8 christos
1392 1.8 christos ++input_line_pointer;
1393 1.8 christos SKIP_WHITESPACE ();
1394 1.8 christos if (startswith (input_line_pointer, "unique"))
1395 1.8 christos {
1396 1.8 christos input_line_pointer += 6;
1397 1.8 christos SKIP_WHITESPACE ();
1398 1.8 christos if (*input_line_pointer == ',')
1399 1.8 christos {
1400 1.8 christos ++input_line_pointer;
1401 1.8 christos SKIP_WHITESPACE ();
1402 1.8 christos if (ISDIGIT (* input_line_pointer))
1403 1.8 christos {
1404 1.8 christos bfd_vma id;
1405 1.8 christos bool overflow;
1406 1.8 christos char *t = input_line_pointer;
1407 1.8 christos if (sizeof (bfd_vma) <= sizeof (unsigned long))
1408 1.8 christos {
1409 1.8 christos errno = 0;
1410 1.8 christos id = strtoul (input_line_pointer,
1411 1.8 christos &input_line_pointer, 0);
1412 1.8 christos overflow = (id == (unsigned long) -1
1413 1.8 christos && errno == ERANGE);
1414 1.8 christos }
1415 1.8 christos else
1416 1.8 christos {
1417 1.8 christos id = bfd_scan_vma
1418 1.8 christos (input_line_pointer,
1419 1.8 christos (const char **) &input_line_pointer, 0);
1420 1.8 christos overflow = id == ~(bfd_vma) 0;
1421 1.8 christos }
1422 1.8 christos if (overflow || id > (unsigned int) -1)
1423 1.8 christos {
1424 1.8 christos char *linefeed, saved_char = 0;
1425 1.8 christos if ((linefeed = strchr (t, '\n')) != NULL)
1426 1.8 christos {
1427 1.8 christos saved_char = *linefeed;
1428 1.8 christos *linefeed = '\0';
1429 1.8 christos }
1430 1.8 christos as_bad (_("unsupported section id: %s"), t);
1431 1.8 christos if (saved_char)
1432 1.8 christos *linefeed = saved_char;
1433 1.8 christos }
1434 1.8 christos else
1435 1.8 christos {
1436 1.8 christos match.section_id = id;
1437 1.8 christos match.flags |= SEC_ASSEMBLER_SECTION_ID;
1438 1.8 christos }
1439 1.8 christos }
1440 1.8 christos }
1441 1.8 christos }
1442 1.8 christos else
1443 1.8 christos input_line_pointer = save;
1444 1.6 christos }
1445 1.1 christos }
1446 1.9 christos #ifdef TC_SPARC
1447 1.1 christos else
1448 1.1 christos {
1449 1.1 christos do
1450 1.1 christos {
1451 1.1 christos char c;
1452 1.1 christos
1453 1.1 christos SKIP_WHITESPACE ();
1454 1.1 christos if (*input_line_pointer != '#')
1455 1.1 christos {
1456 1.1 christos as_bad (_("character following name is not '#'"));
1457 1.1 christos ignore_rest_of_line ();
1458 1.1 christos return;
1459 1.1 christos }
1460 1.3 christos ++input_line_pointer;
1461 1.3 christos c = get_symbol_name (& beg);
1462 1.3 christos (void) restore_line_pointer (c);
1463 1.1 christos
1464 1.7 christos attr |= obj_elf_section_word (beg, input_line_pointer - beg,
1465 1.7 christos &type);
1466 1.1 christos
1467 1.1 christos SKIP_WHITESPACE ();
1468 1.1 christos }
1469 1.1 christos while (*input_line_pointer++ == ',');
1470 1.1 christos --input_line_pointer;
1471 1.1 christos }
1472 1.9 christos #endif
1473 1.1 christos }
1474 1.1 christos
1475 1.8 christos done:
1476 1.1 christos demand_empty_rest_of_line ();
1477 1.1 christos
1478 1.8 christos if ((gnu_attr & (SHF_GNU_MBIND | SHF_GNU_RETAIN)) != 0)
1479 1.7 christos {
1480 1.8 christos const struct elf_backend_data *bed;
1481 1.8 christos bool mbind_p = (gnu_attr & SHF_GNU_MBIND) != 0;
1482 1.7 christos
1483 1.8 christos if (mbind_p && (attr & SHF_ALLOC) == 0)
1484 1.7 christos as_bad (_("SHF_ALLOC isn't set for GNU_MBIND section: %s"), name);
1485 1.7 christos
1486 1.8 christos bed = get_elf_backend_data (stdoutput);
1487 1.8 christos
1488 1.8 christos if (bed->elf_osabi != ELFOSABI_GNU
1489 1.8 christos && bed->elf_osabi != ELFOSABI_FREEBSD
1490 1.8 christos && bed->elf_osabi != ELFOSABI_NONE)
1491 1.8 christos as_bad (_("%s section is supported only by GNU and FreeBSD targets"),
1492 1.8 christos mbind_p ? "GNU_MBIND" : "GNU_RETAIN");
1493 1.8 christos else
1494 1.8 christos {
1495 1.8 christos if (mbind_p)
1496 1.8 christos elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_mbind;
1497 1.8 christos if ((gnu_attr & SHF_GNU_RETAIN) != 0)
1498 1.8 christos elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_retain;
1499 1.8 christos
1500 1.8 christos attr |= gnu_attr;
1501 1.8 christos }
1502 1.8 christos }
1503 1.8 christos
1504 1.9 christos change_section (name, type, attr, entsize, &match, linkonce, push,
1505 1.9 christos new_subsection);
1506 1.8 christos
1507 1.8 christos if (linked_to_section_index != -1UL)
1508 1.8 christos {
1509 1.8 christos elf_section_flags (now_seg) |= SHF_LINK_ORDER;
1510 1.8 christos elf_section_data (now_seg)->this_hdr.sh_link = linked_to_section_index;
1511 1.8 christos /* FIXME: Should we perform some sanity checking on the section index ? */
1512 1.7 christos }
1513 1.1 christos }
1514 1.1 christos
1515 1.8 christos /* Change to the .bss section. */
1516 1.8 christos
1517 1.8 christos void
1518 1.8 christos obj_elf_bss (int i ATTRIBUTE_UNUSED)
1519 1.8 christos {
1520 1.8 christos int temp;
1521 1.8 christos
1522 1.8 christos #ifdef md_flush_pending_output
1523 1.8 christos md_flush_pending_output ();
1524 1.8 christos #endif
1525 1.8 christos
1526 1.8 christos obj_elf_section_change_hook ();
1527 1.8 christos
1528 1.8 christos temp = get_absolute_expression ();
1529 1.8 christos subseg_set (bss_section, (subsegT) temp);
1530 1.8 christos demand_empty_rest_of_line ();
1531 1.8 christos
1532 1.8 christos #ifdef md_elf_section_change_hook
1533 1.8 christos md_elf_section_change_hook ();
1534 1.8 christos #endif
1535 1.8 christos }
1536 1.8 christos
1537 1.1 christos /* Change to the .data section. */
1538 1.1 christos
1539 1.1 christos void
1540 1.1 christos obj_elf_data (int i)
1541 1.1 christos {
1542 1.1 christos #ifdef md_flush_pending_output
1543 1.1 christos md_flush_pending_output ();
1544 1.1 christos #endif
1545 1.1 christos
1546 1.8 christos obj_elf_section_change_hook ();
1547 1.8 christos
1548 1.1 christos s_data (i);
1549 1.1 christos
1550 1.1 christos #ifdef md_elf_section_change_hook
1551 1.1 christos md_elf_section_change_hook ();
1552 1.1 christos #endif
1553 1.1 christos }
1554 1.1 christos
1555 1.1 christos /* Change to the .text section. */
1556 1.1 christos
1557 1.1 christos void
1558 1.1 christos obj_elf_text (int i)
1559 1.1 christos {
1560 1.1 christos #ifdef md_flush_pending_output
1561 1.1 christos md_flush_pending_output ();
1562 1.1 christos #endif
1563 1.1 christos
1564 1.8 christos obj_elf_section_change_hook ();
1565 1.8 christos
1566 1.1 christos s_text (i);
1567 1.1 christos
1568 1.1 christos #ifdef md_elf_section_change_hook
1569 1.1 christos md_elf_section_change_hook ();
1570 1.1 christos #endif
1571 1.1 christos }
1572 1.1 christos
1573 1.1 christos /* Change to the *ABS* section. */
1574 1.1 christos
1575 1.1 christos void
1576 1.1 christos obj_elf_struct (int i)
1577 1.1 christos {
1578 1.1 christos #ifdef md_flush_pending_output
1579 1.1 christos md_flush_pending_output ();
1580 1.1 christos #endif
1581 1.1 christos
1582 1.8 christos obj_elf_section_change_hook ();
1583 1.8 christos
1584 1.1 christos s_struct (i);
1585 1.1 christos
1586 1.1 christos #ifdef md_elf_section_change_hook
1587 1.1 christos md_elf_section_change_hook ();
1588 1.1 christos #endif
1589 1.1 christos }
1590 1.1 christos
1591 1.1 christos static void
1592 1.1 christos obj_elf_subsection (int ignore ATTRIBUTE_UNUSED)
1593 1.1 christos {
1594 1.1 christos int temp;
1595 1.1 christos
1596 1.1 christos #ifdef md_flush_pending_output
1597 1.1 christos md_flush_pending_output ();
1598 1.1 christos #endif
1599 1.1 christos
1600 1.8 christos obj_elf_section_change_hook ();
1601 1.1 christos
1602 1.1 christos temp = get_absolute_expression ();
1603 1.1 christos subseg_set (now_seg, (subsegT) temp);
1604 1.1 christos demand_empty_rest_of_line ();
1605 1.1 christos
1606 1.1 christos #ifdef md_elf_section_change_hook
1607 1.1 christos md_elf_section_change_hook ();
1608 1.1 christos #endif
1609 1.1 christos }
1610 1.1 christos
1611 1.1 christos /* This can be called from the processor backends if they change
1612 1.1 christos sections. */
1613 1.1 christos
1614 1.1 christos void
1615 1.1 christos obj_elf_section_change_hook (void)
1616 1.1 christos {
1617 1.1 christos previous_section = now_seg;
1618 1.1 christos previous_subsection = now_subseg;
1619 1.1 christos }
1620 1.1 christos
1621 1.1 christos void
1622 1.1 christos obj_elf_previous (int ignore ATTRIBUTE_UNUSED)
1623 1.1 christos {
1624 1.1 christos segT new_section;
1625 1.1 christos int new_subsection;
1626 1.1 christos
1627 1.1 christos if (previous_section == 0)
1628 1.1 christos {
1629 1.1 christos as_warn (_(".previous without corresponding .section; ignored"));
1630 1.1 christos return;
1631 1.1 christos }
1632 1.1 christos
1633 1.1 christos #ifdef md_flush_pending_output
1634 1.1 christos md_flush_pending_output ();
1635 1.1 christos #endif
1636 1.1 christos
1637 1.1 christos new_section = previous_section;
1638 1.1 christos new_subsection = previous_subsection;
1639 1.8 christos obj_elf_section_change_hook ();
1640 1.8 christos
1641 1.1 christos subseg_set (new_section, new_subsection);
1642 1.1 christos
1643 1.1 christos #ifdef md_elf_section_change_hook
1644 1.1 christos md_elf_section_change_hook ();
1645 1.1 christos #endif
1646 1.1 christos }
1647 1.1 christos
1648 1.1 christos static void
1649 1.1 christos obj_elf_popsection (int xxx ATTRIBUTE_UNUSED)
1650 1.1 christos {
1651 1.1 christos struct section_stack *top = section_stack;
1652 1.1 christos
1653 1.1 christos if (top == NULL)
1654 1.1 christos {
1655 1.1 christos as_warn (_(".popsection without corresponding .pushsection; ignored"));
1656 1.1 christos return;
1657 1.1 christos }
1658 1.1 christos
1659 1.1 christos #ifdef md_flush_pending_output
1660 1.1 christos md_flush_pending_output ();
1661 1.1 christos #endif
1662 1.1 christos
1663 1.1 christos section_stack = top->next;
1664 1.1 christos previous_section = top->prev_seg;
1665 1.1 christos previous_subsection = top->prev_subseg;
1666 1.1 christos subseg_set (top->seg, top->subseg);
1667 1.1 christos free (top);
1668 1.1 christos
1669 1.1 christos #ifdef md_elf_section_change_hook
1670 1.1 christos md_elf_section_change_hook ();
1671 1.1 christos #endif
1672 1.1 christos }
1673 1.1 christos
1674 1.1 christos static void
1675 1.1 christos obj_elf_line (int ignore ATTRIBUTE_UNUSED)
1676 1.1 christos {
1677 1.1 christos /* Assume delimiter is part of expression. BSD4.2 as fails with
1678 1.1 christos delightful bug, so we are not being incompatible here. */
1679 1.1 christos new_logical_line (NULL, get_absolute_expression ());
1680 1.1 christos demand_empty_rest_of_line ();
1681 1.1 christos }
1682 1.1 christos
1683 1.8 christos static struct elf_versioned_name_list *
1684 1.8 christos obj_elf_find_and_add_versioned_name (const char *version_name,
1685 1.8 christos const char *sym_name,
1686 1.8 christos const char *ver,
1687 1.8 christos struct elf_obj_sy *sy_obj)
1688 1.8 christos {
1689 1.8 christos struct elf_versioned_name_list *versioned_name;
1690 1.8 christos const char *p;
1691 1.8 christos
1692 1.8 christos for (p = ver + 1; *p == ELF_VER_CHR; p++)
1693 1.8 christos ;
1694 1.8 christos
1695 1.8 christos /* NB: Since some tests in ld/testsuite/ld-elfvers have no version
1696 1.8 christos names, we have to disable this. */
1697 1.8 christos if (0 && *p == '\0')
1698 1.8 christos {
1699 1.8 christos as_bad (_("missing version name in `%s' for symbol `%s'"),
1700 1.8 christos version_name, sym_name);
1701 1.8 christos return NULL;
1702 1.8 christos }
1703 1.8 christos
1704 1.8 christos versioned_name = sy_obj->versioned_name;
1705 1.8 christos
1706 1.8 christos switch (p - ver)
1707 1.8 christos {
1708 1.8 christos case 1:
1709 1.8 christos case 2:
1710 1.8 christos break;
1711 1.8 christos case 3:
1712 1.8 christos if (sy_obj->rename)
1713 1.8 christos {
1714 1.8 christos if (strcmp (versioned_name->name, version_name) == 0)
1715 1.8 christos return versioned_name;
1716 1.8 christos else
1717 1.8 christos {
1718 1.8 christos as_bad (_("only one version name with `@@@' is allowed "
1719 1.8 christos "for symbol `%s'"), sym_name);
1720 1.8 christos return NULL;
1721 1.8 christos }
1722 1.8 christos }
1723 1.8 christos sy_obj->rename = true;
1724 1.8 christos break;
1725 1.8 christos default:
1726 1.8 christos as_bad (_("invalid version name '%s' for symbol `%s'"),
1727 1.8 christos version_name, sym_name);
1728 1.8 christos return NULL;
1729 1.8 christos }
1730 1.8 christos
1731 1.8 christos for (;
1732 1.8 christos versioned_name != NULL;
1733 1.8 christos versioned_name = versioned_name->next)
1734 1.8 christos if (strcmp (versioned_name->name, version_name) == 0)
1735 1.8 christos return versioned_name;
1736 1.8 christos
1737 1.8 christos /* Add this versioned name to the head of the list, */
1738 1.8 christos versioned_name = (struct elf_versioned_name_list *)
1739 1.8 christos xmalloc (sizeof (*versioned_name));
1740 1.8 christos versioned_name->name = xstrdup (version_name);
1741 1.8 christos versioned_name->next = sy_obj->versioned_name;
1742 1.8 christos sy_obj->versioned_name = versioned_name;
1743 1.8 christos
1744 1.8 christos return versioned_name;
1745 1.8 christos }
1746 1.8 christos
1747 1.1 christos /* This handles the .symver pseudo-op, which is used to specify a
1748 1.1 christos symbol version. The syntax is ``.symver NAME,SYMVERNAME''.
1749 1.1 christos SYMVERNAME may contain ELF_VER_CHR ('@') characters. This
1750 1.1 christos pseudo-op causes the assembler to emit a symbol named SYMVERNAME
1751 1.1 christos with the same value as the symbol NAME. */
1752 1.1 christos
1753 1.1 christos static void
1754 1.1 christos obj_elf_symver (int ignore ATTRIBUTE_UNUSED)
1755 1.1 christos {
1756 1.1 christos char *name;
1757 1.8 christos const char *sym_name;
1758 1.1 christos char c;
1759 1.1 christos char old_lexat;
1760 1.1 christos symbolS *sym;
1761 1.8 christos struct elf_obj_sy *sy_obj;
1762 1.8 christos char *p;
1763 1.1 christos
1764 1.1 christos sym = get_sym_from_input_line_and_check ();
1765 1.1 christos
1766 1.1 christos if (*input_line_pointer != ',')
1767 1.1 christos {
1768 1.1 christos as_bad (_("expected comma after name in .symver"));
1769 1.1 christos ignore_rest_of_line ();
1770 1.1 christos return;
1771 1.1 christos }
1772 1.1 christos
1773 1.1 christos ++input_line_pointer;
1774 1.1 christos SKIP_WHITESPACE ();
1775 1.1 christos
1776 1.1 christos /* Temporarily include '@' in symbol names. */
1777 1.1 christos old_lexat = lex_type[(unsigned char) '@'];
1778 1.1 christos lex_type[(unsigned char) '@'] |= LEX_NAME;
1779 1.3 christos c = get_symbol_name (& name);
1780 1.1 christos lex_type[(unsigned char) '@'] = old_lexat;
1781 1.8 christos sym_name = S_GET_NAME (sym);
1782 1.1 christos
1783 1.6 christos if (S_IS_COMMON (sym))
1784 1.6 christos {
1785 1.6 christos as_bad (_("`%s' can't be versioned to common symbol '%s'"),
1786 1.8 christos name, sym_name);
1787 1.6 christos ignore_rest_of_line ();
1788 1.6 christos return;
1789 1.6 christos }
1790 1.6 christos
1791 1.8 christos p = strchr (name, ELF_VER_CHR);
1792 1.8 christos if (p == NULL)
1793 1.1 christos {
1794 1.8 christos as_bad (_("missing version name in `%s' for symbol `%s'"),
1795 1.8 christos name, sym_name);
1796 1.8 christos ignore_rest_of_line ();
1797 1.8 christos return;
1798 1.8 christos }
1799 1.8 christos
1800 1.8 christos sy_obj = symbol_get_obj (sym);
1801 1.8 christos if (obj_elf_find_and_add_versioned_name (name, sym_name,
1802 1.8 christos p, sy_obj) == NULL)
1803 1.8 christos {
1804 1.8 christos sy_obj->bad_version = true;
1805 1.8 christos ignore_rest_of_line ();
1806 1.8 christos return;
1807 1.8 christos }
1808 1.8 christos
1809 1.8 christos (void) restore_line_pointer (c);
1810 1.1 christos
1811 1.8 christos if (*input_line_pointer == ',')
1812 1.8 christos {
1813 1.8 christos char *save = input_line_pointer;
1814 1.1 christos
1815 1.8 christos ++input_line_pointer;
1816 1.8 christos SKIP_WHITESPACE ();
1817 1.8 christos if (startswith (input_line_pointer, "local"))
1818 1.1 christos {
1819 1.8 christos input_line_pointer += 5;
1820 1.8 christos sy_obj->visibility = visibility_local;
1821 1.8 christos }
1822 1.8 christos else if (startswith (input_line_pointer, "hidden"))
1823 1.8 christos {
1824 1.8 christos input_line_pointer += 6;
1825 1.8 christos sy_obj->visibility = visibility_hidden;
1826 1.1 christos }
1827 1.8 christos else if (startswith (input_line_pointer, "remove"))
1828 1.1 christos {
1829 1.8 christos input_line_pointer += 6;
1830 1.8 christos sy_obj->visibility = visibility_remove;
1831 1.1 christos }
1832 1.8 christos else
1833 1.8 christos input_line_pointer = save;
1834 1.1 christos }
1835 1.1 christos
1836 1.1 christos demand_empty_rest_of_line ();
1837 1.1 christos }
1838 1.1 christos
1839 1.1 christos /* This handles the .vtable_inherit pseudo-op, which is used to indicate
1840 1.1 christos to the linker the hierarchy in which a particular table resides. The
1841 1.1 christos syntax is ".vtable_inherit CHILDNAME, PARENTNAME". */
1842 1.1 christos
1843 1.1 christos struct fix *
1844 1.6 christos obj_elf_get_vtable_inherit (void)
1845 1.1 christos {
1846 1.1 christos char *cname, *pname;
1847 1.1 christos symbolS *csym, *psym;
1848 1.1 christos char c, bad = 0;
1849 1.1 christos
1850 1.1 christos if (*input_line_pointer == '#')
1851 1.1 christos ++input_line_pointer;
1852 1.1 christos
1853 1.3 christos c = get_symbol_name (& cname);
1854 1.1 christos csym = symbol_find (cname);
1855 1.1 christos
1856 1.1 christos /* GCFIXME: should check that we don't have two .vtable_inherits for
1857 1.1 christos the same child symbol. Also, we can currently only do this if the
1858 1.1 christos child symbol is already exists and is placed in a fragment. */
1859 1.1 christos
1860 1.1 christos if (csym == NULL || symbol_get_frag (csym) == NULL)
1861 1.1 christos {
1862 1.1 christos as_bad (_("expected `%s' to have already been set for .vtable_inherit"),
1863 1.1 christos cname);
1864 1.1 christos bad = 1;
1865 1.1 christos }
1866 1.1 christos
1867 1.1 christos *input_line_pointer = c;
1868 1.1 christos
1869 1.3 christos SKIP_WHITESPACE_AFTER_NAME ();
1870 1.1 christos if (*input_line_pointer != ',')
1871 1.1 christos {
1872 1.1 christos as_bad (_("expected comma after name in .vtable_inherit"));
1873 1.1 christos ignore_rest_of_line ();
1874 1.1 christos return NULL;
1875 1.1 christos }
1876 1.1 christos
1877 1.1 christos ++input_line_pointer;
1878 1.1 christos SKIP_WHITESPACE ();
1879 1.1 christos
1880 1.1 christos if (*input_line_pointer == '#')
1881 1.1 christos ++input_line_pointer;
1882 1.1 christos
1883 1.1 christos if (input_line_pointer[0] == '0'
1884 1.1 christos && (input_line_pointer[1] == '\0'
1885 1.1 christos || ISSPACE (input_line_pointer[1])))
1886 1.1 christos {
1887 1.1 christos psym = section_symbol (absolute_section);
1888 1.1 christos ++input_line_pointer;
1889 1.1 christos }
1890 1.1 christos else
1891 1.1 christos {
1892 1.3 christos c = get_symbol_name (& pname);
1893 1.1 christos psym = symbol_find_or_make (pname);
1894 1.3 christos restore_line_pointer (c);
1895 1.1 christos }
1896 1.1 christos
1897 1.1 christos demand_empty_rest_of_line ();
1898 1.1 christos
1899 1.1 christos if (bad)
1900 1.1 christos return NULL;
1901 1.1 christos
1902 1.1 christos gas_assert (symbol_get_value_expression (csym)->X_op == O_constant);
1903 1.1 christos return fix_new (symbol_get_frag (csym),
1904 1.1 christos symbol_get_value_expression (csym)->X_add_number,
1905 1.1 christos 0, psym, 0, 0, BFD_RELOC_VTABLE_INHERIT);
1906 1.1 christos }
1907 1.1 christos
1908 1.6 christos /* This is a version of obj_elf_get_vtable_inherit() that is
1909 1.6 christos suitable for use in struct _pseudo_type tables. */
1910 1.6 christos
1911 1.6 christos void
1912 1.6 christos obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
1913 1.6 christos {
1914 1.6 christos (void) obj_elf_get_vtable_inherit ();
1915 1.6 christos }
1916 1.6 christos
1917 1.1 christos /* This handles the .vtable_entry pseudo-op, which is used to indicate
1918 1.1 christos to the linker that a vtable slot was used. The syntax is
1919 1.1 christos ".vtable_entry tablename, offset". */
1920 1.1 christos
1921 1.1 christos struct fix *
1922 1.6 christos obj_elf_get_vtable_entry (void)
1923 1.1 christos {
1924 1.1 christos symbolS *sym;
1925 1.1 christos offsetT offset;
1926 1.1 christos
1927 1.1 christos if (*input_line_pointer == '#')
1928 1.1 christos ++input_line_pointer;
1929 1.1 christos
1930 1.1 christos sym = get_sym_from_input_line_and_check ();
1931 1.1 christos if (*input_line_pointer != ',')
1932 1.1 christos {
1933 1.1 christos as_bad (_("expected comma after name in .vtable_entry"));
1934 1.1 christos ignore_rest_of_line ();
1935 1.1 christos return NULL;
1936 1.1 christos }
1937 1.1 christos
1938 1.1 christos ++input_line_pointer;
1939 1.1 christos if (*input_line_pointer == '#')
1940 1.1 christos ++input_line_pointer;
1941 1.1 christos
1942 1.1 christos offset = get_absolute_expression ();
1943 1.1 christos
1944 1.1 christos demand_empty_rest_of_line ();
1945 1.1 christos
1946 1.1 christos return fix_new (frag_now, frag_now_fix (), 0, sym, offset, 0,
1947 1.1 christos BFD_RELOC_VTABLE_ENTRY);
1948 1.1 christos }
1949 1.1 christos
1950 1.6 christos /* This is a version of obj_elf_get_vtable_entry() that is
1951 1.6 christos suitable for use in struct _pseudo_type tables. */
1952 1.6 christos
1953 1.6 christos void
1954 1.6 christos obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
1955 1.6 christos {
1956 1.6 christos (void) obj_elf_get_vtable_entry ();
1957 1.6 christos }
1958 1.6 christos
1959 1.3 christos #define skip_whitespace(str) do { if (*(str) == ' ') ++(str); } while (0)
1960 1.3 christos
1961 1.3 christos static inline int
1962 1.3 christos skip_past_char (char ** str, char c)
1963 1.3 christos {
1964 1.3 christos if (**str == c)
1965 1.3 christos {
1966 1.3 christos (*str)++;
1967 1.3 christos return 0;
1968 1.3 christos }
1969 1.3 christos else
1970 1.3 christos return -1;
1971 1.3 christos }
1972 1.3 christos #define skip_past_comma(str) skip_past_char (str, ',')
1973 1.3 christos
1974 1.3 christos /* A list of attributes that have been explicitly set by the assembly code.
1975 1.3 christos VENDOR is the vendor id, BASE is the tag shifted right by the number
1976 1.3 christos of bits in MASK, and bit N of MASK is set if tag BASE+N has been set. */
1977 1.3 christos struct recorded_attribute_info {
1978 1.3 christos struct recorded_attribute_info *next;
1979 1.3 christos int vendor;
1980 1.3 christos unsigned int base;
1981 1.3 christos unsigned long mask;
1982 1.3 christos };
1983 1.3 christos static struct recorded_attribute_info *recorded_attributes;
1984 1.3 christos
1985 1.3 christos /* Record that we have seen an explicit specification of attribute TAG
1986 1.3 christos for vendor VENDOR. */
1987 1.3 christos
1988 1.3 christos static void
1989 1.3 christos record_attribute (int vendor, unsigned int tag)
1990 1.3 christos {
1991 1.3 christos unsigned int base;
1992 1.3 christos unsigned long mask;
1993 1.3 christos struct recorded_attribute_info *rai;
1994 1.3 christos
1995 1.3 christos base = tag / (8 * sizeof (rai->mask));
1996 1.3 christos mask = 1UL << (tag % (8 * sizeof (rai->mask)));
1997 1.3 christos for (rai = recorded_attributes; rai; rai = rai->next)
1998 1.3 christos if (rai->vendor == vendor && rai->base == base)
1999 1.3 christos {
2000 1.3 christos rai->mask |= mask;
2001 1.3 christos return;
2002 1.3 christos }
2003 1.3 christos
2004 1.3 christos rai = XNEW (struct recorded_attribute_info);
2005 1.3 christos rai->next = recorded_attributes;
2006 1.3 christos rai->vendor = vendor;
2007 1.3 christos rai->base = base;
2008 1.3 christos rai->mask = mask;
2009 1.3 christos recorded_attributes = rai;
2010 1.3 christos }
2011 1.3 christos
2012 1.3 christos /* Return true if we have seen an explicit specification of attribute TAG
2013 1.3 christos for vendor VENDOR. */
2014 1.3 christos
2015 1.8 christos bool
2016 1.3 christos obj_elf_seen_attribute (int vendor, unsigned int tag)
2017 1.3 christos {
2018 1.3 christos unsigned int base;
2019 1.3 christos unsigned long mask;
2020 1.3 christos struct recorded_attribute_info *rai;
2021 1.3 christos
2022 1.3 christos base = tag / (8 * sizeof (rai->mask));
2023 1.3 christos mask = 1UL << (tag % (8 * sizeof (rai->mask)));
2024 1.3 christos for (rai = recorded_attributes; rai; rai = rai->next)
2025 1.3 christos if (rai->vendor == vendor && rai->base == base)
2026 1.3 christos return (rai->mask & mask) != 0;
2027 1.8 christos return false;
2028 1.3 christos }
2029 1.3 christos
2030 1.3 christos /* Parse an attribute directive for VENDOR.
2031 1.3 christos Returns the attribute number read, or zero on error. */
2032 1.3 christos
2033 1.3 christos int
2034 1.3 christos obj_elf_vendor_attribute (int vendor)
2035 1.3 christos {
2036 1.3 christos expressionS exp;
2037 1.3 christos int type;
2038 1.3 christos int tag;
2039 1.3 christos unsigned int i = 0;
2040 1.3 christos char *s = NULL;
2041 1.3 christos
2042 1.3 christos /* Read the first number or name. */
2043 1.3 christos skip_whitespace (input_line_pointer);
2044 1.3 christos s = input_line_pointer;
2045 1.3 christos if (ISDIGIT (*input_line_pointer))
2046 1.3 christos {
2047 1.3 christos expression (& exp);
2048 1.3 christos if (exp.X_op != O_constant)
2049 1.3 christos goto bad;
2050 1.3 christos tag = exp.X_add_number;
2051 1.3 christos }
2052 1.3 christos else
2053 1.3 christos {
2054 1.3 christos char *name;
2055 1.3 christos
2056 1.3 christos /* A name may contain '_', but no other punctuation. */
2057 1.3 christos for (; ISALNUM (*input_line_pointer) || *input_line_pointer == '_';
2058 1.3 christos ++input_line_pointer)
2059 1.3 christos i++;
2060 1.3 christos if (i == 0)
2061 1.3 christos goto bad;
2062 1.3 christos
2063 1.8 christos name = xmemdup0 (s, i);
2064 1.3 christos
2065 1.3 christos #ifndef CONVERT_SYMBOLIC_ATTRIBUTE
2066 1.3 christos #define CONVERT_SYMBOLIC_ATTRIBUTE(a) -1
2067 1.3 christos #endif
2068 1.3 christos
2069 1.3 christos tag = CONVERT_SYMBOLIC_ATTRIBUTE (name);
2070 1.3 christos if (tag == -1)
2071 1.3 christos {
2072 1.3 christos as_bad (_("Attribute name not recognised: %s"), name);
2073 1.3 christos ignore_rest_of_line ();
2074 1.5 christos free (name);
2075 1.3 christos return 0;
2076 1.3 christos }
2077 1.5 christos free (name);
2078 1.3 christos }
2079 1.3 christos
2080 1.3 christos type = _bfd_elf_obj_attrs_arg_type (stdoutput, vendor, tag);
2081 1.3 christos
2082 1.3 christos if (skip_past_comma (&input_line_pointer) == -1)
2083 1.3 christos goto bad;
2084 1.3 christos if (type & 1)
2085 1.3 christos {
2086 1.3 christos expression (& exp);
2087 1.3 christos if (exp.X_op != O_constant)
2088 1.3 christos {
2089 1.3 christos as_bad (_("expected numeric constant"));
2090 1.3 christos ignore_rest_of_line ();
2091 1.3 christos return 0;
2092 1.3 christos }
2093 1.3 christos i = exp.X_add_number;
2094 1.3 christos }
2095 1.3 christos if ((type & 3) == 3
2096 1.3 christos && skip_past_comma (&input_line_pointer) == -1)
2097 1.3 christos {
2098 1.3 christos as_bad (_("expected comma"));
2099 1.3 christos ignore_rest_of_line ();
2100 1.3 christos return 0;
2101 1.3 christos }
2102 1.3 christos if (type & 2)
2103 1.3 christos {
2104 1.3 christos int len;
2105 1.3 christos
2106 1.3 christos skip_whitespace (input_line_pointer);
2107 1.3 christos if (*input_line_pointer != '"')
2108 1.3 christos goto bad_string;
2109 1.3 christos s = demand_copy_C_string (&len);
2110 1.3 christos }
2111 1.3 christos
2112 1.3 christos record_attribute (vendor, tag);
2113 1.9 christos bool ok = false;
2114 1.3 christos switch (type & 3)
2115 1.3 christos {
2116 1.3 christos case 3:
2117 1.9 christos ok = bfd_elf_add_obj_attr_int_string (stdoutput, vendor, tag, i, s);
2118 1.3 christos break;
2119 1.3 christos case 2:
2120 1.9 christos ok = bfd_elf_add_obj_attr_string (stdoutput, vendor, tag, s);
2121 1.3 christos break;
2122 1.3 christos case 1:
2123 1.9 christos ok = bfd_elf_add_obj_attr_int (stdoutput, vendor, tag, i);
2124 1.3 christos break;
2125 1.3 christos default:
2126 1.3 christos abort ();
2127 1.3 christos }
2128 1.9 christos if (!ok)
2129 1.9 christos as_fatal (_("error adding attribute: %s"),
2130 1.9 christos bfd_errmsg (bfd_get_error ()));
2131 1.3 christos
2132 1.3 christos demand_empty_rest_of_line ();
2133 1.3 christos return tag;
2134 1.8 christos bad_string:
2135 1.3 christos as_bad (_("bad string constant"));
2136 1.3 christos ignore_rest_of_line ();
2137 1.3 christos return 0;
2138 1.8 christos bad:
2139 1.3 christos as_bad (_("expected <tag> , <value>"));
2140 1.3 christos ignore_rest_of_line ();
2141 1.3 christos return 0;
2142 1.3 christos }
2143 1.3 christos
2144 1.3 christos /* Parse a .gnu_attribute directive. */
2145 1.3 christos
2146 1.3 christos static void
2147 1.3 christos obj_elf_gnu_attribute (int ignored ATTRIBUTE_UNUSED)
2148 1.3 christos {
2149 1.3 christos obj_elf_vendor_attribute (OBJ_ATTR_GNU);
2150 1.3 christos }
2151 1.3 christos
2152 1.1 christos void
2153 1.1 christos elf_obj_read_begin_hook (void)
2154 1.1 christos {
2155 1.1 christos #ifdef NEED_ECOFF_DEBUG
2156 1.1 christos if (ECOFF_DEBUGGING)
2157 1.1 christos ecoff_read_begin_hook ();
2158 1.1 christos #endif
2159 1.1 christos }
2160 1.1 christos
2161 1.1 christos void
2162 1.1 christos elf_obj_symbol_new_hook (symbolS *symbolP)
2163 1.1 christos {
2164 1.1 christos struct elf_obj_sy *sy_obj;
2165 1.1 christos
2166 1.1 christos sy_obj = symbol_get_obj (symbolP);
2167 1.1 christos sy_obj->size = NULL;
2168 1.1 christos sy_obj->versioned_name = NULL;
2169 1.1 christos
2170 1.1 christos #ifdef NEED_ECOFF_DEBUG
2171 1.1 christos if (ECOFF_DEBUGGING)
2172 1.1 christos ecoff_symbol_new_hook (symbolP);
2173 1.1 christos #endif
2174 1.1 christos }
2175 1.1 christos
2176 1.8 christos /* Deduplicate size expressions. We might get into trouble with
2177 1.8 christos multiple freeing or use after free if we leave them pointing to the
2178 1.8 christos same expressionS. */
2179 1.8 christos
2180 1.8 christos void
2181 1.8 christos elf_obj_symbol_clone_hook (symbolS *newsym, symbolS *orgsym ATTRIBUTE_UNUSED)
2182 1.8 christos {
2183 1.8 christos struct elf_obj_sy *newelf = symbol_get_obj (newsym);
2184 1.8 christos if (newelf->size)
2185 1.8 christos {
2186 1.8 christos expressionS *exp = XNEW (expressionS);
2187 1.8 christos *exp = *newelf->size;
2188 1.8 christos newelf->size = exp;
2189 1.8 christos }
2190 1.8 christos }
2191 1.1 christos
2192 1.1 christos void
2193 1.1 christos elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
2194 1.1 christos {
2195 1.1 christos struct elf_obj_sy *srcelf = symbol_get_obj (src);
2196 1.1 christos struct elf_obj_sy *destelf = symbol_get_obj (dest);
2197 1.8 christos /* If size is unset, copy size from src. Because we don't track whether
2198 1.8 christos .size has been used, we can't differentiate .size dest, 0 from the case
2199 1.8 christos where dest's size is unset. */
2200 1.8 christos if (!destelf->size && S_GET_SIZE (dest) == 0)
2201 1.1 christos {
2202 1.8 christos if (srcelf->size)
2203 1.8 christos {
2204 1.8 christos destelf->size = XNEW (expressionS);
2205 1.8 christos *destelf->size = *srcelf->size;
2206 1.8 christos }
2207 1.8 christos S_SET_SIZE (dest, S_GET_SIZE (src));
2208 1.1 christos }
2209 1.1 christos /* Don't copy visibility. */
2210 1.1 christos S_SET_OTHER (dest, (ELF_ST_VISIBILITY (S_GET_OTHER (dest))
2211 1.1 christos | (S_GET_OTHER (src) & ~ELF_ST_VISIBILITY (-1))));
2212 1.1 christos }
2213 1.1 christos
2214 1.1 christos void
2215 1.1 christos obj_elf_version (int ignore ATTRIBUTE_UNUSED)
2216 1.1 christos {
2217 1.1 christos char *name;
2218 1.1 christos unsigned int c;
2219 1.1 christos char *p;
2220 1.1 christos asection *seg = now_seg;
2221 1.1 christos subsegT subseg = now_subseg;
2222 1.1 christos Elf_Internal_Note i_note;
2223 1.1 christos Elf_External_Note e_note;
2224 1.1 christos asection *note_secp = NULL;
2225 1.1 christos
2226 1.1 christos SKIP_WHITESPACE ();
2227 1.1 christos if (*input_line_pointer == '\"')
2228 1.1 christos {
2229 1.1 christos unsigned int len;
2230 1.1 christos
2231 1.1 christos ++input_line_pointer; /* -> 1st char of string. */
2232 1.1 christos name = input_line_pointer;
2233 1.1 christos
2234 1.1 christos while (is_a_char (c = next_char_of_string ()))
2235 1.1 christos ;
2236 1.1 christos c = *input_line_pointer;
2237 1.1 christos *input_line_pointer = '\0';
2238 1.1 christos *(input_line_pointer - 1) = '\0';
2239 1.1 christos *input_line_pointer = c;
2240 1.1 christos
2241 1.1 christos /* Create the .note section. */
2242 1.1 christos note_secp = subseg_new (".note", 0);
2243 1.7 christos bfd_set_section_flags (note_secp, SEC_HAS_CONTENTS | SEC_READONLY);
2244 1.6 christos record_alignment (note_secp, 2);
2245 1.1 christos
2246 1.1 christos /* Process the version string. */
2247 1.1 christos len = strlen (name) + 1;
2248 1.1 christos
2249 1.1 christos /* PR 3456: Although the name field is padded out to an 4-byte
2250 1.1 christos boundary, the namesz field should not be adjusted. */
2251 1.1 christos i_note.namesz = len;
2252 1.1 christos i_note.descsz = 0; /* No description. */
2253 1.1 christos i_note.type = NT_VERSION;
2254 1.1 christos p = frag_more (sizeof (e_note.namesz));
2255 1.1 christos md_number_to_chars (p, i_note.namesz, sizeof (e_note.namesz));
2256 1.1 christos p = frag_more (sizeof (e_note.descsz));
2257 1.1 christos md_number_to_chars (p, i_note.descsz, sizeof (e_note.descsz));
2258 1.1 christos p = frag_more (sizeof (e_note.type));
2259 1.1 christos md_number_to_chars (p, i_note.type, sizeof (e_note.type));
2260 1.1 christos p = frag_more (len);
2261 1.1 christos memcpy (p, name, len);
2262 1.1 christos
2263 1.1 christos frag_align (2, 0, 0);
2264 1.1 christos
2265 1.1 christos subseg_set (seg, subseg);
2266 1.1 christos }
2267 1.1 christos else
2268 1.1 christos as_bad (_("expected quoted string"));
2269 1.1 christos
2270 1.1 christos demand_empty_rest_of_line ();
2271 1.1 christos }
2272 1.1 christos
2273 1.1 christos static void
2274 1.1 christos obj_elf_size (int ignore ATTRIBUTE_UNUSED)
2275 1.1 christos {
2276 1.3 christos char *name;
2277 1.3 christos char c = get_symbol_name (&name);
2278 1.1 christos char *p;
2279 1.1 christos expressionS exp;
2280 1.1 christos symbolS *sym;
2281 1.1 christos
2282 1.1 christos p = input_line_pointer;
2283 1.1 christos *p = c;
2284 1.3 christos SKIP_WHITESPACE_AFTER_NAME ();
2285 1.1 christos if (*input_line_pointer != ',')
2286 1.1 christos {
2287 1.1 christos *p = 0;
2288 1.1 christos as_bad (_("expected comma after name `%s' in .size directive"), name);
2289 1.1 christos *p = c;
2290 1.1 christos ignore_rest_of_line ();
2291 1.1 christos return;
2292 1.1 christos }
2293 1.1 christos input_line_pointer++;
2294 1.1 christos expression (&exp);
2295 1.1 christos if (exp.X_op == O_absent)
2296 1.1 christos {
2297 1.1 christos as_bad (_("missing expression in .size directive"));
2298 1.1 christos exp.X_op = O_constant;
2299 1.1 christos exp.X_add_number = 0;
2300 1.1 christos }
2301 1.1 christos *p = 0;
2302 1.1 christos sym = symbol_find_or_make (name);
2303 1.1 christos *p = c;
2304 1.1 christos if (exp.X_op == O_constant)
2305 1.1 christos {
2306 1.1 christos S_SET_SIZE (sym, exp.X_add_number);
2307 1.8 christos xfree (symbol_get_obj (sym)->size);
2308 1.8 christos symbol_get_obj (sym)->size = NULL;
2309 1.1 christos }
2310 1.1 christos else
2311 1.1 christos {
2312 1.5 christos symbol_get_obj (sym)->size = XNEW (expressionS);
2313 1.1 christos *symbol_get_obj (sym)->size = exp;
2314 1.1 christos }
2315 1.9 christos
2316 1.9 christos /* If the symbol in the directive matches the current function being
2317 1.9 christos processed, indicate end of the current stream of ginsns. */
2318 1.9 christos if (flag_synth_cfi
2319 1.9 christos && S_IS_FUNCTION (sym) && sym == ginsn_data_func_symbol ())
2320 1.9 christos ginsn_data_end (symbol_temp_new_now ());
2321 1.9 christos
2322 1.1 christos demand_empty_rest_of_line ();
2323 1.1 christos }
2324 1.1 christos
2325 1.1 christos /* Handle the ELF .type pseudo-op. This sets the type of a symbol.
2326 1.1 christos There are six syntaxes:
2327 1.1 christos
2328 1.1 christos The first (used on Solaris) is
2329 1.1 christos .type SYM,#function
2330 1.1 christos The second (used on UnixWare) is
2331 1.1 christos .type SYM,@function
2332 1.1 christos The third (reportedly to be used on Irix 6.0) is
2333 1.1 christos .type SYM STT_FUNC
2334 1.1 christos The fourth (used on NetBSD/Arm and Linux/ARM) is
2335 1.1 christos .type SYM,%function
2336 1.1 christos The fifth (used on SVR4/860) is
2337 1.1 christos .type SYM,"function"
2338 1.1 christos The sixth (emitted by recent SunPRO under Solaris) is
2339 1.1 christos .type SYM,[0-9]
2340 1.1 christos where the integer is the STT_* value.
2341 1.1 christos */
2342 1.1 christos
2343 1.1 christos static char *
2344 1.1 christos obj_elf_type_name (char *cp)
2345 1.1 christos {
2346 1.1 christos char *p;
2347 1.1 christos
2348 1.1 christos p = input_line_pointer;
2349 1.1 christos if (*input_line_pointer >= '0'
2350 1.1 christos && *input_line_pointer <= '9')
2351 1.1 christos {
2352 1.1 christos while (*input_line_pointer >= '0'
2353 1.1 christos && *input_line_pointer <= '9')
2354 1.1 christos ++input_line_pointer;
2355 1.1 christos *cp = *input_line_pointer;
2356 1.1 christos *input_line_pointer = '\0';
2357 1.1 christos }
2358 1.1 christos else
2359 1.3 christos *cp = get_symbol_name (&p);
2360 1.1 christos
2361 1.1 christos return p;
2362 1.1 christos }
2363 1.1 christos
2364 1.1 christos static void
2365 1.1 christos obj_elf_type (int ignore ATTRIBUTE_UNUSED)
2366 1.1 christos {
2367 1.1 christos char c;
2368 1.1 christos int type;
2369 1.1 christos const char *type_name;
2370 1.1 christos symbolS *sym;
2371 1.1 christos elf_symbol_type *elfsym;
2372 1.1 christos
2373 1.1 christos sym = get_sym_from_input_line_and_check ();
2374 1.1 christos c = *input_line_pointer;
2375 1.1 christos elfsym = (elf_symbol_type *) symbol_get_bfdsym (sym);
2376 1.1 christos
2377 1.1 christos if (*input_line_pointer == ',')
2378 1.1 christos ++input_line_pointer;
2379 1.1 christos
2380 1.1 christos SKIP_WHITESPACE ();
2381 1.1 christos if ( *input_line_pointer == '#'
2382 1.1 christos || *input_line_pointer == '@'
2383 1.1 christos || *input_line_pointer == '"'
2384 1.1 christos || *input_line_pointer == '%')
2385 1.1 christos ++input_line_pointer;
2386 1.1 christos
2387 1.1 christos type_name = obj_elf_type_name (& c);
2388 1.1 christos
2389 1.1 christos type = 0;
2390 1.1 christos if (strcmp (type_name, "function") == 0
2391 1.1 christos || strcmp (type_name, "2") == 0
2392 1.1 christos || strcmp (type_name, "STT_FUNC") == 0)
2393 1.1 christos type = BSF_FUNCTION;
2394 1.1 christos else if (strcmp (type_name, "object") == 0
2395 1.1 christos || strcmp (type_name, "1") == 0
2396 1.1 christos || strcmp (type_name, "STT_OBJECT") == 0)
2397 1.1 christos type = BSF_OBJECT;
2398 1.1 christos else if (strcmp (type_name, "tls_object") == 0
2399 1.1 christos || strcmp (type_name, "6") == 0
2400 1.1 christos || strcmp (type_name, "STT_TLS") == 0)
2401 1.1 christos type = BSF_OBJECT | BSF_THREAD_LOCAL;
2402 1.1 christos else if (strcmp (type_name, "notype") == 0
2403 1.1 christos || strcmp (type_name, "0") == 0
2404 1.1 christos || strcmp (type_name, "STT_NOTYPE") == 0)
2405 1.1 christos ;
2406 1.1 christos else if (strcmp (type_name, "common") == 0
2407 1.1 christos || strcmp (type_name, "5") == 0
2408 1.1 christos || strcmp (type_name, "STT_COMMON") == 0)
2409 1.1 christos {
2410 1.1 christos type = BSF_OBJECT;
2411 1.1 christos
2412 1.1 christos if (! S_IS_COMMON (sym))
2413 1.1 christos {
2414 1.1 christos if (S_IS_VOLATILE (sym))
2415 1.1 christos {
2416 1.1 christos sym = symbol_clone (sym, 1);
2417 1.1 christos S_SET_SEGMENT (sym, bfd_com_section_ptr);
2418 1.1 christos S_SET_VALUE (sym, 0);
2419 1.1 christos S_SET_EXTERNAL (sym);
2420 1.1 christos symbol_set_frag (sym, &zero_address_frag);
2421 1.1 christos S_CLEAR_VOLATILE (sym);
2422 1.1 christos }
2423 1.1 christos else if (S_IS_DEFINED (sym) || symbol_equated_p (sym))
2424 1.1 christos as_bad (_("symbol '%s' is already defined"), S_GET_NAME (sym));
2425 1.1 christos else
2426 1.1 christos {
2427 1.1 christos /* FIXME: Is it safe to just change the section ? */
2428 1.1 christos S_SET_SEGMENT (sym, bfd_com_section_ptr);
2429 1.1 christos S_SET_VALUE (sym, 0);
2430 1.1 christos S_SET_EXTERNAL (sym);
2431 1.1 christos }
2432 1.1 christos }
2433 1.1 christos }
2434 1.1 christos else if (strcmp (type_name, "gnu_indirect_function") == 0
2435 1.1 christos || strcmp (type_name, "10") == 0
2436 1.1 christos || strcmp (type_name, "STT_GNU_IFUNC") == 0)
2437 1.1 christos {
2438 1.8 christos const struct elf_backend_data *bed;
2439 1.1 christos
2440 1.8 christos bed = get_elf_backend_data (stdoutput);
2441 1.8 christos if (bed->elf_osabi != ELFOSABI_NONE
2442 1.8 christos && bed->elf_osabi != ELFOSABI_GNU
2443 1.8 christos && bed->elf_osabi != ELFOSABI_FREEBSD)
2444 1.7 christos as_bad (_("symbol type \"%s\" is supported only by GNU "
2445 1.7 christos "and FreeBSD targets"), type_name);
2446 1.8 christos #if 0
2447 1.8 christos /* MIPS targets do not support IFUNCS. */
2448 1.8 christos else if (bed->target_id == MIPS_ELF_DATA)
2449 1.8 christos as_bad (_("symbol type \"%s\" is not supported by "
2450 1.8 christos "MIPS targets"), type_name);
2451 1.1 christos #endif
2452 1.7 christos elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_ifunc;
2453 1.1 christos type = BSF_FUNCTION | BSF_GNU_INDIRECT_FUNCTION;
2454 1.1 christos }
2455 1.1 christos else if (strcmp (type_name, "gnu_unique_object") == 0)
2456 1.1 christos {
2457 1.8 christos const struct elf_backend_data *bed;
2458 1.1 christos
2459 1.8 christos bed = get_elf_backend_data (stdoutput);
2460 1.8 christos if (bed->elf_osabi != ELFOSABI_NONE
2461 1.8 christos && bed->elf_osabi != ELFOSABI_GNU)
2462 1.1 christos as_bad (_("symbol type \"%s\" is supported only by GNU targets"),
2463 1.1 christos type_name);
2464 1.7 christos elf_tdata (stdoutput)->has_gnu_osabi |= elf_gnu_osabi_unique;
2465 1.1 christos type = BSF_OBJECT | BSF_GNU_UNIQUE;
2466 1.1 christos }
2467 1.1 christos #ifdef md_elf_symbol_type
2468 1.1 christos else if ((type = md_elf_symbol_type (type_name, sym, elfsym)) != -1)
2469 1.1 christos ;
2470 1.1 christos #endif
2471 1.1 christos else
2472 1.1 christos as_bad (_("unrecognized symbol type \"%s\""), type_name);
2473 1.1 christos
2474 1.1 christos *input_line_pointer = c;
2475 1.1 christos
2476 1.1 christos if (*input_line_pointer == '"')
2477 1.1 christos ++input_line_pointer;
2478 1.1 christos
2479 1.7 christos #ifdef md_elf_symbol_type_change
2480 1.7 christos if (!md_elf_symbol_type_change (sym, elfsym, type))
2481 1.7 christos #endif
2482 1.7 christos {
2483 1.7 christos flagword mask = BSF_FUNCTION | BSF_OBJECT;
2484 1.7 christos
2485 1.7 christos if (type != BSF_FUNCTION)
2486 1.7 christos mask |= BSF_GNU_INDIRECT_FUNCTION;
2487 1.7 christos if (type != BSF_OBJECT)
2488 1.7 christos {
2489 1.7 christos mask |= BSF_GNU_UNIQUE | BSF_THREAD_LOCAL;
2490 1.7 christos
2491 1.7 christos if (S_IS_COMMON (sym))
2492 1.7 christos {
2493 1.7 christos as_bad (_("cannot change type of common symbol '%s'"),
2494 1.7 christos S_GET_NAME (sym));
2495 1.7 christos mask = type = 0;
2496 1.7 christos }
2497 1.7 christos }
2498 1.7 christos
2499 1.7 christos /* Don't warn when changing to STT_NOTYPE. */
2500 1.7 christos if (type)
2501 1.7 christos {
2502 1.7 christos flagword new = (elfsym->symbol.flags & ~mask) | type;
2503 1.7 christos
2504 1.7 christos if (new != (elfsym->symbol.flags | type))
2505 1.7 christos as_warn (_("symbol '%s' already has its type set"), S_GET_NAME (sym));
2506 1.7 christos elfsym->symbol.flags = new;
2507 1.7 christos }
2508 1.7 christos else
2509 1.7 christos elfsym->symbol.flags &= ~mask;
2510 1.7 christos }
2511 1.1 christos
2512 1.9 christos if (S_IS_FUNCTION (sym) && flag_synth_cfi)
2513 1.9 christos {
2514 1.9 christos /* When using SCFI, .type directive indicates start of a new FDE for SCFI
2515 1.9 christos processing. So, we must first demarcate the previous block of ginsns,
2516 1.9 christos if any, to mark the end of a previous FDE. */
2517 1.9 christos if (frchain_now->frch_ginsn_data)
2518 1.9 christos ginsn_data_end (symbol_temp_new_now ());
2519 1.9 christos ginsn_data_begin (sym);
2520 1.9 christos }
2521 1.9 christos
2522 1.1 christos demand_empty_rest_of_line ();
2523 1.1 christos }
2524 1.1 christos
2525 1.9 christos static segT comment_section;
2526 1.9 christos
2527 1.1 christos static void
2528 1.1 christos obj_elf_ident (int ignore ATTRIBUTE_UNUSED)
2529 1.1 christos {
2530 1.1 christos segT old_section = now_seg;
2531 1.1 christos int old_subsection = now_subseg;
2532 1.1 christos
2533 1.1 christos #ifdef md_flush_pending_output
2534 1.1 christos md_flush_pending_output ();
2535 1.1 christos #endif
2536 1.1 christos
2537 1.1 christos if (!comment_section)
2538 1.1 christos {
2539 1.1 christos char *p;
2540 1.1 christos comment_section = subseg_new (".comment", 0);
2541 1.7 christos bfd_set_section_flags (comment_section, (SEC_READONLY | SEC_HAS_CONTENTS
2542 1.7 christos | SEC_MERGE | SEC_STRINGS));
2543 1.1 christos comment_section->entsize = 1;
2544 1.1 christos #ifdef md_elf_section_change_hook
2545 1.1 christos md_elf_section_change_hook ();
2546 1.1 christos #endif
2547 1.1 christos p = frag_more (1);
2548 1.1 christos *p = 0;
2549 1.1 christos }
2550 1.1 christos else
2551 1.9 christos {
2552 1.9 christos subseg_set (comment_section, 0);
2553 1.9 christos #ifdef md_elf_section_change_hook
2554 1.9 christos md_elf_section_change_hook ();
2555 1.9 christos #endif
2556 1.9 christos }
2557 1.1 christos stringer (8 + 1);
2558 1.1 christos subseg_set (old_section, old_subsection);
2559 1.9 christos #ifdef md_elf_section_change_hook
2560 1.9 christos md_elf_section_change_hook ();
2561 1.9 christos #endif
2562 1.1 christos }
2563 1.1 christos
2564 1.1 christos #ifdef INIT_STAB_SECTION
2565 1.1 christos
2566 1.1 christos /* The first entry in a .stabs section is special. */
2567 1.1 christos
2568 1.1 christos void
2569 1.9 christos obj_elf_init_stab_section (segT stab, segT stabstr)
2570 1.1 christos {
2571 1.8 christos char *file;
2572 1.1 christos char *p;
2573 1.1 christos unsigned int stroff;
2574 1.1 christos
2575 1.1 christos /* Force the section to align to a longword boundary. Without this,
2576 1.1 christos UnixWare ar crashes. */
2577 1.9 christos bfd_set_section_alignment (stab, 2);
2578 1.1 christos
2579 1.1 christos /* Make space for this first symbol. */
2580 1.1 christos p = frag_more (12);
2581 1.1 christos /* Zero it out. */
2582 1.1 christos memset (p, 0, 12);
2583 1.8 christos file = remap_debug_filename (as_where (NULL));
2584 1.9 christos stroff = get_stab_string_offset (file, stabstr);
2585 1.1 christos know (stroff == 1 || (stroff == 0 && file[0] == '\0'));
2586 1.1 christos md_number_to_chars (p, stroff, 4);
2587 1.9 christos seg_info (stab)->stabu.p = p;
2588 1.8 christos free (file);
2589 1.1 christos }
2590 1.1 christos
2591 1.1 christos #endif
2592 1.1 christos
2593 1.1 christos /* Fill in the counts in the first entry in a .stabs section. */
2594 1.1 christos
2595 1.1 christos static void
2596 1.1 christos adjust_stab_sections (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
2597 1.1 christos {
2598 1.1 christos char *name;
2599 1.1 christos asection *strsec;
2600 1.1 christos char *p;
2601 1.1 christos int strsz, nsyms;
2602 1.1 christos
2603 1.8 christos if (!startswith (sec->name, ".stab"))
2604 1.1 christos return;
2605 1.1 christos if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
2606 1.1 christos return;
2607 1.1 christos
2608 1.5 christos name = concat (sec->name, "str", NULL);
2609 1.1 christos strsec = bfd_get_section_by_name (abfd, name);
2610 1.1 christos if (strsec)
2611 1.7 christos strsz = bfd_section_size (strsec);
2612 1.1 christos else
2613 1.1 christos strsz = 0;
2614 1.7 christos nsyms = bfd_section_size (sec) / 12 - 1;
2615 1.1 christos
2616 1.1 christos p = seg_info (sec)->stabu.p;
2617 1.1 christos gas_assert (p != 0);
2618 1.1 christos
2619 1.1 christos bfd_h_put_16 (abfd, nsyms, p + 6);
2620 1.1 christos bfd_h_put_32 (abfd, strsz, p + 8);
2621 1.5 christos free (name);
2622 1.1 christos }
2623 1.1 christos
2624 1.1 christos #ifdef NEED_ECOFF_DEBUG
2625 1.1 christos
2626 1.1 christos /* This function is called by the ECOFF code. It is supposed to
2627 1.1 christos record the external symbol information so that the backend can
2628 1.1 christos write it out correctly. The ELF backend doesn't actually handle
2629 1.1 christos this at the moment, so we do it ourselves. We save the information
2630 1.1 christos in the symbol. */
2631 1.1 christos
2632 1.1 christos #ifdef OBJ_MAYBE_ELF
2633 1.1 christos static
2634 1.1 christos #endif
2635 1.1 christos void
2636 1.1 christos elf_ecoff_set_ext (symbolS *sym, struct ecoff_extr *ext)
2637 1.1 christos {
2638 1.1 christos symbol_get_bfdsym (sym)->udata.p = ext;
2639 1.1 christos }
2640 1.1 christos
2641 1.1 christos /* This function is called by bfd_ecoff_debug_externals. It is
2642 1.1 christos supposed to *EXT to the external symbol information, and return
2643 1.1 christos whether the symbol should be used at all. */
2644 1.1 christos
2645 1.8 christos static bool
2646 1.1 christos elf_get_extr (asymbol *sym, EXTR *ext)
2647 1.1 christos {
2648 1.1 christos if (sym->udata.p == NULL)
2649 1.8 christos return false;
2650 1.1 christos *ext = *(EXTR *) sym->udata.p;
2651 1.8 christos return true;
2652 1.1 christos }
2653 1.1 christos
2654 1.1 christos /* This function is called by bfd_ecoff_debug_externals. It has
2655 1.1 christos nothing to do for ELF. */
2656 1.1 christos
2657 1.1 christos static void
2658 1.1 christos elf_set_index (asymbol *sym ATTRIBUTE_UNUSED,
2659 1.1 christos bfd_size_type indx ATTRIBUTE_UNUSED)
2660 1.1 christos {
2661 1.1 christos }
2662 1.1 christos
2663 1.1 christos #endif /* NEED_ECOFF_DEBUG */
2664 1.1 christos
2665 1.1 christos void
2666 1.1 christos elf_frob_symbol (symbolS *symp, int *puntp)
2667 1.1 christos {
2668 1.1 christos struct elf_obj_sy *sy_obj;
2669 1.1 christos expressionS *size;
2670 1.8 christos struct elf_versioned_name_list *versioned_name;
2671 1.1 christos
2672 1.1 christos #ifdef NEED_ECOFF_DEBUG
2673 1.1 christos if (ECOFF_DEBUGGING)
2674 1.1 christos ecoff_frob_symbol (symp);
2675 1.1 christos #endif
2676 1.1 christos
2677 1.1 christos sy_obj = symbol_get_obj (symp);
2678 1.1 christos
2679 1.1 christos size = sy_obj->size;
2680 1.1 christos if (size != NULL)
2681 1.1 christos {
2682 1.1 christos if (resolve_expression (size)
2683 1.1 christos && size->X_op == O_constant)
2684 1.1 christos S_SET_SIZE (symp, size->X_add_number);
2685 1.1 christos else
2686 1.1 christos {
2687 1.5 christos if (!flag_allow_nonconst_size)
2688 1.1 christos as_bad (_(".size expression for %s "
2689 1.1 christos "does not evaluate to a constant"), S_GET_NAME (symp));
2690 1.1 christos else
2691 1.1 christos as_warn (_(".size expression for %s "
2692 1.1 christos "does not evaluate to a constant"), S_GET_NAME (symp));
2693 1.1 christos }
2694 1.1 christos free (sy_obj->size);
2695 1.1 christos sy_obj->size = NULL;
2696 1.1 christos }
2697 1.1 christos
2698 1.8 christos versioned_name = sy_obj->versioned_name;
2699 1.8 christos if (versioned_name)
2700 1.1 christos {
2701 1.1 christos /* This symbol was given a new name with the .symver directive.
2702 1.1 christos If this is an external reference, just rename the symbol to
2703 1.1 christos include the version string. This will make the relocs be
2704 1.8 christos against the correct versioned symbol. */
2705 1.1 christos
2706 1.8 christos /* We will have already reported an version error. */
2707 1.8 christos if (sy_obj->bad_version)
2708 1.8 christos *puntp = true;
2709 1.8 christos /* elf_frob_file_before_adjust only allows one version symbol for
2710 1.8 christos renamed symbol. */
2711 1.8 christos else if (sy_obj->rename)
2712 1.8 christos S_SET_NAME (symp, versioned_name->name);
2713 1.8 christos else if (S_IS_COMMON (symp))
2714 1.8 christos {
2715 1.8 christos as_bad (_("`%s' can't be versioned to common symbol '%s'"),
2716 1.8 christos versioned_name->name, S_GET_NAME (symp));
2717 1.8 christos *puntp = true;
2718 1.1 christos }
2719 1.1 christos else
2720 1.1 christos {
2721 1.8 christos asymbol *bfdsym;
2722 1.8 christos elf_symbol_type *elfsym;
2723 1.1 christos
2724 1.8 christos /* This is a definition. Add an alias for each version.
2725 1.8 christos FIXME: Using an alias will permit the debugging information
2726 1.8 christos to refer to the right symbol. However, it's not clear
2727 1.8 christos whether it is the best approach. */
2728 1.8 christos
2729 1.8 christos /* FIXME: Creating a new symbol here is risky. We're
2730 1.8 christos in the final loop over the symbol table. We can
2731 1.8 christos get away with it only because the symbol goes to
2732 1.8 christos the end of the list, where the loop will still see
2733 1.8 christos it. It would probably be better to do this in
2734 1.8 christos obj_frob_file_before_adjust. */
2735 1.8 christos for (; versioned_name != NULL;
2736 1.8 christos versioned_name = versioned_name->next)
2737 1.1 christos {
2738 1.8 christos symbolS *symp2 = symbol_find_or_make (versioned_name->name);
2739 1.1 christos
2740 1.1 christos S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
2741 1.1 christos
2742 1.1 christos /* Subtracting out the frag address here is a hack
2743 1.1 christos because we are in the middle of the final loop. */
2744 1.1 christos S_SET_VALUE (symp2,
2745 1.1 christos (S_GET_VALUE (symp)
2746 1.8 christos - (symbol_get_frag (symp)->fr_address
2747 1.8 christos / OCTETS_PER_BYTE)));
2748 1.1 christos
2749 1.1 christos symbol_set_frag (symp2, symbol_get_frag (symp));
2750 1.1 christos
2751 1.1 christos /* This will copy over the size information. */
2752 1.1 christos copy_symbol_attributes (symp2, symp);
2753 1.1 christos
2754 1.1 christos S_SET_OTHER (symp2, S_GET_OTHER (symp));
2755 1.1 christos
2756 1.1 christos if (S_IS_WEAK (symp))
2757 1.1 christos S_SET_WEAK (symp2);
2758 1.1 christos
2759 1.1 christos if (S_IS_EXTERNAL (symp))
2760 1.1 christos S_SET_EXTERNAL (symp2);
2761 1.1 christos }
2762 1.8 christos
2763 1.8 christos switch (sy_obj->visibility)
2764 1.8 christos {
2765 1.8 christos case visibility_unchanged:
2766 1.8 christos break;
2767 1.8 christos case visibility_hidden:
2768 1.8 christos bfdsym = symbol_get_bfdsym (symp);
2769 1.8 christos elfsym = elf_symbol_from (bfdsym);
2770 1.8 christos elfsym->internal_elf_sym.st_other &= ~3;
2771 1.8 christos elfsym->internal_elf_sym.st_other |= STV_HIDDEN;
2772 1.8 christos break;
2773 1.8 christos case visibility_remove:
2774 1.8 christos /* Don't remove the symbol if it is used in relocation.
2775 1.8 christos Instead, mark it as to be removed and issue an error
2776 1.8 christos if the symbol has more than one versioned name. */
2777 1.8 christos if (symbol_used_in_reloc_p (symp))
2778 1.8 christos {
2779 1.8 christos if (sy_obj->versioned_name->next != NULL)
2780 1.8 christos as_bad (_("symbol '%s' with multiple versions cannot be used in relocation"),
2781 1.8 christos S_GET_NAME (symp));
2782 1.8 christos symbol_mark_removed (symp);
2783 1.8 christos }
2784 1.8 christos else
2785 1.8 christos symbol_remove (symp, &symbol_rootP, &symbol_lastP);
2786 1.8 christos break;
2787 1.8 christos case visibility_local:
2788 1.8 christos S_CLEAR_EXTERNAL (symp);
2789 1.8 christos break;
2790 1.8 christos }
2791 1.1 christos }
2792 1.1 christos }
2793 1.1 christos
2794 1.1 christos /* Double check weak symbols. */
2795 1.1 christos if (S_IS_WEAK (symp))
2796 1.1 christos {
2797 1.1 christos if (S_IS_COMMON (symp))
2798 1.1 christos as_bad (_("symbol `%s' can not be both weak and common"),
2799 1.1 christos S_GET_NAME (symp));
2800 1.1 christos }
2801 1.1 christos }
2802 1.1 christos
2803 1.8 christos /* Fix up SYMPP which has been marked to be removed by .symver. */
2804 1.8 christos
2805 1.8 christos void
2806 1.8 christos elf_fixup_removed_symbol (symbolS **sympp)
2807 1.8 christos {
2808 1.8 christos symbolS *symp = *sympp;
2809 1.8 christos struct elf_obj_sy *sy_obj = symbol_get_obj (symp);
2810 1.8 christos
2811 1.8 christos /* Replace the removed symbol with the versioned symbol. */
2812 1.8 christos symp = symbol_find (sy_obj->versioned_name->name);
2813 1.8 christos *sympp = symp;
2814 1.8 christos }
2815 1.8 christos
2816 1.1 christos struct group_list
2817 1.1 christos {
2818 1.1 christos asection **head; /* Section lists. */
2819 1.1 christos unsigned int num_group; /* Number of lists. */
2820 1.8 christos htab_t indexes; /* Maps group name to index in head array. */
2821 1.1 christos };
2822 1.1 christos
2823 1.6 christos static struct group_list groups;
2824 1.6 christos
2825 1.1 christos /* Called via bfd_map_over_sections. If SEC is a member of a group,
2826 1.1 christos add it to a list of sections belonging to the group. INF is a
2827 1.1 christos pointer to a struct group_list, which is where we store the head of
2828 1.8 christos each list. If its link_to_symbol_name isn't NULL, set up its
2829 1.8 christos linked-to section. */
2830 1.1 christos
2831 1.1 christos static void
2832 1.8 christos build_additional_section_info (bfd *abfd ATTRIBUTE_UNUSED,
2833 1.8 christos asection *sec, void *inf)
2834 1.1 christos {
2835 1.1 christos struct group_list *list = (struct group_list *) inf;
2836 1.1 christos const char *group_name = elf_group_name (sec);
2837 1.1 christos unsigned int i;
2838 1.1 christos unsigned int *elem_idx;
2839 1.1 christos unsigned int *idx_ptr;
2840 1.1 christos
2841 1.8 christos if (sec->map_head.linked_to_symbol_name)
2842 1.8 christos {
2843 1.8 christos symbolS *linked_to_sym;
2844 1.8 christos linked_to_sym = symbol_find (sec->map_head.linked_to_symbol_name);
2845 1.8 christos if (!linked_to_sym || !S_IS_DEFINED (linked_to_sym))
2846 1.8 christos as_bad (_("undefined linked-to symbol `%s' on section `%s'"),
2847 1.8 christos sec->map_head.linked_to_symbol_name,
2848 1.8 christos bfd_section_name (sec));
2849 1.8 christos else
2850 1.8 christos elf_linked_to_section (sec) = S_GET_SEGMENT (linked_to_sym);
2851 1.8 christos }
2852 1.8 christos
2853 1.1 christos if (group_name == NULL)
2854 1.1 christos return;
2855 1.1 christos
2856 1.1 christos /* If this group already has a list, add the section to the head of
2857 1.1 christos the list. */
2858 1.8 christos elem_idx = (unsigned int *) str_hash_find (list->indexes, group_name);
2859 1.1 christos if (elem_idx != NULL)
2860 1.1 christos {
2861 1.1 christos elf_next_in_group (sec) = list->head[*elem_idx];
2862 1.1 christos list->head[*elem_idx] = sec;
2863 1.1 christos return;
2864 1.1 christos }
2865 1.1 christos
2866 1.1 christos /* New group. Make the arrays bigger in chunks to minimize calls to
2867 1.1 christos realloc. */
2868 1.1 christos i = list->num_group;
2869 1.1 christos if ((i & 127) == 0)
2870 1.1 christos {
2871 1.1 christos unsigned int newsize = i + 128;
2872 1.5 christos list->head = XRESIZEVEC (asection *, list->head, newsize);
2873 1.1 christos }
2874 1.1 christos list->head[i] = sec;
2875 1.1 christos list->num_group += 1;
2876 1.1 christos
2877 1.1 christos /* Add index to hash. */
2878 1.5 christos idx_ptr = XNEW (unsigned int);
2879 1.1 christos *idx_ptr = i;
2880 1.8 christos str_hash_insert (list->indexes, group_name, idx_ptr, 0);
2881 1.1 christos }
2882 1.1 christos
2883 1.9 christos static void
2884 1.9 christos free_section_idx (void *ent)
2885 1.1 christos {
2886 1.9 christos string_tuple_t *tuple = ent;
2887 1.9 christos free ((char *) tuple->value);
2888 1.1 christos }
2889 1.1 christos
2890 1.6 christos /* Create symbols for group signature. */
2891 1.6 christos
2892 1.1 christos void
2893 1.1 christos elf_adjust_symtab (void)
2894 1.1 christos {
2895 1.1 christos unsigned int i;
2896 1.1 christos
2897 1.1 christos /* Go find section groups. */
2898 1.6 christos groups.num_group = 0;
2899 1.6 christos groups.head = NULL;
2900 1.9 christos groups.indexes = htab_create_alloc (16, hash_string_tuple, eq_string_tuple,
2901 1.9 christos free_section_idx, notes_calloc, NULL);
2902 1.8 christos bfd_map_over_sections (stdoutput, build_additional_section_info,
2903 1.8 christos &groups);
2904 1.3 christos
2905 1.1 christos /* Make the SHT_GROUP sections that describe each section group. We
2906 1.1 christos can't set up the section contents here yet, because elf section
2907 1.1 christos indices have yet to be calculated. elf.c:set_group_contents does
2908 1.1 christos the rest of the work. */
2909 1.6 christos for (i = 0; i < groups.num_group; i++)
2910 1.1 christos {
2911 1.6 christos const char *group_name = elf_group_name (groups.head[i]);
2912 1.1 christos const char *sec_name;
2913 1.1 christos asection *s;
2914 1.1 christos flagword flags;
2915 1.1 christos struct symbol *sy;
2916 1.1 christos
2917 1.1 christos flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_GROUP;
2918 1.6 christos for (s = groups.head[i]; s != NULL; s = elf_next_in_group (s))
2919 1.1 christos if ((s->flags ^ flags) & SEC_LINK_ONCE)
2920 1.1 christos {
2921 1.1 christos flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
2922 1.6 christos if (s != groups.head[i])
2923 1.1 christos {
2924 1.1 christos as_warn (_("assuming all members of group `%s' are COMDAT"),
2925 1.1 christos group_name);
2926 1.1 christos break;
2927 1.1 christos }
2928 1.1 christos }
2929 1.1 christos
2930 1.1 christos sec_name = ".group";
2931 1.1 christos s = subseg_force_new (sec_name, 0);
2932 1.1 christos if (s == NULL
2933 1.7 christos || !bfd_set_section_flags (s, flags)
2934 1.7 christos || !bfd_set_section_alignment (s, 2))
2935 1.1 christos {
2936 1.1 christos as_fatal (_("can't create group: %s"),
2937 1.1 christos bfd_errmsg (bfd_get_error ()));
2938 1.1 christos }
2939 1.1 christos elf_section_type (s) = SHT_GROUP;
2940 1.1 christos
2941 1.1 christos /* Pass a pointer to the first section in this group. */
2942 1.6 christos elf_next_in_group (s) = groups.head[i];
2943 1.6 christos elf_sec_group (groups.head[i]) = s;
2944 1.1 christos /* Make sure that the signature symbol for the group has the
2945 1.1 christos name of the group. */
2946 1.1 christos sy = symbol_find_exact (group_name);
2947 1.7 christos if (!sy || !symbol_on_chain (sy, symbol_rootP, symbol_lastP))
2948 1.1 christos {
2949 1.1 christos /* Create the symbol now. */
2950 1.8 christos sy = symbol_new (group_name, now_seg, frag_now, 0);
2951 1.1 christos #ifdef TE_SOLARIS
2952 1.1 christos /* Before Solaris 11 build 154, Sun ld rejects local group
2953 1.1 christos signature symbols, so make them weak hidden instead. */
2954 1.1 christos symbol_get_bfdsym (sy)->flags |= BSF_WEAK;
2955 1.1 christos S_SET_OTHER (sy, STV_HIDDEN);
2956 1.1 christos #else
2957 1.1 christos symbol_get_obj (sy)->local = 1;
2958 1.1 christos #endif
2959 1.1 christos symbol_table_insert (sy);
2960 1.1 christos }
2961 1.1 christos elf_group_id (s) = symbol_get_bfdsym (sy);
2962 1.8 christos /* Mark the group signature symbol as used so that it will be
2963 1.8 christos included in the symbol table. */
2964 1.8 christos symbol_mark_used_in_reloc (sy);
2965 1.1 christos }
2966 1.1 christos }
2967 1.1 christos
2968 1.1 christos void
2969 1.1 christos elf_frob_file (void)
2970 1.1 christos {
2971 1.1 christos bfd_map_over_sections (stdoutput, adjust_stab_sections, NULL);
2972 1.1 christos
2973 1.1 christos #ifdef elf_tc_final_processing
2974 1.1 christos elf_tc_final_processing ();
2975 1.1 christos #endif
2976 1.1 christos }
2977 1.1 christos
2978 1.1 christos /* It removes any unneeded versioned symbols from the symbol table. */
2979 1.1 christos
2980 1.1 christos void
2981 1.1 christos elf_frob_file_before_adjust (void)
2982 1.1 christos {
2983 1.1 christos if (symbol_rootP)
2984 1.1 christos {
2985 1.1 christos symbolS *symp;
2986 1.1 christos
2987 1.1 christos for (symp = symbol_rootP; symp; symp = symbol_next (symp))
2988 1.8 christos {
2989 1.8 christos struct elf_obj_sy *sy_obj = symbol_get_obj (symp);
2990 1.8 christos int is_defined = !!S_IS_DEFINED (symp);
2991 1.8 christos
2992 1.8 christos if (sy_obj->versioned_name)
2993 1.8 christos {
2994 1.8 christos char *p = strchr (sy_obj->versioned_name->name,
2995 1.8 christos ELF_VER_CHR);
2996 1.8 christos
2997 1.8 christos if (sy_obj->rename)
2998 1.8 christos {
2999 1.8 christos /* The @@@ syntax is a special case. If the symbol is
3000 1.8 christos not defined, 2 `@'s will be removed from the
3001 1.8 christos versioned_name. Otherwise, 1 `@' will be removed. */
3002 1.8 christos size_t l = strlen (&p[3]) + 1;
3003 1.8 christos memmove (&p[1 + is_defined], &p[3], l);
3004 1.8 christos }
3005 1.8 christos
3006 1.8 christos if (!is_defined)
3007 1.8 christos {
3008 1.8 christos /* Verify that the name isn't using the @@ syntax--this
3009 1.8 christos is reserved for definitions of the default version
3010 1.8 christos to link against. */
3011 1.8 christos if (!sy_obj->rename && p[1] == ELF_VER_CHR)
3012 1.8 christos {
3013 1.8 christos as_bad (_("invalid attempt to declare external "
3014 1.8 christos "version name as default in symbol `%s'"),
3015 1.8 christos sy_obj->versioned_name->name);
3016 1.8 christos return;
3017 1.8 christos }
3018 1.1 christos
3019 1.8 christos /* Only one version symbol is allowed for undefined
3020 1.8 christos symbol. */
3021 1.8 christos if (sy_obj->versioned_name->next)
3022 1.8 christos {
3023 1.8 christos as_bad (_("multiple versions [`%s'|`%s'] for "
3024 1.8 christos "symbol `%s'"),
3025 1.8 christos sy_obj->versioned_name->name,
3026 1.8 christos sy_obj->versioned_name->next->name,
3027 1.8 christos S_GET_NAME (symp));
3028 1.8 christos return;
3029 1.8 christos }
3030 1.1 christos
3031 1.8 christos sy_obj->rename = true;
3032 1.8 christos }
3033 1.8 christos }
3034 1.1 christos
3035 1.8 christos /* If there was .symver or .weak, but symbol was neither
3036 1.8 christos defined nor used anywhere, remove it. */
3037 1.8 christos if (!is_defined
3038 1.8 christos && (sy_obj->versioned_name || S_IS_WEAK (symp))
3039 1.8 christos && symbol_used_p (symp) == 0
3040 1.8 christos && symbol_used_in_reloc_p (symp) == 0)
3041 1.8 christos symbol_remove (symp, &symbol_rootP, &symbol_lastP);
3042 1.8 christos }
3043 1.1 christos }
3044 1.1 christos }
3045 1.1 christos
3046 1.1 christos /* It is required that we let write_relocs have the opportunity to
3047 1.1 christos optimize away fixups before output has begun, since it is possible
3048 1.1 christos to eliminate all fixups for a section and thus we never should
3049 1.1 christos have generated the relocation section. */
3050 1.1 christos
3051 1.1 christos void
3052 1.1 christos elf_frob_file_after_relocs (void)
3053 1.1 christos {
3054 1.6 christos unsigned int i;
3055 1.6 christos
3056 1.6 christos /* Set SHT_GROUP section size. */
3057 1.6 christos for (i = 0; i < groups.num_group; i++)
3058 1.6 christos {
3059 1.6 christos asection *s, *head, *group;
3060 1.6 christos bfd_size_type size;
3061 1.6 christos
3062 1.6 christos head = groups.head[i];
3063 1.6 christos size = 4;
3064 1.6 christos for (s = head; s != NULL; s = elf_next_in_group (s))
3065 1.6 christos size += (s->flags & SEC_RELOC) != 0 ? 8 : 4;
3066 1.6 christos
3067 1.6 christos group = elf_sec_group (head);
3068 1.6 christos subseg_set (group, 0);
3069 1.7 christos bfd_set_section_size (group, size);
3070 1.6 christos group->contents = (unsigned char *) frag_more (size);
3071 1.6 christos frag_now->fr_fix = frag_now_fix_octets ();
3072 1.6 christos frag_wane (frag_now);
3073 1.6 christos }
3074 1.6 christos
3075 1.1 christos #ifdef NEED_ECOFF_DEBUG
3076 1.1 christos if (ECOFF_DEBUGGING)
3077 1.1 christos /* Generate the ECOFF debugging information. */
3078 1.1 christos {
3079 1.1 christos const struct ecoff_debug_swap *debug_swap;
3080 1.1 christos struct ecoff_debug_info debug;
3081 1.1 christos char *buf;
3082 1.1 christos asection *sec;
3083 1.1 christos
3084 1.1 christos debug_swap
3085 1.1 christos = get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
3086 1.1 christos know (debug_swap != NULL);
3087 1.1 christos ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
3088 1.1 christos
3089 1.1 christos /* Set up the pointers in debug. */
3090 1.9 christos debug.alloc_syments = true;
3091 1.1 christos #define SET(ptr, offset, type) \
3092 1.1 christos debug.ptr = (type) (buf + debug.symbolic_header.offset)
3093 1.1 christos
3094 1.1 christos SET (line, cbLineOffset, unsigned char *);
3095 1.1 christos SET (external_dnr, cbDnOffset, void *);
3096 1.1 christos SET (external_pdr, cbPdOffset, void *);
3097 1.1 christos SET (external_sym, cbSymOffset, void *);
3098 1.1 christos SET (external_opt, cbOptOffset, void *);
3099 1.1 christos SET (external_aux, cbAuxOffset, union aux_ext *);
3100 1.1 christos SET (ss, cbSsOffset, char *);
3101 1.1 christos SET (external_fdr, cbFdOffset, void *);
3102 1.1 christos SET (external_rfd, cbRfdOffset, void *);
3103 1.1 christos /* ssext and external_ext are set up just below. */
3104 1.1 christos
3105 1.1 christos #undef SET
3106 1.1 christos
3107 1.1 christos /* Set up the external symbols. */
3108 1.1 christos debug.ssext = debug.ssext_end = NULL;
3109 1.1 christos debug.external_ext = debug.external_ext_end = NULL;
3110 1.8 christos if (! bfd_ecoff_debug_externals (stdoutput, &debug, debug_swap, true,
3111 1.1 christos elf_get_extr, elf_set_index))
3112 1.1 christos as_fatal (_("failed to set up debugging information: %s"),
3113 1.1 christos bfd_errmsg (bfd_get_error ()));
3114 1.1 christos
3115 1.1 christos sec = bfd_get_section_by_name (stdoutput, ".mdebug");
3116 1.1 christos gas_assert (sec != NULL);
3117 1.1 christos
3118 1.1 christos know (!stdoutput->output_has_begun);
3119 1.1 christos
3120 1.1 christos /* We set the size of the section, call bfd_set_section_contents
3121 1.1 christos to force the ELF backend to allocate a file position, and then
3122 1.1 christos write out the data. FIXME: Is this really the best way to do
3123 1.1 christos this? */
3124 1.7 christos bfd_set_section_size (sec, bfd_ecoff_debug_size (stdoutput, &debug,
3125 1.7 christos debug_swap));
3126 1.1 christos
3127 1.1 christos /* Pass BUF to bfd_set_section_contents because this will
3128 1.1 christos eventually become a call to fwrite, and ISO C prohibits
3129 1.1 christos passing a NULL pointer to a stdio function even if the
3130 1.1 christos pointer will not be used. */
3131 1.1 christos if (! bfd_set_section_contents (stdoutput, sec, buf, 0, 0))
3132 1.1 christos as_fatal (_("can't start writing .mdebug section: %s"),
3133 1.1 christos bfd_errmsg (bfd_get_error ()));
3134 1.1 christos
3135 1.1 christos know (stdoutput->output_has_begun);
3136 1.1 christos know (sec->filepos != 0);
3137 1.1 christos
3138 1.1 christos if (! bfd_ecoff_write_debug (stdoutput, &debug, debug_swap,
3139 1.1 christos sec->filepos))
3140 1.1 christos as_fatal (_("could not write .mdebug section: %s"),
3141 1.1 christos bfd_errmsg (bfd_get_error ()));
3142 1.1 christos }
3143 1.1 christos #endif /* NEED_ECOFF_DEBUG */
3144 1.1 christos }
3145 1.1 christos
3146 1.1 christos static void
3147 1.1 christos elf_generate_asm_lineno (void)
3148 1.1 christos {
3149 1.1 christos #ifdef NEED_ECOFF_DEBUG
3150 1.1 christos if (ECOFF_DEBUGGING)
3151 1.1 christos ecoff_generate_asm_lineno ();
3152 1.1 christos #endif
3153 1.1 christos }
3154 1.1 christos
3155 1.1 christos static void
3156 1.9 christos elf_process_stab (int what ATTRIBUTE_UNUSED,
3157 1.1 christos const char *string ATTRIBUTE_UNUSED,
3158 1.1 christos int type ATTRIBUTE_UNUSED,
3159 1.1 christos int other ATTRIBUTE_UNUSED,
3160 1.1 christos int desc ATTRIBUTE_UNUSED)
3161 1.1 christos {
3162 1.1 christos #ifdef NEED_ECOFF_DEBUG
3163 1.1 christos if (ECOFF_DEBUGGING)
3164 1.9 christos ecoff_stab (what, string, type, other, desc);
3165 1.1 christos #endif
3166 1.1 christos }
3167 1.1 christos
3168 1.1 christos static int
3169 1.1 christos elf_separate_stab_sections (void)
3170 1.1 christos {
3171 1.1 christos #ifdef NEED_ECOFF_DEBUG
3172 1.1 christos return (!ECOFF_DEBUGGING);
3173 1.1 christos #else
3174 1.1 christos return 1;
3175 1.1 christos #endif
3176 1.1 christos }
3177 1.1 christos
3178 1.1 christos static void
3179 1.9 christos elf_init_stab_section (segT stab, segT stabstr)
3180 1.1 christos {
3181 1.1 christos #ifdef NEED_ECOFF_DEBUG
3182 1.1 christos if (!ECOFF_DEBUGGING)
3183 1.1 christos #endif
3184 1.9 christos obj_elf_init_stab_section (stab, stabstr);
3185 1.9 christos }
3186 1.9 christos
3187 1.9 christos /* This is called when the assembler starts. */
3188 1.9 christos
3189 1.9 christos void
3190 1.9 christos elf_begin (void)
3191 1.9 christos {
3192 1.9 christos asection *s;
3193 1.9 christos
3194 1.9 christos /* Add symbols for the known sections to the symbol table. */
3195 1.9 christos s = bfd_get_section_by_name (stdoutput, TEXT_SECTION_NAME);
3196 1.9 christos symbol_table_insert (section_symbol (s));
3197 1.9 christos s = bfd_get_section_by_name (stdoutput, DATA_SECTION_NAME);
3198 1.9 christos symbol_table_insert (section_symbol (s));
3199 1.9 christos s = bfd_get_section_by_name (stdoutput, BSS_SECTION_NAME);
3200 1.9 christos symbol_table_insert (section_symbol (s));
3201 1.9 christos elf_com_section_ptr = bfd_com_section_ptr;
3202 1.9 christos previous_section = NULL;
3203 1.9 christos previous_subsection = 0;
3204 1.9 christos comment_section = NULL;
3205 1.9 christos memset (&groups, 0, sizeof (groups));
3206 1.9 christos }
3207 1.9 christos
3208 1.9 christos void
3209 1.9 christos elf_end (void)
3210 1.9 christos {
3211 1.9 christos while (section_stack)
3212 1.9 christos {
3213 1.9 christos struct section_stack *top = section_stack;
3214 1.9 christos section_stack = top->next;
3215 1.9 christos free (top);
3216 1.9 christos }
3217 1.9 christos while (recorded_attributes)
3218 1.9 christos {
3219 1.9 christos struct recorded_attribute_info *rai = recorded_attributes;
3220 1.9 christos recorded_attributes = rai->next;
3221 1.9 christos free (rai);
3222 1.9 christos }
3223 1.9 christos if (groups.indexes)
3224 1.9 christos {
3225 1.9 christos htab_delete (groups.indexes);
3226 1.9 christos free (groups.head);
3227 1.9 christos }
3228 1.1 christos }
3229 1.1 christos
3230 1.1 christos const struct format_ops elf_format_ops =
3231 1.1 christos {
3232 1.1 christos bfd_target_elf_flavour,
3233 1.1 christos 0, /* dfl_leading_underscore */
3234 1.1 christos 1, /* emit_section_symbols */
3235 1.1 christos elf_begin,
3236 1.9 christos elf_end,
3237 1.1 christos elf_file_symbol,
3238 1.1 christos elf_frob_symbol,
3239 1.1 christos elf_frob_file,
3240 1.1 christos elf_frob_file_before_adjust,
3241 1.1 christos 0, /* obj_frob_file_before_fix */
3242 1.1 christos elf_frob_file_after_relocs,
3243 1.1 christos elf_s_get_size, elf_s_set_size,
3244 1.1 christos elf_s_get_align, elf_s_set_align,
3245 1.1 christos elf_s_get_other,
3246 1.1 christos elf_s_set_other,
3247 1.1 christos 0, /* s_get_desc */
3248 1.1 christos 0, /* s_set_desc */
3249 1.1 christos 0, /* s_get_type */
3250 1.1 christos 0, /* s_set_type */
3251 1.1 christos elf_copy_symbol_attributes,
3252 1.1 christos elf_generate_asm_lineno,
3253 1.1 christos elf_process_stab,
3254 1.1 christos elf_separate_stab_sections,
3255 1.1 christos elf_init_stab_section,
3256 1.1 christos elf_sec_sym_ok_for_reloc,
3257 1.1 christos elf_pop_insert,
3258 1.1 christos #ifdef NEED_ECOFF_DEBUG
3259 1.1 christos elf_ecoff_set_ext,
3260 1.1 christos #else
3261 1.1 christos 0, /* ecoff_set_ext */
3262 1.1 christos #endif
3263 1.1 christos elf_obj_read_begin_hook,
3264 1.1 christos elf_obj_symbol_new_hook,
3265 1.8 christos elf_obj_symbol_clone_hook,
3266 1.1 christos elf_adjust_symtab
3267 1.1 christos };
3268