Changes to support ELF strip and objcopy on dynamically linked

files.
	* elfcode.h (elf_fake_sections): Add prototype.
	(bfd_section_from_shdr): Make a BFD section from an SHT_HASH
	section, and from an SHT_DYNSYM section, and from the dynamic
	string table section.
	(elf_object_p): Set D_PAGED if there is a program header.
	(elf_make_sections): Remove.
	(fix_up_strtabs): Remove.
	(elf_fake_sections): Rewrite.  Now sets sh_entsize.
	(assign_section_numbers): Rewrite.  Now sets sh_link and sh_info
	for all sections.
	(elf_compute_section_file_positions):  Don't call obsolete
	functions elf_make_sections or fix_up_strtabs.
	(swap_out_syms): Set sh_addralign to FILE_ALIGN rather than 4.
	(NAME(bfd_elf,write_object_contents)): Permit writing DYNAMIC
	objects.
	(elf_section_from_bfd_section): Treat SHT_DYNSYM like other normal
	sections.  If an SHT_REL or SHT_RELA section is allocated or uses
	an unusual symbol table, permit a BFD section to map to it.
	Permit most SHT_STRTAB sections to have a BFD section mapped to
	them.
	(elf_bfd_final_link): Don't set sh_link, sh_info or sh_entsize
	fields of dynamic sections here; do it in assign_section_numbers.
	* elf32-target.h, elf64-target.h: Add D_PAGED to permitted object
	flags.
This commit is contained in:
Ian Lance Taylor 1994-06-05 20:00:42 +00:00
parent a04e14b672
commit fa15568ac1
4 changed files with 317 additions and 353 deletions

View File

@ -1,5 +1,32 @@
Sun Jun 5 15:02:30 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
Changes to support ELF strip and objcopy on dynamically linked
files.
* elfcode.h (elf_fake_sections): Add prototype.
(bfd_section_from_shdr): Make a BFD section from an SHT_HASH
section, and from an SHT_DYNSYM section, and from the dynamic
string table section.
(elf_object_p): Set D_PAGED if there is a program header.
(elf_make_sections): Remove.
(fix_up_strtabs): Remove.
(elf_fake_sections): Rewrite. Now sets sh_entsize.
(assign_section_numbers): Rewrite. Now sets sh_link and sh_info
for all sections.
(elf_compute_section_file_positions): Don't call obsolete
functions elf_make_sections or fix_up_strtabs.
(swap_out_syms): Set sh_addralign to FILE_ALIGN rather than 4.
(NAME(bfd_elf,write_object_contents)): Permit writing DYNAMIC
objects.
(elf_section_from_bfd_section): Treat SHT_DYNSYM like other normal
sections. If an SHT_REL or SHT_RELA section is allocated or uses
an unusual symbol table, permit a BFD section to map to it.
Permit most SHT_STRTAB sections to have a BFD section mapped to
them.
(elf_bfd_final_link): Don't set sh_link, sh_info or sh_entsize
fields of dynamic sections here; do it in assign_section_numbers.
* elf32-target.h, elf64-target.h: Add D_PAGED to permitted object
flags.
* elf.c (_bfd_elf_make_section_from_shdr): Only set SEC_DATA if
SEC_LOAD is set, rather than checking SEC_ALLOC.

View File

@ -194,7 +194,7 @@ bfd_target TARGET_BIG_SYM =
/* object_flags: mask of all file flags */
(HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS |
DYNAMIC | WP_TEXT),
DYNAMIC | WP_TEXT | D_PAGED),
/* section_flags: mask of all section flags */
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY |
@ -282,7 +282,7 @@ bfd_target TARGET_LITTLE_SYM =
/* object_flags: mask of all file flags */
(HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS |
DYNAMIC | WP_TEXT),
DYNAMIC | WP_TEXT | D_PAGED),
/* section_flags: mask of all section flags */
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY |

View File

@ -197,7 +197,7 @@ bfd_target TARGET_BIG_SYM =
/* object_flags: mask of all file flags */
(HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS |
DYNAMIC | WP_TEXT),
DYNAMIC | WP_TEXT | D_PAGED),
/* section_flags: mask of all section flags */
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY |
@ -285,7 +285,7 @@ bfd_target TARGET_LITTLE_SYM =
/* object_flags: mask of all file flags */
(HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS |
DYNAMIC | WP_TEXT),
DYNAMIC | WP_TEXT | D_PAGED),
/* section_flags: mask of all section flags */
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY |

View File

@ -145,6 +145,7 @@ static int elf_symbol_from_bfd_symbol PARAMS ((bfd *,
static boolean elf_compute_section_file_positions
PARAMS ((bfd *, struct bfd_link_info *));
static boolean prep_headers PARAMS ((bfd *));
static void elf_fake_sections PARAMS ((bfd *, asection *, PTR));
static boolean assign_section_numbers PARAMS ((bfd *));
static file_ptr align_file_position PARAMS ((file_ptr));
static file_ptr assign_file_position_for_section
@ -520,6 +521,7 @@ bfd_section_from_shdr (abfd, shindex)
case SHT_PROGBITS: /* Normal section with contents. */
case SHT_DYNAMIC: /* Dynamic linking information. */
case SHT_NOBITS: /* .bss section. */
case SHT_HASH: /* .hash section. */
return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
case SHT_SYMTAB: /* A symbol table */
@ -544,7 +546,10 @@ bfd_section_from_shdr (abfd, shindex)
elf_tdata (abfd)->dynsymtab_hdr = *hdr;
elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->dynsymtab_hdr;
abfd->flags |= HAS_SYMS;
return true;
/* Besides being a symbol table, we also treat this as a regular
section, so that objcopy can handle it. */
return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
case SHT_STRTAB: /* A string table */
if (hdr->rawdata != NULL)
@ -569,14 +574,18 @@ bfd_section_from_shdr (abfd, shindex)
if (elf_onesymtab (abfd) == i)
{
elf_tdata (abfd)->strtab_hdr = *hdr;
elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->strtab_hdr;
elf_elfsections (abfd)[shindex] =
&elf_tdata (abfd)->strtab_hdr;
return true;
}
if (elf_dynsymtab (abfd) == i)
{
elf_tdata (abfd)->dynstrtab_hdr = *hdr;
elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->dynstrtab_hdr;
return true;
elf_elfsections (abfd)[shindex] =
&elf_tdata (abfd)->dynstrtab_hdr;
/* We also treat this as a regular section, so
that objcopy can handle it. */
break;
}
#if 0 /* Not handling other string tables specially right now. */
hdr2 = elf_elfsections (abfd)[i]; /* in case it moved */
@ -649,13 +658,6 @@ bfd_section_from_shdr (abfd, shindex)
}
break;
case SHT_HASH:
#if 0
fprintf (stderr, "Dynamic Linking sections not yet supported.\n");
BFD_FAIL ();
#endif
break;
case SHT_NOTE:
#if 0
fprintf (stderr, "Note Sections not yet supported.\n");
@ -926,13 +928,14 @@ elf_object_p (abfd)
}
}
/* Set the flags and architecture before calling the backend so that
it can override them. */
if (i_ehdrp->e_type == ET_EXEC)
abfd->flags |= EXEC_P;
else if (i_ehdrp->e_type == ET_DYN)
abfd->flags |= DYNAMIC;
if (i_ehdrp->e_phnum > 0)
abfd->flags |= D_PAGED;
if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0))
goto got_no_match;
@ -1036,78 +1039,6 @@ elf_symbol_from (ignore_abfd, symbol)
return (elf_symbol_type *) symbol;
}
/* Create ELF output from BFD sections.
Essentially, just create the section header and forget about the program
header for now. */
static void
elf_make_sections (abfd, asect, obj)
bfd *abfd;
asection *asect;
PTR obj;
{
/* most of what is in bfd_shdr_from_section goes in here... */
/* and all of these sections generate at *least* one ELF section. */
Elf_Internal_Shdr *this_hdr;
this_hdr = &elf_section_data (asect)->this_hdr;
this_hdr->sh_addr = asect->vma;
this_hdr->sh_size = asect->_raw_size;
/* contents already set by elf_set_section_contents */
if (asect->flags & SEC_RELOC)
{
/* emit a reloc section, and thus strtab and symtab... */
Elf_Internal_Shdr *rela_hdr;
int use_rela_p = get_elf_backend_data (abfd)->use_rela_p;
rela_hdr = &elf_section_data (asect)->rel_hdr;
/* orelocation has the data, reloc_count has the count... */
if (use_rela_p)
{
rela_hdr->sh_type = SHT_RELA;
rela_hdr->sh_entsize = sizeof (Elf_External_Rela);
}
else
/* REL relocations */
{
rela_hdr->sh_type = SHT_REL;
rela_hdr->sh_entsize = sizeof (Elf_External_Rel);
}
rela_hdr->sh_flags = 0;
rela_hdr->sh_addr = 0;
rela_hdr->sh_offset = 0;
/* FIXME: Systems I've checked use an alignment of 4, but it is
possible that some systems use a different alignment. */
rela_hdr->sh_addralign = 4;
rela_hdr->size = 0;
}
if (asect->flags & SEC_ALLOC)
{
this_hdr->sh_flags |= SHF_ALLOC;
if (asect->flags & SEC_LOAD)
{
/* @@ Do something with sh_type? */
}
}
else
{
/* If this section is not part of the program image during
execution, leave the address fields at 0. */
this_hdr->sh_addr = 0;
asect->vma = 0;
}
if (!(asect->flags & SEC_READONLY))
this_hdr->sh_flags |= SHF_WRITE;
if (asect->flags & SEC_CODE)
this_hdr->sh_flags |= SHF_EXECINSTR;
}
void
write_relocs (abfd, sec, xxx)
bfd *abfd;
@ -1211,96 +1142,97 @@ write_relocs (abfd, sec, xxx)
}
}
/* Set up an ELF internal section header for a section. */
/*ARGSUSED*/
static void
fix_up_strtabs (abfd, asect, obj)
elf_fake_sections (abfd, asect, ignore)
bfd *abfd;
asection *asect;
PTR obj;
PTR ignore;
{
Elf_Internal_Shdr *this_hdr = &elf_section_data (asect)->this_hdr;
int this_idx = elf_section_data (asect)->this_idx;
/* @@ Check flags! */
if (!strncmp (asect->name, ".stab", 5)
&& !strcmp ("str", asect->name + strlen (asect->name) - 3))
{
size_t len = strlen (asect->name) + 1;
char *s = (char *) malloc (len);
if (s == NULL)
/* FIXME: Should deal more gracefully with errors. */
abort ();
strcpy (s, asect->name);
s[len - 4] = 0;
asect = bfd_get_section_by_name (abfd, s);
free (s);
if (!asect)
abort ();
elf_section_data (asect)->this_hdr.sh_link = this_idx;
/* @@ Assuming 32 bits! */
elf_section_data (asect)->this_hdr.sh_entsize = 0xc;
this_hdr->sh_type = SHT_STRTAB;
}
}
static void
elf_fake_sections (abfd, asect, obj)
bfd *abfd;
asection *asect;
PTR obj;
{
/* most of what is in bfd_shdr_from_section goes in here... */
/* and all of these sections generate at *least* one ELF section. */
Elf_Internal_Shdr *this_hdr;
this_hdr = &elf_section_data (asect)->this_hdr;
this_hdr->sh_name =
bfd_add_to_strtab (abfd, elf_shstrtab (abfd), asect->name);
this_hdr->sh_name = bfd_add_to_strtab (abfd, elf_shstrtab (abfd),
asect->name);
if (this_hdr->sh_name == (unsigned long) -1)
abort (); /* FIXME */
/* We need to log the type *now* so that elf_section_from_bfd_section
can find us... have to set rawdata too. */
this_hdr->rawdata = (void *) asect;
this_hdr->sh_flags = 0;
if ((asect->flags & SEC_ALLOC) != 0)
this_hdr->sh_addr = asect->vma;
else
this_hdr->sh_addr = 0;
this_hdr->sh_offset = 0;
this_hdr->sh_size = asect->_raw_size;
this_hdr->sh_link = 0;
this_hdr->sh_info = 0;
this_hdr->sh_addralign = 1 << asect->alignment_power;
this_hdr->sh_entsize = 0;
this_hdr->rawdata = (PTR) asect;
this_hdr->contents = NULL;
this_hdr->size = 0;
/* FIXME: This should not be based on section names. */
if (strcmp (asect->name, ".dynstr") == 0)
this_hdr->sh_type = SHT_STRTAB;
else if (strcmp (asect->name, ".hash") == 0)
this_hdr->sh_type = SHT_HASH;
{
this_hdr->sh_type = SHT_HASH;
this_hdr->sh_entsize = ARCH_SIZE / 8;
}
else if (strcmp (asect->name, ".dynsym") == 0)
this_hdr->sh_type = SHT_DYNSYM;
{
this_hdr->sh_type = SHT_DYNSYM;
this_hdr->sh_entsize = sizeof (Elf_External_Sym);
}
else if (strcmp (asect->name, ".dynamic") == 0)
this_hdr->sh_type = SHT_DYNAMIC;
{
this_hdr->sh_type = SHT_DYNAMIC;
this_hdr->sh_entsize = sizeof (Elf_External_Dyn);
}
else if (strncmp (asect->name, ".rel.", 5) == 0)
this_hdr->sh_type = SHT_REL;
{
this_hdr->sh_type = SHT_REL;
this_hdr->sh_entsize = sizeof (Elf_External_Rel);
}
else if (strncmp (asect->name, ".rela.", 6) == 0)
this_hdr->sh_type = SHT_RELA;
else if ((asect->flags & SEC_ALLOC) && (asect->flags & SEC_LOAD))
{
this_hdr->sh_type = SHT_RELA;
this_hdr->sh_entsize = sizeof (Elf_External_Rela);
}
else if (strcmp (asect->name, ".note") == 0)
this_hdr->sh_type = SHT_NOTE;
else if (strncmp (asect->name, ".stab", 5) == 0
&& strcmp (asect->name + strlen (asect->name) - 3, "str") == 0)
this_hdr->sh_type = SHT_STRTAB;
else if ((asect->flags & SEC_ALLOC) != 0
&& (asect->flags & SEC_LOAD) != 0)
this_hdr->sh_type = SHT_PROGBITS;
else if ((asect->flags & SEC_ALLOC) && ((asect->flags & SEC_LOAD) == 0))
else if ((asect->flags & SEC_ALLOC) != 0
&& ((asect->flags & SEC_LOAD) == 0))
{
BFD_ASSERT (strcmp (asect->name, ".bss") == 0
|| strcmp (asect->name, ".sbss") == 0);
this_hdr->sh_type = SHT_NOBITS;
}
/* FIXME I am not sure how to detect a .note section from the flags
word of an `asection'. */
else if (!strcmp (asect->name, ".note"))
this_hdr->sh_type = SHT_NOTE;
else
this_hdr->sh_type = SHT_PROGBITS;
{
/* Who knows? */
this_hdr->sh_type = SHT_PROGBITS;
}
this_hdr->sh_flags = 0;
this_hdr->sh_addr = 0;
this_hdr->sh_size = 0;
this_hdr->sh_entsize = 0;
this_hdr->sh_info = 0;
this_hdr->sh_link = 0;
this_hdr->sh_offset = 0;
this_hdr->size = 0;
if ((asect->flags & SEC_ALLOC) != 0)
this_hdr->sh_flags |= SHF_ALLOC;
if ((asect->flags & SEC_READONLY) == 0)
this_hdr->sh_flags |= SHF_WRITE;
if ((asect->flags & SEC_CODE) != 0)
this_hdr->sh_flags |= SHF_EXECINSTR;
/* Now, check for processor-specific section types. */
/* Check for processor-specific section types. */
{
struct elf_backend_data *bed = get_elf_backend_data (abfd);
@ -1308,51 +1240,199 @@ elf_fake_sections (abfd, asect, obj)
(*bed->elf_backend_fake_sections) (abfd, this_hdr, asect);
}
{
/* Emit a strtab and symtab, and possibly a reloc section. */
Elf_Internal_Shdr *rela_hdr;
/* Note that only one symtab is used, so just remember it
for now. */
if (asect->flags & SEC_RELOC)
{
int use_rela_p = get_elf_backend_data (abfd)->use_rela_p;
rela_hdr = &elf_section_data (asect)->rel_hdr;
rela_hdr->sh_name =
bfd_add_2_to_strtab (abfd, elf_shstrtab (abfd),
use_rela_p ? ".rela" : ".rel",
asect->name);
rela_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL;
rela_hdr->sh_entsize = (use_rela_p
? sizeof (Elf_External_Rela)
: sizeof (Elf_External_Rel));
rela_hdr->sh_flags = 0;
rela_hdr->sh_addr = 0;
rela_hdr->sh_size = 0;
rela_hdr->sh_offset = 0;
/* FIXME: Systems I've checked use an alignment of 4, but some
systems may use a different alignment. */
rela_hdr->sh_addralign = 4;
rela_hdr->size = 0;
}
}
if (asect->flags & SEC_ALLOC)
/* If the section has relocs, set up a section header for the
SHT_REL[A] section. */
if ((asect->flags & SEC_RELOC) != 0)
{
this_hdr->sh_flags |= SHF_ALLOC;
if (asect->flags & SEC_LOAD)
Elf_Internal_Shdr *rela_hdr;
int use_rela_p = get_elf_backend_data (abfd)->use_rela_p;
rela_hdr = &elf_section_data (asect)->rel_hdr;
rela_hdr->sh_name =
bfd_add_2_to_strtab (abfd, elf_shstrtab (abfd),
use_rela_p ? ".rela" : ".rel",
asect->name);
rela_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL;
rela_hdr->sh_entsize = (use_rela_p
? sizeof (Elf_External_Rela)
: sizeof (Elf_External_Rel));
rela_hdr->sh_addralign = FILE_ALIGN;
rela_hdr->sh_flags = 0;
rela_hdr->sh_addr = 0;
rela_hdr->sh_size = 0;
rela_hdr->sh_offset = 0;
rela_hdr->size = 0;
}
}
/* Assign all ELF section numbers. The dummy first section is handled here
too. The link/info pointers for the standard section types are filled
in here too, while we're at it. (Link pointers for .stab sections are
not filled in here.) */
static boolean
assign_section_numbers (abfd)
bfd *abfd;
{
struct elf_obj_tdata *t = elf_tdata (abfd);
asection *sec;
unsigned int section_number;
Elf_Internal_Shdr **i_shdrp;
section_number = 1;
t->shstrtab_section = section_number++;
elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section;
t->shstrtab_hdr.sh_size = elf_shstrtab (abfd)->length;
t->shstrtab_hdr.contents = (PTR) elf_shstrtab (abfd)->tab;
if (abfd->symcount > 0)
{
t->symtab_section = section_number++;
t->strtab_section = section_number++;
}
for (sec = abfd->sections; sec; sec = sec->next)
{
struct bfd_elf_section_data *d = elf_section_data (sec);
d->this_idx = section_number++;
if ((sec->flags & SEC_RELOC) == 0)
d->rel_idx = 0;
else
d->rel_idx = section_number++;
}
elf_elfheader (abfd)->e_shnum = section_number;
/* Set up the list of section header pointers, in agreement with the
indices. */
i_shdrp = ((Elf_Internal_Shdr **)
bfd_alloc (abfd, section_number * sizeof (Elf_Internal_Shdr *)));
if (i_shdrp == NULL)
{
bfd_set_error (bfd_error_no_memory);
return false;
}
i_shdrp[0] = ((Elf_Internal_Shdr *)
bfd_alloc (abfd, sizeof (Elf_Internal_Shdr)));
if (i_shdrp[0] == NULL)
{
bfd_release (abfd, i_shdrp);
bfd_set_error (bfd_error_no_memory);
return false;
}
memset (i_shdrp[0], 0, sizeof (Elf_Internal_Shdr));
elf_elfsections (abfd) = i_shdrp;
i_shdrp[t->shstrtab_section] = &t->shstrtab_hdr;
if (abfd->symcount > 0)
{
i_shdrp[t->symtab_section] = &t->symtab_hdr;
i_shdrp[t->strtab_section] = &t->strtab_hdr;
t->symtab_hdr.sh_link = t->strtab_section;
}
for (sec = abfd->sections; sec; sec = sec->next)
{
struct bfd_elf_section_data *d = elf_section_data (sec);
asection *s;
const char *name;
i_shdrp[d->this_idx] = &d->this_hdr;
if (d->rel_idx != 0)
i_shdrp[d->rel_idx] = &d->rel_hdr;
/* Fill in the sh_link and sh_info fields while we're at it. */
/* sh_link of a reloc section is the section index of the symbol
table. sh_info is the section index of the section to which
the relocation entries apply. */
if (d->rel_idx != 0)
{
/* @@ Do something with sh_type? */
d->rel_hdr.sh_link = t->symtab_section;
d->rel_hdr.sh_info = d->this_idx;
}
switch (d->this_hdr.sh_type)
{
case SHT_REL:
case SHT_RELA:
/* A reloc section which we are treating as a normal BFD
section. sh_link is the section index of the symbol
table. sh_info is the section index of the section to
which the relocation entries apply. We assume that an
allocated reloc section uses the dynamic symbol table.
FIXME: How can we be sure? */
s = bfd_get_section_by_name (abfd, ".dynsym");
if (s != NULL)
d->this_hdr.sh_link = elf_section_data (s)->this_idx;
/* We look up the section the relocs apply to by name. */
name = sec->name;
if (d->this_hdr.sh_type == SHT_REL)
name += 4;
else
name += 5;
s = bfd_get_section_by_name (abfd, name);
if (s != NULL)
d->this_hdr.sh_info = elf_section_data (s)->this_idx;
break;
case SHT_STRTAB:
/* We assume that a section named .stab*str is a stabs
string section. We look for a section with the same name
but without the trailing ``str'', and set its sh_link
field to point to this section. */
if (strncmp (sec->name, ".stab", sizeof ".stab" - 1) == 0
&& strcmp (sec->name + strlen (sec->name) - 3, "str") == 0)
{
size_t len;
char *alc;
len = strlen (sec->name);
alc = (char *) malloc (len - 2);
if (alc == NULL)
{
bfd_set_error (bfd_error_no_memory);
return false;
}
strncpy (alc, sec->name, len - 3);
alc[len - 3] = '\0';
s = bfd_get_section_by_name (abfd, alc);
free (alc);
if (s != NULL)
{
elf_section_data (s)->this_hdr.sh_link = d->this_idx;
/* This is a .stab section. */
elf_section_data (s)->this_hdr.sh_entsize =
4 + 2 * (ARCH_SIZE / 8);
}
}
break;
case SHT_DYNAMIC:
case SHT_DYNSYM:
/* sh_link is the section header index of the string table
used for the dynamic entries or symbol table. */
s = bfd_get_section_by_name (abfd, ".dynstr");
if (s != NULL)
d->this_hdr.sh_link = elf_section_data (s)->this_idx;
break;
case SHT_HASH:
/* sh_link is the section header index of the symbol table
this hash table is for. */
s = bfd_get_section_by_name (abfd, ".dynsym");
if (s != NULL)
d->this_hdr.sh_link = elf_section_data (s)->this_idx;
break;
}
}
if (!(asect->flags & SEC_READONLY))
this_hdr->sh_flags |= SHF_WRITE;
if (asect->flags & SEC_CODE)
this_hdr->sh_flags |= SHF_EXECINSTR;
return true;
}
/* Map symbol from it's internal number to the external number, moving
@ -1540,10 +1620,6 @@ elf_compute_section_file_positions (abfd, link_info)
if (!assign_section_numbers (abfd))
return false;
bfd_map_over_sections (abfd, elf_make_sections, 0);
bfd_map_over_sections (abfd, fix_up_strtabs, 0); /* .stab/.stabstr &c */
/* The backend linker builds symbol table information itself. */
if (link_info == NULL)
{
@ -1574,89 +1650,6 @@ elf_compute_section_file_positions (abfd, link_info)
}
/* Assign all ELF section numbers. The dummy first section is handled here
too. The link/info pointers for the standard section types are filled
in here too, while we're at it. (Link pointers for .stab sections are
not filled in here.) */
static boolean
assign_section_numbers (abfd)
bfd *abfd;
{
struct elf_obj_tdata *t = elf_tdata (abfd);
asection *sec;
int section_number = 1;
int i;
Elf_Internal_Shdr **i_shdrp;
t->shstrtab_hdr.sh_size = elf_shstrtab (abfd)->length;
t->shstrtab_hdr.contents = (void *) elf_shstrtab (abfd)->tab;
t->shstrtab_section = section_number++;
elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section;
if (abfd->symcount)
{
t->symtab_section = section_number++;
t->strtab_section = section_number++;
t->symtab_hdr.sh_link = t->strtab_section;
}
for (sec = abfd->sections; sec; sec = sec->next)
{
struct bfd_elf_section_data *d = elf_section_data (sec);
d->this_idx = section_number++;
if (sec->flags & SEC_RELOC)
{
d->rel_idx = section_number++;
d->rel_hdr.sh_link = t->symtab_section;
d->rel_hdr.sh_info = d->this_idx;
}
else
d->rel_idx = 0;
/* No handling for per-section string tables currently. */
}
elf_elfheader (abfd)->e_shnum = section_number;
/* Set up the list of section header pointers, in agreement with the
indices. */
i_shdrp = ((Elf_Internal_Shdr **)
bfd_alloc (abfd, section_number * sizeof (Elf_Internal_Shdr *)));
if (i_shdrp == NULL)
{
bfd_set_error (bfd_error_no_memory);
return false;
}
i_shdrp[0] = ((Elf_Internal_Shdr *)
bfd_alloc (abfd, sizeof (Elf_Internal_Shdr)));
if (i_shdrp[0] == NULL)
{
bfd_release (abfd, i_shdrp);
bfd_set_error (bfd_error_no_memory);
return false;
}
elf_elfsections (abfd) = i_shdrp;
for (i = 1; i < section_number; i++)
i_shdrp[i] = NULL;
memset (i_shdrp[0], 0, sizeof (Elf_Internal_Shdr));
i_shdrp[t->shstrtab_section] = &t->shstrtab_hdr;
if (abfd->symcount)
{
i_shdrp[t->symtab_section] = &t->symtab_hdr;
i_shdrp[t->strtab_section] = &t->strtab_hdr;
}
for (sec = abfd->sections; sec; sec = sec->next)
{
struct bfd_elf_section_data *d = elf_section_data (sec);
i_shdrp[d->this_idx] = &d->this_hdr;
if (d->rel_idx)
i_shdrp[d->rel_idx] = &d->rel_hdr;
}
/* Make sure we got everything.... */
for (i = 0; i < section_number; i++)
if (i_shdrp[i] == NULL)
abort ();
return true;
}
/* Align to the maximum file alignment that could be required for any
ELF data structure. */
@ -2246,13 +2239,8 @@ swap_out_syms (abfd)
symtab_hdr->sh_entsize = sizeof (Elf_External_Sym);
symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1);
symtab_hdr->sh_info = elf_num_locals (abfd) + 1;
symtab_hdr->sh_addralign = FILE_ALIGN;
/* FIXME: Systems I've checked use 4 byte alignment for .symtab,
but it is possible that there are systems which use a different
alignment. */
symtab_hdr->sh_addralign = 4;
/* see assert in elf_fake_sections that supports this: */
symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
symstrtab_hdr->sh_type = SHT_STRTAB;
@ -2473,15 +2461,6 @@ NAME(bfd_elf,write_object_contents) (abfd)
Elf_Internal_Shdr **i_shdrp;
unsigned int count;
/* We don't know how to write dynamic objects. Specifically, we
don't know how to construct the program header. */
if ((abfd->flags & DYNAMIC) != 0)
{
fprintf (stderr, "Writing ELF dynamic objects is not supported\n");
bfd_set_error (bfd_error_wrong_format);
return false;
}
if (! abfd->output_has_begun
&& ! elf_compute_section_file_positions (abfd,
(struct bfd_link_info *) NULL))
@ -2591,6 +2570,7 @@ elf_section_from_bfd_section (abfd, asect)
case SHT_NOTE:
case SHT_HASH:
case SHT_DYNAMIC:
case SHT_DYNSYM:
if (hdr->rawdata)
{
if (((struct sec *) (hdr->rawdata)) == asect)
@ -2598,19 +2578,22 @@ elf_section_from_bfd_section (abfd, asect)
}
break;
case SHT_REL:
case SHT_RELA:
/* We sometimes map a reloc section to a BFD section. */
if (((hdr->sh_flags & SHF_ALLOC) != 0
|| hdr->sh_link != elf_onesymtab (abfd))
&& (asection *) hdr->rawdata == asect)
return index;
break;
case SHT_STRTAB:
/* fix_up_strtabs will generate STRTAB sections with names
of .stab*str. */
if (!strncmp (asect->name, ".stab", 5)
&& !strcmp ("str", asect->name + strlen (asect->name) - 3))
{
if (hdr->rawdata)
{
if (((struct sec *) (hdr->rawdata)) == asect)
return index;
}
break;
}
/* We map most string tables to BFD sections. */
if (index != elf_elfheader (abfd)->e_shstrndx
&& index != elf_onesymtab (abfd)
&& (asection *) hdr->rawdata == asect)
return index;
/* FALL THROUGH */
default:
{
@ -5524,10 +5507,6 @@ elf_bfd_final_link (abfd, info)
for (o = dynobj->sections; o != NULL; o = o->next)
{
Elf_Internal_Shdr *hdr;
asection *s;
const char *name;
if ((o->flags & SEC_HAS_CONTENTS) == 0)
continue;
BFD_ASSERT ((o->flags & SEC_IN_MEMORY) != 0);
@ -5535,48 +5514,6 @@ elf_bfd_final_link (abfd, info)
o->contents, o->output_offset,
o->_raw_size))
goto error_return;
hdr = &elf_section_data (o->output_section)->this_hdr;
switch (hdr->sh_type)
{
case SHT_DYNAMIC:
s = bfd_get_section_by_name (abfd, ".dynstr");
hdr->sh_link = elf_section_data (s)->this_idx;
hdr->sh_entsize = sizeof (Elf_External_Dyn);
break;
case SHT_HASH:
s = finfo.dynsym_sec->output_section;
hdr->sh_link = elf_section_data (s)->this_idx;
hdr->sh_entsize = ARCH_SIZE / 8;
break;
case SHT_DYNSYM:
s = bfd_get_section_by_name (abfd, ".dynstr");
hdr->sh_link = elf_section_data (s)->this_idx;
hdr->sh_entsize = sizeof (Elf_External_Sym);
break;
case SHT_REL:
case SHT_RELA:
name = bfd_get_section_name (abfd, o->output_section);
s = finfo.dynsym_sec->output_section;
hdr->sh_link = elf_section_data (s)->this_idx;
if (hdr->sh_type == SHT_REL)
{
name += 4;
hdr->sh_entsize = sizeof (Elf_External_Rel);
}
else
{
name += 5;
hdr->sh_entsize = sizeof (Elf_External_Rela);
}
s = bfd_get_section_by_name (abfd, name);
if (s != NULL)
hdr->sh_info = elf_section_data (s)->this_idx;
break;
}
}
}