* elfcode.h (NAME(bfd_elf,size_dynamic_sections)): Add

export_dynamic argument, and handle it.
	(elf_export_symbol): New function.
	* bfd-in.h (bfd_elf32_size_dynamic_sections): Update declaration.
	(bfd_elf64_size_dynamic_sections): Update declaration.
	* bfd-in2.h: Rebuild.
This commit is contained in:
Ian Lance Taylor 1994-11-12 20:55:33 +00:00
parent 5efddb2e7c
commit 11bb5591d6
2 changed files with 115 additions and 41 deletions

View File

@ -1,3 +1,12 @@
Fri Nov 11 14:29:31 1994 Ian Lance Taylor <ian@sanguine.cygnus.com>
* elfcode.h (NAME(bfd_elf,size_dynamic_sections)): Add
export_dynamic argument, and handle it.
(elf_export_symbol): New function.
* bfd-in.h (bfd_elf32_size_dynamic_sections): Update declaration.
(bfd_elf64_size_dynamic_sections): Update declaration.
* bfd-in2.h: Rebuild.
Fri Nov 11 10:35:33 1994 Jeff Law (law@snake.cs.utah.edu) Fri Nov 11 10:35:33 1994 Jeff Law (law@snake.cs.utah.edu)
* hpux-core.c (hpux_core_struct): Delete handles for the * hpux-core.c (hpux_core_struct): Delete handles for the

View File

@ -161,6 +161,7 @@ static file_ptr align_file_position PARAMS ((file_ptr));
static file_ptr assign_file_position_for_section static file_ptr assign_file_position_for_section
PARAMS ((Elf_Internal_Shdr *, file_ptr, boolean)); PARAMS ((Elf_Internal_Shdr *, file_ptr, boolean));
static boolean assign_file_positions_except_relocs PARAMS ((bfd *, boolean)); static boolean assign_file_positions_except_relocs PARAMS ((bfd *, boolean));
static int elf_sort_hdrs PARAMS ((const PTR, const PTR));
static void assign_file_positions_for_relocs PARAMS ((bfd *)); static void assign_file_positions_for_relocs PARAMS ((bfd *));
static bfd_size_type get_program_header_size PARAMS ((bfd *)); static bfd_size_type get_program_header_size PARAMS ((bfd *));
static file_ptr map_program_segments static file_ptr map_program_segments
@ -2028,6 +2029,8 @@ assign_file_positions_except_relocs (abfd, dosyms)
file_ptr phdr_off; file_ptr phdr_off;
bfd_size_type phdr_size; bfd_size_type phdr_size;
bfd_vma maxpagesize; bfd_vma maxpagesize;
size_t hdrppsize;
Elf_Internal_Shdr **sorted_hdrs;
Elf_Internal_Shdr **hdrpp; Elf_Internal_Shdr **hdrpp;
unsigned int i; unsigned int i;
Elf_Internal_Shdr *first; Elf_Internal_Shdr *first;
@ -2048,57 +2051,57 @@ assign_file_positions_except_relocs (abfd, dosyms)
if (maxpagesize == 0) if (maxpagesize == 0)
maxpagesize = 1; maxpagesize = 1;
/* FIXME: We might want to sort the sections on the sh_addr /* We must sort the sections. The GNU linker will always create
field here. For now, we just assume that the linker will the sections in an appropriate order, but the Irix 5 linker
create the sections in an appropriate order. */ will not. We don't include the dummy first section in the
sort. We sort sections which are not SHF_ALLOC to the end. */
hdrppsize = (i_ehdrp->e_shnum - 1) * sizeof (Elf_Internal_Shdr *);
sorted_hdrs = (Elf_Internal_Shdr **) malloc (hdrppsize);
if (sorted_hdrs == NULL)
{
bfd_set_error (bfd_error_no_memory);
return false;
}
memcpy (sorted_hdrs, i_shdrpp + 1, hdrppsize);
qsort (sorted_hdrs, i_ehdrp->e_shnum - 1, sizeof (Elf_Internal_Shdr *),
elf_sort_hdrs);
/* Assign file positions in two passes. In the first pass, we
assign a file position to every section which forms part of
the executable image. */
first = NULL; first = NULL;
for (i = 1, hdrpp = i_shdrpp + 1; i < i_ehdrp->e_shnum; i++, hdrpp++) for (i = 1, hdrpp = sorted_hdrs; i < i_ehdrp->e_shnum; i++, hdrpp++)
{ {
Elf_Internal_Shdr *hdr; Elf_Internal_Shdr *hdr;
hdr = *hdrpp; hdr = *hdrpp;
if ((hdr->sh_flags & SHF_ALLOC) == 0) if ((hdr->sh_flags & SHF_ALLOC) == 0)
continue; {
if (hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
{
hdr->sh_offset = -1;
continue;
}
if (! dosyms
&& (hdr == i_shdrpp[tdata->symtab_section]
|| hdr == i_shdrpp[tdata->strtab_section]))
{
hdr->sh_offset = -1;
continue;
}
}
else
{
if (first == NULL)
first = hdr;
if (first == NULL) /* The section VMA must equal the file position modulo
first = hdr; the page size. This is required by the program
header. */
/* The section VMA must equal the file position modulo the off += (hdr->sh_addr - off) % maxpagesize;
page size. This is required by the program header. */ }
off += (hdr->sh_addr - off) % maxpagesize;
off = assign_file_position_for_section (hdr, off, false); off = assign_file_position_for_section (hdr, off, false);
} }
/* Assign file positions to all the sections which do not form
part of the loadable image, except for the relocs. */
for (i = 1, hdrpp = i_shdrpp + 1; i < i_ehdrp->e_shnum; i++, hdrpp++)
{
Elf_Internal_Shdr *hdr;
hdr = *hdrpp;
if ((hdr->sh_flags & SHF_ALLOC) != 0)
continue;
if (hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
{
hdr->sh_offset = -1;
continue;
}
if (! dosyms
&& (i == tdata->symtab_section
|| i == tdata->strtab_section))
{
hdr->sh_offset = -1;
continue;
}
off = assign_file_position_for_section (hdr, off, true);
}
phdr_map = map_program_segments (abfd, phdr_off, first, phdr_size); phdr_map = map_program_segments (abfd, phdr_off, first, phdr_size);
if (phdr_map == (file_ptr) -1) if (phdr_map == (file_ptr) -1)
return false; return false;
@ -2115,6 +2118,36 @@ assign_file_positions_except_relocs (abfd, dosyms)
return true; return true;
} }
/* Sort the ELF headers by VMA. We sort headers which are not
SHF_ALLOC to the end. */
static int
elf_sort_hdrs (arg1, arg2)
const PTR arg1;
const PTR arg2;
{
const Elf_Internal_Shdr *hdr1 = *(const Elf_Internal_Shdr **) arg1;
const Elf_Internal_Shdr *hdr2 = *(const Elf_Internal_Shdr **) arg2;
if ((hdr1->sh_flags & SHF_ALLOC) != 0)
{
if ((hdr2->sh_flags & SHF_ALLOC) == 0)
return -1;
if (hdr1->sh_addr < hdr2->sh_addr)
return -1;
else if (hdr1->sh_addr > hdr2->sh_addr)
return 1;
else
return 0;
}
else
{
if ((hdr1->sh_flags & SHF_ALLOC) != 0)
return 1;
return 0;
}
}
static boolean static boolean
prep_headers (abfd) prep_headers (abfd)
bfd *abfd; bfd *abfd;
@ -3677,6 +3710,8 @@ static boolean elf_link_add_archive_symbols
PARAMS ((bfd *, struct bfd_link_info *)); PARAMS ((bfd *, struct bfd_link_info *));
static Elf_Internal_Rela *elf_link_read_relocs static Elf_Internal_Rela *elf_link_read_relocs
PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, boolean)); PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, boolean));
static boolean elf_export_symbol
PARAMS ((struct elf_link_hash_entry *, PTR));
static boolean elf_adjust_dynamic_symbol static boolean elf_adjust_dynamic_symbol
PARAMS ((struct elf_link_hash_entry *, PTR)); PARAMS ((struct elf_link_hash_entry *, PTR));
@ -4796,11 +4831,12 @@ static const size_t elf_buckets[] =
addresses of the various sections. */ addresses of the various sections. */
boolean boolean
NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath, info, NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
sinterpptr) export_dynamic, info, sinterpptr)
bfd *output_bfd; bfd *output_bfd;
const char *soname; const char *soname;
const char *rpath; const char *rpath;
boolean export_dynamic;
struct bfd_link_info *info; struct bfd_link_info *info;
asection **sinterpptr; asection **sinterpptr;
{ {
@ -4820,6 +4856,12 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath, info,
if (dynobj == NULL) if (dynobj == NULL)
return true; return true;
/* If we are supposed to export all symbols into the dynamic symbol
table (this is not the normal case), then do so. */
if (export_dynamic)
elf_link_hash_traverse (elf_hash_table (info), elf_export_symbol,
(PTR) info);
if (elf_hash_table (info)->dynamic_sections_created) if (elf_hash_table (info)->dynamic_sections_created)
{ {
bfd_size_type strsize; bfd_size_type strsize;
@ -4951,6 +4993,29 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath, info,
return true; return true;
} }
/* This routine is used to export all defined symbols into the dynamic
symbol table. It is called via elf_link_hash_traverse. */
static boolean
elf_export_symbol (h, data)
struct elf_link_hash_entry *h;
PTR data;
{
struct bfd_link_info *info = (struct bfd_link_info *) data;
if (h->dynindx == -1
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0)
{
if (! elf_link_record_dynamic_symbol (info, h))
{
/* FIXME: No way to report error. */
abort ();
}
}
return true;
}
/* Make the backend pick a good value for a dynamic symbol. This is /* Make the backend pick a good value for a dynamic symbol. This is
called via elf_link_hash_traverse, and also calls itself called via elf_link_hash_traverse, and also calls itself
recursively. */ recursively. */