bfd:
* elf-attrs.c: New. * Makefile.am (BFD32_BACKENDS): Add elf-attrs.lo. (BFD32_BACKENDS_CFILES): Add elf-attrs.c. (elf-attrs.lo): Generate dependencies. * Makefile.in: Regenerate. * configure.in (elf): Add elf-attrs.lo. * configure: Regenerate. * elf-bfd.h (struct elf_backend_data): Add entries for object attributes. (NUM_KNOWN_OBJ_ATTRIBUTES, obj_attribute, obj_attribute_list, OBJ_ATTR_PROC, OBJ_ATTR_GNU, OBJ_ATTR_FIRST, OBJ_ATTR_LAST, Tag_NULL, Tag_File, Tag_Section, Tag_Symbol, Tag_compatibility): New. (struct elf_obj_tdata): Add entries for object attributes. (elf_known_obj_attributes, elf_other_obj_attributes, elf_known_obj_attributes_proc, elf_other_obj_attributes_proc): New. (bfd_elf_obj_attr_size, bfd_elf_set_obj_attr_contents, bfd_elf_get_obj_attr_int, bfd_elf_add_obj_attr_int, bfd_elf_add_proc_attr_int, bfd_elf_add_obj_attr_string, bfd_elf_add_proc_attr_string, bfd_elf_add_obj_attr_compat, bfd_elf_add_proc_attr_compat, _bfd_elf_attr_strdup, _bfd_elf_copy_obj_attributes, _bfd_elf_obj_attrs_arg_type, _bfd_elf_parse_attributes, _bfd_elf_merge_object_attributes): New. * elf.c (_bfd_elf_copy_private_bfd_data): Copy object attributes. (bfd_section_from_shdr): Handle attributes sections. * elflink.c (bfd_elf_final_link): Handle attributes sections. * elfxx-target.h (elf_backend_obj_attrs_vendor, elf_backend_obj_attrs_section, elf_backend_obj_attrs_arg_type, elf_backend_obj_attrs_section_type): New. (elfNN_bed): Update. * elf32-arm.c (NUM_KNOWN_ATTRIBUTES, aeabi_attribute, aeabi_attribute_list): Remove. (struct elf32_arm_obj_tdata): Remove object attributes fields. (check_use_blx, bfd_elf32_arm_set_vfp11_fix, using_thumb2, elf32_arm_copy_private_bfd_data, elf32_arm_merge_eabi_attributes): Update for new object attributes interfaces. (uleb128_size, is_default_attr, eabi_attr_size, elf32_arm_eabi_attr_size, write_uleb128, write_eabi_attribute, elf32_arm_set_eabi_attr_contents, elf32_arm_bfd_final_link, elf32_arm_new_eabi_attr, elf32_arm_get_eabi_attr_int, elf32_arm_add_eabi_attr_int, attr_strdup, elf32_arm_add_eabi_attr_string, elf32_arm_add_eabi_attr_compat, copy_eabi_attributes, elf32_arm_parse_attributes): Remove. Moved to generic code in elf-attrs.c. (elf32_arm_obj_attrs_arg_type): New. (elf32_arm_fake_sections): Do not handle .ARM.attributes. (elf32_arm_section_from_shdr): Do not handle SHT_ARM_ATTRIBUTES. (bfd_elf32_bfd_final_link): Remove. (elf_backend_obj_attrs_vendor, elf_backend_obj_attrs_section, elf_backend_obj_attrs_arg_type, elf_backend_obj_attrs_section_type): New. * elf32-bfin.c (bfin_elf_copy_private_bfd_data): Copy object attributes. * elf32-frv.c (frv_elf_copy_private_bfd_data): Likewise. * elf32-iq2000.c (iq2000_elf_copy_private_bfd_data): Likewise. * elf32-mep.c (mep_elf_copy_private_bfd_data): Likewise. * elf32-mt.c (mt_elf_copy_private_bfd_data): Likewise. * elf32-sh.c (sh_elf_copy_private_data): Likewise. * elf64-sh64.c (sh_elf64_copy_private_data_internal): Likewise. binutils: * readelf.c (display_gnu_attribute): New. (process_arm_specific): Rearrange as process_attributes. (process_arm_specific): Replace by wrapper of process_attributes. gas: * as.c (create_obj_attrs_section): New. (main): Call create_obj_attrs_section for ELF. * read.c (s_gnu_attribute, skip_whitespace, skip_past_char, skip_past_comma, s_vendor_attribute): New. (potable): Add gnu_attribute for ELF. * read.h (s_vendor_attribute): Declare. * config/tc-arm.c (s_arm_eabi_attribute): Replace by wrapper round s_vendor_attribute. (aeabi_set_public_attributes): Update for new attributes interfaces. (arm_md_end): Remove attributes contents setting now done generically. include/elf: * arm.h (elf32_arm_add_eabi_attr_int, elf32_arm_add_eabi_attr_string, elf32_arm_add_eabi_attr_compat, elf32_arm_get_eabi_attr_int, elf32_arm_set_eabi_attr_contents, elf32_arm_eabi_attr_size, Tag_NULL, Tag_File, Tag_Section, Tag_Symbol, Tag_compatibility): Remove. * common.h (SHT_GNU_ATTRIBUTES): Define. ld: * emulparams/armelf.sh (OTHER_SECTIONS): Remove .ARM.attributes. (ATTRS_SECTIONS): Define. * scripttempl/elf.sc, scripttempl/elf32sh-symbian.sc, scripttempl/elf_chaos.sc, scripttempl/elfi370.sc, scripttempl/elfxtensa.sc: Handle ATTRS_SECTIONS.
This commit is contained in:
parent
5ab7998193
commit
104d59d19c
|
@ -1,3 +1,66 @@
|
|||
2007-06-29 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* elf-attrs.c: New.
|
||||
* Makefile.am (BFD32_BACKENDS): Add elf-attrs.lo.
|
||||
(BFD32_BACKENDS_CFILES): Add elf-attrs.c.
|
||||
(elf-attrs.lo): Generate dependencies.
|
||||
* Makefile.in: Regenerate.
|
||||
* configure.in (elf): Add elf-attrs.lo.
|
||||
* configure: Regenerate.
|
||||
* elf-bfd.h (struct elf_backend_data): Add entries for object
|
||||
attributes.
|
||||
(NUM_KNOWN_OBJ_ATTRIBUTES, obj_attribute, obj_attribute_list,
|
||||
OBJ_ATTR_PROC, OBJ_ATTR_GNU, OBJ_ATTR_FIRST, OBJ_ATTR_LAST,
|
||||
Tag_NULL, Tag_File, Tag_Section, Tag_Symbol, Tag_compatibility):
|
||||
New.
|
||||
(struct elf_obj_tdata): Add entries for object attributes.
|
||||
(elf_known_obj_attributes, elf_other_obj_attributes,
|
||||
elf_known_obj_attributes_proc, elf_other_obj_attributes_proc):
|
||||
New.
|
||||
(bfd_elf_obj_attr_size, bfd_elf_set_obj_attr_contents,
|
||||
bfd_elf_get_obj_attr_int, bfd_elf_add_obj_attr_int,
|
||||
bfd_elf_add_proc_attr_int, bfd_elf_add_obj_attr_string,
|
||||
bfd_elf_add_proc_attr_string, bfd_elf_add_obj_attr_compat,
|
||||
bfd_elf_add_proc_attr_compat, _bfd_elf_attr_strdup,
|
||||
_bfd_elf_copy_obj_attributes, _bfd_elf_obj_attrs_arg_type,
|
||||
_bfd_elf_parse_attributes, _bfd_elf_merge_object_attributes): New.
|
||||
* elf.c (_bfd_elf_copy_private_bfd_data): Copy object attributes.
|
||||
(bfd_section_from_shdr): Handle attributes sections.
|
||||
* elflink.c (bfd_elf_final_link): Handle attributes sections.
|
||||
* elfxx-target.h (elf_backend_obj_attrs_vendor,
|
||||
elf_backend_obj_attrs_section, elf_backend_obj_attrs_arg_type,
|
||||
elf_backend_obj_attrs_section_type): New.
|
||||
(elfNN_bed): Update.
|
||||
* elf32-arm.c (NUM_KNOWN_ATTRIBUTES, aeabi_attribute,
|
||||
aeabi_attribute_list): Remove.
|
||||
(struct elf32_arm_obj_tdata): Remove object attributes fields.
|
||||
(check_use_blx, bfd_elf32_arm_set_vfp11_fix, using_thumb2,
|
||||
elf32_arm_copy_private_bfd_data, elf32_arm_merge_eabi_attributes):
|
||||
Update for new object attributes interfaces.
|
||||
(uleb128_size, is_default_attr, eabi_attr_size,
|
||||
elf32_arm_eabi_attr_size, write_uleb128, write_eabi_attribute,
|
||||
elf32_arm_set_eabi_attr_contents, elf32_arm_bfd_final_link,
|
||||
elf32_arm_new_eabi_attr, elf32_arm_get_eabi_attr_int,
|
||||
elf32_arm_add_eabi_attr_int, attr_strdup,
|
||||
elf32_arm_add_eabi_attr_string, elf32_arm_add_eabi_attr_compat,
|
||||
copy_eabi_attributes, elf32_arm_parse_attributes): Remove. Moved
|
||||
to generic code in elf-attrs.c.
|
||||
(elf32_arm_obj_attrs_arg_type): New.
|
||||
(elf32_arm_fake_sections): Do not handle .ARM.attributes.
|
||||
(elf32_arm_section_from_shdr): Do not handle SHT_ARM_ATTRIBUTES.
|
||||
(bfd_elf32_bfd_final_link): Remove.
|
||||
(elf_backend_obj_attrs_vendor, elf_backend_obj_attrs_section,
|
||||
elf_backend_obj_attrs_arg_type,
|
||||
elf_backend_obj_attrs_section_type): New.
|
||||
* elf32-bfin.c (bfin_elf_copy_private_bfd_data): Copy object
|
||||
attributes.
|
||||
* elf32-frv.c (frv_elf_copy_private_bfd_data): Likewise.
|
||||
* elf32-iq2000.c (iq2000_elf_copy_private_bfd_data): Likewise.
|
||||
* elf32-mep.c (mep_elf_copy_private_bfd_data): Likewise.
|
||||
* elf32-mt.c (mt_elf_copy_private_bfd_data): Likewise.
|
||||
* elf32-sh.c (sh_elf_copy_private_data): Likewise.
|
||||
* elf64-sh64.c (sh_elf64_copy_private_data_internal): Likewise.
|
||||
|
||||
2007-06-29 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* elf32-arm.c (bfd_elf32_arm_process_before_allocation): Suppress
|
||||
|
|
|
@ -297,6 +297,7 @@ BFD32_BACKENDS = \
|
|||
elf32-xc16x.lo \
|
||||
elf32.lo \
|
||||
elflink.lo \
|
||||
elf-attrs.lo \
|
||||
elf-strtab.lo \
|
||||
elf-eh-frame.lo \
|
||||
elf-vxworks.lo \
|
||||
|
@ -475,6 +476,7 @@ BFD32_BACKENDS_CFILES = \
|
|||
elf32-xc16x.c \
|
||||
elf32.c \
|
||||
elflink.c \
|
||||
elf-attrs.c \
|
||||
elf-strtab.c \
|
||||
elf-eh-frame.c \
|
||||
elf-vxworks.c \
|
||||
|
@ -1562,6 +1564,9 @@ elflink.lo: elflink.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
|
|||
$(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \
|
||||
$(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/safe-ctype.h \
|
||||
$(INCDIR)/libiberty.h $(INCDIR)/objalloc.h
|
||||
elf-attrs.lo: elf-attrs.c $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \
|
||||
$(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \
|
||||
$(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h
|
||||
elf-strtab.lo: elf-strtab.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
|
||||
elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
|
||||
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(INCDIR)/libiberty.h
|
||||
|
|
|
@ -546,6 +546,7 @@ BFD32_BACKENDS = \
|
|||
elf32-xc16x.lo \
|
||||
elf32.lo \
|
||||
elflink.lo \
|
||||
elf-attrs.lo \
|
||||
elf-strtab.lo \
|
||||
elf-eh-frame.lo \
|
||||
elf-vxworks.lo \
|
||||
|
@ -724,6 +725,7 @@ BFD32_BACKENDS_CFILES = \
|
|||
elf32-xc16x.c \
|
||||
elf32.c \
|
||||
elflink.c \
|
||||
elf-attrs.c \
|
||||
elf-strtab.c \
|
||||
elf-eh-frame.c \
|
||||
elf-vxworks.c \
|
||||
|
@ -2141,6 +2143,9 @@ elflink.lo: elflink.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
|
|||
$(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \
|
||||
$(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/safe-ctype.h \
|
||||
$(INCDIR)/libiberty.h $(INCDIR)/objalloc.h
|
||||
elf-attrs.lo: elf-attrs.c $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \
|
||||
$(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \
|
||||
$(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h
|
||||
elf-strtab.lo: elf-strtab.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
|
||||
elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
|
||||
$(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(INCDIR)/libiberty.h
|
||||
|
|
|
@ -18578,7 +18578,7 @@ selarchs="$f"
|
|||
# Target backend .o files.
|
||||
tb=
|
||||
|
||||
elf="elf.lo elflink.lo elf-strtab.lo elf-eh-frame.lo dwarf1.lo"
|
||||
elf="elf.lo elflink.lo elf-attrs.lo elf-strtab.lo elf-eh-frame.lo dwarf1.lo"
|
||||
|
||||
for vec in $selvecs
|
||||
do
|
||||
|
|
|
@ -569,7 +569,7 @@ selarchs="$f"
|
|||
# Target backend .o files.
|
||||
tb=
|
||||
|
||||
elf="elf.lo elflink.lo elf-strtab.lo elf-eh-frame.lo dwarf1.lo"
|
||||
elf="elf.lo elflink.lo elf-attrs.lo elf-strtab.lo elf-eh-frame.lo dwarf1.lo"
|
||||
|
||||
for vec in $selvecs
|
||||
do
|
||||
|
|
|
@ -0,0 +1,628 @@
|
|||
/* ELF attributes support (based on ARM EABI attributes).
|
||||
Copyright 2005, 2006, 2007
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include "sysdep.h"
|
||||
#include "bfd.h"
|
||||
#include "libiberty.h"
|
||||
#include "libbfd.h"
|
||||
#include "elf-bfd.h"
|
||||
|
||||
/* Return the number of bytes needed by I in uleb128 format. */
|
||||
static int
|
||||
uleb128_size (unsigned int i)
|
||||
{
|
||||
int size;
|
||||
size = 1;
|
||||
while (i >= 0x80)
|
||||
{
|
||||
i >>= 7;
|
||||
size++;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Return TRUE if the attribute has the default value (0/""). */
|
||||
static bfd_boolean
|
||||
is_default_attr (obj_attribute *attr)
|
||||
{
|
||||
if ((attr->type & 1) && attr->i != 0)
|
||||
return FALSE;
|
||||
if ((attr->type & 2) && attr->s && *attr->s)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Return the size of a single attribute. */
|
||||
static bfd_vma
|
||||
obj_attr_size (int tag, obj_attribute *attr)
|
||||
{
|
||||
bfd_vma size;
|
||||
|
||||
if (is_default_attr (attr))
|
||||
return 0;
|
||||
|
||||
size = uleb128_size (tag);
|
||||
if (attr->type & 1)
|
||||
size += uleb128_size (attr->i);
|
||||
if (attr->type & 2)
|
||||
size += strlen ((char *)attr->s) + 1;
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Return the vendor name for a given object attributes section. */
|
||||
static const char *
|
||||
vendor_obj_attr_name (bfd *abfd, int vendor)
|
||||
{
|
||||
return (vendor == OBJ_ATTR_PROC
|
||||
? get_elf_backend_data (abfd)->obj_attrs_vendor
|
||||
: "gnu");
|
||||
}
|
||||
|
||||
/* Return the size of the object attributes section for VENDOR
|
||||
(OBJ_ATTR_PROC or OBJ_ATTR_GNU), or 0 if there are no attributes
|
||||
for that vendor to record and the vendor is OBJ_ATTR_GNU. */
|
||||
static bfd_vma
|
||||
vendor_obj_attr_size (bfd *abfd, int vendor)
|
||||
{
|
||||
bfd_vma size;
|
||||
obj_attribute *attr;
|
||||
obj_attribute_list *list;
|
||||
int i;
|
||||
const char *vendor_name = vendor_obj_attr_name (abfd, vendor);
|
||||
|
||||
if (!vendor_name)
|
||||
return 0;
|
||||
|
||||
attr = elf_known_obj_attributes (abfd)[vendor];
|
||||
size = 0;
|
||||
for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
|
||||
size += obj_attr_size (i, &attr[i]);
|
||||
|
||||
for (list = elf_other_obj_attributes (abfd)[vendor];
|
||||
list;
|
||||
list = list->next)
|
||||
size += obj_attr_size (list->tag, &list->attr);
|
||||
|
||||
/* <size> <vendor_name> NUL 0x1 <size> */
|
||||
return ((size || vendor == OBJ_ATTR_PROC)
|
||||
? size + 10 + strlen (vendor_name)
|
||||
: 0);
|
||||
}
|
||||
|
||||
/* Return the size of the object attributes section. */
|
||||
bfd_vma
|
||||
bfd_elf_obj_attr_size (bfd *abfd)
|
||||
{
|
||||
bfd_vma size;
|
||||
|
||||
size = vendor_obj_attr_size (abfd, OBJ_ATTR_PROC);
|
||||
size += vendor_obj_attr_size (abfd, OBJ_ATTR_GNU);
|
||||
|
||||
/* 'A' <sections for each vendor> */
|
||||
return (size ? size + 1 : 0);
|
||||
}
|
||||
|
||||
/* Write VAL in uleb128 format to P, returning a pointer to the
|
||||
following byte. */
|
||||
static bfd_byte *
|
||||
write_uleb128 (bfd_byte *p, unsigned int val)
|
||||
{
|
||||
bfd_byte c;
|
||||
do
|
||||
{
|
||||
c = val & 0x7f;
|
||||
val >>= 7;
|
||||
if (val)
|
||||
c |= 0x80;
|
||||
*(p++) = c;
|
||||
}
|
||||
while (val);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Write attribute ATTR to butter P, and return a pointer to the following
|
||||
byte. */
|
||||
static bfd_byte *
|
||||
write_obj_attribute (bfd_byte *p, int tag, obj_attribute *attr)
|
||||
{
|
||||
/* Suppress default entries. */
|
||||
if (is_default_attr (attr))
|
||||
return p;
|
||||
|
||||
p = write_uleb128 (p, tag);
|
||||
if (attr->type & 1)
|
||||
p = write_uleb128 (p, attr->i);
|
||||
if (attr->type & 2)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = strlen (attr->s) + 1;
|
||||
memcpy (p, attr->s, len);
|
||||
p += len;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Write the contents of the object attributes section (length SIZE)
|
||||
for VENDOR to CONTENTS. */
|
||||
static void
|
||||
vendor_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size,
|
||||
int vendor)
|
||||
{
|
||||
bfd_byte *p;
|
||||
obj_attribute *attr;
|
||||
obj_attribute_list *list;
|
||||
int i;
|
||||
const char *vendor_name = vendor_obj_attr_name (abfd, vendor);
|
||||
size_t vendor_length = strlen (vendor_name) + 1;
|
||||
|
||||
p = contents;
|
||||
bfd_put_32 (abfd, size, p);
|
||||
p += 4;
|
||||
memcpy (p, vendor_name, vendor_length);
|
||||
p += vendor_length;
|
||||
*(p++) = Tag_File;
|
||||
bfd_put_32 (abfd, size - 4 - vendor_length, p);
|
||||
p += 4;
|
||||
|
||||
attr = elf_known_obj_attributes (abfd)[vendor];
|
||||
for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
|
||||
p = write_obj_attribute (p, i, &attr[i]);
|
||||
|
||||
for (list = elf_other_obj_attributes (abfd)[vendor];
|
||||
list;
|
||||
list = list->next)
|
||||
p = write_obj_attribute (p, list->tag, &list->attr);
|
||||
}
|
||||
|
||||
/* Write the contents of the object attributes section to CONTENTS. */
|
||||
void
|
||||
bfd_elf_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size)
|
||||
{
|
||||
bfd_byte *p;
|
||||
int vendor;
|
||||
bfd_vma my_size;
|
||||
|
||||
p = contents;
|
||||
*(p++) = 'A';
|
||||
my_size = 1;
|
||||
for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
|
||||
{
|
||||
bfd_vma vendor_size = vendor_obj_attr_size (abfd, vendor);
|
||||
if (vendor_size)
|
||||
vendor_set_obj_attr_contents (abfd, p, vendor_size, vendor);
|
||||
p += vendor_size;
|
||||
my_size += vendor_size;
|
||||
}
|
||||
|
||||
if (size != my_size)
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Allocate/find an object attribute. */
|
||||
static obj_attribute *
|
||||
elf_new_obj_attr (bfd *abfd, int vendor, int tag)
|
||||
{
|
||||
obj_attribute *attr;
|
||||
obj_attribute_list *list;
|
||||
obj_attribute_list *p;
|
||||
obj_attribute_list **lastp;
|
||||
|
||||
|
||||
if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
|
||||
{
|
||||
/* Knwon tags are preallocated. */
|
||||
attr = &elf_known_obj_attributes (abfd)[vendor][tag];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create a new tag. */
|
||||
list = (obj_attribute_list *)
|
||||
bfd_alloc (abfd, sizeof (obj_attribute_list));
|
||||
memset (list, 0, sizeof (obj_attribute_list));
|
||||
list->tag = tag;
|
||||
/* Keep the tag list in order. */
|
||||
lastp = &elf_other_obj_attributes (abfd)[vendor];
|
||||
for (p = *lastp; p; p = p->next)
|
||||
{
|
||||
if (tag < p->tag)
|
||||
break;
|
||||
lastp = &p->next;
|
||||
}
|
||||
list->next = *lastp;
|
||||
*lastp = list;
|
||||
attr = &list->attr;
|
||||
}
|
||||
|
||||
return attr;
|
||||
}
|
||||
|
||||
/* Return the value of an integer object attribute. */
|
||||
int
|
||||
bfd_elf_get_obj_attr_int (bfd *abfd, int vendor, int tag)
|
||||
{
|
||||
obj_attribute_list *p;
|
||||
|
||||
if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
|
||||
{
|
||||
/* Knwon tags are preallocated. */
|
||||
return elf_known_obj_attributes (abfd)[vendor][tag].i;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (p = elf_other_obj_attributes (abfd)[vendor];
|
||||
p;
|
||||
p = p->next)
|
||||
{
|
||||
if (tag == p->tag)
|
||||
return p->attr.i;
|
||||
if (tag < p->tag)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add an integer object attribute. */
|
||||
void
|
||||
bfd_elf_add_obj_attr_int (bfd *abfd, int vendor, int tag, unsigned int i)
|
||||
{
|
||||
obj_attribute *attr;
|
||||
|
||||
attr = elf_new_obj_attr (abfd, vendor, tag);
|
||||
attr->type = 1;
|
||||
attr->i = i;
|
||||
}
|
||||
|
||||
/* Duplicate an object attribute string value. */
|
||||
char *
|
||||
_bfd_elf_attr_strdup (bfd *abfd, const char * s)
|
||||
{
|
||||
char * p;
|
||||
int len;
|
||||
|
||||
len = strlen (s) + 1;
|
||||
p = (char *) bfd_alloc (abfd, len);
|
||||
return memcpy (p, s, len);
|
||||
}
|
||||
|
||||
/* Add a string object attribute. */
|
||||
void
|
||||
bfd_elf_add_obj_attr_string (bfd *abfd, int vendor, int tag, const char *s)
|
||||
{
|
||||
obj_attribute *attr;
|
||||
|
||||
attr = elf_new_obj_attr (abfd, vendor, tag);
|
||||
attr->type = 2;
|
||||
attr->s = _bfd_elf_attr_strdup (abfd, s);
|
||||
}
|
||||
|
||||
/* Add a Tag_compatibility object attribute. */
|
||||
void
|
||||
bfd_elf_add_obj_attr_compat (bfd *abfd, int vendor, unsigned int i,
|
||||
const char *s)
|
||||
{
|
||||
obj_attribute_list *list;
|
||||
obj_attribute_list *p;
|
||||
obj_attribute_list **lastp;
|
||||
|
||||
list = (obj_attribute_list *)
|
||||
bfd_alloc (abfd, sizeof (obj_attribute_list));
|
||||
memset (list, 0, sizeof (obj_attribute_list));
|
||||
list->tag = Tag_compatibility;
|
||||
list->attr.type = 3;
|
||||
list->attr.i = i;
|
||||
list->attr.s = _bfd_elf_attr_strdup (abfd, s);
|
||||
|
||||
lastp = &elf_other_obj_attributes (abfd)[vendor];
|
||||
for (p = *lastp; p; p = p->next)
|
||||
{
|
||||
int cmp;
|
||||
if (p->tag != Tag_compatibility)
|
||||
break;
|
||||
cmp = strcmp(s, p->attr.s);
|
||||
if (cmp < 0 || (cmp == 0 && i < p->attr.i))
|
||||
break;
|
||||
lastp = &p->next;
|
||||
}
|
||||
list->next = *lastp;
|
||||
*lastp = list;
|
||||
}
|
||||
|
||||
/* Copy the object attributes from IBFD to OBFD. */
|
||||
void
|
||||
_bfd_elf_copy_obj_attributes (bfd *ibfd, bfd *obfd)
|
||||
{
|
||||
obj_attribute *in_attr;
|
||||
obj_attribute *out_attr;
|
||||
obj_attribute_list *list;
|
||||
int i;
|
||||
int vendor;
|
||||
|
||||
for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
|
||||
{
|
||||
in_attr = &elf_known_obj_attributes (ibfd)[vendor][4];
|
||||
out_attr = &elf_known_obj_attributes (obfd)[vendor][4];
|
||||
for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
|
||||
{
|
||||
out_attr->type = in_attr->type;
|
||||
out_attr->i = in_attr->i;
|
||||
if (in_attr->s && *in_attr->s)
|
||||
out_attr->s = _bfd_elf_attr_strdup (obfd, in_attr->s);
|
||||
in_attr++;
|
||||
out_attr++;
|
||||
}
|
||||
|
||||
for (list = elf_other_obj_attributes (ibfd)[vendor];
|
||||
list;
|
||||
list = list->next)
|
||||
{
|
||||
in_attr = &list->attr;
|
||||
switch (in_attr->type)
|
||||
{
|
||||
case 1:
|
||||
bfd_elf_add_obj_attr_int (obfd, vendor, list->tag, in_attr->i);
|
||||
break;
|
||||
case 2:
|
||||
bfd_elf_add_obj_attr_string (obfd, vendor, list->tag,
|
||||
in_attr->s);
|
||||
break;
|
||||
case 3:
|
||||
bfd_elf_add_obj_attr_compat (obfd, vendor, in_attr->i,
|
||||
in_attr->s);
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine whether a GNU object attribute tag takes an integer, a
|
||||
string or both. */
|
||||
static int
|
||||
gnu_obj_attrs_arg_type (int tag)
|
||||
{
|
||||
/* Except for Tag_compatibility, for GNU attributes we follow the
|
||||
same rule ARM ones > 32 follow: odd-numbered tags take strings
|
||||
and even-numbered tags take integers. In addition, tag & 2 is
|
||||
nonzero for architecture-independent tags and zero for
|
||||
architecture-dependent ones. */
|
||||
if (tag == Tag_compatibility)
|
||||
return 3;
|
||||
else
|
||||
return (tag & 1) != 0 ? 2 : 1;
|
||||
}
|
||||
|
||||
/* Determine what arguments an attribute tag takes. */
|
||||
int
|
||||
_bfd_elf_obj_attrs_arg_type (bfd *abfd, int vendor, int tag)
|
||||
{
|
||||
switch (vendor)
|
||||
{
|
||||
case OBJ_ATTR_PROC:
|
||||
return get_elf_backend_data (abfd)->obj_attrs_arg_type (tag);
|
||||
break;
|
||||
case OBJ_ATTR_GNU:
|
||||
return gnu_obj_attrs_arg_type (tag);
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse an object attributes section. */
|
||||
void
|
||||
_bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
|
||||
{
|
||||
bfd_byte *contents;
|
||||
bfd_byte *p;
|
||||
bfd_vma len;
|
||||
const char *std_section;
|
||||
|
||||
contents = bfd_malloc (hdr->sh_size);
|
||||
if (!contents)
|
||||
return;
|
||||
if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
|
||||
hdr->sh_size))
|
||||
{
|
||||
free (contents);
|
||||
return;
|
||||
}
|
||||
p = contents;
|
||||
std_section = get_elf_backend_data (abfd)->obj_attrs_vendor;
|
||||
if (*(p++) == 'A')
|
||||
{
|
||||
len = hdr->sh_size - 1;
|
||||
while (len > 0)
|
||||
{
|
||||
int namelen;
|
||||
bfd_vma section_len;
|
||||
int vendor;
|
||||
|
||||
section_len = bfd_get_32 (abfd, p);
|
||||
p += 4;
|
||||
if (section_len > len)
|
||||
section_len = len;
|
||||
len -= section_len;
|
||||
namelen = strlen ((char *)p) + 1;
|
||||
section_len -= namelen + 4;
|
||||
if (std_section && strcmp ((char *)p, std_section) == 0)
|
||||
vendor = OBJ_ATTR_PROC;
|
||||
else if (strcmp ((char *)p, "gnu") == 0)
|
||||
vendor = OBJ_ATTR_GNU;
|
||||
else
|
||||
{
|
||||
/* Other vendor section. Ignore it. */
|
||||
p += namelen + section_len;
|
||||
continue;
|
||||
}
|
||||
|
||||
p += namelen;
|
||||
while (section_len > 0)
|
||||
{
|
||||
int tag;
|
||||
unsigned int n;
|
||||
unsigned int val;
|
||||
bfd_vma subsection_len;
|
||||
bfd_byte *end;
|
||||
|
||||
tag = read_unsigned_leb128 (abfd, p, &n);
|
||||
p += n;
|
||||
subsection_len = bfd_get_32 (abfd, p);
|
||||
p += 4;
|
||||
if (subsection_len > section_len)
|
||||
subsection_len = section_len;
|
||||
section_len -= subsection_len;
|
||||
subsection_len -= n + 4;
|
||||
end = p + subsection_len;
|
||||
switch (tag)
|
||||
{
|
||||
case Tag_File:
|
||||
while (p < end)
|
||||
{
|
||||
int type;
|
||||
|
||||
tag = read_unsigned_leb128 (abfd, p, &n);
|
||||
p += n;
|
||||
type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
|
||||
switch (type)
|
||||
{
|
||||
case 3:
|
||||
val = read_unsigned_leb128 (abfd, p, &n);
|
||||
p += n;
|
||||
bfd_elf_add_obj_attr_compat (abfd, vendor, val,
|
||||
(char *)p);
|
||||
p += strlen ((char *)p) + 1;
|
||||
break;
|
||||
case 2:
|
||||
bfd_elf_add_obj_attr_string (abfd, vendor, tag,
|
||||
(char *)p);
|
||||
p += strlen ((char *)p) + 1;
|
||||
break;
|
||||
case 1:
|
||||
val = read_unsigned_leb128 (abfd, p, &n);
|
||||
p += n;
|
||||
bfd_elf_add_obj_attr_int (abfd, vendor, tag, val);
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Tag_Section:
|
||||
case Tag_Symbol:
|
||||
/* Don't have anywhere convenient to attach these.
|
||||
Fall through for now. */
|
||||
default:
|
||||
/* Ignore things we don't kow about. */
|
||||
p += subsection_len;
|
||||
subsection_len = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free (contents);
|
||||
}
|
||||
|
||||
/* Merge common object attributes from IBFD into OBFD. Raise an error
|
||||
if there are conflicting attributes. Any processor-specific
|
||||
attributes have already been merged. This must be called from the
|
||||
bfd_elfNN_bfd_merge_private_bfd_data hook for each individual
|
||||
target, along with any target-specific merging. Because there are
|
||||
no common attributes other than Tag_compatibility at present, and
|
||||
non-"gnu" Tag_compatibility is not expected in "gnu" sections, this
|
||||
is not presently called for targets without their own
|
||||
attributes. */
|
||||
|
||||
bfd_boolean
|
||||
_bfd_elf_merge_object_attributes (bfd *ibfd, bfd *obfd)
|
||||
{
|
||||
obj_attribute *in_attr;
|
||||
obj_attribute *out_attr;
|
||||
obj_attribute_list *in_list;
|
||||
obj_attribute_list *out_list;
|
||||
int vendor;
|
||||
|
||||
/* The only common attribute is currently Tag_compatibility,
|
||||
accepted in both processor and "gnu" sections. */
|
||||
for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
|
||||
{
|
||||
in_list = elf_other_obj_attributes (ibfd)[vendor];
|
||||
out_list = elf_other_obj_attributes (ibfd)[vendor];
|
||||
while (in_list && in_list->tag == Tag_compatibility)
|
||||
{
|
||||
in_attr = &in_list->attr;
|
||||
if (in_attr->i == 0)
|
||||
continue;
|
||||
if (in_attr->i == 1 && strcmp (in_attr->s, "gnu") != 0)
|
||||
{
|
||||
_bfd_error_handler
|
||||
(_("ERROR: %B: Must be processed by '%s' toolchain"),
|
||||
ibfd, in_attr->s);
|
||||
return FALSE;
|
||||
}
|
||||
if (!out_list || out_list->tag != Tag_compatibility
|
||||
|| strcmp (in_attr->s, out_list->attr.s) != 0)
|
||||
{
|
||||
/* Add this compatibility tag to the output. */
|
||||
bfd_elf_add_proc_attr_compat (obfd, in_attr->i, in_attr->s);
|
||||
continue;
|
||||
}
|
||||
out_attr = &out_list->attr;
|
||||
/* Check all the input tags with the same identifier. */
|
||||
for (;;)
|
||||
{
|
||||
if (out_list->tag != Tag_compatibility
|
||||
|| in_attr->i != out_attr->i
|
||||
|| strcmp (in_attr->s, out_attr->s) != 0)
|
||||
{
|
||||
_bfd_error_handler
|
||||
(_("ERROR: %B: Incompatible object tag '%s':%d"),
|
||||
ibfd, in_attr->s, in_attr->i);
|
||||
return FALSE;
|
||||
}
|
||||
in_list = in_list->next;
|
||||
if (in_list->tag != Tag_compatibility
|
||||
|| strcmp (in_attr->s, in_list->attr.s) != 0)
|
||||
break;
|
||||
in_attr = &in_list->attr;
|
||||
out_list = out_list->next;
|
||||
if (out_list)
|
||||
out_attr = &out_list->attr;
|
||||
}
|
||||
|
||||
/* Check the output doesn't have extra tags with this identifier. */
|
||||
if (out_list && out_list->tag == Tag_compatibility
|
||||
&& strcmp (in_attr->s, out_list->attr.s) == 0)
|
||||
{
|
||||
_bfd_error_handler
|
||||
(_("ERROR: %B: Incompatible object tag '%s':%d"),
|
||||
ibfd, in_attr->s, out_list->attr.i);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -1075,6 +1075,19 @@ struct elf_backend_data
|
|||
so-called reserved entries on some systems. */
|
||||
bfd_vma got_header_size;
|
||||
|
||||
/* The vendor name to use for a processor-standard attributes section. */
|
||||
const char *obj_attrs_vendor;
|
||||
|
||||
/* The section name to use for a processor-standard attributes section. */
|
||||
const char *obj_attrs_section;
|
||||
|
||||
/* Return 1, 2 or 3 to indicate what type of arguments a
|
||||
processor-specific tag takes. */
|
||||
int (*obj_attrs_arg_type) (int);
|
||||
|
||||
/* The section type to use for an attributes section. */
|
||||
unsigned int obj_attrs_section_type;
|
||||
|
||||
/* This is TRUE if the linker should act like collect and gather
|
||||
global constructors and destructors by name. This is TRUE for
|
||||
MIPS ELF because the Irix 5 tools can not handle the .init
|
||||
|
@ -1268,6 +1281,46 @@ struct elf_find_verdep_info
|
|||
bfd_boolean failed;
|
||||
};
|
||||
|
||||
/* The maximum number of known object attributes for any target. */
|
||||
#define NUM_KNOWN_OBJ_ATTRIBUTES 32
|
||||
|
||||
/* The value of an object attribute. type & 1 indicates whether there
|
||||
is an integer value; type & 2 indicates whether there is a string
|
||||
value. */
|
||||
|
||||
typedef struct obj_attribute
|
||||
{
|
||||
int type;
|
||||
unsigned int i;
|
||||
char *s;
|
||||
} obj_attribute;
|
||||
|
||||
typedef struct obj_attribute_list
|
||||
{
|
||||
struct obj_attribute_list *next;
|
||||
int tag;
|
||||
obj_attribute attr;
|
||||
} obj_attribute_list;
|
||||
|
||||
/* Object attributes may either be defined by the processor ABI, index
|
||||
OBJ_ATTR_PROC in the *_obj_attributes arrays, or be GNU-specific
|
||||
(and possibly also processor-specific), index OBJ_ATTR_GNU. */
|
||||
#define OBJ_ATTR_PROC 0
|
||||
#define OBJ_ATTR_GNU 1
|
||||
#define OBJ_ATTR_FIRST OBJ_ATTR_PROC
|
||||
#define OBJ_ATTR_LAST OBJ_ATTR_GNU
|
||||
|
||||
/* The following object attribute tags are taken as generic, for all
|
||||
targets and for "gnu" where there is no target standard. */
|
||||
enum
|
||||
{
|
||||
Tag_NULL = 0,
|
||||
Tag_File = 1,
|
||||
Tag_Section = 2,
|
||||
Tag_Symbol = 3,
|
||||
Tag_compatibility = 32
|
||||
};
|
||||
|
||||
/* Some private data is stashed away for future use using the tdata pointer
|
||||
in the bfd structure. */
|
||||
|
||||
|
@ -1409,6 +1462,9 @@ struct elf_obj_tdata
|
|||
|
||||
/* Symbol buffer. */
|
||||
void *symbuf;
|
||||
|
||||
obj_attribute known_obj_attributes[2][NUM_KNOWN_OBJ_ATTRIBUTES];
|
||||
obj_attribute_list *other_obj_attributes[2];
|
||||
};
|
||||
|
||||
#define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data)
|
||||
|
@ -1438,6 +1494,12 @@ struct elf_obj_tdata
|
|||
#define elf_dyn_lib_class(bfd) (elf_tdata(bfd) -> dyn_lib_class)
|
||||
#define elf_bad_symtab(bfd) (elf_tdata(bfd) -> bad_symtab)
|
||||
#define elf_flags_init(bfd) (elf_tdata(bfd) -> flags_init)
|
||||
#define elf_known_obj_attributes(bfd) (elf_tdata (bfd) -> known_obj_attributes)
|
||||
#define elf_other_obj_attributes(bfd) (elf_tdata (bfd) -> other_obj_attributes)
|
||||
#define elf_known_obj_attributes_proc(bfd) \
|
||||
(elf_known_obj_attributes (bfd) [OBJ_ATTR_PROC])
|
||||
#define elf_other_obj_attributes_proc(bfd) \
|
||||
(elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC])
|
||||
|
||||
extern void _bfd_elf_swap_verdef_in
|
||||
(bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
|
||||
|
@ -1953,6 +2015,26 @@ extern bfd *_bfd_elf64_bfd_from_remote_memory
|
|||
(bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
|
||||
int (*target_read_memory) (bfd_vma, bfd_byte *, int));
|
||||
|
||||
extern bfd_vma bfd_elf_obj_attr_size (bfd *);
|
||||
extern void bfd_elf_set_obj_attr_contents (bfd *, bfd_byte *, bfd_vma);
|
||||
extern int bfd_elf_get_obj_attr_int (bfd *, int, int);
|
||||
extern void bfd_elf_add_obj_attr_int (bfd *, int, int, unsigned int);
|
||||
#define bfd_elf_add_proc_attr_int(BFD, TAG, VALUE) \
|
||||
bfd_elf_add_obj_attr_int ((BFD), OBJ_ATTR_PROC, (TAG), (VALUE))
|
||||
extern void bfd_elf_add_obj_attr_string (bfd *, int, int, const char *);
|
||||
#define bfd_elf_add_proc_attr_string(BFD, TAG, VALUE) \
|
||||
bfd_elf_add_obj_attr_string ((BFD), OBJ_ATTR_PROC, (TAG), (VALUE))
|
||||
extern void bfd_elf_add_obj_attr_compat (bfd *, int, unsigned int,
|
||||
const char *);
|
||||
#define bfd_elf_add_proc_attr_compat(BFD, INTVAL, STRVAL) \
|
||||
bfd_elf_add_obj_attr_compat ((BFD), OBJ_ATTR_PROC, (INTVAL), (STRVAL))
|
||||
|
||||
extern char *_bfd_elf_attr_strdup (bfd *, const char *);
|
||||
extern void _bfd_elf_copy_obj_attributes (bfd *, bfd *);
|
||||
extern int _bfd_elf_obj_attrs_arg_type (bfd *, int, int);
|
||||
extern void _bfd_elf_parse_attributes (bfd *, Elf_Internal_Shdr *);
|
||||
extern bfd_boolean _bfd_elf_merge_object_attributes (bfd *, bfd *);
|
||||
|
||||
/* Large common section. */
|
||||
extern asection _bfd_elf_large_com_section;
|
||||
|
||||
|
|
14
bfd/elf.c
14
bfd/elf.c
|
@ -1113,6 +1113,10 @@ _bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
|
|||
elf_gp (obfd) = elf_gp (ibfd);
|
||||
elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
|
||||
elf_flags_init (obfd) = TRUE;
|
||||
|
||||
/* Copy object attributes. */
|
||||
_bfd_elf_copy_obj_attributes (ibfd, obfd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -2195,6 +2199,16 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
|
|||
break;
|
||||
|
||||
default:
|
||||
/* Possibly an attributes section. */
|
||||
if (hdr->sh_type == SHT_GNU_ATTRIBUTES
|
||||
|| hdr->sh_type == bed->obj_attrs_section_type)
|
||||
{
|
||||
if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
|
||||
return FALSE;
|
||||
_bfd_elf_parse_attributes (abfd, hdr);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Check for any processor-specific section types. */
|
||||
if (bed->elf_backend_section_from_shdr (abfd, hdr, name, shindex))
|
||||
return TRUE;
|
||||
|
|
610
bfd/elf32-arm.c
610
bfd/elf32-arm.c
|
@ -2064,22 +2064,6 @@ _arm_elf_section_data;
|
|||
/* The size of the thread control block. */
|
||||
#define TCB_SIZE 8
|
||||
|
||||
#define NUM_KNOWN_ATTRIBUTES 32
|
||||
|
||||
typedef struct aeabi_attribute
|
||||
{
|
||||
int type;
|
||||
unsigned int i;
|
||||
char *s;
|
||||
} aeabi_attribute;
|
||||
|
||||
typedef struct aeabi_attribute_list
|
||||
{
|
||||
struct aeabi_attribute_list *next;
|
||||
int tag;
|
||||
aeabi_attribute attr;
|
||||
} aeabi_attribute_list;
|
||||
|
||||
struct elf32_arm_obj_tdata
|
||||
{
|
||||
struct elf_obj_tdata root;
|
||||
|
@ -2087,9 +2071,6 @@ struct elf32_arm_obj_tdata
|
|||
/* tls_type for each local got entry. */
|
||||
char *local_got_tls_type;
|
||||
|
||||
aeabi_attribute known_eabi_attributes[NUM_KNOWN_ATTRIBUTES];
|
||||
aeabi_attribute_list *other_eabi_attributes;
|
||||
|
||||
/* Zero to warn when linking objects with incompatible enum sizes. */
|
||||
int no_enum_size_warning;
|
||||
};
|
||||
|
@ -3103,7 +3084,8 @@ bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info)
|
|||
|
||||
static void check_use_blx(struct elf32_arm_link_hash_table *globals)
|
||||
{
|
||||
if (elf32_arm_get_eabi_attr_int (globals->obfd, Tag_CPU_arch) > 2)
|
||||
if (bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
|
||||
Tag_CPU_arch) > 2)
|
||||
globals->use_blx = 1;
|
||||
}
|
||||
|
||||
|
@ -3321,7 +3303,7 @@ void
|
|||
bfd_elf32_arm_set_vfp11_fix (bfd *obfd, struct bfd_link_info *link_info)
|
||||
{
|
||||
struct elf32_arm_link_hash_table *globals = elf32_arm_hash_table (link_info);
|
||||
aeabi_attribute *out_attr = elf32_arm_tdata (obfd)->known_eabi_attributes;
|
||||
obj_attribute *out_attr = elf_known_obj_attributes_proc (obfd);
|
||||
|
||||
/* We assume that ARMv7+ does not need the VFP11 denorm erratum fix. */
|
||||
if (out_attr[Tag_CPU_arch].i >= TAG_CPU_ARCH_V7)
|
||||
|
@ -4488,7 +4470,8 @@ identify_add_or_sub(bfd_vma insn)
|
|||
|
||||
static int using_thumb2 (struct elf32_arm_link_hash_table *globals)
|
||||
{
|
||||
int arch = elf32_arm_get_eabi_attr_int (globals->obfd, Tag_CPU_arch);
|
||||
int arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
|
||||
Tag_CPU_arch);
|
||||
return arch == TAG_CPU_ARCH_V6T2 || arch >= TAG_CPU_ARCH_V7;
|
||||
}
|
||||
|
||||
|
@ -6273,194 +6256,6 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
uleb128_size (unsigned int i)
|
||||
{
|
||||
int size;
|
||||
size = 1;
|
||||
while (i >= 0x80)
|
||||
{
|
||||
i >>= 7;
|
||||
size++;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Return TRUE if the attribute has the default value (0/""). */
|
||||
static bfd_boolean
|
||||
is_default_attr (aeabi_attribute *attr)
|
||||
{
|
||||
if ((attr->type & 1) && attr->i != 0)
|
||||
return FALSE;
|
||||
if ((attr->type & 2) && attr->s && *attr->s)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Return the size of a single attribute. */
|
||||
static bfd_vma
|
||||
eabi_attr_size(int tag, aeabi_attribute *attr)
|
||||
{
|
||||
bfd_vma size;
|
||||
|
||||
if (is_default_attr (attr))
|
||||
return 0;
|
||||
|
||||
size = uleb128_size (tag);
|
||||
if (attr->type & 1)
|
||||
size += uleb128_size (attr->i);
|
||||
if (attr->type & 2)
|
||||
size += strlen ((char *)attr->s) + 1;
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Returns the size of the eabi object attributess section. */
|
||||
bfd_vma
|
||||
elf32_arm_eabi_attr_size (bfd *abfd)
|
||||
{
|
||||
bfd_vma size;
|
||||
aeabi_attribute *attr;
|
||||
aeabi_attribute_list *list;
|
||||
int i;
|
||||
|
||||
attr = elf32_arm_tdata (abfd)->known_eabi_attributes;
|
||||
size = 16; /* 'A' <size> "aeabi" 0x1 <size>. */
|
||||
for (i = 4; i < NUM_KNOWN_ATTRIBUTES; i++)
|
||||
size += eabi_attr_size (i, &attr[i]);
|
||||
|
||||
for (list = elf32_arm_tdata (abfd)->other_eabi_attributes;
|
||||
list;
|
||||
list = list->next)
|
||||
size += eabi_attr_size (list->tag, &list->attr);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static bfd_byte *
|
||||
write_uleb128 (bfd_byte *p, unsigned int val)
|
||||
{
|
||||
bfd_byte c;
|
||||
do
|
||||
{
|
||||
c = val & 0x7f;
|
||||
val >>= 7;
|
||||
if (val)
|
||||
c |= 0x80;
|
||||
*(p++) = c;
|
||||
}
|
||||
while (val);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Write attribute ATTR to butter P, and return a pointer to the following
|
||||
byte. */
|
||||
static bfd_byte *
|
||||
write_eabi_attribute (bfd_byte *p, int tag, aeabi_attribute *attr)
|
||||
{
|
||||
/* Suppress default entries. */
|
||||
if (is_default_attr(attr))
|
||||
return p;
|
||||
|
||||
p = write_uleb128 (p, tag);
|
||||
if (attr->type & 1)
|
||||
p = write_uleb128 (p, attr->i);
|
||||
if (attr->type & 2)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = strlen (attr->s) + 1;
|
||||
memcpy (p, attr->s, len);
|
||||
p += len;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Write the contents of the eabi attributes section to p. */
|
||||
void
|
||||
elf32_arm_set_eabi_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size)
|
||||
{
|
||||
bfd_byte *p;
|
||||
aeabi_attribute *attr;
|
||||
aeabi_attribute_list *list;
|
||||
int i;
|
||||
|
||||
p = contents;
|
||||
*(p++) = 'A';
|
||||
bfd_put_32 (abfd, size - 1, p);
|
||||
p += 4;
|
||||
memcpy (p, "aeabi", 6);
|
||||
p += 6;
|
||||
*(p++) = Tag_File;
|
||||
bfd_put_32 (abfd, size - 11, p);
|
||||
p += 4;
|
||||
|
||||
attr = elf32_arm_tdata (abfd)->known_eabi_attributes;
|
||||
for (i = 4; i < NUM_KNOWN_ATTRIBUTES; i++)
|
||||
p = write_eabi_attribute (p, i, &attr[i]);
|
||||
|
||||
for (list = elf32_arm_tdata (abfd)->other_eabi_attributes;
|
||||
list;
|
||||
list = list->next)
|
||||
p = write_eabi_attribute (p, list->tag, &list->attr);
|
||||
}
|
||||
|
||||
/* Override final_link to handle EABI object attribute sections. */
|
||||
|
||||
static bfd_boolean
|
||||
elf32_arm_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
|
||||
{
|
||||
asection *o;
|
||||
struct bfd_link_order *p;
|
||||
asection *attr_section = NULL;
|
||||
bfd_byte *contents;
|
||||
bfd_vma size = 0;
|
||||
|
||||
/* elf32_arm_merge_private_bfd_data will already have merged the
|
||||
object attributes. Remove the input sections from the link, and set
|
||||
the contents of the output secton. */
|
||||
for (o = abfd->sections; o != NULL; o = o->next)
|
||||
{
|
||||
if (strcmp (o->name, ".ARM.attributes") == 0)
|
||||
{
|
||||
for (p = o->map_head.link_order; p != NULL; p = p->next)
|
||||
{
|
||||
asection *input_section;
|
||||
|
||||
if (p->type != bfd_indirect_link_order)
|
||||
continue;
|
||||
input_section = p->u.indirect.section;
|
||||
/* Hack: reset the SEC_HAS_CONTENTS flag so that
|
||||
elf_link_input_bfd ignores this section. */
|
||||
input_section->flags &= ~SEC_HAS_CONTENTS;
|
||||
}
|
||||
|
||||
size = elf32_arm_eabi_attr_size (abfd);
|
||||
bfd_set_section_size (abfd, o, size);
|
||||
attr_section = o;
|
||||
/* Skip this section later on. */
|
||||
o->map_head.link_order = NULL;
|
||||
}
|
||||
}
|
||||
/* Invoke the ELF linker to do all the work. */
|
||||
if (!bfd_elf_final_link (abfd, info))
|
||||
return FALSE;
|
||||
|
||||
if (attr_section)
|
||||
{
|
||||
contents = bfd_malloc(size);
|
||||
if (contents == NULL)
|
||||
return FALSE;
|
||||
elf32_arm_set_eabi_attr_contents (abfd, contents, size);
|
||||
bfd_set_section_contents (abfd, attr_section, contents, 0, size);
|
||||
free (contents);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS. */
|
||||
static void
|
||||
arm_add_to_rel (bfd * abfd,
|
||||
|
@ -6795,130 +6590,6 @@ elf32_arm_relocate_section (bfd * output_bfd,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Allocate/find an object attribute. */
|
||||
static aeabi_attribute *
|
||||
elf32_arm_new_eabi_attr (bfd *abfd, int tag)
|
||||
{
|
||||
aeabi_attribute *attr;
|
||||
aeabi_attribute_list *list;
|
||||
aeabi_attribute_list *p;
|
||||
aeabi_attribute_list **lastp;
|
||||
|
||||
|
||||
if (tag < NUM_KNOWN_ATTRIBUTES)
|
||||
{
|
||||
/* Knwon tags are preallocated. */
|
||||
attr = &elf32_arm_tdata (abfd)->known_eabi_attributes[tag];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create a new tag. */
|
||||
list = (aeabi_attribute_list *)
|
||||
bfd_alloc (abfd, sizeof (aeabi_attribute_list));
|
||||
memset (list, 0, sizeof (aeabi_attribute_list));
|
||||
list->tag = tag;
|
||||
/* Keep the tag list in order. */
|
||||
lastp = &elf32_arm_tdata (abfd)->other_eabi_attributes;
|
||||
for (p = *lastp; p; p = p->next)
|
||||
{
|
||||
if (tag < p->tag)
|
||||
break;
|
||||
lastp = &p->next;
|
||||
}
|
||||
list->next = *lastp;
|
||||
*lastp = list;
|
||||
attr = &list->attr;
|
||||
}
|
||||
|
||||
return attr;
|
||||
}
|
||||
|
||||
int
|
||||
elf32_arm_get_eabi_attr_int (bfd *abfd, int tag)
|
||||
{
|
||||
aeabi_attribute_list *p;
|
||||
|
||||
if (tag < NUM_KNOWN_ATTRIBUTES)
|
||||
{
|
||||
/* Knwon tags are preallocated. */
|
||||
return elf32_arm_tdata (abfd)->known_eabi_attributes[tag].i;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (p = elf32_arm_tdata (abfd)->other_eabi_attributes;
|
||||
p;
|
||||
p = p->next)
|
||||
{
|
||||
if (tag == p->tag)
|
||||
return p->attr.i;
|
||||
if (tag < p->tag)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
elf32_arm_add_eabi_attr_int (bfd *abfd, int tag, unsigned int i)
|
||||
{
|
||||
aeabi_attribute *attr;
|
||||
|
||||
attr = elf32_arm_new_eabi_attr (abfd, tag);
|
||||
attr->type = 1;
|
||||
attr->i = i;
|
||||
}
|
||||
|
||||
static char *
|
||||
attr_strdup (bfd *abfd, const char * s)
|
||||
{
|
||||
char * p;
|
||||
int len;
|
||||
|
||||
len = strlen (s) + 1;
|
||||
p = (char *)bfd_alloc(abfd, len);
|
||||
return memcpy (p, s, len);
|
||||
}
|
||||
|
||||
void
|
||||
elf32_arm_add_eabi_attr_string (bfd *abfd, int tag, const char *s)
|
||||
{
|
||||
aeabi_attribute *attr;
|
||||
|
||||
attr = elf32_arm_new_eabi_attr (abfd, tag);
|
||||
attr->type = 2;
|
||||
attr->s = attr_strdup (abfd, s);
|
||||
}
|
||||
|
||||
void
|
||||
elf32_arm_add_eabi_attr_compat (bfd *abfd, unsigned int i, const char *s)
|
||||
{
|
||||
aeabi_attribute_list *list;
|
||||
aeabi_attribute_list *p;
|
||||
aeabi_attribute_list **lastp;
|
||||
|
||||
list = (aeabi_attribute_list *)
|
||||
bfd_alloc (abfd, sizeof (aeabi_attribute_list));
|
||||
memset (list, 0, sizeof (aeabi_attribute_list));
|
||||
list->tag = Tag_compatibility;
|
||||
list->attr.type = 3;
|
||||
list->attr.i = i;
|
||||
list->attr.s = attr_strdup (abfd, s);
|
||||
|
||||
lastp = &elf32_arm_tdata (abfd)->other_eabi_attributes;
|
||||
for (p = *lastp; p; p = p->next)
|
||||
{
|
||||
int cmp;
|
||||
if (p->tag != Tag_compatibility)
|
||||
break;
|
||||
cmp = strcmp(s, p->attr.s);
|
||||
if (cmp < 0 || (cmp == 0 && i < p->attr.i))
|
||||
break;
|
||||
lastp = &p->next;
|
||||
}
|
||||
list->next = *lastp;
|
||||
*lastp = list;
|
||||
}
|
||||
|
||||
/* Set the right machine number. */
|
||||
|
||||
static bfd_boolean
|
||||
|
@ -6969,50 +6640,6 @@ elf32_arm_set_private_flags (bfd *abfd, flagword flags)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Copy the eabi object attribute from IBFD to OBFD. */
|
||||
static void
|
||||
copy_eabi_attributes (bfd *ibfd, bfd *obfd)
|
||||
{
|
||||
aeabi_attribute *in_attr;
|
||||
aeabi_attribute *out_attr;
|
||||
aeabi_attribute_list *list;
|
||||
int i;
|
||||
|
||||
in_attr = &elf32_arm_tdata (ibfd)->known_eabi_attributes[4];
|
||||
out_attr = &elf32_arm_tdata (obfd)->known_eabi_attributes[4];
|
||||
for (i = 4; i < NUM_KNOWN_ATTRIBUTES; i++)
|
||||
{
|
||||
out_attr->type = in_attr->type;
|
||||
out_attr->i = in_attr->i;
|
||||
if (in_attr->s && *in_attr->s)
|
||||
out_attr->s = attr_strdup (obfd, in_attr->s);
|
||||
in_attr++;
|
||||
out_attr++;
|
||||
}
|
||||
|
||||
for (list = elf32_arm_tdata (ibfd)->other_eabi_attributes;
|
||||
list;
|
||||
list = list->next)
|
||||
{
|
||||
in_attr = &list->attr;
|
||||
switch (in_attr->type)
|
||||
{
|
||||
case 1:
|
||||
elf32_arm_add_eabi_attr_int (obfd, list->tag, in_attr->i);
|
||||
break;
|
||||
case 2:
|
||||
elf32_arm_add_eabi_attr_string (obfd, list->tag, in_attr->s);
|
||||
break;
|
||||
case 3:
|
||||
elf32_arm_add_eabi_attr_compat (obfd, in_attr->i, in_attr->s);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Copy backend specific data from one object module to another. */
|
||||
|
||||
static bfd_boolean
|
||||
|
@ -7064,8 +6691,8 @@ elf32_arm_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
|
|||
elf_elfheader (obfd)->e_ident[EI_OSABI] =
|
||||
elf_elfheader (ibfd)->e_ident[EI_OSABI];
|
||||
|
||||
/* Copy EABI object attributes. */
|
||||
copy_eabi_attributes (ibfd, obfd);
|
||||
/* Copy object attributes. */
|
||||
_bfd_elf_copy_obj_attributes (ibfd, obfd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -7097,34 +6724,48 @@ enum
|
|||
AEABI_enum_forced_wide
|
||||
};
|
||||
|
||||
/* Determine whether an object attribute tag takes an integer, a
|
||||
string or both. */
|
||||
static int
|
||||
elf32_arm_obj_attrs_arg_type (int tag)
|
||||
{
|
||||
if (tag == Tag_compatibility)
|
||||
return 3;
|
||||
else if (tag == 4 || tag == 5)
|
||||
return 2;
|
||||
else if (tag < 32)
|
||||
return 1;
|
||||
else
|
||||
return (tag & 1) != 0 ? 2 : 1;
|
||||
}
|
||||
|
||||
/* Merge EABI object attributes from IBFD into OBFD. Raise an error if there
|
||||
are conflicting attributes. */
|
||||
static bfd_boolean
|
||||
elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
|
||||
{
|
||||
aeabi_attribute *in_attr;
|
||||
aeabi_attribute *out_attr;
|
||||
aeabi_attribute_list *in_list;
|
||||
aeabi_attribute_list *out_list;
|
||||
obj_attribute *in_attr;
|
||||
obj_attribute *out_attr;
|
||||
obj_attribute_list *in_list;
|
||||
/* Some tags have 0 = don't care, 1 = strong requirement,
|
||||
2 = weak requirement. */
|
||||
static const int order_312[3] = {3, 1, 2};
|
||||
int i;
|
||||
|
||||
if (!elf32_arm_tdata (obfd)->known_eabi_attributes[0].i)
|
||||
if (!elf_known_obj_attributes_proc (obfd)[0].i)
|
||||
{
|
||||
/* This is the first object. Copy the attributes. */
|
||||
copy_eabi_attributes (ibfd, obfd);
|
||||
_bfd_elf_copy_obj_attributes (ibfd, obfd);
|
||||
|
||||
/* Use the Tag_null value to indicate the attributes have been
|
||||
initialized. */
|
||||
elf32_arm_tdata (obfd)->known_eabi_attributes[0].i = 1;
|
||||
elf_known_obj_attributes_proc (obfd)[0].i = 1;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
in_attr = elf32_arm_tdata (ibfd)->known_eabi_attributes;
|
||||
out_attr = elf32_arm_tdata (obfd)->known_eabi_attributes;
|
||||
in_attr = elf_known_obj_attributes_proc (ibfd);
|
||||
out_attr = elf_known_obj_attributes_proc (obfd);
|
||||
/* This needs to happen before Tag_ABI_FP_number_model is merged. */
|
||||
if (in_attr[Tag_ABI_VFP_args].i != out_attr[Tag_ABI_VFP_args].i)
|
||||
{
|
||||
|
@ -7140,7 +6781,7 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 4; i < NUM_KNOWN_ATTRIBUTES; i++)
|
||||
for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
|
||||
{
|
||||
/* Merge this attribute with existing attributes. */
|
||||
switch (i)
|
||||
|
@ -7152,7 +6793,7 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
|
|||
name is non-NULL. */
|
||||
if (in_attr[Tag_CPU_arch].i > out_attr[Tag_CPU_arch].i
|
||||
&& in_attr[i].s)
|
||||
out_attr[i].s = attr_strdup(obfd, in_attr[i].s);
|
||||
out_attr[i].s = _bfd_elf_attr_strdup (obfd, in_attr[i].s);
|
||||
break;
|
||||
|
||||
case Tag_ABI_optimization_goals:
|
||||
|
@ -7294,60 +6935,13 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
|
|||
}
|
||||
}
|
||||
|
||||
in_list = elf32_arm_tdata (ibfd)->other_eabi_attributes;
|
||||
out_list = elf32_arm_tdata (ibfd)->other_eabi_attributes;
|
||||
while (in_list && in_list->tag == Tag_compatibility)
|
||||
{
|
||||
in_attr = &in_list->attr;
|
||||
if (in_attr->i == 0)
|
||||
continue;
|
||||
if (in_attr->i == 1)
|
||||
{
|
||||
_bfd_error_handler
|
||||
(_("ERROR: %B: Must be processed by '%s' toolchain"),
|
||||
ibfd, in_attr->s);
|
||||
return FALSE;
|
||||
}
|
||||
if (!out_list || out_list->tag != Tag_compatibility
|
||||
|| strcmp (in_attr->s, out_list->attr.s) != 0)
|
||||
{
|
||||
/* Add this compatibility tag to the output. */
|
||||
elf32_arm_add_eabi_attr_compat (obfd, in_attr->i, in_attr->s);
|
||||
continue;
|
||||
}
|
||||
out_attr = &out_list->attr;
|
||||
/* Check all the input tags with the same identifier. */
|
||||
for (;;)
|
||||
{
|
||||
if (out_list->tag != Tag_compatibility
|
||||
|| in_attr->i != out_attr->i
|
||||
|| strcmp (in_attr->s, out_attr->s) != 0)
|
||||
{
|
||||
_bfd_error_handler
|
||||
(_("ERROR: %B: Incompatible object tag '%s':%d"),
|
||||
ibfd, in_attr->s, in_attr->i);
|
||||
return FALSE;
|
||||
}
|
||||
in_list = in_list->next;
|
||||
if (in_list->tag != Tag_compatibility
|
||||
|| strcmp (in_attr->s, in_list->attr.s) != 0)
|
||||
break;
|
||||
in_attr = &in_list->attr;
|
||||
out_list = out_list->next;
|
||||
if (out_list)
|
||||
out_attr = &out_list->attr;
|
||||
}
|
||||
/* Merge Tag_compatibility attributes and any common GNU ones. */
|
||||
_bfd_elf_merge_object_attributes (ibfd, obfd);
|
||||
|
||||
/* Check the output doesn't have extra tags with this identifier. */
|
||||
if (out_list && out_list->tag == Tag_compatibility
|
||||
&& strcmp (in_attr->s, out_list->attr.s) == 0)
|
||||
{
|
||||
_bfd_error_handler
|
||||
(_("ERROR: %B: Incompatible object tag '%s':%d"),
|
||||
ibfd, in_attr->s, out_list->attr.i);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/* Check for any attributes not known on ARM. */
|
||||
in_list = elf_other_obj_attributes_proc (ibfd);
|
||||
while (in_list && in_list->tag == Tag_compatibility)
|
||||
in_list = in_list->next;
|
||||
|
||||
for (; in_list; in_list = in_list->next)
|
||||
{
|
||||
|
@ -9800,125 +9394,9 @@ elf32_arm_fake_sections (bfd * abfd, Elf_Internal_Shdr * hdr, asection * sec)
|
|||
hdr->sh_type = SHT_ARM_EXIDX;
|
||||
hdr->sh_flags |= SHF_LINK_ORDER;
|
||||
}
|
||||
else if (strcmp(name, ".ARM.attributes") == 0)
|
||||
{
|
||||
hdr->sh_type = SHT_ARM_ATTRIBUTES;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Parse an Arm EABI attributes section. */
|
||||
static void
|
||||
elf32_arm_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
|
||||
{
|
||||
bfd_byte *contents;
|
||||
bfd_byte *p;
|
||||
bfd_vma len;
|
||||
|
||||
contents = bfd_malloc (hdr->sh_size);
|
||||
if (!contents)
|
||||
return;
|
||||
if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
|
||||
hdr->sh_size))
|
||||
{
|
||||
free (contents);
|
||||
return;
|
||||
}
|
||||
p = contents;
|
||||
if (*(p++) == 'A')
|
||||
{
|
||||
len = hdr->sh_size - 1;
|
||||
while (len > 0)
|
||||
{
|
||||
int namelen;
|
||||
bfd_vma section_len;
|
||||
|
||||
section_len = bfd_get_32 (abfd, p);
|
||||
p += 4;
|
||||
if (section_len > len)
|
||||
section_len = len;
|
||||
len -= section_len;
|
||||
namelen = strlen ((char *)p) + 1;
|
||||
section_len -= namelen + 4;
|
||||
if (strcmp((char *)p, "aeabi") != 0)
|
||||
{
|
||||
/* Vendor section. Ignore it. */
|
||||
p += namelen + section_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
p += namelen;
|
||||
while (section_len > 0)
|
||||
{
|
||||
int tag;
|
||||
unsigned int n;
|
||||
unsigned int val;
|
||||
bfd_vma subsection_len;
|
||||
bfd_byte *end;
|
||||
|
||||
tag = read_unsigned_leb128 (abfd, p, &n);
|
||||
p += n;
|
||||
subsection_len = bfd_get_32 (abfd, p);
|
||||
p += 4;
|
||||
if (subsection_len > section_len)
|
||||
subsection_len = section_len;
|
||||
section_len -= subsection_len;
|
||||
subsection_len -= n + 4;
|
||||
end = p + subsection_len;
|
||||
switch (tag)
|
||||
{
|
||||
case Tag_File:
|
||||
while (p < end)
|
||||
{
|
||||
bfd_boolean is_string;
|
||||
|
||||
tag = read_unsigned_leb128 (abfd, p, &n);
|
||||
p += n;
|
||||
if (tag == 4 || tag == 5)
|
||||
is_string = 1;
|
||||
else if (tag < 32)
|
||||
is_string = 0;
|
||||
else
|
||||
is_string = (tag & 1) != 0;
|
||||
if (tag == Tag_compatibility)
|
||||
{
|
||||
val = read_unsigned_leb128 (abfd, p, &n);
|
||||
p += n;
|
||||
elf32_arm_add_eabi_attr_compat (abfd, val,
|
||||
(char *)p);
|
||||
p += strlen ((char *)p) + 1;
|
||||
}
|
||||
else if (is_string)
|
||||
{
|
||||
elf32_arm_add_eabi_attr_string (abfd, tag,
|
||||
(char *)p);
|
||||
p += strlen ((char *)p) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = read_unsigned_leb128 (abfd, p, &n);
|
||||
p += n;
|
||||
elf32_arm_add_eabi_attr_int (abfd, tag, val);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Tag_Section:
|
||||
case Tag_Symbol:
|
||||
/* Don't have anywhere convenient to attach these.
|
||||
Fall through for now. */
|
||||
default:
|
||||
/* Ignore things we don't kow about. */
|
||||
p += subsection_len;
|
||||
subsection_len = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free (contents);
|
||||
}
|
||||
|
||||
/* Handle an ARM specific section when reading an object file. This is
|
||||
called when bfd_section_from_shdr finds a section with an unknown
|
||||
type. */
|
||||
|
@ -9948,8 +9426,6 @@ elf32_arm_section_from_shdr (bfd *abfd,
|
|||
if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
|
||||
return FALSE;
|
||||
|
||||
if (hdr->sh_type == SHT_ARM_ATTRIBUTES)
|
||||
elf32_arm_parse_attributes(abfd, hdr);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -10677,7 +10153,6 @@ const struct elf_size_info elf32_arm_size_info = {
|
|||
#define bfd_elf32_bfd_is_target_special_symbol elf32_arm_is_target_special_symbol
|
||||
#define bfd_elf32_close_and_cleanup elf32_arm_close_and_cleanup
|
||||
#define bfd_elf32_bfd_free_cached_info elf32_arm_bfd_free_cached_info
|
||||
#define bfd_elf32_bfd_final_link elf32_arm_bfd_final_link
|
||||
|
||||
#define elf_backend_get_symbol_type elf32_arm_get_symbol_type
|
||||
#define elf_backend_gc_mark_hook elf32_arm_gc_mark_hook
|
||||
|
@ -10722,6 +10197,15 @@ const struct elf_size_info elf32_arm_size_info = {
|
|||
|
||||
#define elf_backend_got_header_size 12
|
||||
|
||||
#undef elf_backend_obj_attrs_vendor
|
||||
#define elf_backend_obj_attrs_vendor "aeabi"
|
||||
#undef elf_backend_obj_attrs_section
|
||||
#define elf_backend_obj_attrs_section ".ARM.attributes"
|
||||
#undef elf_backend_obj_attrs_arg_type
|
||||
#define elf_backend_obj_attrs_arg_type elf32_arm_obj_attrs_arg_type
|
||||
#undef elf_backend_obj_attrs_section_type
|
||||
#define elf_backend_obj_attrs_section_type SHT_ARM_ATTRIBUTES
|
||||
|
||||
#include "elf32-target.h"
|
||||
|
||||
/* VxWorks Targets */
|
||||
|
|
|
@ -4725,6 +4725,10 @@ bfin_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
|
|||
|
||||
elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
|
||||
elf_flags_init (obfd) = TRUE;
|
||||
|
||||
/* Copy object attributes. */
|
||||
_bfd_elf_copy_obj_attributes (ibfd, obfd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -6490,6 +6490,10 @@ frv_elf_copy_private_bfd_data (ibfd, obfd)
|
|||
|
||||
elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
|
||||
elf_flags_init (obfd) = TRUE;
|
||||
|
||||
/* Copy object attributes. */
|
||||
_bfd_elf_copy_obj_attributes (ibfd, obfd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -736,6 +736,10 @@ iq2000_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
|
|||
|
||||
elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
|
||||
elf_flags_init (obfd) = TRUE;
|
||||
|
||||
/* Copy object attributes. */
|
||||
_bfd_elf_copy_obj_attributes (ibfd, obfd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -750,6 +750,10 @@ mep_elf_copy_private_bfd_data (bfd * ibfd, bfd * obfd)
|
|||
|
||||
elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
|
||||
elf_flags_init (obfd) = TRUE;
|
||||
|
||||
/* Copy object attributes. */
|
||||
_bfd_elf_copy_obj_attributes (ibfd, obfd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -515,6 +515,10 @@ mt_elf_copy_private_bfd_data (bfd * ibfd, bfd * obfd)
|
|||
|
||||
elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
|
||||
elf_flags_init (obfd) = TRUE;
|
||||
|
||||
/* Copy object attributes. */
|
||||
_bfd_elf_copy_obj_attributes (ibfd, obfd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -5356,6 +5356,9 @@ sh_elf_copy_private_data (bfd * ibfd, bfd * obfd)
|
|||
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour)
|
||||
return TRUE;
|
||||
|
||||
/* Copy object attributes. */
|
||||
_bfd_elf_copy_obj_attributes (ibfd, obfd);
|
||||
|
||||
return sh_elf_set_private_flags (obfd, elf_elfheader (ibfd)->e_flags);
|
||||
}
|
||||
#endif /* not sh_elf_copy_private_data */
|
||||
|
|
|
@ -2316,6 +2316,9 @@ sh_elf64_copy_private_data_internal (bfd *ibfd, bfd *obfd)
|
|||
}
|
||||
}
|
||||
|
||||
/* Copy object attributes. */
|
||||
_bfd_elf_copy_obj_attributes (ibfd, obfd);
|
||||
|
||||
return sh_elf64_set_private_flags (obfd, elf_elfheader (ibfd)->e_flags);
|
||||
}
|
||||
|
||||
|
|
|
@ -9266,6 +9266,9 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||
size_t relativecount = 0;
|
||||
asection *reldyn = 0;
|
||||
bfd_size_type amt;
|
||||
asection *attr_section = NULL;
|
||||
bfd_vma attr_size = 0;
|
||||
const char *std_attrs_section;
|
||||
|
||||
if (! is_elf_hash_table (info->hash))
|
||||
return FALSE;
|
||||
|
@ -9313,6 +9316,40 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||
finfo.symbuf_count = 0;
|
||||
finfo.shndxbuf_size = 0;
|
||||
|
||||
/* The object attributes have been merged. Remove the input
|
||||
sections from the link, and set the contents of the output
|
||||
secton. */
|
||||
std_attrs_section = get_elf_backend_data (abfd)->obj_attrs_section;
|
||||
for (o = abfd->sections; o != NULL; o = o->next)
|
||||
{
|
||||
if ((std_attrs_section && strcmp (o->name, std_attrs_section) == 0)
|
||||
|| strcmp (o->name, ".gnu.attributes") == 0)
|
||||
{
|
||||
for (p = o->map_head.link_order; p != NULL; p = p->next)
|
||||
{
|
||||
asection *input_section;
|
||||
|
||||
if (p->type != bfd_indirect_link_order)
|
||||
continue;
|
||||
input_section = p->u.indirect.section;
|
||||
/* Hack: reset the SEC_HAS_CONTENTS flag so that
|
||||
elf_link_input_bfd ignores this section. */
|
||||
input_section->flags &= ~SEC_HAS_CONTENTS;
|
||||
}
|
||||
|
||||
attr_size = bfd_elf_obj_attr_size (abfd);
|
||||
if (attr_size)
|
||||
{
|
||||
bfd_set_section_size (abfd, o, attr_size);
|
||||
attr_section = o;
|
||||
/* Skip this section later on. */
|
||||
o->map_head.link_order = NULL;
|
||||
}
|
||||
else
|
||||
o->flags |= SEC_EXCLUDE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Count up the number of relocations we will output for each output
|
||||
section, so that we know the sizes of the reloc sections. We
|
||||
also figure out some maximum sizes. */
|
||||
|
@ -10257,6 +10294,16 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||
|
||||
elf_tdata (abfd)->linker = TRUE;
|
||||
|
||||
if (attr_section)
|
||||
{
|
||||
bfd_byte *contents = bfd_malloc (attr_size);
|
||||
if (contents == NULL)
|
||||
goto error_return;
|
||||
bfd_elf_set_obj_attr_contents (abfd, contents, attr_size);
|
||||
bfd_set_section_contents (abfd, attr_section, contents, 0, attr_size);
|
||||
free (contents);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
error_return:
|
||||
|
|
|
@ -431,6 +431,18 @@
|
|||
#ifndef elf_backend_got_header_size
|
||||
#define elf_backend_got_header_size 0
|
||||
#endif
|
||||
#ifndef elf_backend_obj_attrs_vendor
|
||||
#define elf_backend_obj_attrs_vendor NULL
|
||||
#endif
|
||||
#ifndef elf_backend_obj_attrs_section
|
||||
#define elf_backend_obj_attrs_section NULL
|
||||
#endif
|
||||
#ifndef elf_backend_obj_attrs_arg_type
|
||||
#define elf_backend_obj_attrs_arg_type NULL
|
||||
#endif
|
||||
#ifndef elf_backend_obj_attrs_section_type
|
||||
#define elf_backend_obj_attrs_section_type SHT_GNU_ATTRIBUTES
|
||||
#endif
|
||||
#ifndef elf_backend_post_process_headers
|
||||
#define elf_backend_post_process_headers NULL
|
||||
#endif
|
||||
|
@ -684,6 +696,10 @@ static struct elf_backend_data elfNN_bed =
|
|||
&elf_backend_size_info,
|
||||
elf_backend_special_sections,
|
||||
elf_backend_got_header_size,
|
||||
elf_backend_obj_attrs_vendor,
|
||||
elf_backend_obj_attrs_section,
|
||||
elf_backend_obj_attrs_arg_type,
|
||||
elf_backend_obj_attrs_section_type,
|
||||
elf_backend_collect,
|
||||
elf_backend_type_change_ok,
|
||||
elf_backend_may_use_rel_p,
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2007-06-29 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* readelf.c (display_gnu_attribute): New.
|
||||
(process_arm_specific): Rearrange as process_attributes.
|
||||
(process_arm_specific): Replace by wrapper of process_attributes.
|
||||
|
||||
2007-06-28 Roland McGrath <roland@frob.com>
|
||||
|
||||
* objcopy.c (setup_section): Don't reset ELF section type to
|
||||
|
|
|
@ -8297,8 +8297,61 @@ display_arm_attribute (unsigned char *p)
|
|||
return p;
|
||||
}
|
||||
|
||||
|
||||
static unsigned char *
|
||||
display_gnu_attribute (unsigned char *p,
|
||||
unsigned char *(*display_proc_gnu_attribute)
|
||||
(unsigned char *, int))
|
||||
{
|
||||
int tag;
|
||||
unsigned int len;
|
||||
int val;
|
||||
int type;
|
||||
|
||||
tag = read_uleb128 (p, &len);
|
||||
p += len;
|
||||
|
||||
/* Tag_compatibility is the only generic GNU attribute defined at
|
||||
present. */
|
||||
if (tag == 32)
|
||||
{
|
||||
val = read_uleb128 (p, &len);
|
||||
p += len;
|
||||
printf ("flag = %d, vendor = %s\n", val, p);
|
||||
p += strlen((char *)p) + 1;
|
||||
return p;
|
||||
}
|
||||
|
||||
if ((tag & 2) == 0 && display_proc_gnu_attribute)
|
||||
return display_proc_gnu_attribute (p, tag);
|
||||
|
||||
if (tag & 1)
|
||||
type = 1; /* String. */
|
||||
else
|
||||
type = 2; /* uleb128. */
|
||||
printf (" Tag_unknown_%d: ", tag);
|
||||
|
||||
if (type == 1)
|
||||
{
|
||||
printf ("\"%s\"\n", p);
|
||||
p += strlen ((char *)p) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = read_uleb128 (p, &len);
|
||||
p += len;
|
||||
printf ("%d (0x%x)\n", val, val);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static int
|
||||
process_arm_specific (FILE *file)
|
||||
process_attributes (FILE *file, const char *public_name,
|
||||
unsigned int proc_type,
|
||||
unsigned char *(*display_pub_attribute) (unsigned char *),
|
||||
unsigned char *(*display_proc_gnu_attribute)
|
||||
(unsigned char *, int))
|
||||
{
|
||||
Elf_Internal_Shdr *sect;
|
||||
unsigned char *contents;
|
||||
|
@ -8313,7 +8366,7 @@ process_arm_specific (FILE *file)
|
|||
i < elf_header.e_shnum;
|
||||
i++, sect++)
|
||||
{
|
||||
if (sect->sh_type != SHT_ARM_ATTRIBUTES)
|
||||
if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
|
||||
continue;
|
||||
|
||||
contents = get_data (NULL, file, sect->sh_offset, 1, sect->sh_size,
|
||||
|
@ -8330,6 +8383,7 @@ process_arm_specific (FILE *file)
|
|||
{
|
||||
int namelen;
|
||||
bfd_boolean public_section;
|
||||
bfd_boolean gnu_section;
|
||||
|
||||
section_len = byte_get (p, 4);
|
||||
p += 4;
|
||||
|
@ -8341,10 +8395,14 @@ process_arm_specific (FILE *file)
|
|||
}
|
||||
len -= section_len;
|
||||
printf ("Attribute Section: %s\n", p);
|
||||
if (strcmp ((char *)p, "aeabi") == 0)
|
||||
if (public_name && strcmp ((char *)p, public_name) == 0)
|
||||
public_section = TRUE;
|
||||
else
|
||||
public_section = FALSE;
|
||||
if (strcmp ((char *)p, "gnu") == 0)
|
||||
gnu_section = TRUE;
|
||||
else
|
||||
gnu_section = FALSE;
|
||||
namelen = strlen ((char *)p) + 1;
|
||||
p += namelen;
|
||||
section_len -= namelen + 4;
|
||||
|
@ -8393,7 +8451,13 @@ process_arm_specific (FILE *file)
|
|||
if (public_section)
|
||||
{
|
||||
while (p < end)
|
||||
p = display_arm_attribute(p);
|
||||
p = display_pub_attribute (p);
|
||||
}
|
||||
else if (gnu_section)
|
||||
{
|
||||
while (p < end)
|
||||
p = display_gnu_attribute (p,
|
||||
display_proc_gnu_attribute);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -8414,6 +8478,13 @@ process_arm_specific (FILE *file)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
process_arm_specific (FILE *file)
|
||||
{
|
||||
return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
|
||||
display_arm_attribute, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
process_mips_specific (FILE *file)
|
||||
{
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
2007-06-29 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* as.c (create_obj_attrs_section): New.
|
||||
(main): Call create_obj_attrs_section for ELF.
|
||||
* read.c (s_gnu_attribute, skip_whitespace, skip_past_char,
|
||||
skip_past_comma, s_vendor_attribute): New.
|
||||
(potable): Add gnu_attribute for ELF.
|
||||
* read.h (s_vendor_attribute): Declare.
|
||||
* config/tc-arm.c (s_arm_eabi_attribute): Replace by wrapper
|
||||
round s_vendor_attribute.
|
||||
(aeabi_set_public_attributes): Update for new attributes
|
||||
interfaces.
|
||||
(arm_md_end): Remove attributes contents setting now done
|
||||
generically.
|
||||
|
||||
2007-06-29 M R Swami Reddy <MR.Swami.Redd@nsc.com>
|
||||
|
||||
* Makefile.am: Add CR16 related entry.
|
||||
|
|
31
gas/as.c
31
gas/as.c
|
@ -1031,6 +1031,33 @@ perform_an_assembly_pass (int argc, char ** argv)
|
|||
read_a_source_file ("");
|
||||
}
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
static void
|
||||
create_obj_attrs_section (void)
|
||||
{
|
||||
segT s;
|
||||
char *p;
|
||||
addressT addr;
|
||||
offsetT size;
|
||||
const char *name;
|
||||
|
||||
size = bfd_elf_obj_attr_size (stdoutput);
|
||||
if (size)
|
||||
{
|
||||
name = get_elf_backend_data (stdoutput)->obj_attrs_section;
|
||||
if (!name)
|
||||
name = ".gnu.attributes";
|
||||
s = subseg_new (name, 0);
|
||||
elf_section_type (s)
|
||||
= get_elf_backend_data (stdoutput)->obj_attrs_section_type;
|
||||
bfd_set_section_flags (stdoutput, s, SEC_READONLY | SEC_DATA);
|
||||
addr = frag_now_fix ();
|
||||
p = frag_more (size);
|
||||
bfd_elf_set_obj_attr_contents (stdoutput, (bfd_byte *)p, size);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char ** argv)
|
||||
|
@ -1146,6 +1173,10 @@ main (int argc, char ** argv)
|
|||
md_end ();
|
||||
#endif
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
create_obj_attrs_section ();
|
||||
#endif
|
||||
|
||||
#if defined OBJ_ELF || defined OBJ_MAYBE_ELF
|
||||
if ((flag_execstack || flag_noexecstack)
|
||||
&& OUTPUT_FLAVOR == bfd_target_elf_flavour)
|
||||
|
|
|
@ -3829,84 +3829,7 @@ s_arm_unwind_raw (int ignored ATTRIBUTE_UNUSED)
|
|||
static void
|
||||
s_arm_eabi_attribute (int ignored ATTRIBUTE_UNUSED)
|
||||
{
|
||||
expressionS exp;
|
||||
bfd_boolean is_string;
|
||||
int tag;
|
||||
unsigned int i = 0;
|
||||
char *s = NULL;
|
||||
char saved_char;
|
||||
|
||||
expression (& exp);
|
||||
if (exp.X_op != O_constant)
|
||||
goto bad;
|
||||
|
||||
tag = exp.X_add_number;
|
||||
if (tag == 4 || tag == 5 || tag == 32 || (tag > 32 && (tag & 1) != 0))
|
||||
is_string = 1;
|
||||
else
|
||||
is_string = 0;
|
||||
|
||||
if (skip_past_comma (&input_line_pointer) == FAIL)
|
||||
goto bad;
|
||||
if (tag == 32 || !is_string)
|
||||
{
|
||||
expression (& exp);
|
||||
if (exp.X_op != O_constant)
|
||||
{
|
||||
as_bad (_("expected numeric constant"));
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
i = exp.X_add_number;
|
||||
}
|
||||
if (tag == Tag_compatibility
|
||||
&& skip_past_comma (&input_line_pointer) == FAIL)
|
||||
{
|
||||
as_bad (_("expected comma"));
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
if (is_string)
|
||||
{
|
||||
skip_whitespace(input_line_pointer);
|
||||
if (*input_line_pointer != '"')
|
||||
goto bad_string;
|
||||
input_line_pointer++;
|
||||
s = input_line_pointer;
|
||||
while (*input_line_pointer && *input_line_pointer != '"')
|
||||
input_line_pointer++;
|
||||
if (*input_line_pointer != '"')
|
||||
goto bad_string;
|
||||
saved_char = *input_line_pointer;
|
||||
*input_line_pointer = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
s = NULL;
|
||||
saved_char = 0;
|
||||
}
|
||||
|
||||
if (tag == Tag_compatibility)
|
||||
elf32_arm_add_eabi_attr_compat (stdoutput, i, s);
|
||||
else if (is_string)
|
||||
elf32_arm_add_eabi_attr_string (stdoutput, tag, s);
|
||||
else
|
||||
elf32_arm_add_eabi_attr_int (stdoutput, tag, i);
|
||||
|
||||
if (s)
|
||||
{
|
||||
*input_line_pointer = saved_char;
|
||||
input_line_pointer++;
|
||||
}
|
||||
demand_empty_rest_of_line ();
|
||||
return;
|
||||
bad_string:
|
||||
as_bad (_("bad string constant"));
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
bad:
|
||||
as_bad (_("expected <tag> , <value>"));
|
||||
ignore_rest_of_line ();
|
||||
s_vendor_attribute (OBJ_ATTR_PROC);
|
||||
}
|
||||
#endif /* OBJ_ELF */
|
||||
|
||||
|
@ -20609,65 +20532,54 @@ aeabi_set_public_attributes (void)
|
|||
for (i = 0; p[i]; i++)
|
||||
p[i] = TOUPPER (p[i]);
|
||||
}
|
||||
elf32_arm_add_eabi_attr_string (stdoutput, 5, p);
|
||||
bfd_elf_add_proc_attr_string (stdoutput, 5, p);
|
||||
}
|
||||
/* Tag_CPU_arch. */
|
||||
elf32_arm_add_eabi_attr_int (stdoutput, 6, arch);
|
||||
bfd_elf_add_proc_attr_int (stdoutput, 6, arch);
|
||||
/* Tag_CPU_arch_profile. */
|
||||
if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v7a))
|
||||
elf32_arm_add_eabi_attr_int (stdoutput, 7, 'A');
|
||||
bfd_elf_add_proc_attr_int (stdoutput, 7, 'A');
|
||||
else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v7r))
|
||||
elf32_arm_add_eabi_attr_int (stdoutput, 7, 'R');
|
||||
bfd_elf_add_proc_attr_int (stdoutput, 7, 'R');
|
||||
else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v7m))
|
||||
elf32_arm_add_eabi_attr_int (stdoutput, 7, 'M');
|
||||
bfd_elf_add_proc_attr_int (stdoutput, 7, 'M');
|
||||
/* Tag_ARM_ISA_use. */
|
||||
if (ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_full))
|
||||
elf32_arm_add_eabi_attr_int (stdoutput, 8, 1);
|
||||
bfd_elf_add_proc_attr_int (stdoutput, 8, 1);
|
||||
/* Tag_THUMB_ISA_use. */
|
||||
if (ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_full))
|
||||
elf32_arm_add_eabi_attr_int (stdoutput, 9,
|
||||
bfd_elf_add_proc_attr_int (stdoutput, 9,
|
||||
ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_t2) ? 2 : 1);
|
||||
/* Tag_VFP_arch. */
|
||||
if (ARM_CPU_HAS_FEATURE (thumb_arch_used, fpu_vfp_ext_v3)
|
||||
|| ARM_CPU_HAS_FEATURE (arm_arch_used, fpu_vfp_ext_v3))
|
||||
elf32_arm_add_eabi_attr_int (stdoutput, 10, 3);
|
||||
bfd_elf_add_proc_attr_int (stdoutput, 10, 3);
|
||||
else if (ARM_CPU_HAS_FEATURE (thumb_arch_used, fpu_vfp_ext_v2)
|
||||
|| ARM_CPU_HAS_FEATURE (arm_arch_used, fpu_vfp_ext_v2))
|
||||
elf32_arm_add_eabi_attr_int (stdoutput, 10, 2);
|
||||
bfd_elf_add_proc_attr_int (stdoutput, 10, 2);
|
||||
else if (ARM_CPU_HAS_FEATURE (thumb_arch_used, fpu_vfp_ext_v1)
|
||||
|| ARM_CPU_HAS_FEATURE (arm_arch_used, fpu_vfp_ext_v1)
|
||||
|| ARM_CPU_HAS_FEATURE (thumb_arch_used, fpu_vfp_ext_v1xd)
|
||||
|| ARM_CPU_HAS_FEATURE (arm_arch_used, fpu_vfp_ext_v1xd))
|
||||
elf32_arm_add_eabi_attr_int (stdoutput, 10, 1);
|
||||
bfd_elf_add_proc_attr_int (stdoutput, 10, 1);
|
||||
/* Tag_WMMX_arch. */
|
||||
if (ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_cext_iwmmxt)
|
||||
|| ARM_CPU_HAS_FEATURE (arm_arch_used, arm_cext_iwmmxt))
|
||||
elf32_arm_add_eabi_attr_int (stdoutput, 11, 1);
|
||||
bfd_elf_add_proc_attr_int (stdoutput, 11, 1);
|
||||
/* Tag_NEON_arch. */
|
||||
if (ARM_CPU_HAS_FEATURE (thumb_arch_used, fpu_neon_ext_v1)
|
||||
|| ARM_CPU_HAS_FEATURE (arm_arch_used, fpu_neon_ext_v1))
|
||||
elf32_arm_add_eabi_attr_int (stdoutput, 12, 1);
|
||||
bfd_elf_add_proc_attr_int (stdoutput, 12, 1);
|
||||
}
|
||||
|
||||
/* Add the .ARM.attributes section. */
|
||||
/* Add the default contents for the .ARM.attributes section. */
|
||||
void
|
||||
arm_md_end (void)
|
||||
{
|
||||
segT s;
|
||||
char *p;
|
||||
addressT addr;
|
||||
offsetT size;
|
||||
|
||||
if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
|
||||
return;
|
||||
|
||||
aeabi_set_public_attributes ();
|
||||
size = elf32_arm_eabi_attr_size (stdoutput);
|
||||
s = subseg_new (".ARM.attributes", 0);
|
||||
bfd_set_section_flags (stdoutput, s, SEC_READONLY | SEC_DATA);
|
||||
addr = frag_now_fix ();
|
||||
p = frag_more (size);
|
||||
elf32_arm_set_eabi_attr_contents (stdoutput, (bfd_byte *)p, size);
|
||||
}
|
||||
#endif /* OBJ_ELF */
|
||||
|
||||
|
|
120
gas/read.c
120
gas/read.c
|
@ -213,6 +213,9 @@ static void do_align (int, char *, int, int);
|
|||
static void s_align (int, int);
|
||||
static void s_altmacro (int);
|
||||
static void s_bad_end (int);
|
||||
#ifdef OBJ_ELF
|
||||
static void s_gnu_attribute (int);
|
||||
#endif
|
||||
static void s_reloc (int);
|
||||
static int hex_float (int, char *);
|
||||
static segT get_known_segmented_expression (expressionS * expP);
|
||||
|
@ -339,6 +342,9 @@ static const pseudo_typeS potable[] = {
|
|||
{"func", s_func, 0},
|
||||
{"global", s_globl, 0},
|
||||
{"globl", s_globl, 0},
|
||||
#ifdef OBJ_ELF
|
||||
{"gnu_attribute", s_gnu_attribute, 0},
|
||||
#endif
|
||||
{"hword", cons, 2},
|
||||
{"if", s_if, (int) O_ne},
|
||||
{"ifb", s_ifb, 1},
|
||||
|
@ -2033,6 +2039,120 @@ s_globl (int ignore ATTRIBUTE_UNUSED)
|
|||
mri_comment_end (stop, stopc);
|
||||
}
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
#define skip_whitespace(str) do { if (*(str) == ' ') ++(str); } while (0)
|
||||
|
||||
static inline int
|
||||
skip_past_char (char ** str, char c)
|
||||
{
|
||||
if (**str == c)
|
||||
{
|
||||
(*str)++;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
#define skip_past_comma(str) skip_past_char (str, ',')
|
||||
|
||||
/* Parse an attribute directive for VENDOR. */
|
||||
void
|
||||
s_vendor_attribute (int vendor)
|
||||
{
|
||||
expressionS exp;
|
||||
int type;
|
||||
int tag;
|
||||
unsigned int i = 0;
|
||||
char *s = NULL;
|
||||
char saved_char;
|
||||
|
||||
expression (& exp);
|
||||
if (exp.X_op != O_constant)
|
||||
goto bad;
|
||||
|
||||
tag = exp.X_add_number;
|
||||
type = _bfd_elf_obj_attrs_arg_type (stdoutput, vendor, tag);
|
||||
|
||||
if (skip_past_comma (&input_line_pointer) == -1)
|
||||
goto bad;
|
||||
if (type & 1)
|
||||
{
|
||||
expression (& exp);
|
||||
if (exp.X_op != O_constant)
|
||||
{
|
||||
as_bad (_("expected numeric constant"));
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
i = exp.X_add_number;
|
||||
}
|
||||
if (type == 3
|
||||
&& skip_past_comma (&input_line_pointer) == -1)
|
||||
{
|
||||
as_bad (_("expected comma"));
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
if (type & 2)
|
||||
{
|
||||
skip_whitespace(input_line_pointer);
|
||||
if (*input_line_pointer != '"')
|
||||
goto bad_string;
|
||||
input_line_pointer++;
|
||||
s = input_line_pointer;
|
||||
while (*input_line_pointer && *input_line_pointer != '"')
|
||||
input_line_pointer++;
|
||||
if (*input_line_pointer != '"')
|
||||
goto bad_string;
|
||||
saved_char = *input_line_pointer;
|
||||
*input_line_pointer = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
s = NULL;
|
||||
saved_char = 0;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case 3:
|
||||
bfd_elf_add_obj_attr_compat (stdoutput, vendor, i, s);
|
||||
break;
|
||||
case 2:
|
||||
bfd_elf_add_obj_attr_string (stdoutput, vendor, tag, s);
|
||||
break;
|
||||
case 1:
|
||||
bfd_elf_add_obj_attr_int (stdoutput, vendor, tag, i);
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
if (s)
|
||||
{
|
||||
*input_line_pointer = saved_char;
|
||||
input_line_pointer++;
|
||||
}
|
||||
demand_empty_rest_of_line ();
|
||||
return;
|
||||
bad_string:
|
||||
as_bad (_("bad string constant"));
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
bad:
|
||||
as_bad (_("expected <tag> , <value>"));
|
||||
ignore_rest_of_line ();
|
||||
}
|
||||
|
||||
/* Parse a .gnu_attribute directive. */
|
||||
|
||||
static void
|
||||
s_gnu_attribute (int ignored ATTRIBUTE_UNUSED)
|
||||
{
|
||||
s_vendor_attribute (OBJ_ATTR_GNU);
|
||||
}
|
||||
#endif /* OBJ_ELF */
|
||||
|
||||
/* Handle the MRI IRP and IRPC pseudo-ops. */
|
||||
|
||||
void
|
||||
|
|
|
@ -185,4 +185,5 @@ extern void stringer (int append_zero);
|
|||
extern void s_xstab (int what);
|
||||
extern void s_rva (int);
|
||||
extern void s_incbin (int);
|
||||
extern void s_vendor_attribute (int);
|
||||
extern void s_weakref (int);
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
2007-06-29 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* arm.h (elf32_arm_add_eabi_attr_int,
|
||||
elf32_arm_add_eabi_attr_string, elf32_arm_add_eabi_attr_compat,
|
||||
elf32_arm_get_eabi_attr_int, elf32_arm_set_eabi_attr_contents,
|
||||
elf32_arm_eabi_attr_size, Tag_NULL, Tag_File, Tag_Section,
|
||||
Tag_Symbol, Tag_compatibility): Remove.
|
||||
* common.h (SHT_GNU_ATTRIBUTES): Define.
|
||||
|
||||
2007-06-29 M R Swami Reddy <MR.Swami.Reddy@nsc.com>
|
||||
|
||||
* common.h (EM_CR16): New entry for CR16 cpu.
|
||||
|
|
|
@ -237,22 +237,12 @@ START_RELOC_NUMBERS (elf_arm_reloc_type)
|
|||
END_RELOC_NUMBERS (R_ARM_max)
|
||||
|
||||
#ifdef BFD_ARCH_SIZE
|
||||
/* Routines for manipulating EABI object attributes. */
|
||||
void elf32_arm_add_eabi_attr_int (bfd *, int, unsigned int);
|
||||
void elf32_arm_add_eabi_attr_string (bfd *, int, const char *);
|
||||
void elf32_arm_add_eabi_attr_compat (bfd *, unsigned int, const char *);
|
||||
int elf32_arm_get_eabi_attr_int (bfd *, int);
|
||||
|
||||
void elf32_arm_set_eabi_attr_contents (bfd *, bfd_byte *, bfd_vma);
|
||||
bfd_vma elf32_arm_eabi_attr_size (bfd *);
|
||||
/* EABI object attributes. */
|
||||
|
||||
enum
|
||||
{
|
||||
Tag_NULL,
|
||||
Tag_File,
|
||||
Tag_Section,
|
||||
Tag_Symbol,
|
||||
Tag_CPU_raw_name,
|
||||
/* 0-3 are generic. */
|
||||
Tag_CPU_raw_name = 4,
|
||||
Tag_CPU_name,
|
||||
Tag_CPU_arch,
|
||||
Tag_CPU_arch_profile,
|
||||
|
@ -280,7 +270,7 @@ enum
|
|||
Tag_ABI_WMMX_args,
|
||||
Tag_ABI_optimization_goals,
|
||||
Tag_ABI_FP_optimization_goals,
|
||||
Tag_compatibility,
|
||||
/* 32 is generic. */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -343,6 +343,7 @@
|
|||
#define SHT_LOOS 0x60000000 /* First of OS specific semantics */
|
||||
#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */
|
||||
|
||||
#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes */
|
||||
#define SHT_GNU_HASH 0x6ffffff6 /* GNU style symbol hash table */
|
||||
#define SHT_GNU_LIBLIST 0x6ffffff7 /* List of prelink dependencies */
|
||||
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2007-06-29 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* emulparams/armelf.sh (OTHER_SECTIONS): Remove .ARM.attributes.
|
||||
(ATTRS_SECTIONS): Define.
|
||||
* scripttempl/elf.sc, scripttempl/elf32sh-symbian.sc,
|
||||
scripttempl/elf_chaos.sc, scripttempl/elfi370.sc,
|
||||
scripttempl/elfxtensa.sc: Handle ATTRS_SECTIONS.
|
||||
|
||||
2006-06-29 M R Swami Reddy <MR.Swami.Reddy@nsc.com>
|
||||
|
||||
* scripttemp/elf32cr16.sc: Default linker script.
|
||||
|
|
|
@ -10,8 +10,8 @@ OTHER_TEXT_SECTIONS='*(.glue_7t) *(.glue_7) *(.vfp11_veneer)'
|
|||
OTHER_BSS_SYMBOLS='__bss_start__ = .;'
|
||||
OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ;'
|
||||
OTHER_END_SYMBOLS='__end__ = . ;'
|
||||
OTHER_SECTIONS='.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
||||
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }'
|
||||
OTHER_SECTIONS='.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }'
|
||||
ATTRS_SECTIONS='.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }'
|
||||
OTHER_READONLY_SECTIONS="
|
||||
.ARM.extab ${RELOCATING-0} : { *(.ARM.extab${RELOCATING+* .gnu.linkonce.armextab.*}) }
|
||||
${RELOCATING+ __exidx_start = .; }
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
# OTHER_RELRO_SECTIONS - other than .data.rel.ro ...
|
||||
# (e.g. PPC32 .fixup, .got[12])
|
||||
# OTHER_BSS_SECTIONS - other than .bss .sbss ...
|
||||
# ATTRS_SECTIONS - at the end
|
||||
# OTHER_SECTIONS - at the end
|
||||
# EXECUTABLE_SYMBOLS - symbols that must be defined for an
|
||||
# executable (e.g., _DYNAMIC_LINK)
|
||||
|
@ -96,6 +97,7 @@ test -z "${ETEXT_NAME}" && ETEXT_NAME=etext
|
|||
test -n "$CREATE_SHLIB$CREATE_PIE" && test -n "$SHLIB_DATA_ADDR" && COMMONPAGESIZE=""
|
||||
test -z "$CREATE_SHLIB$CREATE_PIE" && test -n "$DATA_ADDR" && COMMONPAGESIZE=""
|
||||
test -n "$RELRO_NOW" && unset SEPARATE_GOTPLT
|
||||
test -z "$ATTRS_SECTIONS" && ATTRS_SECTIONS=".gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }"
|
||||
DATA_SEGMENT_ALIGN="ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))"
|
||||
DATA_SEGMENT_RELRO_END=""
|
||||
DATA_SEGMENT_END=""
|
||||
|
@ -513,6 +515,7 @@ cat <<EOF
|
|||
${TINY_BSS_SECTION}
|
||||
|
||||
${STACK_ADDR+${STACK}}
|
||||
${ATTRS_SECTIONS}
|
||||
${OTHER_SECTIONS}
|
||||
${RELOCATING+${OTHER_SYMBOLS}}
|
||||
${RELOCATING+${STACKNOTE}}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
# OTHER_TEXT_SECTIONS - these get put in .text when relocating
|
||||
# OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ...
|
||||
# (e.g., .PARISC.global)
|
||||
# ATTRS_SECTIONS - at the end
|
||||
# OTHER_SECTIONS - at the end
|
||||
# EXECUTABLE_SYMBOLS - symbols that must be defined for an
|
||||
# executable (e.g., _DYNAMIC_LINK)
|
||||
|
@ -71,6 +72,7 @@ test -z "${ALIGNMENT}" && ALIGNMENT="${ELFSIZE} / 8"
|
|||
test "$LD_FLAG" = "N" && DATA_ADDR=.
|
||||
test -n "$CREATE_SHLIB$CREATE_PIE" && test -n "$SHLIB_DATA_ADDR" && COMMONPAGESIZE=""
|
||||
test -z "$CREATE_SHLIB$CREATE_PIE" && test -n "$DATA_ADDR" && COMMONPAGESIZE=""
|
||||
test -z "$ATTRS_SECTIONS" && ATTRS_SECTIONS=".gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }"
|
||||
DATA_SEGMENT_ALIGN="ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))"
|
||||
DATA_SEGMENT_END=""
|
||||
if test -n "${COMMONPAGESIZE}"; then
|
||||
|
@ -375,6 +377,7 @@ cat <<EOF
|
|||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
|
||||
${STACK_ADDR+${STACK}}
|
||||
${ATTRS_SECTIONS}
|
||||
${OTHER_SECTIONS}
|
||||
${RELOCATING+${OTHER_SYMBOLS}}
|
||||
${RELOCATING+${STACKNOTE}}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
# OTHER_TEXT_SECTIONS - these get put in .text when relocating
|
||||
# OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ...
|
||||
# (e.g., .PARISC.global)
|
||||
# ATTRS_SECTIONS - at the end
|
||||
# OTHER_SECTIONS - at the end
|
||||
# EXECUTABLE_SYMBOLS - symbols that must be defined for an
|
||||
# executable (e.g., _DYNAMIC_LINK)
|
||||
|
@ -68,6 +69,7 @@ test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT}
|
|||
if [ -z "$MACHINE" ]; then OUTPUT_ARCH=${ARCH}; else OUTPUT_ARCH=${ARCH}:${MACHINE}; fi
|
||||
test -z "${ELFSIZE}" && ELFSIZE=32
|
||||
test -z "${ALIGNMENT}" && ALIGNMENT="${ELFSIZE} / 8"
|
||||
test -z "$ATTRS_SECTIONS" && ATTRS_SECTIONS=".gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }"
|
||||
test "$LD_FLAG" = "N" && DATA_ADDR=.
|
||||
INTERP=".interp ${RELOCATING-0} : { *(.interp) }"
|
||||
PLT=".plt ${RELOCATING-0} : { *(.plt) }"
|
||||
|
@ -349,6 +351,7 @@ cat <<EOF
|
|||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
|
||||
${STACK_ADDR+${STACK}}
|
||||
${ATTRS_SECTIONS}
|
||||
${OTHER_SECTIONS}
|
||||
${RELOCATING+${OTHER_SYMBOLS}}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
# (e.g., .PARISC.milli)
|
||||
# OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ...
|
||||
# (e.g., .PARISC.global)
|
||||
# ATTRS_SECTIONS - at the end
|
||||
# OTHER_SECTIONS - at the end
|
||||
# EXECUTABLE_SYMBOLS - symbols that must be defined for an
|
||||
# executable (e.g., _DYNAMIC_LINK)
|
||||
|
@ -24,6 +25,7 @@
|
|||
test -z "$ENTRY" && ENTRY=_start
|
||||
test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT}
|
||||
test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT}
|
||||
test -z "$ATTRS_SECTIONS" && ATTRS_SECTIONS=".gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }"
|
||||
test "$LD_FLAG" = "N" && DATA_ADDR=.
|
||||
SBSS2=".sbss2 ${RELOCATING-0} : { *(.sbss2) }"
|
||||
SDATA2=".sdata2 ${RELOCATING-0} : { *(.sdata2) }"
|
||||
|
@ -212,6 +214,7 @@ SECTIONS
|
|||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
|
||||
${ATTRS_SECTIONS}
|
||||
${OTHER_SECTIONS}
|
||||
}
|
||||
EOF
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
# OTHER_RELRO_SECTIONS - other than .data.rel.ro ...
|
||||
# (e.g. PPC32 .fixup, .got[12])
|
||||
# OTHER_BSS_SECTIONS - other than .bss .sbss ...
|
||||
# ATTRS_SECTIONS - at the end
|
||||
# OTHER_SECTIONS - at the end
|
||||
# EXECUTABLE_SYMBOLS - symbols that must be defined for an
|
||||
# executable (e.g., _DYNAMIC_LINK)
|
||||
|
@ -109,6 +110,7 @@ test -z "${ETEXT_NAME}" && ETEXT_NAME=etext
|
|||
test -n "$CREATE_SHLIB$CREATE_PIE" && test -n "$SHLIB_DATA_ADDR" && COMMONPAGESIZE=""
|
||||
test -z "$CREATE_SHLIB$CREATE_PIE" && test -n "$DATA_ADDR" && COMMONPAGESIZE=""
|
||||
test -n "$RELRO_NOW" && unset SEPARATE_GOTPLT
|
||||
test -z "$ATTRS_SECTIONS" && ATTRS_SECTIONS=".gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }"
|
||||
DATA_SEGMENT_ALIGN="ALIGN(${SEGMENT_SIZE}) + (. & (${MAXPAGESIZE} - 1))"
|
||||
DATA_SEGMENT_RELRO_END=""
|
||||
DATA_SEGMENT_END=""
|
||||
|
@ -533,6 +535,7 @@ cat <<EOF
|
|||
${TINY_BSS_SECTION}
|
||||
|
||||
${STACK_ADDR+${STACK}}
|
||||
${ATTRS_SECTIONS}
|
||||
${OTHER_SECTIONS}
|
||||
${RELOCATING+${OTHER_SYMBOLS}}
|
||||
${RELOCATING+${STACKNOTE}}
|
||||
|
|
Loading…
Reference in New Issue