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