* elf-bfd.h (struct bfd_elf_section_data): Add "group" and
"next_in_group". Fix gp and gp_size comments. * elf.c (union elf_internal_group): New. (setup_group): New function. (_bfd_elf_make_section_from_shdr): Set BFD flags for SHT_GROUP. Call setup_group for SHF_GROUP sections. (bfd_section_from_shdr): Build a BFD section for SHT_GROUP. (elf_fake_sections): Set header type for SEC_GROUP, and header flags for sections in a group. (set_group_contents): New function. (_bfd_elf_compute_section_file_positions): Call it. (assign_section_numbers): Set sh_link for SHT_GROUP. * elflink.h (gc_mark_hook): Handle section groups. * elfxx-target.h: Add SEC_GROUP to applicable_flags. * section.c (SEC_GROUP): Define. (struct sec): Comment fixes. * bfd-in2.h: Regenerate. * elf.c (bfd_elf_print_symbol): Formatting fix; migrate expression out of function args. (_bfd_elf_canonicalize_reloc): Similarly. (_bfd_elf_get_symtab): Here too. (_bfd_elf_canonicalize_dynamic_symtab): And here. * elfcode.h (elf_slurp_symbol_table): Don't recalculate size for bfd_bread, and remove unnecessary cast.
This commit is contained in:
parent
ddb2683535
commit
dbb410c3e2
8 changed files with 392 additions and 34 deletions
|
@ -1,3 +1,31 @@
|
||||||
|
2001-10-09 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
|
* elf-bfd.h (struct bfd_elf_section_data): Add "group" and
|
||||||
|
"next_in_group". Fix gp and gp_size comments.
|
||||||
|
* elf.c (union elf_internal_group): New.
|
||||||
|
(setup_group): New function.
|
||||||
|
(_bfd_elf_make_section_from_shdr): Set BFD flags for SHT_GROUP.
|
||||||
|
Call setup_group for SHF_GROUP sections.
|
||||||
|
(bfd_section_from_shdr): Build a BFD section for SHT_GROUP.
|
||||||
|
(elf_fake_sections): Set header type for SEC_GROUP, and header
|
||||||
|
flags for sections in a group.
|
||||||
|
(set_group_contents): New function.
|
||||||
|
(_bfd_elf_compute_section_file_positions): Call it.
|
||||||
|
(assign_section_numbers): Set sh_link for SHT_GROUP.
|
||||||
|
* elflink.h (gc_mark_hook): Handle section groups.
|
||||||
|
* elfxx-target.h: Add SEC_GROUP to applicable_flags.
|
||||||
|
* section.c (SEC_GROUP): Define.
|
||||||
|
(struct sec): Comment fixes.
|
||||||
|
* bfd-in2.h: Regenerate.
|
||||||
|
|
||||||
|
* elf.c (bfd_elf_print_symbol): Formatting fix; migrate expression
|
||||||
|
out of function args.
|
||||||
|
(_bfd_elf_canonicalize_reloc): Similarly.
|
||||||
|
(_bfd_elf_get_symtab): Here too.
|
||||||
|
(_bfd_elf_canonicalize_dynamic_symtab): And here.
|
||||||
|
* elfcode.h (elf_slurp_symbol_table): Don't recalculate size for
|
||||||
|
bfd_bread, and remove unnecessary cast.
|
||||||
|
|
||||||
2001-10-08 Aldy Hernandez <aldyh@redhat.com>
|
2001-10-08 Aldy Hernandez <aldyh@redhat.com>
|
||||||
|
|
||||||
* bfd/config.bfd (targ_cpu): Add arm9e-*-elf.
|
* bfd/config.bfd (targ_cpu): Add arm9e-*-elf.
|
||||||
|
|
|
@ -983,7 +983,7 @@ typedef struct sec
|
||||||
|
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
/* Which section is it; 0..nth. */
|
/* Which section in the bfd; 0..n-1 as sections are created in a bfd. */
|
||||||
|
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
|
@ -1098,9 +1098,10 @@ typedef struct sec
|
||||||
objects are to be further relocated. */
|
objects are to be further relocated. */
|
||||||
#define SEC_EXCLUDE 0x40000
|
#define SEC_EXCLUDE 0x40000
|
||||||
|
|
||||||
/* The contents of this section are to be sorted by the
|
/* The contents of this section are to be sorted based on the sum of
|
||||||
based on the address specified in the associated symbol
|
the symbol and addend values specified by the associated relocation
|
||||||
table. */
|
entries. Entries without associated relocation entries will be
|
||||||
|
appended to the end of the section in an unspecified order. */
|
||||||
#define SEC_SORT_ENTRIES 0x80000
|
#define SEC_SORT_ENTRIES 0x80000
|
||||||
|
|
||||||
/* When linking, duplicate sections of the same name should be
|
/* When linking, duplicate sections of the same name should be
|
||||||
|
@ -1167,6 +1168,9 @@ typedef struct sec
|
||||||
size entries. */
|
size entries. */
|
||||||
#define SEC_STRINGS 0x40000000
|
#define SEC_STRINGS 0x40000000
|
||||||
|
|
||||||
|
/* This section contains data about section groups. */
|
||||||
|
#define SEC_GROUP 0x80000000
|
||||||
|
|
||||||
/* End of section flags. */
|
/* End of section flags. */
|
||||||
|
|
||||||
/* Some internal packed boolean fields. */
|
/* Some internal packed boolean fields. */
|
||||||
|
@ -1187,7 +1191,8 @@ typedef struct sec
|
||||||
/* A mark flag used by some linker backends for garbage collection. */
|
/* A mark flag used by some linker backends for garbage collection. */
|
||||||
unsigned int gc_mark : 1;
|
unsigned int gc_mark : 1;
|
||||||
|
|
||||||
/* Used by the ELF code to mark sections which have been allocated to segments. */
|
/* Used by the ELF code to mark sections which have been allocated
|
||||||
|
to segments. */
|
||||||
unsigned int segment_mark : 1;
|
unsigned int segment_mark : 1;
|
||||||
|
|
||||||
/* End of internal packed boolean fields. */
|
/* End of internal packed boolean fields. */
|
||||||
|
|
|
@ -815,6 +815,13 @@ struct bfd_elf_section_data
|
||||||
/* A pointer used for SEC_MERGE optimizations. */
|
/* A pointer used for SEC_MERGE optimizations. */
|
||||||
PTR merge_info;
|
PTR merge_info;
|
||||||
|
|
||||||
|
/* Group name, if this section is part of a group. */
|
||||||
|
const char *group;
|
||||||
|
|
||||||
|
/* A linked list of sections in the group. Circular when used by
|
||||||
|
the linker. */
|
||||||
|
asection *next_in_group;
|
||||||
|
|
||||||
/* A pointer available for the processor specific ELF backend. */
|
/* A pointer available for the processor specific ELF backend. */
|
||||||
PTR tdata;
|
PTR tdata;
|
||||||
|
|
||||||
|
@ -905,8 +912,11 @@ struct elf_obj_tdata
|
||||||
void *prstatus; /* The raw /proc prstatus structure */
|
void *prstatus; /* The raw /proc prstatus structure */
|
||||||
void *prpsinfo; /* The raw /proc prpsinfo structure */
|
void *prpsinfo; /* The raw /proc prpsinfo structure */
|
||||||
#endif
|
#endif
|
||||||
bfd_vma gp; /* The gp value (MIPS only, for now) */
|
bfd_vma gp; /* The gp value */
|
||||||
unsigned int gp_size; /* The gp size (MIPS only, for now) */
|
unsigned int gp_size; /* The gp size */
|
||||||
|
|
||||||
|
Elf_Internal_Shdr **group_sect_ptr;
|
||||||
|
int num_group;
|
||||||
|
|
||||||
/* Information grabbed from an elf core file. */
|
/* Information grabbed from an elf core file. */
|
||||||
int core_signal;
|
int core_signal;
|
||||||
|
|
329
bfd/elf.c
329
bfd/elf.c
|
@ -51,7 +51,9 @@ static boolean prep_headers PARAMS ((bfd *));
|
||||||
static boolean swap_out_syms PARAMS ((bfd *, struct bfd_strtab_hash **, int));
|
static boolean swap_out_syms PARAMS ((bfd *, struct bfd_strtab_hash **, int));
|
||||||
static boolean copy_private_bfd_data PARAMS ((bfd *, bfd *));
|
static boolean copy_private_bfd_data PARAMS ((bfd *, bfd *));
|
||||||
static char *elf_read PARAMS ((bfd *, file_ptr, bfd_size_type));
|
static char *elf_read PARAMS ((bfd *, file_ptr, bfd_size_type));
|
||||||
|
static boolean setup_group PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
|
||||||
static void elf_fake_sections PARAMS ((bfd *, asection *, PTR));
|
static void elf_fake_sections PARAMS ((bfd *, asection *, PTR));
|
||||||
|
static void set_group_contents PARAMS ((bfd *, asection *, PTR));
|
||||||
static boolean assign_section_numbers PARAMS ((bfd *));
|
static boolean assign_section_numbers PARAMS ((bfd *));
|
||||||
static INLINE int sym_is_global PARAMS ((bfd *, asymbol *));
|
static INLINE int sym_is_global PARAMS ((bfd *, asymbol *));
|
||||||
static boolean elf_map_symbols PARAMS ((bfd *));
|
static boolean elf_map_symbols PARAMS ((bfd *));
|
||||||
|
@ -345,6 +347,191 @@ bfd_elf_string_from_elf_section (abfd, shindex, strindex)
|
||||||
return ((char *) hdr->contents) + strindex;
|
return ((char *) hdr->contents) + strindex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Elf_Internal_Shdr->contents is an array of these for SHT_GROUP
|
||||||
|
sections. The first element is the flags, the rest are section
|
||||||
|
pointers. */
|
||||||
|
|
||||||
|
typedef union elf_internal_group {
|
||||||
|
Elf_Internal_Shdr *shdr;
|
||||||
|
unsigned int flags;
|
||||||
|
} Elf_Internal_Group;
|
||||||
|
|
||||||
|
/* Set next_in_group list pointer, and group name for NEWSECT. */
|
||||||
|
|
||||||
|
static boolean
|
||||||
|
setup_group (abfd, hdr, newsect)
|
||||||
|
bfd *abfd;
|
||||||
|
Elf_Internal_Shdr *hdr;
|
||||||
|
asection *newsect;
|
||||||
|
{
|
||||||
|
unsigned int num_group = elf_tdata (abfd)->num_group;
|
||||||
|
|
||||||
|
/* If num_group is zero, read in all SHT_GROUP sections. The count
|
||||||
|
is set to -1 if there are no SHT_GROUP sections. */
|
||||||
|
if (num_group == 0)
|
||||||
|
{
|
||||||
|
unsigned int i, shnum;
|
||||||
|
|
||||||
|
/* First count the number of groups. If we have a SHT_GROUP
|
||||||
|
section with just a flag word (ie. sh_size is 4), ignore it. */
|
||||||
|
shnum = elf_elfheader (abfd)->e_shnum;
|
||||||
|
num_group = 0;
|
||||||
|
for (i = 0; i < shnum; i++)
|
||||||
|
{
|
||||||
|
Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
|
||||||
|
if (shdr->sh_type == SHT_GROUP && shdr->sh_size >= 8)
|
||||||
|
num_group += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_group == 0)
|
||||||
|
num_group = -1;
|
||||||
|
elf_tdata (abfd)->num_group = num_group;
|
||||||
|
|
||||||
|
if (num_group > 0)
|
||||||
|
{
|
||||||
|
/* We keep a list of elf section headers for group sections,
|
||||||
|
so we can find them quickly. */
|
||||||
|
bfd_size_type amt = num_group * sizeof (Elf_Internal_Shdr *);
|
||||||
|
elf_tdata (abfd)->group_sect_ptr = bfd_alloc (abfd, amt);
|
||||||
|
if (elf_tdata (abfd)->group_sect_ptr == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
num_group = 0;
|
||||||
|
for (i = 0; i < shnum; i++)
|
||||||
|
{
|
||||||
|
Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
|
||||||
|
if (shdr->sh_type == SHT_GROUP && shdr->sh_size >= 8)
|
||||||
|
{
|
||||||
|
char *src;
|
||||||
|
Elf_Internal_Group *dest;
|
||||||
|
|
||||||
|
/* Add to list of sections. */
|
||||||
|
elf_tdata (abfd)->group_sect_ptr[num_group] = shdr;
|
||||||
|
num_group += 1;
|
||||||
|
|
||||||
|
/* Read the raw contents. */
|
||||||
|
BFD_ASSERT (sizeof (*dest) >= 4);
|
||||||
|
amt = shdr->sh_size * sizeof (*dest) / 4;
|
||||||
|
shdr->contents = bfd_alloc (abfd, amt);
|
||||||
|
if (shdr->contents == NULL
|
||||||
|
|| bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0
|
||||||
|
|| (bfd_bread (shdr->contents, shdr->sh_size, abfd)
|
||||||
|
!= shdr->sh_size))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Translate raw contents, a flag word followed by an
|
||||||
|
array of elf section indices all in target byte order,
|
||||||
|
to the flag word followed by an array of elf section
|
||||||
|
pointers. */
|
||||||
|
src = shdr->contents + shdr->sh_size;
|
||||||
|
dest = (Elf_Internal_Group *) (shdr->contents + amt);
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
unsigned int idx;
|
||||||
|
|
||||||
|
src -= 4;
|
||||||
|
--dest;
|
||||||
|
idx = H_GET_32 (abfd, src);
|
||||||
|
if (src == shdr->contents)
|
||||||
|
{
|
||||||
|
dest->flags = idx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (idx >= shnum)
|
||||||
|
{
|
||||||
|
((*_bfd_error_handler)
|
||||||
|
(_("%s: invalid SHT_GROUP entry"),
|
||||||
|
bfd_archive_filename (abfd)));
|
||||||
|
idx = 0;
|
||||||
|
}
|
||||||
|
dest->shdr = elf_elfsections (abfd)[idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_group != (unsigned) -1)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < num_group; i++)
|
||||||
|
{
|
||||||
|
Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
|
||||||
|
Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
|
||||||
|
unsigned int n_elt = shdr->sh_size / 4;
|
||||||
|
|
||||||
|
/* Look through this group's sections to see if current
|
||||||
|
section is a member. */
|
||||||
|
while (--n_elt != 0)
|
||||||
|
if ((++idx)->shdr == hdr)
|
||||||
|
{
|
||||||
|
asection *s;
|
||||||
|
|
||||||
|
/* We are a member of this group. Go looking through
|
||||||
|
other members to see if any others are linked via
|
||||||
|
next_in_group. */
|
||||||
|
idx = (Elf_Internal_Group *) shdr->contents;
|
||||||
|
n_elt = shdr->sh_size / 4;
|
||||||
|
while (--n_elt != 0)
|
||||||
|
if ((s = (++idx)->shdr->bfd_section) != NULL
|
||||||
|
&& elf_section_data (s)->next_in_group != NULL)
|
||||||
|
break;
|
||||||
|
if (n_elt != 0)
|
||||||
|
{
|
||||||
|
const char *gname;
|
||||||
|
asection *next;
|
||||||
|
|
||||||
|
/* Snarf the group name from other member, and
|
||||||
|
insert current section in circular list. */
|
||||||
|
gname = elf_section_data (s)->group;
|
||||||
|
elf_section_data (newsect)->group = gname;
|
||||||
|
next = elf_section_data (s)->next_in_group;
|
||||||
|
elf_section_data (newsect)->next_in_group = next;
|
||||||
|
elf_section_data (s)->next_in_group = newsect;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct elf_backend_data *bed;
|
||||||
|
file_ptr pos;
|
||||||
|
unsigned char ename[4];
|
||||||
|
unsigned long iname;
|
||||||
|
const char *gname;
|
||||||
|
|
||||||
|
/* Humbug. Get the name from the group signature
|
||||||
|
symbol. Why isn't the signature just a string?
|
||||||
|
Fortunately, the name index is at the same
|
||||||
|
place in the external symbol for both 32 and 64
|
||||||
|
bit ELF. */
|
||||||
|
bed = get_elf_backend_data (abfd);
|
||||||
|
pos = elf_tdata (abfd)->symtab_hdr.sh_offset;
|
||||||
|
pos += shdr->sh_info * bed->s->sizeof_sym;
|
||||||
|
if (bfd_seek (abfd, pos, SEEK_SET) != 0
|
||||||
|
|| bfd_bread (ename, 4, abfd) != 4)
|
||||||
|
return false;
|
||||||
|
iname = H_GET_32 (abfd, ename);
|
||||||
|
gname = elf_string_from_elf_strtab (abfd, iname);
|
||||||
|
elf_section_data (newsect)->group = gname;
|
||||||
|
|
||||||
|
/* Start a circular list with one element. */
|
||||||
|
elf_section_data (newsect)->next_in_group = newsect;
|
||||||
|
}
|
||||||
|
if (shdr->bfd_section != NULL)
|
||||||
|
shdr->bfd_section->lineno = (alent *) newsect;
|
||||||
|
i = num_group - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elf_section_data (newsect)->group == NULL)
|
||||||
|
{
|
||||||
|
(*_bfd_error_handler) (_("%s: no group info for section %s"),
|
||||||
|
bfd_archive_filename (abfd), newsect->name);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Make a BFD section from an ELF section. We store a pointer to the
|
/* Make a BFD section from an ELF section. We store a pointer to the
|
||||||
BFD section in the bfd_section field of the header. */
|
BFD section in the bfd_section field of the header. */
|
||||||
|
|
||||||
|
@ -380,6 +567,8 @@ _bfd_elf_make_section_from_shdr (abfd, hdr, name)
|
||||||
flags = SEC_NO_FLAGS;
|
flags = SEC_NO_FLAGS;
|
||||||
if (hdr->sh_type != SHT_NOBITS)
|
if (hdr->sh_type != SHT_NOBITS)
|
||||||
flags |= SEC_HAS_CONTENTS;
|
flags |= SEC_HAS_CONTENTS;
|
||||||
|
if (hdr->sh_type == SHT_GROUP)
|
||||||
|
flags |= SEC_GROUP | SEC_EXCLUDE;
|
||||||
if ((hdr->sh_flags & SHF_ALLOC) != 0)
|
if ((hdr->sh_flags & SHF_ALLOC) != 0)
|
||||||
{
|
{
|
||||||
flags |= SEC_ALLOC;
|
flags |= SEC_ALLOC;
|
||||||
|
@ -399,6 +588,9 @@ _bfd_elf_make_section_from_shdr (abfd, hdr, name)
|
||||||
if ((hdr->sh_flags & SHF_STRINGS) != 0)
|
if ((hdr->sh_flags & SHF_STRINGS) != 0)
|
||||||
flags |= SEC_STRINGS;
|
flags |= SEC_STRINGS;
|
||||||
}
|
}
|
||||||
|
if (hdr->sh_flags & SHF_GROUP)
|
||||||
|
if (!setup_group (abfd, hdr, newsect))
|
||||||
|
return false;
|
||||||
|
|
||||||
/* The debugging sections appear to be recognized only by name, not
|
/* The debugging sections appear to be recognized only by name, not
|
||||||
any sort of flag. */
|
any sort of flag. */
|
||||||
|
@ -841,6 +1033,7 @@ bfd_elf_print_symbol (abfd, filep, symbol, how)
|
||||||
const char *name = NULL;
|
const char *name = NULL;
|
||||||
struct elf_backend_data *bed;
|
struct elf_backend_data *bed;
|
||||||
unsigned char st_other;
|
unsigned char st_other;
|
||||||
|
bfd_vma val;
|
||||||
|
|
||||||
section_name = symbol->section ? symbol->section->name : "(*none*)";
|
section_name = symbol->section ? symbol->section->name : "(*none*)";
|
||||||
|
|
||||||
|
@ -859,10 +1052,11 @@ bfd_elf_print_symbol (abfd, filep, symbol, how)
|
||||||
we've already printed the size; now print the alignment.
|
we've already printed the size; now print the alignment.
|
||||||
For other symbols, we have no specified alignment, and
|
For other symbols, we have no specified alignment, and
|
||||||
we've printed the address; now print the size. */
|
we've printed the address; now print the size. */
|
||||||
bfd_fprintf_vma (abfd, file,
|
if (bfd_is_com_section (symbol->section))
|
||||||
(bfd_is_com_section (symbol->section)
|
val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
|
||||||
? ((elf_symbol_type *) symbol)->internal_elf_sym.st_value
|
else
|
||||||
: ((elf_symbol_type *) symbol)->internal_elf_sym.st_size));
|
val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_size;
|
||||||
|
bfd_fprintf_vma (abfd, file, val);
|
||||||
|
|
||||||
/* If we have version information, print it. */
|
/* If we have version information, print it. */
|
||||||
if (elf_tdata (abfd)->dynversym_section != 0
|
if (elf_tdata (abfd)->dynversym_section != 0
|
||||||
|
@ -1512,6 +1706,26 @@ bfd_section_from_shdr (abfd, shindex)
|
||||||
case SHT_SHLIB:
|
case SHT_SHLIB:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case SHT_GROUP:
|
||||||
|
/* Make a section for objcopy and relocatable links. */
|
||||||
|
if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name))
|
||||||
|
return false;
|
||||||
|
if (hdr->contents != NULL)
|
||||||
|
{
|
||||||
|
Elf_Internal_Group *idx = (Elf_Internal_Group *) hdr->contents;
|
||||||
|
unsigned int n_elt = hdr->sh_size / 4;
|
||||||
|
asection *s;
|
||||||
|
|
||||||
|
while (--n_elt != 0)
|
||||||
|
if ((s = (++idx)->shdr->bfd_section) != NULL
|
||||||
|
&& elf_section_data (s)->next_in_group != NULL)
|
||||||
|
{
|
||||||
|
hdr->bfd_section->lineno = (alent *) s;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Check for any processor-specific section types. */
|
/* Check for any processor-specific section types. */
|
||||||
{
|
{
|
||||||
|
@ -1847,6 +2061,11 @@ elf_fake_sections (abfd, asect, failedptrarg)
|
||||||
BFD_ASSERT (elf_tdata (abfd)->cverrefs == 0
|
BFD_ASSERT (elf_tdata (abfd)->cverrefs == 0
|
||||||
|| this_hdr->sh_info == elf_tdata (abfd)->cverrefs);
|
|| this_hdr->sh_info == elf_tdata (abfd)->cverrefs);
|
||||||
}
|
}
|
||||||
|
else if ((asect->flags & SEC_GROUP) != 0)
|
||||||
|
{
|
||||||
|
this_hdr->sh_type = SHT_GROUP;
|
||||||
|
this_hdr->sh_entsize = 4;
|
||||||
|
}
|
||||||
else if ((asect->flags & SEC_ALLOC) != 0
|
else if ((asect->flags & SEC_ALLOC) != 0
|
||||||
&& ((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0))
|
&& ((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0))
|
||||||
this_hdr->sh_type = SHT_NOBITS;
|
this_hdr->sh_type = SHT_NOBITS;
|
||||||
|
@ -1866,6 +2085,8 @@ elf_fake_sections (abfd, asect, failedptrarg)
|
||||||
if ((asect->flags & SEC_STRINGS) != 0)
|
if ((asect->flags & SEC_STRINGS) != 0)
|
||||||
this_hdr->sh_flags |= SHF_STRINGS;
|
this_hdr->sh_flags |= SHF_STRINGS;
|
||||||
}
|
}
|
||||||
|
if (elf_section_data (asect)->group != NULL)
|
||||||
|
this_hdr->sh_flags |= SHF_GROUP;
|
||||||
|
|
||||||
/* Check for processor-specific section types. */
|
/* Check for processor-specific section types. */
|
||||||
if (bed->elf_backend_fake_sections)
|
if (bed->elf_backend_fake_sections)
|
||||||
|
@ -1883,6 +2104,82 @@ elf_fake_sections (abfd, asect, failedptrarg)
|
||||||
*failedptr = true;
|
*failedptr = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fill in the contents of a SHT_GROUP section. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_group_contents (abfd, sec, failedptrarg)
|
||||||
|
bfd *abfd;
|
||||||
|
asection *sec;
|
||||||
|
PTR failedptrarg ATTRIBUTE_UNUSED;
|
||||||
|
{
|
||||||
|
boolean *failedptr = (boolean *) failedptrarg;
|
||||||
|
unsigned long symindx;
|
||||||
|
asection *elt;
|
||||||
|
unsigned char *loc;
|
||||||
|
struct bfd_link_order *l;
|
||||||
|
|
||||||
|
if (elf_section_data (sec)->this_hdr.sh_type != SHT_GROUP
|
||||||
|
|| *failedptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* If called from the assembler, swap_out_syms will have set up
|
||||||
|
udata.i; If called for "ld -r", the symbols won't yet be mapped,
|
||||||
|
so emulate elf_bfd_final_link. */
|
||||||
|
symindx = sec->symbol->udata.i;
|
||||||
|
if (symindx == 0)
|
||||||
|
symindx = elf_section_data (sec)->this_idx;
|
||||||
|
elf_section_data (sec)->this_hdr.sh_info = symindx;
|
||||||
|
|
||||||
|
/* Nor will the contents be allocated for "ld -r". */
|
||||||
|
if (sec->contents == NULL)
|
||||||
|
{
|
||||||
|
sec->contents = bfd_alloc (abfd, sec->_raw_size);
|
||||||
|
if (sec->contents == NULL)
|
||||||
|
{
|
||||||
|
*failedptr = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loc = sec->contents + sec->_raw_size;
|
||||||
|
|
||||||
|
/* Get the pointer to the first section in the group that we
|
||||||
|
squirreled away here. */
|
||||||
|
elt = (asection *) sec->lineno;
|
||||||
|
|
||||||
|
/* First element is a flag word. Rest of section is elf section
|
||||||
|
indices for all the sections of the group. Write them backwards
|
||||||
|
just to keep the group in the same order as given in .section
|
||||||
|
directives, not that it matters. */
|
||||||
|
while (elt != NULL)
|
||||||
|
{
|
||||||
|
loc -= 4;
|
||||||
|
H_PUT_32 (abfd, elf_section_data (elt)->this_idx, loc);
|
||||||
|
elt = elf_section_data (elt)->next_in_group;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If this is a relocatable link, then the above did nothing because
|
||||||
|
SEC is the output section. Look through the input sections
|
||||||
|
instead. */
|
||||||
|
for (l = sec->link_order_head; l != NULL; l = l->next)
|
||||||
|
if (l->type == bfd_indirect_link_order
|
||||||
|
&& (elt = (asection *) l->u.indirect.section->lineno) != NULL)
|
||||||
|
do
|
||||||
|
{
|
||||||
|
loc -= 4;
|
||||||
|
H_PUT_32 (abfd,
|
||||||
|
elf_section_data (elt->output_section)->this_idx, loc);
|
||||||
|
elt = elf_section_data (elt)->next_in_group;
|
||||||
|
/* During a relocatable link, the lists are circular. */
|
||||||
|
}
|
||||||
|
while (elt != (asection *) l->u.indirect.section->lineno);
|
||||||
|
|
||||||
|
loc -= 4;
|
||||||
|
H_PUT_32 (abfd, 0, loc);
|
||||||
|
|
||||||
|
BFD_ASSERT (loc == sec->contents);
|
||||||
|
}
|
||||||
|
|
||||||
/* Assign all ELF section numbers. The dummy first section is handled here
|
/* Assign all ELF section numbers. The dummy first section is handled here
|
||||||
too. The link/info pointers for the standard section types are filled
|
too. The link/info pointers for the standard section types are filled
|
||||||
in here too, while we're at it. */
|
in here too, while we're at it. */
|
||||||
|
@ -2055,6 +2352,9 @@ assign_section_numbers (abfd)
|
||||||
if (s != NULL)
|
if (s != NULL)
|
||||||
d->this_hdr.sh_link = elf_section_data (s)->this_idx;
|
d->this_hdr.sh_link = elf_section_data (s)->this_idx;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SHT_GROUP:
|
||||||
|
d->this_hdr.sh_link = t->symtab_section;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2331,6 +2631,13 @@ _bfd_elf_compute_section_file_positions (abfd, link_info)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (link_info == NULL || link_info->relocateable)
|
||||||
|
{
|
||||||
|
bfd_map_over_sections (abfd, set_group_contents, &failed);
|
||||||
|
if (failed)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr;
|
shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr;
|
||||||
/* sh_name was set in prep_headers. */
|
/* sh_name was set in prep_headers. */
|
||||||
shstrtab_hdr->sh_type = SHT_STRTAB;
|
shstrtab_hdr->sh_type = SHT_STRTAB;
|
||||||
|
@ -4569,11 +4876,9 @@ _bfd_elf_canonicalize_reloc (abfd, section, relptr, symbols)
|
||||||
{
|
{
|
||||||
arelent *tblptr;
|
arelent *tblptr;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
||||||
|
|
||||||
if (! get_elf_backend_data (abfd)->s->slurp_reloc_table (abfd,
|
if (! bed->s->slurp_reloc_table (abfd, section, symbols, false))
|
||||||
section,
|
|
||||||
symbols,
|
|
||||||
false))
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
tblptr = section->relocation;
|
tblptr = section->relocation;
|
||||||
|
@ -4590,8 +4895,8 @@ _bfd_elf_get_symtab (abfd, alocation)
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
asymbol **alocation;
|
asymbol **alocation;
|
||||||
{
|
{
|
||||||
long symcount = get_elf_backend_data (abfd)->s->slurp_symbol_table
|
struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
||||||
(abfd, alocation, false);
|
long symcount = bed->s->slurp_symbol_table (abfd, alocation, false);
|
||||||
|
|
||||||
if (symcount >= 0)
|
if (symcount >= 0)
|
||||||
bfd_get_symcount (abfd) = symcount;
|
bfd_get_symcount (abfd) = symcount;
|
||||||
|
@ -4603,8 +4908,8 @@ _bfd_elf_canonicalize_dynamic_symtab (abfd, alocation)
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
asymbol **alocation;
|
asymbol **alocation;
|
||||||
{
|
{
|
||||||
return get_elf_backend_data (abfd)->s->slurp_symbol_table
|
struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
||||||
(abfd, alocation, true);
|
return bed->s->slurp_symbol_table (abfd, alocation, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the size required for the dynamic reloc entries. Any
|
/* Return the size required for the dynamic reloc entries. Any
|
||||||
|
|
|
@ -1084,10 +1084,7 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
|
||||||
if (x_symp == NULL && symcount != 0)
|
if (x_symp == NULL && symcount != 0)
|
||||||
goto error_return;
|
goto error_return;
|
||||||
|
|
||||||
if (bfd_bread ((PTR) x_symp,
|
if (bfd_bread ((PTR) x_symp, amt, abfd) != amt)
|
||||||
(bfd_size_type) (symcount * sizeof (Elf_External_Sym)),
|
|
||||||
abfd)
|
|
||||||
!= symcount * sizeof (Elf_External_Sym))
|
|
||||||
goto error_return;
|
goto error_return;
|
||||||
|
|
||||||
/* Read the raw ELF version symbol information. */
|
/* Read the raw ELF version symbol information. */
|
||||||
|
@ -1115,7 +1112,7 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
|
||||||
if (x_versymp == NULL && verhdr->sh_size != 0)
|
if (x_versymp == NULL && verhdr->sh_size != 0)
|
||||||
goto error_return;
|
goto error_return;
|
||||||
|
|
||||||
if (bfd_bread ((PTR) x_versymp, (bfd_size_type) verhdr->sh_size, abfd)
|
if (bfd_bread ((PTR) x_versymp, verhdr->sh_size, abfd)
|
||||||
!= verhdr->sh_size)
|
!= verhdr->sh_size)
|
||||||
goto error_return;
|
goto error_return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6878,7 +6878,8 @@ static boolean elf_gc_smash_unused_vtentry_relocs
|
||||||
PARAMS ((struct elf_link_hash_entry *h, PTR dummy));
|
PARAMS ((struct elf_link_hash_entry *h, PTR dummy));
|
||||||
|
|
||||||
/* The mark phase of garbage collection. For a given section, mark
|
/* The mark phase of garbage collection. For a given section, mark
|
||||||
it, and all the sections which define symbols to which it refers. */
|
it and any sections in this section's group, and all the sections
|
||||||
|
which define symbols to which it refers. */
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
elf_gc_mark (info, sec, gc_mark_hook)
|
elf_gc_mark (info, sec, gc_mark_hook)
|
||||||
|
@ -6888,12 +6889,19 @@ elf_gc_mark (info, sec, gc_mark_hook)
|
||||||
PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,
|
PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,
|
||||||
struct elf_link_hash_entry *, Elf_Internal_Sym *));
|
struct elf_link_hash_entry *, Elf_Internal_Sym *));
|
||||||
{
|
{
|
||||||
boolean ret = true;
|
boolean ret;
|
||||||
|
asection *group_sec;
|
||||||
|
|
||||||
sec->gc_mark = 1;
|
sec->gc_mark = 1;
|
||||||
|
|
||||||
/* Look through the section relocs. */
|
/* Mark all the sections in the group. */
|
||||||
|
group_sec = elf_section_data (sec)->next_in_group;
|
||||||
|
if (group_sec && !group_sec->gc_mark)
|
||||||
|
if (!elf_gc_mark (info, group_sec, gc_mark_hook))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Look through the section relocs. */
|
||||||
|
ret = true;
|
||||||
if ((sec->flags & SEC_RELOC) != 0 && sec->reloc_count > 0)
|
if ((sec->flags & SEC_RELOC) != 0 && sec->reloc_count > 0)
|
||||||
{
|
{
|
||||||
Elf_Internal_Rela *relstart, *rel, *relend;
|
Elf_Internal_Rela *relstart, *rel, *relend;
|
||||||
|
|
|
@ -495,7 +495,7 @@ const bfd_target TARGET_BIG_SYM =
|
||||||
/* section_flags: mask of all section flags */
|
/* section_flags: mask of all section flags */
|
||||||
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY
|
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY
|
||||||
| SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_EXCLUDE | SEC_SORT_ENTRIES
|
| SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_EXCLUDE | SEC_SORT_ENTRIES
|
||||||
| SEC_ARCH_BIT_0 | SEC_SMALL_DATA | SEC_MERGE | SEC_STRINGS),
|
| SEC_ARCH_BIT_0 | SEC_SMALL_DATA | SEC_MERGE | SEC_STRINGS | SEC_GROUP),
|
||||||
|
|
||||||
/* leading_symbol_char: is the first char of a user symbol
|
/* leading_symbol_char: is the first char of a user symbol
|
||||||
predictable, and if so what is it */
|
predictable, and if so what is it */
|
||||||
|
@ -591,7 +591,7 @@ const bfd_target TARGET_LITTLE_SYM =
|
||||||
/* section_flags: mask of all section flags */
|
/* section_flags: mask of all section flags */
|
||||||
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY
|
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY
|
||||||
| SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_EXCLUDE | SEC_SORT_ENTRIES
|
| SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_EXCLUDE | SEC_SORT_ENTRIES
|
||||||
| SEC_ARCH_BIT_0 | SEC_SMALL_DATA | SEC_MERGE | SEC_STRINGS),
|
| SEC_ARCH_BIT_0 | SEC_SMALL_DATA | SEC_MERGE | SEC_STRINGS | SEC_GROUP),
|
||||||
|
|
||||||
/* leading_symbol_char: is the first char of a user symbol
|
/* leading_symbol_char: is the first char of a user symbol
|
||||||
predictable, and if so what is it */
|
predictable, and if so what is it */
|
||||||
|
|
|
@ -177,7 +177,7 @@ CODE_FRAGMENT
|
||||||
.
|
.
|
||||||
. int id;
|
. int id;
|
||||||
.
|
.
|
||||||
. {* Which section is it; 0..nth. *}
|
. {* Which section in the bfd; 0..n-1 as sections are created in a bfd. *}
|
||||||
.
|
.
|
||||||
. int index;
|
. int index;
|
||||||
.
|
.
|
||||||
|
@ -292,9 +292,10 @@ CODE_FRAGMENT
|
||||||
. objects are to be further relocated. *}
|
. objects are to be further relocated. *}
|
||||||
.#define SEC_EXCLUDE 0x40000
|
.#define SEC_EXCLUDE 0x40000
|
||||||
.
|
.
|
||||||
. {* The contents of this section are to be sorted by the
|
. {* The contents of this section are to be sorted based on the sum of
|
||||||
. based on the address specified in the associated symbol
|
. the symbol and addend values specified by the associated relocation
|
||||||
. table. *}
|
. entries. Entries without associated relocation entries will be
|
||||||
|
. appended to the end of the section in an unspecified order. *}
|
||||||
.#define SEC_SORT_ENTRIES 0x80000
|
.#define SEC_SORT_ENTRIES 0x80000
|
||||||
.
|
.
|
||||||
. {* When linking, duplicate sections of the same name should be
|
. {* When linking, duplicate sections of the same name should be
|
||||||
|
@ -361,6 +362,9 @@ CODE_FRAGMENT
|
||||||
. size entries. *}
|
. size entries. *}
|
||||||
.#define SEC_STRINGS 0x40000000
|
.#define SEC_STRINGS 0x40000000
|
||||||
.
|
.
|
||||||
|
. {* This section contains data about section groups. *}
|
||||||
|
.#define SEC_GROUP 0x80000000
|
||||||
|
.
|
||||||
. {* End of section flags. *}
|
. {* End of section flags. *}
|
||||||
.
|
.
|
||||||
. {* Some internal packed boolean fields. *}
|
. {* Some internal packed boolean fields. *}
|
||||||
|
@ -381,7 +385,8 @@ CODE_FRAGMENT
|
||||||
. {* A mark flag used by some linker backends for garbage collection. *}
|
. {* A mark flag used by some linker backends for garbage collection. *}
|
||||||
. unsigned int gc_mark : 1;
|
. unsigned int gc_mark : 1;
|
||||||
.
|
.
|
||||||
. {* Used by the ELF code to mark sections which have been allocated to segments. *}
|
. {* Used by the ELF code to mark sections which have been allocated
|
||||||
|
. to segments. *}
|
||||||
. unsigned int segment_mark : 1;
|
. unsigned int segment_mark : 1;
|
||||||
.
|
.
|
||||||
. {* End of internal packed boolean fields. *}
|
. {* End of internal packed boolean fields. *}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue