X-Git-Url: https://oss.titaniummirror.com/gitweb?p=msp430-binutils.git;a=blobdiff_plain;f=gas%2Fconfig%2Fobj-elf.c;fp=gas%2Fconfig%2Fobj-elf.c;h=532b319166c27044cd76a798a0a544c43aae79ad;hp=014117a69591c951a9cab7027c5ec8b6a3c1c475;hb=88750007d7869f178f0ba528f41efd3b74c424cf;hpb=6df9443a374e2b81278c61b8afc0a1eef7db280b diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index 014117a..532b319 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -1,6 +1,6 @@ /* ELF object file format Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -260,9 +260,20 @@ elf_file_symbol (const char *s, int appfile) || (symbol_rootP->bsym->flags & BSF_FILE) == 0) { symbolS *sym; + unsigned int name_length; sym = symbol_new (s, absolute_section, 0, NULL); symbol_set_frag (sym, &zero_address_frag); + + name_length = strlen (s); + if (name_length > strlen (S_GET_NAME (sym))) + { + obstack_grow (¬es, s, name_length + 1); + S_SET_NAME (sym, (const char *) obstack_finish (¬es)); + } + else + strcpy ((char *) S_GET_NAME (sym), s); + symbol_get_bfdsym (sym)->flags |= BSF_FILE; if (symbol_rootP != sym) @@ -459,7 +470,7 @@ obj_elf_visibility (int visibility) bfdsym = symbol_get_bfdsym (symbolP); elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym); - assert (elfsym); + gas_assert (elfsym); elfsym->internal_elf_sym.st_other &= ~3; elfsym->internal_elf_sym.st_other |= visibility; @@ -494,9 +505,9 @@ 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 *gname = (const char *) inf; const char *group_name = elf_group_name (sec); - + return (group_name == gname || (group_name != NULL && gname != NULL @@ -524,7 +535,7 @@ get_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf) void obj_elf_change_section (const char *name, int type, - int attr, + bfd_vma attr, int entsize, const char *group_name, int linkonce, @@ -544,7 +555,7 @@ obj_elf_change_section (const char *name, if (push) { struct section_stack *elt; - elt = xmalloc (sizeof (struct section_stack)); + elt = (struct section_stack *) xmalloc (sizeof (struct section_stack)); elt->next = section_stack; elt->seg = now_seg; elt->prev_seg = previous_section; @@ -674,6 +685,8 @@ obj_elf_change_section (const char *name, { symbolS *secsym; + if (type == SHT_NULL) + type = bfd_elf_get_default_section_type (flags); elf_section_type (sec) = type; elf_section_flags (sec) = attr; @@ -720,10 +733,10 @@ obj_elf_change_section (const char *name, #endif } -static int +static bfd_vma obj_elf_parse_section_letters (char *str, size_t len) { - int attr = 0; + bfd_vma attr = 0; while (len > 0) { @@ -766,8 +779,8 @@ obj_elf_parse_section_letters (char *str, size_t len) { char *bad_msg = _("unrecognized .section attribute: want a,w,x,M,S,G,T"); #ifdef md_elf_section_letter - int md_attr = md_elf_section_letter (*str, &bad_msg); - if (md_attr >= 0) + bfd_vma md_attr = md_elf_section_letter (*str, &bad_msg); + if (md_attr > 0) attr |= md_attr; else #endif @@ -782,31 +795,7 @@ obj_elf_parse_section_letters (char *str, size_t len) } static int -obj_elf_section_word (char *str, size_t len) -{ - if (len == 5 && strncmp (str, "write", 5) == 0) - return SHF_WRITE; - if (len == 5 && strncmp (str, "alloc", 5) == 0) - return SHF_ALLOC; - if (len == 9 && strncmp (str, "execinstr", 9) == 0) - return SHF_EXECINSTR; - if (len == 3 && strncmp (str, "tls", 3) == 0) - return SHF_TLS; - -#ifdef md_elf_section_word - { - int md_attr = md_elf_section_word (str, len); - if (md_attr >= 0) - return md_attr; - } -#endif - - as_warn (_("unrecognized section attribute")); - return 0; -} - -static int -obj_elf_section_type (char *str, size_t len) +obj_elf_section_type (char *str, size_t len, bfd_boolean warn) { if (len == 8 && strncmp (str, "progbits", 8) == 0) return SHT_PROGBITS; @@ -829,7 +818,39 @@ obj_elf_section_type (char *str, size_t len) } #endif - as_warn (_("unrecognized section type")); + if (warn) + as_warn (_("unrecognized section type")); + return 0; +} + +static bfd_vma +obj_elf_section_word (char *str, size_t len, int *type) +{ + int ret; + + if (len == 5 && strncmp (str, "write", 5) == 0) + return SHF_WRITE; + if (len == 5 && strncmp (str, "alloc", 5) == 0) + return SHF_ALLOC; + if (len == 9 && strncmp (str, "execinstr", 9) == 0) + return SHF_EXECINSTR; + if (len == 3 && strncmp (str, "tls", 3) == 0) + return SHF_TLS; + +#ifdef md_elf_section_word + { + bfd_vma md_attr = md_elf_section_word (str, len); + if (md_attr > 0) + return md_attr; + } +#endif + + ret = obj_elf_section_type (str, len, FALSE); + if (ret != 0) + *type = ret; + else + as_warn (_("unrecognized section attribute")); + return 0; } @@ -864,7 +885,7 @@ obj_elf_section_name (void) return NULL; } - name = xmalloc (end - input_line_pointer + 1); + name = (char *) xmalloc (end - input_line_pointer + 1); memcpy (name, input_line_pointer, end - input_line_pointer); name[end - input_line_pointer] = '\0'; #ifdef tc_canonicalize_section_name @@ -880,9 +901,11 @@ void obj_elf_section (int push) { char *name, *group_name, *beg; - int type, attr, dummy; + int type, dummy; + bfd_vma attr; int entsize; int linkonce; + subsegT new_subsection = -1; #ifndef TC_I370 if (flag_mri) @@ -921,6 +944,22 @@ obj_elf_section (int push) ++input_line_pointer; SKIP_WHITESPACE (); + if (push && ISDIGIT (*input_line_pointer)) + { + /* .pushsection has an optional subsection. */ + new_subsection = (subsegT) get_absolute_expression (); + + SKIP_WHITESPACE (); + + /* Stop if we don't see a comma. */ + if (*input_line_pointer != ',') + goto done; + + /* Skip the comma. */ + ++input_line_pointer; + SKIP_WHITESPACE (); + } + if (*input_line_pointer == '"') { beg = demand_copy_C_string (&dummy); @@ -948,14 +987,14 @@ obj_elf_section (int push) ignore_rest_of_line (); return; } - type = obj_elf_section_type (beg, strlen (beg)); + type = obj_elf_section_type (beg, strlen (beg), TRUE); } else if (c == '@' || c == '%') { beg = ++input_line_pointer; c = get_symbol_end (); *input_line_pointer = c; - type = obj_elf_section_type (beg, input_line_pointer - beg); + type = obj_elf_section_type (beg, input_line_pointer - beg, TRUE); } else input_line_pointer = save; @@ -1018,7 +1057,7 @@ obj_elf_section (int push) c = get_symbol_end (); *input_line_pointer = c; - attr |= obj_elf_section_word (beg, input_line_pointer - beg); + attr |= obj_elf_section_word (beg, input_line_pointer - beg, & type); SKIP_WHITESPACE (); } @@ -1027,9 +1066,13 @@ obj_elf_section (int push) } } +done: demand_empty_rest_of_line (); obj_elf_change_section (name, type, attr, entsize, group_name, linkonce, push); + + if (push && new_subsection != -1) + subseg_set (now_seg, new_subsection); } /* Change to the .data section. */ @@ -1089,7 +1132,7 @@ obj_elf_struct (int i) static void obj_elf_subsection (int ignore ATTRIBUTE_UNUSED) { - register int temp; + int temp; #ifdef md_flush_pending_output md_flush_pending_output (); @@ -1275,7 +1318,7 @@ obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED) if (csym == NULL || symbol_get_frag (csym) == NULL) { - as_bad ("expected `%s' to have already been set for .vtable_inherit", + as_bad (_("expected `%s' to have already been set for .vtable_inherit"), cname); bad = 1; } @@ -1285,7 +1328,7 @@ obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED) SKIP_WHITESPACE (); if (*input_line_pointer != ',') { - as_bad ("expected comma after name in .vtable_inherit"); + as_bad (_("expected comma after name in .vtable_inherit")); ignore_rest_of_line (); return NULL; } @@ -1316,7 +1359,7 @@ obj_elf_vtable_inherit (int ignore ATTRIBUTE_UNUSED) if (bad) return NULL; - assert (symbol_get_value_expression (csym)->X_op == O_constant); + gas_assert (symbol_get_value_expression (csym)->X_op == O_constant); return fix_new (symbol_get_frag (csym), symbol_get_value_expression (csym)->X_add_number, 0, psym, 0, 0, BFD_RELOC_VTABLE_INHERIT); @@ -1345,7 +1388,7 @@ obj_elf_vtable_entry (int ignore ATTRIBUTE_UNUSED) SKIP_WHITESPACE (); if (*input_line_pointer != ',') { - as_bad ("expected comma after name in .vtable_entry"); + as_bad (_("expected comma after name in .vtable_entry")); ignore_rest_of_line (); return NULL; } @@ -1398,7 +1441,7 @@ elf_copy_symbol_attributes (symbolS *dest, symbolS *src) if (srcelf->size) { if (destelf->size == NULL) - destelf->size = xmalloc (sizeof (expressionS)); + destelf->size = (expressionS *) xmalloc (sizeof (expressionS)); *destelf->size = *srcelf->size; } else @@ -1515,14 +1558,15 @@ obj_elf_size (int ignore ATTRIBUTE_UNUSED) } else { - symbol_get_obj (sym)->size = xmalloc (sizeof (expressionS)); + symbol_get_obj (sym)->size = + (expressionS *) xmalloc (sizeof (expressionS)); *symbol_get_obj (sym)->size = exp; } demand_empty_rest_of_line (); } /* Handle the ELF .type pseudo-op. This sets the type of a symbol. - There are five syntaxes: + There are six syntaxes: The first (used on Solaris) is .type SYM,#function @@ -1534,15 +1578,39 @@ obj_elf_size (int ignore ATTRIBUTE_UNUSED) .type SYM,%function The fifth (used on SVR4/860) is .type SYM,"function" + The sixth (emitted by recent SunPRO under Solaris) is + .type SYM,[0-9] + where the integer is the STT_* value. */ +static char * +obj_elf_type_name (char *cp) +{ + char *p; + + p = input_line_pointer; + if (*input_line_pointer >= '0' + && *input_line_pointer <= '9') + { + while (*input_line_pointer >= '0' + && *input_line_pointer <= '9') + ++input_line_pointer; + *cp = *input_line_pointer; + *input_line_pointer = '\0'; + } + else + *cp = get_symbol_end (); + + return p; +} + static void obj_elf_type (int ignore ATTRIBUTE_UNUSED) { char *name; char c; int type; - const char *typename; + const char *type_name; symbolS *sym; elf_symbol_type *elfsym; @@ -1563,28 +1631,87 @@ obj_elf_type (int ignore ATTRIBUTE_UNUSED) || *input_line_pointer == '%') ++input_line_pointer; - typename = input_line_pointer; - c = get_symbol_end (); + type_name = obj_elf_type_name (& c); type = 0; - if (strcmp (typename, "function") == 0 - || strcmp (typename, "STT_FUNC") == 0) + if (strcmp (type_name, "function") == 0 + || strcmp (type_name, "2") == 0 + || strcmp (type_name, "STT_FUNC") == 0) type = BSF_FUNCTION; - else if (strcmp (typename, "object") == 0 - || strcmp (typename, "STT_OBJECT") == 0) + else if (strcmp (type_name, "object") == 0 + || strcmp (type_name, "1") == 0 + || strcmp (type_name, "STT_OBJECT") == 0) type = BSF_OBJECT; - else if (strcmp (typename, "tls_object") == 0 - || strcmp (typename, "STT_TLS") == 0) + else if (strcmp (type_name, "tls_object") == 0 + || strcmp (type_name, "6") == 0 + || strcmp (type_name, "STT_TLS") == 0) type = BSF_OBJECT | BSF_THREAD_LOCAL; - else if (strcmp (typename, "notype") == 0 - || strcmp (typename, "STT_NOTYPE") == 0) + else if (strcmp (type_name, "notype") == 0 + || strcmp (type_name, "0") == 0 + || strcmp (type_name, "STT_NOTYPE") == 0) ; + else if (strcmp (type_name, "common") == 0 + || strcmp (type_name, "5") == 0 + || strcmp (type_name, "STT_COMMON") == 0) + { + type = BSF_OBJECT; + + if (! S_IS_COMMON (sym)) + { + if (S_IS_VOLATILE (sym)) + { + sym = symbol_clone (sym, 1); + S_SET_SEGMENT (sym, bfd_com_section_ptr); + S_SET_VALUE (sym, 0); + S_SET_EXTERNAL (sym); + symbol_set_frag (sym, &zero_address_frag); + S_CLEAR_VOLATILE (sym); + } + else if (S_IS_DEFINED (sym) || symbol_equated_p (sym)) + as_bad (_("symbol '%s' is already defined"), S_GET_NAME (sym)); + else + { + /* FIXME: Is it safe to just change the section ? */ + S_SET_SEGMENT (sym, bfd_com_section_ptr); + S_SET_VALUE (sym, 0); + S_SET_EXTERNAL (sym); + } + } + } + else if (strcmp (type_name, "gnu_indirect_function") == 0 + || strcmp (type_name, "10") == 0 + || strcmp (type_name, "STT_GNU_IFUNC") == 0) + { + const struct elf_backend_data *bed; + + bed = get_elf_backend_data (stdoutput); + if (!(bed->elf_osabi == ELFOSABI_LINUX + /* GNU/Linux is still using the default value 0. */ + || bed->elf_osabi == ELFOSABI_NONE)) + as_bad (_("symbol type \"%s\" is supported only by GNU targets"), + type_name); + type = BSF_FUNCTION | BSF_GNU_INDIRECT_FUNCTION; + } + else if (strcmp (type_name, "gnu_unique_object") == 0) + { + struct elf_backend_data *bed; + + bed = (struct elf_backend_data *) get_elf_backend_data (stdoutput); + if (!(bed->elf_osabi == ELFOSABI_LINUX + /* GNU/Linux is still using the default value 0. */ + || bed->elf_osabi == ELFOSABI_NONE)) + as_bad (_("symbol type \"%s\" is supported only by GNU targets"), + type_name); + type = BSF_OBJECT | BSF_GNU_UNIQUE; + /* PR 10549: Always set OSABI field to LINUX for objects containing unique symbols. */ + bed->elf_osabi = ELFOSABI_LINUX; + } #ifdef md_elf_symbol_type - else if ((type = md_elf_symbol_type (typename, sym, elfsym)) != -1) + else if ((type = md_elf_symbol_type (type_name, sym, elfsym)) != -1) ; #endif else - as_bad (_("unrecognized symbol type \"%s\""), typename); + as_bad (_("unrecognized symbol type \"%s\""), type_name); *input_line_pointer = c; @@ -1612,13 +1739,18 @@ obj_elf_ident (int ignore ATTRIBUTE_UNUSED) char *p; comment_section = subseg_new (".comment", 0); bfd_set_section_flags (stdoutput, comment_section, - SEC_READONLY | SEC_HAS_CONTENTS); + SEC_READONLY | SEC_HAS_CONTENTS + | SEC_MERGE | SEC_STRINGS); + comment_section->entsize = 1; +#ifdef md_elf_section_change_hook + md_elf_section_change_hook (); +#endif p = frag_more (1); *p = 0; } else subseg_set (comment_section, 0); - stringer (1); + stringer (8 + 1); subseg_set (old_section, old_subsection); } @@ -1643,7 +1775,7 @@ obj_elf_init_stab_section (segT seg) /* Zero it out. */ memset (p, 0, 12); as_where (&file, NULL); - stabstr_name = xmalloc (strlen (segment_name (seg)) + 4); + stabstr_name = (char *) xmalloc (strlen (segment_name (seg)) + 4); strcpy (stabstr_name, segment_name (seg)); strcat (stabstr_name, "str"); stroff = get_stab_string_offset (file, stabstr_name); @@ -1669,7 +1801,7 @@ adjust_stab_sections (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED) if (!strcmp ("str", sec->name + strlen (sec->name) - 3)) return; - name = alloca (strlen (sec->name) + 4); + name = (char *) alloca (strlen (sec->name) + 4); strcpy (name, sec->name); strcat (name, "str"); strsec = bfd_get_section_by_name (abfd, name); @@ -1680,7 +1812,7 @@ adjust_stab_sections (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED) nsyms = bfd_section_size (abfd, sec) / 12 - 1; p = seg_info (sec)->stabu.p; - assert (p != 0); + gas_assert (p != 0); bfd_h_put_16 (abfd, nsyms, p + 6); bfd_h_put_32 (abfd, strsz, p + 8); @@ -1885,7 +2017,7 @@ struct group_list static void build_group_lists (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf) { - struct group_list *list = inf; + struct group_list *list = (struct group_list *) inf; const char *group_name = elf_group_name (sec); unsigned int i; @@ -1911,9 +2043,10 @@ build_group_lists (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf) if ((i & 127) == 0) { unsigned int newsize = i + 128; - list->head = xrealloc (list->head, newsize * sizeof (*list->head)); - list->elt_count = xrealloc (list->elt_count, - newsize * sizeof (*list->elt_count)); + list->head = (asection **) xrealloc (list->head, + newsize * sizeof (*list->head)); + list->elt_count = (unsigned int *) + xrealloc (list->elt_count, newsize * sizeof (*list->elt_count)); } list->head[i] = sec; list->elt_count[i] = 1; @@ -2091,7 +2224,7 @@ elf_frob_file_after_relocs (void) bfd_errmsg (bfd_get_error ())); sec = bfd_get_section_by_name (stdoutput, ".mdebug"); - assert (sec != NULL); + gas_assert (sec != NULL); know (!stdoutput->output_has_begun);