/* ELF object file format
- Copyright (C) 1992-2014 Free Software Foundation, Inc.
+ Copyright (C) 1992-2016 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
|| (symbol_rootP->bsym->flags & BSF_FILE) == 0)
{
symbolS *sym;
- unsigned int name_length;
+ size_t name_length;
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)
+ if (symbol_rootP != sym
+ && (symbol_rootP->bsym == NULL
+ || !(symbol_rootP->bsym->flags & BSF_FILE)))
{
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
char c;
symbolS *sym;
- name = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (& name);
sym = symbol_find_or_make (name);
*input_line_pointer = c;
- SKIP_WHITESPACE ();
+ SKIP_WHITESPACE_AFTER_NAME ();
/* There is no symbol name if input_line_pointer has not moved. */
if (name == input_line_pointer)
void
obj_elf_change_section (const char *name,
- int type,
+ unsigned int type,
bfd_vma attr,
int entsize,
const char *group_name,
if (push)
{
struct section_stack *elt;
- elt = (struct section_stack *) xmalloc (sizeof (struct section_stack));
+ elt = XNEW (struct section_stack);
elt->next = section_stack;
elt->seg = now_seg;
elt->prev_seg = previous_section;
&& ssect->type != SHT_PREINIT_ARRAY)
{
/* We allow to specify any type for a .note section. */
- if (ssect->type != SHT_NOTE)
+ if (ssect->type != SHT_NOTE
+ /* Processor and application defined types are allowed too. */
+ && type < SHT_LOPROC)
as_warn (_("setting incorrect section type for %s"),
name);
}
}
}
- if (old_sec == NULL && (attr & ~ssect->attr) != 0)
+ if (old_sec == NULL && ((attr & ~(SHF_MASKOS | SHF_MASKPROC))
+ & ~ssect->attr) != 0)
{
/* As a GNU extension, we permit a .note section to be
allocatable. If the linker sees an allocatable .note
override = TRUE;
}
}
+
if (!override && old_sec == NULL)
attr |= ssect->attr;
}
| SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
| SEC_THREAD_LOCAL)))
as_warn (_("ignoring changed section attributes for %s"), name);
+ else
+ /* FIXME: Maybe we should consider removing a previously set
+ processor or application specific attribute as suspicious ? */
+ elf_section_flags (sec) = attr;
+
if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
as_warn (_("ignoring changed section entity size for %s"), name);
}
}
default:
{
- char *bad_msg = _("unrecognized .section attribute: want a,e,w,x,M,S,G,T");
+ const char *bad_msg = _("unrecognized .section attribute:"
+ " want a,e,w,x,M,S,G,T or number");
#ifdef md_elf_section_letter
bfd_vma md_attr = md_elf_section_letter (*str, &bad_msg);
if (md_attr != (bfd_vma) -1)
attr |= md_attr;
else
#endif
- as_fatal ("%s", bad_msg);
+ if (ISDIGIT (*str))
+ {
+ char * end;
+
+ attr |= strtoul (str, & end, 0);
+ /* Update str and len, allowing for the fact that
+ we will execute str++ and len-- below. */
+ end --;
+ len -= (end - str);
+ str = end;
+ }
+ else
+ as_fatal ("%s", bad_msg);
}
break;
}
}
#endif
+ if (ISDIGIT (*str))
+ {
+ char * end;
+ int type = strtoul (str, & end, 0);
+
+ if (warn && (size_t) (end - str) != len)
+ as_warn (_("extraneous characters at end of numeric section type"));
+
+ return type;
+ }
+
if (warn)
as_warn (_("unrecognized section type"));
return 0;
}
/* Get name of section. */
-char *
+const char *
obj_elf_section_name (void)
{
char *name;
return NULL;
}
- name = (char *) xmalloc (end - input_line_pointer + 1);
- memcpy (name, input_line_pointer, end - input_line_pointer);
- name[end - input_line_pointer] = '\0';
+ name = xmemdup0 (input_line_pointer, end - input_line_pointer);
+
+ while (flag_sectname_subst)
+ {
+ char *subst = strchr (name, '%');
+ if (subst && subst[1] == 'S')
+ {
+ int oldlen = strlen (name);
+ int substlen = strlen (now_seg->name);
+ int newlen = oldlen - 2 + substlen;
+ char *newname = XNEWVEC (char, newlen + 1);
+ int headlen = subst - name;
+ memcpy (newname, name, headlen);
+ strcpy (newname + headlen, now_seg->name);
+ strcat (newname + headlen, subst + 2);
+ xfree (name);
+ name = newname;
+ }
+ else
+ break;
+ }
+
#ifdef tc_canonicalize_section_name
name = tc_canonicalize_section_name (name);
#endif
void
obj_elf_section (int push)
{
- char *name, *group_name, *beg;
+ const char *name, *group_name;
+ char *beg;
int type, dummy;
bfd_vma attr;
int entsize;
}
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, TRUE);
+ ++input_line_pointer;
+
+ if (ISDIGIT (* input_line_pointer))
+ {
+ type = strtoul (input_line_pointer, & input_line_pointer, 0);
+ }
+ else
+ {
+ c = get_symbol_name (& beg);
+ (void) restore_line_pointer (c);
+ type = obj_elf_section_type (beg, input_line_pointer - beg, TRUE);
+ }
}
else
input_line_pointer = save;
ignore_rest_of_line ();
return;
}
- beg = ++input_line_pointer;
- c = get_symbol_end ();
- *input_line_pointer = c;
+ ++input_line_pointer;
+ c = get_symbol_name (& beg);
+ (void) restore_line_pointer (c);
attr |= obj_elf_section_word (beg, input_line_pointer - beg, & type);
++input_line_pointer;
SKIP_WHITESPACE ();
- name = input_line_pointer;
/* Temporarily include '@' in symbol names. */
old_lexat = lex_type[(unsigned char) '@'];
lex_type[(unsigned char) '@'] |= LEX_NAME;
- c = get_symbol_end ();
+ c = get_symbol_name (& name);
lex_type[(unsigned char) '@'] = old_lexat;
if (symbol_get_obj (sym)->versioned_name == NULL)
{
symbol_get_obj (sym)->versioned_name = xstrdup (name);
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
if (strchr (symbol_get_obj (sym)->versioned_name,
ELF_VER_CHR) == NULL)
return;
}
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
}
demand_empty_rest_of_line ();
if (*input_line_pointer == '#')
++input_line_pointer;
- cname = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (& cname);
csym = symbol_find (cname);
/* GCFIXME: should check that we don't have two .vtable_inherits for
*input_line_pointer = c;
- SKIP_WHITESPACE ();
+ SKIP_WHITESPACE_AFTER_NAME ();
if (*input_line_pointer != ',')
{
as_bad (_("expected comma after name in .vtable_inherit"));
}
else
{
- pname = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (& pname);
psym = symbol_find_or_make (pname);
- *input_line_pointer = c;
+ restore_line_pointer (c);
}
demand_empty_rest_of_line ();
if (i == 0)
goto bad;
- name = (char *) alloca (i + 1);
- memcpy (name, s, i);
- name[i] = '\0';
+ name = xstrndup (s, i);
#ifndef CONVERT_SYMBOLIC_ATTRIBUTE
#define CONVERT_SYMBOLIC_ATTRIBUTE(a) -1
{
as_bad (_("Attribute name not recognised: %s"), name);
ignore_rest_of_line ();
+ free (name);
return 0;
}
+ free (name);
}
type = _bfd_elf_obj_attrs_arg_type (stdoutput, vendor, tag);
if (srcelf->size)
{
if (destelf->size == NULL)
- destelf->size = (expressionS *) xmalloc (sizeof (expressionS));
+ destelf->size = XNEW (expressionS);
*destelf->size = *srcelf->size;
}
else
static void
obj_elf_size (int ignore ATTRIBUTE_UNUSED)
{
- char *name = input_line_pointer;
- char c = get_symbol_end ();
+ char *name;
+ char c = get_symbol_name (&name);
char *p;
expressionS exp;
symbolS *sym;
p = input_line_pointer;
*p = c;
- SKIP_WHITESPACE ();
+ SKIP_WHITESPACE_AFTER_NAME ();
if (*input_line_pointer != ',')
{
*p = 0;
}
else
{
- symbol_get_obj (sym)->size =
- (expressionS *) xmalloc (sizeof (expressionS));
+ symbol_get_obj (sym)->size = XNEW (expressionS);
*symbol_get_obj (sym)->size = exp;
}
demand_empty_rest_of_line ();
*input_line_pointer = '\0';
}
else
- *cp = get_symbol_end ();
+ *cp = get_symbol_name (&p);
return p;
}
void
obj_elf_init_stab_section (segT seg)
{
- char *file;
+ const char *file;
char *p;
char *stabstr_name;
unsigned int stroff;
p = frag_more (12);
/* Zero it out. */
memset (p, 0, 12);
- as_where (&file, NULL);
- stabstr_name = (char *) xmalloc (strlen (segment_name (seg)) + 4);
- strcpy (stabstr_name, segment_name (seg));
- strcat (stabstr_name, "str");
+ file = as_where (NULL);
+ stabstr_name = concat (segment_name (seg), "str", (char *) NULL);
stroff = get_stab_string_offset (file, stabstr_name);
know (stroff == 1 || (stroff == 0 && file[0] == '\0'));
md_number_to_chars (p, stroff, 4);
if (!strcmp ("str", sec->name + strlen (sec->name) - 3))
return;
- name = (char *) alloca (strlen (sec->name) + 4);
- strcpy (name, sec->name);
- strcat (name, "str");
+ name = concat (sec->name, "str", NULL);
strsec = bfd_get_section_by_name (abfd, name);
if (strsec)
strsz = bfd_section_size (abfd, strsec);
bfd_h_put_16 (abfd, nsyms, p + 6);
bfd_h_put_32 (abfd, strsz, p + 8);
+ free (name);
}
#ifdef NEED_ECOFF_DEBUG
S_SET_SIZE (symp, size->X_add_number);
else
{
- if (flag_size_check == size_check_error)
+ if (!flag_allow_nonconst_size)
as_bad (_(".size expression for %s "
"does not evaluate to a constant"), S_GET_NAME (symp));
else
if ((i & 127) == 0)
{
unsigned int newsize = i + 128;
- 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 = XRESIZEVEC (asection *, list->head, newsize);
+ list->elt_count = XRESIZEVEC (unsigned int, list->elt_count, newsize);
}
list->head[i] = sec;
list->elt_count[i] = 1;
list->num_group += 1;
/* Add index to hash. */
- idx_ptr = (unsigned int *) xmalloc (sizeof (unsigned int));
+ idx_ptr = XNEW (unsigned int);
*idx_ptr = i;
hash_insert (list->indexes, group_name, idx_ptr);
}
list.elt_count = NULL;
list.indexes = hash_new ();
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
indices have yet to be calculated. elf.c:set_group_contents does