/* ELF object file format
Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to the Free
- Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
#define OBJ_HEADER "obj-elf.h"
#include "as.h"
#include "elf/i370.h"
#endif
-static bfd_vma elf_s_get_size PARAMS ((symbolS *));
-static void elf_s_set_size PARAMS ((symbolS *, bfd_vma));
-static bfd_vma elf_s_get_align PARAMS ((symbolS *));
-static void elf_s_set_align PARAMS ((symbolS *, bfd_vma));
-static void elf_s_set_other PARAMS ((symbolS *, int));
-static int elf_sec_sym_ok_for_reloc PARAMS ((asection *));
-static void adjust_stab_sections PARAMS ((bfd *, asection *, PTR));
-static void build_group_lists PARAMS ((bfd *, asection *, PTR));
-static int elf_separate_stab_sections PARAMS ((void));
-static void elf_init_stab_section PARAMS ((segT));
-static symbolS *elf_common PARAMS ((int));
-
-#ifdef NEED_ECOFF_DEBUG
-static bfd_boolean elf_get_extr PARAMS ((asymbol *, EXTR *));
-static void elf_set_index PARAMS ((asymbol *, bfd_size_type));
+#ifdef TC_I386
+#include "elf/x86-64.h"
#endif
-static void obj_elf_line PARAMS ((int));
-void obj_elf_version PARAMS ((int));
-static void obj_elf_size PARAMS ((int));
-static void obj_elf_type PARAMS ((int));
-static void obj_elf_ident PARAMS ((int));
-static void obj_elf_weak PARAMS ((int));
-static void obj_elf_local PARAMS ((int));
-static void obj_elf_visibility PARAMS ((int));
-static int obj_elf_parse_section_letters PARAMS ((char *, size_t));
-static int obj_elf_section_word PARAMS ((char *, size_t));
-static char *obj_elf_section_name PARAMS ((void));
-static int obj_elf_section_type PARAMS ((char *, size_t));
-static void obj_elf_symver PARAMS ((int));
-static void obj_elf_subsection PARAMS ((int));
-static void obj_elf_popsection PARAMS ((int));
-static void obj_elf_tls_common PARAMS ((int));
+static void obj_elf_line (int);
+static void obj_elf_size (int);
+static void obj_elf_type (int);
+static void obj_elf_ident (int);
+static void obj_elf_weak (int);
+static void obj_elf_local (int);
+static void obj_elf_visibility (int);
+static void obj_elf_symver (int);
+static void obj_elf_subsection (int);
+static void obj_elf_popsection (int);
+static void obj_elf_tls_common (int);
+static void obj_elf_lcomm (int);
+static void obj_elf_struct (int);
static const pseudo_typeS elf_pseudo_table[] =
{
{"comm", obj_elf_common, 0},
{"common", obj_elf_common, 1},
{"ident", obj_elf_ident, 0},
+ {"lcomm", obj_elf_lcomm, 0},
{"local", obj_elf_local, 0},
{"previous", obj_elf_previous, 0},
{"section", obj_elf_section, 0},
{"subsection", obj_elf_subsection, 0},
/* These are GNU extensions to aid in garbage collecting C++ vtables. */
- {"vtable_inherit", (void (*) PARAMS ((int))) &obj_elf_vtable_inherit, 0},
- {"vtable_entry", (void (*) PARAMS ((int))) &obj_elf_vtable_entry, 0},
+ {"vtable_inherit", (void (*) (int)) &obj_elf_vtable_inherit, 0},
+ {"vtable_entry", (void (*) (int)) &obj_elf_vtable_entry, 0},
/* These are used for dwarf. */
{"2byte", cons, 2},
{"4byte", cons, 4},
{"8byte", cons, 8},
/* These are used for dwarf2. */
- { "file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0 },
+ { "file", (void (*) (int)) dwarf2_directive_file, 0 },
{ "loc", dwarf2_directive_loc, 0 },
+ { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 },
/* We need to trap the section changing calls to handle .previous. */
{"data", obj_elf_data, 0},
+ {"offset", obj_elf_struct, 0},
+ {"struct", obj_elf_struct, 0},
{"text", obj_elf_text, 0},
{"tls_common", obj_elf_tls_common, 0},
/* This is called when the assembler starts. */
+asection *elf_com_section_ptr;
+
void
-elf_begin ()
+elf_begin (void)
{
+ asection *s;
+
/* Add symbols for the known sections to the symbol table. */
- symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput,
- TEXT_SECTION_NAME)));
- symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput,
- DATA_SECTION_NAME)));
- symbol_table_insert (section_symbol (bfd_get_section_by_name (stdoutput,
- BSS_SECTION_NAME)));
+ s = bfd_get_section_by_name (stdoutput, TEXT_SECTION_NAME);
+ symbol_table_insert (section_symbol (s));
+ s = bfd_get_section_by_name (stdoutput, DATA_SECTION_NAME);
+ symbol_table_insert (section_symbol (s));
+ s = bfd_get_section_by_name (stdoutput, BSS_SECTION_NAME);
+ symbol_table_insert (section_symbol (s));
+ elf_com_section_ptr = bfd_com_section_ptr;
}
void
-elf_pop_insert ()
+elf_pop_insert (void)
{
pop_insert (elf_pseudo_table);
if (ECOFF_DEBUGGING)
}
static bfd_vma
-elf_s_get_size (sym)
- symbolS *sym;
+elf_s_get_size (symbolS *sym)
{
return S_GET_SIZE (sym);
}
static void
-elf_s_set_size (sym, sz)
- symbolS *sym;
- bfd_vma sz;
+elf_s_set_size (symbolS *sym, bfd_vma sz)
{
S_SET_SIZE (sym, sz);
}
static bfd_vma
-elf_s_get_align (sym)
- symbolS *sym;
+elf_s_get_align (symbolS *sym)
{
return S_GET_ALIGN (sym);
}
static void
-elf_s_set_align (sym, align)
- symbolS *sym;
- bfd_vma align;
+elf_s_set_align (symbolS *sym, bfd_vma align)
{
S_SET_ALIGN (sym, align);
}
int
-elf_s_get_other (sym)
- symbolS *sym;
+elf_s_get_other (symbolS *sym)
{
return elf_symbol (symbol_get_bfdsym (sym))->internal_elf_sym.st_other;
}
static void
-elf_s_set_other (sym, other)
- symbolS *sym;
- int other;
+elf_s_set_other (symbolS *sym, int other)
{
S_SET_OTHER (sym, other);
}
static int
-elf_sec_sym_ok_for_reloc (sec)
- asection *sec;
+elf_sec_sym_ok_for_reloc (asection *sec)
{
return obj_sec_sym_ok_for_reloc (sec);
}
void
-elf_file_symbol (s)
- const char *s;
+elf_file_symbol (const char *s, int appfile)
{
- symbolS *sym;
+ if (!appfile
+ || symbol_rootP == NULL
+ || symbol_rootP->bsym == NULL
+ || (symbol_rootP->bsym->flags & BSF_FILE) == 0)
+ {
+ symbolS *sym;
- sym = symbol_new (s, absolute_section, (valueT) 0, (struct frag *) 0);
- symbol_set_frag (sym, &zero_address_frag);
- symbol_get_bfdsym (sym)->flags |= BSF_FILE;
+ sym = symbol_new (s, absolute_section, 0, NULL);
+ symbol_set_frag (sym, &zero_address_frag);
+ symbol_get_bfdsym (sym)->flags |= BSF_FILE;
- if (symbol_rootP != sym)
- {
- symbol_remove (sym, &symbol_rootP, &symbol_lastP);
- symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
+ if (symbol_rootP != sym)
+ {
+ symbol_remove (sym, &symbol_rootP, &symbol_lastP);
+ symbol_insert (sym, symbol_rootP, &symbol_rootP, &symbol_lastP);
#ifdef DEBUG
- verify_symbol_chain (symbol_rootP, symbol_lastP);
+ verify_symbol_chain (symbol_rootP, symbol_lastP);
#endif
+ }
}
#ifdef NEED_ECOFF_DEBUG
- ecoff_new_file (s);
+ ecoff_new_file (s, appfile);
#endif
}
-static symbolS *
-elf_common (is_common)
- int is_common;
+/* Called from read.c:s_comm after we've parsed .comm symbol, size.
+ Parse a possible alignment value. */
+
+symbolS *
+elf_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size)
{
- char *name;
- char c;
- char *p;
- offsetT temp, size, sign;
- symbolS *symbolP;
- int have_align;
- expressionS exp;
+ addressT align = 0;
+ int is_local = symbol_get_obj (symbolP)->local;
- if (flag_mri && is_common)
+ if (*input_line_pointer == ',')
{
- s_mri_common (0);
- return NULL;
- }
+ char *save = input_line_pointer;
- name = input_line_pointer;
- c = get_symbol_end ();
- /* just after name is now '\0' */
- p = input_line_pointer;
- *p = c;
- SKIP_WHITESPACE ();
- if (*input_line_pointer != ',')
- {
- as_bad (_("expected comma after symbol-name"));
- ignore_rest_of_line ();
- return NULL;
- }
- input_line_pointer++; /* skip ',' */
- temp = get_absolute_expr (&exp);
- sign = (offsetT) 1 << (stdoutput->arch_info->bits_per_address - 1);
- size = temp & ((sign << 1) - 1);
- if (temp != size || !exp.X_unsigned)
- {
- as_bad (_(".COMMon length (%ld) out of range, ignored."), (long) temp);
- ignore_rest_of_line ();
- return NULL;
- }
- *p = 0;
- symbolP = symbol_find_or_make (name);
- *p = c;
- if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
- {
- as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP));
- ignore_rest_of_line ();
- return NULL;
- }
- if (S_GET_VALUE (symbolP) != 0)
- {
- if (S_GET_VALUE (symbolP) != (valueT) size)
- {
- as_warn (_("length of .comm \"%s\" is already %ld; not changed to %ld"),
- S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP),
- (long) size);
- }
- }
- know (symbolP->sy_frag == &zero_address_frag);
- if (*input_line_pointer != ',')
- have_align = 0;
- else
- {
- have_align = 1;
input_line_pointer++;
SKIP_WHITESPACE ();
- }
- if (! have_align || *input_line_pointer != '"')
- {
- if (! have_align)
- temp = 0;
- else
- {
- temp = get_absolute_expr (&exp);
- if (!exp.X_unsigned)
- {
- temp = 0;
- as_warn (_("common alignment negative; 0 assumed"));
- }
- }
- if (symbol_get_obj (symbolP)->local)
+
+ if (*input_line_pointer == '"')
{
- segT old_sec;
- int old_subsec;
- char *pfrag;
- int align;
-
- /* allocate_bss: */
- old_sec = now_seg;
- old_subsec = now_subseg;
- if (temp)
+ /* For sparc. Accept .common symbol, length, "bss" */
+ input_line_pointer++;
+ /* Some use the dot, some don't. */
+ if (*input_line_pointer == '.')
+ input_line_pointer++;
+ /* Some say data, some say bss. */
+ if (strncmp (input_line_pointer, "bss\"", 4) == 0)
+ input_line_pointer += 4;
+ else if (strncmp (input_line_pointer, "data\"", 5) == 0)
+ input_line_pointer += 5;
+ else
{
- /* convert to a power of 2 alignment */
- for (align = 0; (temp & 1) == 0; temp >>= 1, ++align);
- if (temp != 1)
- {
- as_bad (_("common alignment not a power of 2"));
- ignore_rest_of_line ();
- return NULL;
- }
+ char *p = input_line_pointer;
+ char c;
+
+ while (*--p != '"')
+ ;
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ if (*input_line_pointer++ == '"')
+ break;
+ c = *input_line_pointer;
+ *input_line_pointer = '\0';
+ as_bad (_("bad .common segment %s"), p);
+ *input_line_pointer = c;
+ ignore_rest_of_line ();
+ return NULL;
}
- else
- align = 0;
- record_alignment (bss_section, align);
- subseg_set (bss_section, 0);
- if (align)
- frag_align (align, 0, 0);
- if (S_GET_SEGMENT (symbolP) == bss_section)
- symbol_get_frag (symbolP)->fr_symbol = 0;
- symbol_set_frag (symbolP, frag_now);
- pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
- (offsetT) size, (char *) 0);
- *pfrag = 0;
- S_SET_SIZE (symbolP, size);
- S_SET_SEGMENT (symbolP, bss_section);
- S_CLEAR_EXTERNAL (symbolP);
- subseg_set (old_sec, old_subsec);
+ /* ??? Don't ask me why these are always global. */
+ is_local = 0;
}
else
{
- allocate_common:
- S_SET_VALUE (symbolP, (valueT) size);
- S_SET_ALIGN (symbolP, temp);
- S_SET_EXTERNAL (symbolP);
- S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
+ input_line_pointer = save;
+ align = parse_align (is_local);
+ if (align == (addressT) -1)
+ return NULL;
}
}
+
+ if (is_local)
+ {
+ bss_alloc (symbolP, size, align);
+ S_CLEAR_EXTERNAL (symbolP);
+ }
else
{
- input_line_pointer++;
- /* @@ Some use the dot, some don't. Can we get some consistency?? */
- if (*input_line_pointer == '.')
- input_line_pointer++;
- /* @@ Some say data, some say bss. */
- if (strncmp (input_line_pointer, "bss\"", 4)
- && strncmp (input_line_pointer, "data\"", 5))
- {
- while (*--input_line_pointer != '"')
- ;
- input_line_pointer--;
- goto bad_common_segment;
- }
- while (*input_line_pointer++ != '"')
- ;
- goto allocate_common;
+ S_SET_VALUE (symbolP, size);
+ S_SET_ALIGN (symbolP, align);
+ S_SET_EXTERNAL (symbolP);
+ S_SET_SEGMENT (symbolP, elf_com_section_ptr);
}
symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
- demand_empty_rest_of_line ();
return symbolP;
-
- {
- bad_common_segment:
- p = input_line_pointer;
- while (*p && *p != '\n')
- p++;
- c = *p;
- *p = '\0';
- as_bad (_("bad .common segment %s"), input_line_pointer + 1);
- *p = c;
- input_line_pointer = p;
- ignore_rest_of_line ();
- return NULL;
- }
}
void
-obj_elf_common (is_common)
- int is_common;
+obj_elf_common (int is_common)
{
- elf_common (is_common);
+ if (flag_mri && is_common)
+ s_mri_common (0);
+ else
+ s_comm_internal (0, elf_common_parse);
}
static void
-obj_elf_tls_common (ignore)
- int ignore ATTRIBUTE_UNUSED;
+obj_elf_tls_common (int ignore ATTRIBUTE_UNUSED)
{
- symbolS *symbolP = elf_common (0);
+ symbolS *symbolP = s_comm_internal (0, elf_common_parse);
if (symbolP)
symbol_get_bfdsym (symbolP)->flags |= BSF_THREAD_LOCAL;
}
static void
-obj_elf_local (ignore)
- int ignore ATTRIBUTE_UNUSED;
+obj_elf_lcomm (int ignore ATTRIBUTE_UNUSED)
+{
+ symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
+
+ if (symbolP)
+ symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
+}
+
+static void
+obj_elf_local (int ignore ATTRIBUTE_UNUSED)
{
char *name;
int c;
}
static void
-obj_elf_weak (ignore)
- int ignore ATTRIBUTE_UNUSED;
+obj_elf_weak (int ignore ATTRIBUTE_UNUSED)
{
char *name;
int c;
}
static void
-obj_elf_visibility (visibility)
- int visibility;
+obj_elf_visibility (int visibility)
{
char *name;
int c;
static struct section_stack *section_stack;
+static bfd_boolean
+get_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
+{
+ const char *gname = inf;
+ const char *group_name = elf_group_name (sec);
+
+ return (group_name == gname
+ || (group_name != NULL
+ && gname != NULL
+ && strcmp (group_name, gname) == 0));
+}
+
/* Handle the .section pseudo-op. This code supports two different
syntaxes.
BFD doesn't really let us set the section type. */
void
-obj_elf_change_section (name, type, attr, entsize, group_name, linkonce, push)
- const char *name;
- int type;
- int attr;
- int entsize;
- const char *group_name;
- int linkonce;
- int push;
+obj_elf_change_section (const char *name,
+ int type,
+ int attr,
+ int entsize,
+ const char *group_name,
+ int linkonce,
+ int push)
{
asection *old_sec;
segT sec;
flagword flags;
+ const struct elf_backend_data *bed;
const struct bfd_elf_special_section *ssect;
#ifdef md_flush_pending_output
previous_section = now_seg;
previous_subsection = now_subseg;
- old_sec = bfd_get_section_by_name (stdoutput, name);
- sec = subseg_new (name, 0);
- ssect = _bfd_elf_get_sec_type_attr (stdoutput, name);
+ old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section,
+ (void *) group_name);
+ if (old_sec)
+ {
+ sec = old_sec;
+ subseg_set (sec, 0);
+ }
+ else
+ sec = subseg_force_new (name, 0);
+
+ bed = get_elf_backend_data (stdoutput);
+ ssect = (*bed->get_sec_type_attr) (stdoutput, sec);
if (ssect != NULL)
{
.section .init_array,"aw",@progbits
for __attribute__ ((section (".init_array"))).
+ "@progbits" is incorrect. Also for x86-64 large bss
+ sections, gcc, as of 2005-07-06, will emit
+
+ .section .lbss,"aw",@progbits
+
"@progbits" is incorrect. */
+#ifdef TC_I386
+ && (bed->s->arch_size != 64
+ || !(ssect->attr & SHF_X86_64_LARGE))
+#endif
&& ssect->type != SHT_INIT_ARRAY
&& ssect->type != SHT_FINI_ARRAY
&& ssect->type != SHT_PREINIT_ARRAY)
|| strcmp (name, ".strtab") == 0
|| strcmp (name, ".symtab") == 0))
override = TRUE;
+ /* .note.GNU-stack can have SHF_EXECINSTR. */
+ else if (attr == SHF_EXECINSTR
+ && strcmp (name, ".note.GNU-stack") == 0)
+ override = TRUE;
+#ifdef TC_ALPHA
+ /* A section on Alpha may have SHF_ALPHA_GPREL. */
+ else if ((attr & ~ssect->attr) == SHF_ALPHA_GPREL)
+ override = TRUE;
+#endif
else
{
- as_warn (_("setting incorrect section attributes for %s"),
- name);
+ if (group_name == NULL)
+ as_warn (_("setting incorrect section attributes for %s"),
+ name);
override = TRUE;
}
}
attr |= ssect->attr;
}
- if (type != SHT_NULL)
- elf_section_type (sec) = type;
- if (attr != 0)
- elf_section_flags (sec) = attr;
-
/* Convert ELF type and flags to BFD flags. */
flags = (SEC_RELOC
| ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
flags = md_elf_section_flags (flags, attr, type);
#endif
+ if (linkonce)
+ flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
+
if (old_sec == NULL)
{
symbolS *secsym;
+ elf_section_type (sec) = type;
+ elf_section_flags (sec) = attr;
+
/* Prevent SEC_HAS_CONTENTS from being inadvertently set. */
if (type == SHT_NOBITS)
- seg_info (sec)->bss = 1;
+ seg_info (sec)->bss = 1;
- if (linkonce)
- flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
bfd_set_section_flags (stdoutput, sec, flags);
if (flags & SEC_MERGE)
sec->entsize = entsize;
if (secsym != NULL)
symbol_set_bfdsym (secsym, sec->symbol);
else
- symbol_table_insert (section_symbol (sec));
+ symbol_table_insert (section_symbol (sec));
}
- else if (attr != 0)
+ else
{
- /* If section attributes are specified the second time we see a
- particular section, then check that they are the same as we
- saw the first time. */
- if (((old_sec->flags ^ flags)
- & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
- | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS
- | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
- | SEC_THREAD_LOCAL)))
- as_warn (_("ignoring changed section attributes for %s"), name);
- if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
- as_warn (_("ignoring changed section entity size for %s"), name);
- if ((attr & SHF_GROUP) != 0
- && strcmp (elf_group_name (old_sec), group_name) != 0)
- as_warn (_("ignoring new section group for %s"), name);
+ if (type != SHT_NULL
+ && (unsigned) type != elf_section_type (old_sec))
+ as_warn (_("ignoring changed section type for %s"), name);
+
+ if (attr != 0)
+ {
+ /* If section attributes are specified the second time we see a
+ particular section, then check that they are the same as we
+ saw the first time. */
+ if (((old_sec->flags ^ flags)
+ & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
+ | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS
+ | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
+ | SEC_THREAD_LOCAL)))
+ as_warn (_("ignoring changed section attributes for %s"), name);
+ if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
+ as_warn (_("ignoring changed section entity size for %s"), name);
+ }
}
#ifdef md_elf_section_change_hook
}
static int
-obj_elf_parse_section_letters (str, len)
- char *str;
- size_t len;
+obj_elf_parse_section_letters (char *str, size_t len)
{
int attr = 0;
}
static int
-obj_elf_section_word (str, len)
- char *str;
- size_t len;
+obj_elf_section_word (char *str, size_t len)
{
if (len == 5 && strncmp (str, "write", 5) == 0)
return SHF_WRITE;
}
static int
-obj_elf_section_type (str, len)
- char *str;
- size_t len;
+obj_elf_section_type (char *str, size_t len)
{
if (len == 8 && strncmp (str, "progbits", 8) == 0)
return SHT_PROGBITS;
return SHT_NOBITS;
if (len == 4 && strncmp (str, "note", 4) == 0)
return SHT_NOTE;
+ if (len == 10 && strncmp (str, "init_array", 10) == 0)
+ return SHT_INIT_ARRAY;
+ if (len == 10 && strncmp (str, "fini_array", 10) == 0)
+ return SHT_FINI_ARRAY;
+ if (len == 13 && strncmp (str, "preinit_array", 13) == 0)
+ return SHT_PREINIT_ARRAY;
#ifdef md_elf_section_type
{
/* Get name of section. */
static char *
-obj_elf_section_name ()
+obj_elf_section_name (void)
{
char *name;
end++;
if (end == input_line_pointer)
{
- as_warn (_("missing name"));
+ as_bad (_("missing name"));
ignore_rest_of_line ();
return NULL;
}
}
void
-obj_elf_section (push)
- int push;
+obj_elf_section (int push)
{
char *name, *group_name, *beg;
int type, attr, dummy;
SKIP_WHITESPACE ();
if (*input_line_pointer != '#')
{
- as_warn (_("character following name is not '#'"));
+ as_bad (_("character following name is not '#'"));
ignore_rest_of_line ();
return;
}
/* Change to the .data section. */
void
-obj_elf_data (i)
- int i;
+obj_elf_data (int i)
{
#ifdef md_flush_pending_output
md_flush_pending_output ();
/* Change to the .text section. */
void
-obj_elf_text (i)
- int i;
+obj_elf_text (int i)
{
#ifdef md_flush_pending_output
md_flush_pending_output ();
#endif
}
+/* Change to the *ABS* section. */
+
+void
+obj_elf_struct (int i)
+{
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ previous_section = now_seg;
+ previous_subsection = now_subseg;
+ s_struct (i);
+
+#ifdef md_elf_section_change_hook
+ md_elf_section_change_hook ();
+#endif
+}
+
static void
-obj_elf_subsection (ignore)
- int ignore ATTRIBUTE_UNUSED;
+obj_elf_subsection (int ignore ATTRIBUTE_UNUSED)
{
register int temp;
sections. */
void
-obj_elf_section_change_hook ()
+obj_elf_section_change_hook (void)
{
previous_section = now_seg;
previous_subsection = now_subseg;
}
void
-obj_elf_previous (ignore)
- int ignore ATTRIBUTE_UNUSED;
+obj_elf_previous (int ignore ATTRIBUTE_UNUSED)
{
segT new_section;
int new_subsection;
}
static void
-obj_elf_popsection (xxx)
- int xxx ATTRIBUTE_UNUSED;
+obj_elf_popsection (int xxx ATTRIBUTE_UNUSED)
{
struct section_stack *top = section_stack;
}
static void
-obj_elf_line (ignore)
- int ignore ATTRIBUTE_UNUSED;
+obj_elf_line (int ignore ATTRIBUTE_UNUSED)
{
/* Assume delimiter is part of expression. BSD4.2 as fails with
delightful bug, so we are not being incompatible here. */
- new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
+ new_logical_line (NULL, get_absolute_expression ());
demand_empty_rest_of_line ();
}
with the same value as the symbol NAME. */
static void
-obj_elf_symver (ignore)
- int ignore ATTRIBUTE_UNUSED;
+obj_elf_symver (int ignore ATTRIBUTE_UNUSED)
{
char *name;
char c;
syntax is ".vtable_inherit CHILDNAME, PARENTNAME". */
struct fix *
-obj_elf_vtable_inherit (ignore)
- int ignore ATTRIBUTE_UNUSED;
+obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
{
char *cname, *pname;
symbolS *csym, *psym;
".vtable_entry tablename, offset". */
struct fix *
-obj_elf_vtable_entry (ignore)
- int ignore ATTRIBUTE_UNUSED;
+obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED)
{
char *name;
symbolS *sym;
}
void
-elf_obj_read_begin_hook ()
+elf_obj_read_begin_hook (void)
{
#ifdef NEED_ECOFF_DEBUG
if (ECOFF_DEBUGGING)
}
void
-elf_obj_symbol_new_hook (symbolP)
- symbolS *symbolP;
+elf_obj_symbol_new_hook (symbolS *symbolP)
{
struct elf_obj_sy *sy_obj;
context. */
void
-elf_copy_symbol_attributes (dest, src)
- symbolS *dest, *src;
+elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
{
struct elf_obj_sy *srcelf = symbol_get_obj (src);
struct elf_obj_sy *destelf = symbol_get_obj (dest);
if (srcelf->size)
{
if (destelf->size == NULL)
- destelf->size =
- (expressionS *) xmalloc (sizeof (expressionS));
+ destelf->size = xmalloc (sizeof (expressionS));
*destelf->size = *srcelf->size;
}
else
}
void
-obj_elf_version (ignore)
- int ignore ATTRIBUTE_UNUSED;
+obj_elf_version (int ignore ATTRIBUTE_UNUSED)
{
char *name;
unsigned int c;
subsegT subseg = now_subseg;
Elf_Internal_Note i_note;
Elf_External_Note e_note;
- asection *note_secp = (asection *) NULL;
- int len;
+ asection *note_secp = NULL;
SKIP_WHITESPACE ();
if (*input_line_pointer == '\"')
{
+ unsigned int len;
+
++input_line_pointer; /* -> 1st char of string. */
name = input_line_pointer;
*(input_line_pointer - 1) = '\0';
*input_line_pointer = c;
- /* create the .note section */
-
+ /* Create the .note section. */
note_secp = subseg_new (".note", 0);
bfd_set_section_flags (stdoutput,
note_secp,
SEC_HAS_CONTENTS | SEC_READONLY);
- /* process the version string */
-
- len = strlen (name);
+ /* Process the version string. */
+ len = strlen (name) + 1;
- i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
- i_note.descsz = 0; /* no description */
+ /* PR 3456: Although the name field is padded out to an 4-byte
+ boundary, the namesz field should not be adjusted. */
+ i_note.namesz = len;
+ i_note.descsz = 0; /* No description. */
i_note.type = NT_VERSION;
p = frag_more (sizeof (e_note.namesz));
- md_number_to_chars (p, (valueT) i_note.namesz, sizeof (e_note.namesz));
+ md_number_to_chars (p, i_note.namesz, sizeof (e_note.namesz));
p = frag_more (sizeof (e_note.descsz));
- md_number_to_chars (p, (valueT) i_note.descsz, sizeof (e_note.descsz));
+ md_number_to_chars (p, i_note.descsz, sizeof (e_note.descsz));
p = frag_more (sizeof (e_note.type));
- md_number_to_chars (p, (valueT) i_note.type, sizeof (e_note.type));
- p = frag_more (len + 1);
- strcpy (p, name);
+ md_number_to_chars (p, i_note.type, sizeof (e_note.type));
+ p = frag_more (len);
+ memcpy (p, name, len);
frag_align (2, 0, 0);
subseg_set (seg, subseg);
}
else
- {
- as_bad (_("expected quoted string"));
- }
+ as_bad (_("expected quoted string"));
+
demand_empty_rest_of_line ();
}
static void
-obj_elf_size (ignore)
- int ignore ATTRIBUTE_UNUSED;
+obj_elf_size (int ignore ATTRIBUTE_UNUSED)
{
char *name = input_line_pointer;
char c = get_symbol_end ();
}
else
{
- symbol_get_obj (sym)->size =
- (expressionS *) xmalloc (sizeof (expressionS));
+ symbol_get_obj (sym)->size = xmalloc (sizeof (expressionS));
*symbol_get_obj (sym)->size = exp;
}
demand_empty_rest_of_line ();
*/
static void
-obj_elf_type (ignore)
- int ignore ATTRIBUTE_UNUSED;
+obj_elf_type (int ignore ATTRIBUTE_UNUSED)
{
char *name;
char c;
}
static void
-obj_elf_ident (ignore)
- int ignore ATTRIBUTE_UNUSED;
+obj_elf_ident (int ignore ATTRIBUTE_UNUSED)
{
static segT comment_section;
segT old_section = now_seg;
/* The first entry in a .stabs section is special. */
void
-obj_elf_init_stab_section (seg)
- segT seg;
+obj_elf_init_stab_section (segT seg)
{
char *file;
char *p;
p = frag_more (12);
/* Zero it out. */
memset (p, 0, 12);
- as_where (&file, (unsigned int *) NULL);
- stabstr_name = (char *) xmalloc (strlen (segment_name (seg)) + 4);
+ as_where (&file, NULL);
+ stabstr_name = xmalloc (strlen (segment_name (seg)) + 4);
strcpy (stabstr_name, segment_name (seg));
strcat (stabstr_name, "str");
stroff = get_stab_string_offset (file, stabstr_name);
/* Fill in the counts in the first entry in a .stabs section. */
static void
-adjust_stab_sections (abfd, sec, xxx)
- bfd *abfd;
- asection *sec;
- PTR xxx ATTRIBUTE_UNUSED;
+adjust_stab_sections (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
{
char *name;
asection *strsec;
if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
return;
- name = (char *) alloca (strlen (sec->name) + 4);
+ name = alloca (strlen (sec->name) + 4);
strcpy (name, sec->name);
strcat (name, "str");
strsec = bfd_get_section_by_name (abfd, name);
p = seg_info (sec)->stabu.p;
assert (p != 0);
- bfd_h_put_16 (abfd, (bfd_vma) nsyms, (bfd_byte *) p + 6);
- bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
+ bfd_h_put_16 (abfd, nsyms, p + 6);
+ bfd_h_put_32 (abfd, strsz, p + 8);
}
#ifdef NEED_ECOFF_DEBUG
in the symbol. */
void
-elf_ecoff_set_ext (sym, ext)
- symbolS *sym;
- struct ecoff_extr *ext;
+elf_ecoff_set_ext (symbolS *sym, struct ecoff_extr *ext)
{
- symbol_get_bfdsym (sym)->udata.p = (PTR) ext;
+ symbol_get_bfdsym (sym)->udata.p = ext;
}
/* This function is called by bfd_ecoff_debug_externals. It is
whether the symbol should be used at all. */
static bfd_boolean
-elf_get_extr (sym, ext)
- asymbol *sym;
- EXTR *ext;
+elf_get_extr (asymbol *sym, EXTR *ext)
{
if (sym->udata.p == NULL)
return FALSE;
nothing to do for ELF. */
static void
-elf_set_index (sym, indx)
- asymbol *sym ATTRIBUTE_UNUSED;
- bfd_size_type indx ATTRIBUTE_UNUSED;
+elf_set_index (asymbol *sym ATTRIBUTE_UNUSED,
+ bfd_size_type indx ATTRIBUTE_UNUSED)
{
}
#endif /* NEED_ECOFF_DEBUG */
void
-elf_frob_symbol (symp, puntp)
- symbolS *symp;
- int *puntp;
+elf_frob_symbol (symbolS *symp, int *puntp)
{
struct elf_obj_sy *sy_obj;
/* This symbol was given a new name with the .symver directive.
- If this is an external reference, just rename the symbol to
- include the version string. This will make the relocs be
- against the correct versioned symbol.
+ If this is an external reference, just rename the symbol to
+ include the version string. This will make the relocs be
+ against the correct versioned symbol.
If this is a definition, add an alias. FIXME: Using an alias
will permit the debugging information to refer to the right
if (! S_IS_DEFINED (symp))
{
/* Verify that the name isn't using the @@ syntax--this is
- reserved for definitions of the default version to link
- against. */
+ reserved for definitions of the default version to link
+ against. */
if (p[1] == ELF_VER_CHR)
{
as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"),
}
else
{
- if (p [1] == ELF_VER_CHR && p [2] == ELF_VER_CHR)
+ if (p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
{
size_t l;
/* The @@@ syntax is a special case. It renames the
symbol name to versioned_name with one `@' removed. */
l = strlen (&p[3]) + 1;
- memmove (&p [2], &p[3], l);
+ memmove (&p[2], &p[3], l);
S_SET_NAME (symp, sy_obj->versioned_name);
}
else
&& (symbol_get_bfdsym (symp)->flags & BSF_FUNCTION) == 0)
symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
#endif
-
-#if 0 /* TC_PPC */
- /* If TC_PPC is defined, we used to force the type of a symbol to be
- BSF_OBJECT if it was otherwise unset. This was required by some
- that this is no longer needed, so it is now commented out. */
- if ((symbol_get_bfdsym (symp)->flags
- & (BSF_FUNCTION | BSF_FILE | BSF_SECTION_SYM)) == 0
- && S_IS_DEFINED (symp))
- symbol_get_bfdsym (symp)->flags |= BSF_OBJECT;
-#endif
}
struct group_list
each list. */
static void
-build_group_lists (abfd, sec, inf)
- bfd *abfd ATTRIBUTE_UNUSED;
- asection *sec;
- PTR inf;
+build_group_lists (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
{
- struct group_list *list = (struct group_list *) inf;
+ struct group_list *list = inf;
const char *group_name = elf_group_name (sec);
unsigned int i;
}
void
-elf_frob_file ()
+elf_frob_file (void)
{
struct group_list list;
unsigned int i;
- bfd_map_over_sections (stdoutput, adjust_stab_sections, (PTR) 0);
+ bfd_map_over_sections (stdoutput, adjust_stab_sections, NULL);
/* Go find section groups. */
list.num_group = 0;
list.head = NULL;
list.elt_count = NULL;
- bfd_map_over_sections (stdoutput, build_group_lists, (PTR) &list);
+ bfd_map_over_sections (stdoutput, build_group_lists, &list);
/* Make the SHT_GROUP sections that describe each section group. We
can't set up the section contents here yet, because elf section
flagword flags;
struct symbol *sy;
int has_sym;
+ bfd_size_type size;
flags = SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_GROUP;
for (s = list.head[i]; s != NULL; s = elf_next_in_group (s))
if (has_sym)
elf_group_id (s) = sy->bsym;
- s->_raw_size = 4 * (list.elt_count[i] + 1);
- s->contents = frag_more (s->_raw_size);
+ size = 4 * (list.elt_count[i] + 1);
+ bfd_set_section_size (stdoutput, s, size);
+ s->contents = (unsigned char *) frag_more (size);
frag_now->fr_fix = frag_now_fix_octets ();
}
/* It removes any unneeded versioned symbols from the symbol table. */
void
-elf_frob_file_before_adjust ()
+elf_frob_file_before_adjust (void)
{
if (symbol_rootP)
{
p = strchr (symbol_get_obj (symp)->versioned_name,
ELF_VER_CHR);
know (p != NULL);
- if (p [1] == ELF_VER_CHR && p [2] == ELF_VER_CHR)
+ if (p[1] == ELF_VER_CHR && p[2] == ELF_VER_CHR)
{
size_t l = strlen (&p[3]) + 1;
- memmove (&p [1], &p[3], l);
+ memmove (&p[1], &p[3], l);
}
if (symbol_used_p (symp) == 0
&& symbol_used_in_reloc_p (symp) == 0)
have generated the relocation section. */
void
-elf_frob_file_after_relocs ()
+elf_frob_file_after_relocs (void)
{
#ifdef NEED_ECOFF_DEBUG
if (ECOFF_DEBUGGING)
debug_swap
= get_elf_backend_data (stdoutput)->elf_backend_ecoff_debug_swap;
- know (debug_swap != (const struct ecoff_debug_swap *) NULL);
+ know (debug_swap != NULL);
ecoff_build_debug (&debug.symbolic_header, &buf, debug_swap);
/* Set up the pointers in debug. */
debug.ptr = (type) (buf + debug.symbolic_header.offset)
SET (line, cbLineOffset, unsigned char *);
- SET (external_dnr, cbDnOffset, PTR);
- SET (external_pdr, cbPdOffset, PTR);
- SET (external_sym, cbSymOffset, PTR);
- SET (external_opt, cbOptOffset, PTR);
+ SET (external_dnr, cbDnOffset, void *);
+ SET (external_pdr, cbPdOffset, void *);
+ SET (external_sym, cbSymOffset, void *);
+ SET (external_opt, cbOptOffset, void *);
SET (external_aux, cbAuxOffset, union aux_ext *);
SET (ss, cbSsOffset, char *);
- SET (external_fdr, cbFdOffset, PTR);
- SET (external_rfd, cbRfdOffset, PTR);
+ SET (external_fdr, cbFdOffset, void *);
+ SET (external_rfd, cbRfdOffset, void *);
/* ssext and external_ext are set up just below. */
#undef SET
to force the ELF backend to allocate a file position, and then
write out the data. FIXME: Is this really the best way to do
this? */
- sec->_raw_size = bfd_ecoff_debug_size (stdoutput, &debug, debug_swap);
+ bfd_set_section_size
+ (stdoutput, sec, bfd_ecoff_debug_size (stdoutput, &debug, debug_swap));
/* Pass BUF to bfd_set_section_contents because this will
- eventually become a call to fwrite, and ISO C prohibits
- passing a NULL pointer to a stdio function even if the
- pointer will not be used. */
- if (! bfd_set_section_contents (stdoutput, sec, (PTR) buf,
- (file_ptr) 0, (bfd_size_type) 0))
+ eventually become a call to fwrite, and ISO C prohibits
+ passing a NULL pointer to a stdio function even if the
+ pointer will not be used. */
+ if (! bfd_set_section_contents (stdoutput, sec, buf, 0, 0))
as_fatal (_("can't start writing .mdebug section: %s"),
bfd_errmsg (bfd_get_error ()));
int_32 version = (major ver # << 16) | version of tools ;
int_32 source = (tool_id << 16 ) | 1 ;
int_32 info = 0 ; These are set by the SCO tools, but we
- don't know enough about the source
+ don't know enough about the source
environment to set them. SCO ld currently
ignores them, and recommends we set them
to zero. */
#define SCO_MINOR_VERSION 0x1
void
-sco_id ()
+sco_id (void)
{
char *name;
subsegT subseg = now_subseg;
Elf_Internal_Note i_note;
Elf_External_Note e_note;
- asection *note_secp = (asection *) NULL;
+ asection *note_secp = NULL;
int i, len;
/* create the .note section */
i_note.type = NT_VERSION; /* Contains a version string */
p = frag_more (sizeof (i_note.namesz));
- md_number_to_chars (p, (valueT) i_note.namesz, 4);
+ md_number_to_chars (p, i_note.namesz, 4);
p = frag_more (sizeof (i_note.descsz));
- md_number_to_chars (p, (valueT) i_note.descsz, 4);
+ md_number_to_chars (p, i_note.descsz, 4);
p = frag_more (sizeof (i_note.type));
- md_number_to_chars (p, (valueT) i_note.type, 4);
+ md_number_to_chars (p, i_note.type, 4);
p = frag_more (4);
strcpy (p, "SCO");
#endif /* SCO_ELF */
static int
-elf_separate_stab_sections ()
+elf_separate_stab_sections (void)
{
#ifdef NEED_ECOFF_DEBUG
return (!ECOFF_DEBUGGING);
}
static void
-elf_init_stab_section (seg)
- segT seg;
+elf_init_stab_section (segT seg)
{
#ifdef NEED_ECOFF_DEBUG
if (!ECOFF_DEBUGGING)