* 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:
parent
5efddb2e7c
commit
11bb5591d6
2 changed files with 115 additions and 41 deletions
|
@ -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
|
||||||
|
|
147
bfd/elfcode.h
147
bfd/elfcode.h
|
@ -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. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue