mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-17 13:10:12 +08:00
* elf32-mips.c: Extensive changes for a start at dynamic linking
support, from Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>. * elf-bfd.h (struct elf_backend_data): Add type_change_ok field. (struct elf_backend_data): Remove elf_backend_create_program_headers field. Add elf_backend_additional_program_headers and elf_backend_modify_segment_map fields. * elfxx-target.h (elf_backend_type_change_ok): Define if not defined. (elf_backend_additional_program_headers): Likewise. (elf_backend_modify_segment_map): Likewise. (elf_backend_create_program_headers): Don't define. (elfNN_bed): Change to account for field changes. * elf.c (assign_file_positions_for_segments): Call new modify_segment_map backend function. Don't call old create_program_headers backend function. (get_program_header_size): Call additional_program_headers rather than create_program_headers. * elflink.h (elf_link_add_object_symbols): Initialize type_change_ok from new backend field. (elf_link_output_extsym): Don't warn if _rld_new_interface is defined. (elf_reloc_link_order): Treat a reloc against a defined symbol as a reloc against the appropriate section.
This commit is contained in:
parent
f9407a89f4
commit
5b3b9ff61d
@ -1,5 +1,31 @@
|
||||
Thu Jan 11 11:23:30 1996 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* elf32-mips.c: Extensive changes for a start at dynamic linking
|
||||
support, from Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>.
|
||||
|
||||
* elf-bfd.h (struct elf_backend_data): Add type_change_ok field.
|
||||
(struct elf_backend_data): Remove
|
||||
elf_backend_create_program_headers field. Add
|
||||
elf_backend_additional_program_headers and
|
||||
elf_backend_modify_segment_map fields.
|
||||
* elfxx-target.h (elf_backend_type_change_ok): Define if not
|
||||
defined.
|
||||
(elf_backend_additional_program_headers): Likewise.
|
||||
(elf_backend_modify_segment_map): Likewise.
|
||||
(elf_backend_create_program_headers): Don't define.
|
||||
(elfNN_bed): Change to account for field changes.
|
||||
* elf.c (assign_file_positions_for_segments): Call new
|
||||
modify_segment_map backend function. Don't call old
|
||||
create_program_headers backend function.
|
||||
(get_program_header_size): Call additional_program_headers rather
|
||||
than create_program_headers.
|
||||
* elflink.h (elf_link_add_object_symbols): Initialize
|
||||
type_change_ok from new backend field.
|
||||
(elf_link_output_extsym): Don't warn if _rld_new_interface is
|
||||
defined.
|
||||
(elf_reloc_link_order): Treat a reloc against a defined symbol as
|
||||
a reloc against the appropriate section.
|
||||
|
||||
* elf-bfd.h (struct bfd_elf_section_data): Add tdata field.
|
||||
(struct elf_obj_tdata): Rename ppc_flags_init field to flags_init.
|
||||
(elf_flags_init): Rename from elf_ppc_flags_init.
|
||||
|
@ -212,6 +212,12 @@ struct elf_backend_data
|
||||
section. */
|
||||
boolean collect;
|
||||
|
||||
/* This is true if the linker should ignore changes to the type of a
|
||||
symbol. This is true for MIPS ELF because some Irix 5 objects
|
||||
record undefined functions as STT_OBJECT although the definitions
|
||||
are STT_FUNC. */
|
||||
boolean type_change_ok;
|
||||
|
||||
/* A function to translate an ELF RELA relocation to a BFD arelent
|
||||
structure. */
|
||||
void (*elf_info_to_howto) PARAMS ((bfd *, arelent *,
|
||||
@ -412,13 +418,14 @@ struct elf_backend_data
|
||||
void (*elf_backend_final_write_processing)
|
||||
PARAMS ((bfd *, boolean linker));
|
||||
|
||||
/* A function to create any special program headers required by the
|
||||
backend. PHDRS are the program headers, and PHDR_COUNT is the
|
||||
number of them. If PHDRS is NULL, this just counts headers
|
||||
without creating them. This returns an updated value for
|
||||
PHDR_COUNT. */
|
||||
int (*elf_backend_create_program_headers)
|
||||
PARAMS ((bfd *, Elf_Internal_Phdr *phdrs, int phdr_count));
|
||||
/* This function is called by get_program_header_size. It should
|
||||
return the number of additional program segments which this BFD
|
||||
will need. It should return -1 on error. */
|
||||
int (*elf_backend_additional_program_headers) PARAMS ((bfd *));
|
||||
|
||||
/* This function is called to modify an existing segment map in a
|
||||
backend specific fashion. */
|
||||
boolean (*elf_backend_modify_segment_map) PARAMS ((bfd *));
|
||||
|
||||
/* The swapping table to use when dealing with ECOFF information.
|
||||
Used for the MIPS ELF .mdebug section. */
|
||||
|
32
bfd/elf.c
32
bfd/elf.c
@ -576,6 +576,7 @@ bfd_section_from_shdr (abfd, shindex)
|
||||
case SHT_DYNAMIC: /* Dynamic linking information. */
|
||||
case SHT_NOBITS: /* .bss section. */
|
||||
case SHT_HASH: /* .hash section. */
|
||||
case SHT_NOTE: /* .note section. */
|
||||
return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
|
||||
|
||||
case SHT_SYMTAB: /* A symbol table */
|
||||
@ -752,9 +753,6 @@ bfd_section_from_shdr (abfd, shindex)
|
||||
}
|
||||
break;
|
||||
|
||||
case SHT_NOTE:
|
||||
break;
|
||||
|
||||
case SHT_SHLIB:
|
||||
return true;
|
||||
|
||||
@ -1746,6 +1744,12 @@ assign_file_positions_for_segments (abfd)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bed->elf_backend_modify_segment_map)
|
||||
{
|
||||
if (! (*bed->elf_backend_modify_segment_map) (abfd))
|
||||
return false;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
|
||||
++count;
|
||||
@ -1757,11 +1761,6 @@ assign_file_positions_for_segments (abfd)
|
||||
if (count == 0)
|
||||
return true;
|
||||
|
||||
/* Let the backend count up any program headers it might need. */
|
||||
if (bed->elf_backend_create_program_headers)
|
||||
count = ((*bed->elf_backend_create_program_headers)
|
||||
(abfd, (Elf_Internal_Phdr *) NULL, count));
|
||||
|
||||
/* If we already counted the number of program segments, make sure
|
||||
that we allocated enough space. This happens when SIZEOF_HEADERS
|
||||
is used in a linker script. */
|
||||
@ -1978,11 +1977,6 @@ assign_file_positions_for_segments (abfd)
|
||||
}
|
||||
}
|
||||
|
||||
/* Let the backend set up any program headers it might need. */
|
||||
if (bed->elf_backend_create_program_headers)
|
||||
count = ((*bed->elf_backend_create_program_headers)
|
||||
(abfd, phdrs, count));
|
||||
|
||||
/* Clear out any program headers we allocated but did not use. */
|
||||
for (; count < alloc; count++, p++)
|
||||
{
|
||||
@ -2057,9 +2051,15 @@ get_program_header_size (abfd)
|
||||
}
|
||||
|
||||
/* Let the backend count up any program headers it might need. */
|
||||
if (bed->elf_backend_create_program_headers)
|
||||
segs = ((*bed->elf_backend_create_program_headers)
|
||||
(abfd, (Elf_Internal_Phdr *) NULL, segs));
|
||||
if (bed->elf_backend_additional_program_headers)
|
||||
{
|
||||
int a;
|
||||
|
||||
a = (*bed->elf_backend_additional_program_headers) (abfd);
|
||||
if (a == -1)
|
||||
abort ();
|
||||
segs += a;
|
||||
}
|
||||
|
||||
elf_tdata (abfd)->program_header_size = segs * bed->s->sizeof_phdr;
|
||||
return elf_tdata (abfd)->program_header_size;
|
||||
|
3078
bfd/elf32-mips.c
3078
bfd/elf32-mips.c
File diff suppressed because it is too large
Load Diff
131
bfd/elflink.h
131
bfd/elflink.h
@ -629,7 +629,7 @@ elf_link_add_object_symbols (abfd, info)
|
||||
definition = true;
|
||||
|
||||
size_change_ok = false;
|
||||
type_change_ok = false;
|
||||
type_change_ok = get_elf_backend_data (abfd)->type_change_ok;
|
||||
if (info->hash->creator->flavour == bfd_target_elf_flavour)
|
||||
{
|
||||
/* We need to look up the symbol now in order to get some of
|
||||
@ -648,15 +648,16 @@ elf_link_add_object_symbols (abfd, info)
|
||||
|
||||
/* It's OK to change the type if it used to be a weak
|
||||
definition. */
|
||||
type_change_ok = (h->root.type == bfd_link_hash_defweak
|
||||
|| h->root.type == bfd_link_hash_undefweak);
|
||||
if (h->root.type == bfd_link_hash_defweak
|
||||
|| h->root.type == bfd_link_hash_undefweak)
|
||||
type_change_ok = true;
|
||||
|
||||
/* It's OK to change the size if it used to be a weak
|
||||
definition, or if it used to be undefined, or if we will
|
||||
be overriding an old definition.
|
||||
*/
|
||||
size_change_ok = (type_change_ok
|
||||
|| h->root.type == bfd_link_hash_undefined);
|
||||
be overriding an old definition. */
|
||||
if (type_change_ok
|
||||
|| h->root.type == bfd_link_hash_undefined)
|
||||
size_change_ok = true;
|
||||
|
||||
/* If we are looking at a dynamic object, and this is a
|
||||
definition, we need to see if it has already been defined
|
||||
@ -2401,12 +2402,15 @@ elf_link_output_extsym (h, data)
|
||||
linker will complain that the symbol is undefined when the
|
||||
program is run. We don't have to worry about symbols that are
|
||||
referenced by regular files, because we will already have issued
|
||||
warnings for them. */
|
||||
warnings for them. FIXME: _rld_new_interface is apparently
|
||||
supposed to be undefined on Irix 5.3. This should be handled in
|
||||
a better way. */
|
||||
if (! finfo->info->relocateable
|
||||
&& ! finfo->info->shared
|
||||
&& h->root.type == bfd_link_hash_undefined
|
||||
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0
|
||||
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0)
|
||||
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0
|
||||
&& strcmp (h->root.root.string, "_rld_new_interface") != 0)
|
||||
{
|
||||
if (! ((*finfo->info->callbacks->undefined_symbol)
|
||||
(finfo->info, h->root.root.string, h->root.u.undef.abfd,
|
||||
@ -2987,6 +2991,7 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
|
||||
reloc_howto_type *howto;
|
||||
long indx;
|
||||
bfd_vma offset;
|
||||
bfd_vma addend;
|
||||
struct elf_link_hash_entry **rel_hash_ptr;
|
||||
Elf_Internal_Shdr *rel_hdr;
|
||||
|
||||
@ -2997,50 +3002,7 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If this is an inplace reloc, we must write the addend into the
|
||||
object file. */
|
||||
if (howto->partial_inplace
|
||||
&& link_order->u.reloc.p->addend != 0)
|
||||
{
|
||||
bfd_size_type size;
|
||||
bfd_reloc_status_type rstat;
|
||||
bfd_byte *buf;
|
||||
boolean ok;
|
||||
|
||||
size = bfd_get_reloc_size (howto);
|
||||
buf = (bfd_byte *) bfd_zmalloc (size);
|
||||
if (buf == (bfd_byte *) NULL)
|
||||
return false;
|
||||
rstat = _bfd_relocate_contents (howto, output_bfd,
|
||||
link_order->u.reloc.p->addend, buf);
|
||||
switch (rstat)
|
||||
{
|
||||
case bfd_reloc_ok:
|
||||
break;
|
||||
default:
|
||||
case bfd_reloc_outofrange:
|
||||
abort ();
|
||||
case bfd_reloc_overflow:
|
||||
if (! ((*info->callbacks->reloc_overflow)
|
||||
(info,
|
||||
(link_order->type == bfd_section_reloc_link_order
|
||||
? bfd_section_name (output_bfd,
|
||||
link_order->u.reloc.p->u.section)
|
||||
: link_order->u.reloc.p->u.name),
|
||||
howto->name, link_order->u.reloc.p->addend,
|
||||
(bfd *) NULL, (asection *) NULL, (bfd_vma) 0)))
|
||||
{
|
||||
free (buf);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf,
|
||||
(file_ptr) link_order->offset, size);
|
||||
free (buf);
|
||||
if (! ok)
|
||||
return false;
|
||||
}
|
||||
addend = link_order->u.reloc.p->addend;
|
||||
|
||||
/* Figure out the symbol index. */
|
||||
rel_hash_ptr = (elf_section_data (output_section)->rel_hashes
|
||||
@ -3055,10 +3017,26 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
|
||||
{
|
||||
struct elf_link_hash_entry *h;
|
||||
|
||||
/* Treat a reloc against a defined symbol as though it were
|
||||
actually against the section. */
|
||||
h = elf_link_hash_lookup (elf_hash_table (info),
|
||||
link_order->u.reloc.p->u.name,
|
||||
false, false, true);
|
||||
if (h != NULL)
|
||||
if (h != NULL
|
||||
&& (h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak))
|
||||
{
|
||||
asection *section;
|
||||
|
||||
section = h->root.u.def.section;
|
||||
indx = section->output_section->target_index;
|
||||
*rel_hash_ptr = NULL;
|
||||
/* It seems that we ought to add the symbol value to the
|
||||
addend here, but in practice it has already been added
|
||||
because it was passed to constructor_callback. */
|
||||
addend += section->output_section->vma + section->output_offset;
|
||||
}
|
||||
else if (h != NULL)
|
||||
{
|
||||
/* Setting the index to -2 tells elf_link_output_extsym that
|
||||
this symbol is used by a reloc. */
|
||||
@ -3076,6 +3054,49 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is an inplace reloc, we must write the addend into the
|
||||
object file. */
|
||||
if (howto->partial_inplace && addend != 0)
|
||||
{
|
||||
bfd_size_type size;
|
||||
bfd_reloc_status_type rstat;
|
||||
bfd_byte *buf;
|
||||
boolean ok;
|
||||
|
||||
size = bfd_get_reloc_size (howto);
|
||||
buf = (bfd_byte *) bfd_zmalloc (size);
|
||||
if (buf == (bfd_byte *) NULL)
|
||||
return false;
|
||||
rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf);
|
||||
switch (rstat)
|
||||
{
|
||||
case bfd_reloc_ok:
|
||||
break;
|
||||
default:
|
||||
case bfd_reloc_outofrange:
|
||||
abort ();
|
||||
case bfd_reloc_overflow:
|
||||
if (! ((*info->callbacks->reloc_overflow)
|
||||
(info,
|
||||
(link_order->type == bfd_section_reloc_link_order
|
||||
? bfd_section_name (output_bfd,
|
||||
link_order->u.reloc.p->u.section)
|
||||
: link_order->u.reloc.p->u.name),
|
||||
howto->name, addend, (bfd *) NULL, (asection *) NULL,
|
||||
(bfd_vma) 0)))
|
||||
{
|
||||
free (buf);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf,
|
||||
(file_ptr) link_order->offset, size);
|
||||
free (buf);
|
||||
if (! ok)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* The address of a reloc is relative to the section in a
|
||||
relocateable file, and is a virtual address in an executable
|
||||
file. */
|
||||
@ -3103,7 +3124,7 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
|
||||
|
||||
irela.r_offset = offset;
|
||||
irela.r_info = ELF_R_INFO (indx, howto->type);
|
||||
irela.r_addend = link_order->u.reloc.p->addend;
|
||||
irela.r_addend = addend;
|
||||
erela = ((Elf_External_Rela *) rel_hdr->contents
|
||||
+ output_section->reloc_count);
|
||||
elf_swap_reloca_out (output_bfd, &irela, erela);
|
||||
|
@ -156,6 +156,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#ifndef elf_backend_collect
|
||||
#define elf_backend_collect false
|
||||
#endif
|
||||
#ifndef elf_backend_type_change_ok
|
||||
#define elf_backend_type_change_ok false
|
||||
#endif
|
||||
|
||||
#ifndef elf_backend_sym_is_global
|
||||
#define elf_backend_sym_is_global 0
|
||||
@ -214,8 +217,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#ifndef elf_backend_final_write_processing
|
||||
#define elf_backend_final_write_processing 0
|
||||
#endif
|
||||
#ifndef elf_backend_create_program_headers
|
||||
#define elf_backend_create_program_headers 0
|
||||
#ifndef elf_backend_additional_program_headers
|
||||
#define elf_backend_additional_program_headers 0
|
||||
#endif
|
||||
#ifndef elf_backend_modify_segment_map
|
||||
#define elf_backend_modify_segment_map 0
|
||||
#endif
|
||||
#ifndef elf_backend_ecoff_debug_swap
|
||||
#define elf_backend_ecoff_debug_swap 0
|
||||
@ -242,6 +248,7 @@ static CONST struct elf_backend_data elfNN_bed =
|
||||
ELF_MACHINE_CODE, /* elf_machine_code */
|
||||
ELF_MAXPAGESIZE, /* maxpagesize */
|
||||
elf_backend_collect,
|
||||
elf_backend_type_change_ok,
|
||||
elf_info_to_howto,
|
||||
elf_info_to_howto_rel,
|
||||
elf_backend_sym_is_global,
|
||||
@ -263,7 +270,8 @@ static CONST struct elf_backend_data elfNN_bed =
|
||||
elf_backend_finish_dynamic_sections,
|
||||
elf_backend_begin_write_processing,
|
||||
elf_backend_final_write_processing,
|
||||
elf_backend_create_program_headers,
|
||||
elf_backend_additional_program_headers,
|
||||
elf_backend_modify_segment_map,
|
||||
elf_backend_ecoff_debug_swap,
|
||||
ELF_MACHINE_ALT1,
|
||||
ELF_MACHINE_ALT2,
|
||||
@ -283,11 +291,11 @@ const bfd_target TARGET_BIG_SYM =
|
||||
/* flavour: general indication about file */
|
||||
bfd_target_elf_flavour,
|
||||
|
||||
/* byteorder_big_p: data is big endian */
|
||||
true,
|
||||
/* byteorder: data is big endian */
|
||||
BFD_ENDIAN_BIG,
|
||||
|
||||
/* header_byteorder_big_p: header is also big endian */
|
||||
true,
|
||||
/* header_byteorder: header is also big endian */
|
||||
BFD_ENDIAN_BIG,
|
||||
|
||||
/* object_flags: mask of all file flags */
|
||||
(HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS |
|
||||
@ -367,11 +375,11 @@ const bfd_target TARGET_LITTLE_SYM =
|
||||
/* flavour: general indication about file */
|
||||
bfd_target_elf_flavour,
|
||||
|
||||
/* byteorder_big_p: data is big endian */
|
||||
false, /* Nope -- this one's little endian */
|
||||
/* byteorder: data is little endian */
|
||||
BFD_ENDIAN_LITTLE,
|
||||
|
||||
/* header_byteorder_big_p: header is also big endian */
|
||||
false, /* Nope -- this one's little endian */
|
||||
/* header_byteorder: header is also little endian */
|
||||
BFD_ENDIAN_LITTLE,
|
||||
|
||||
/* object_flags: mask of all file flags */
|
||||
(HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS |
|
||||
|
Loading…
Reference in New Issue
Block a user