* elfcode.h (elf_slurp_reloc_table): Add dynamic parameter.

* elf.c (_bfd_elf_canonicalize_reloc): Pass new argument to
	slurp_reloc_table.
	(_bfd_elf_get_dynamic_reloc_upper_bound): New function.
	(_bfd_elf_canonicalize_dynamic_reloc): New function.
	* elf-bfd.h (struct elf_size_info): Update declaration of
	slurp_reloc_table.
	(_bfd_elf_get_dynamic_reloc_upper_bound): Declare.
	(_bfd_elf_canonicalize_dynamic_reloc): Declare.
	* elfxx-target.h: Use new dynamic reloc routines by default.
	* elf64-mips.c (mips_elf64_slurp_reloc_table): Add dynamic
	parameter.
This commit is contained in:
Ian Lance Taylor 1996-12-15 19:59:18 +00:00
parent d31b72a314
commit e35765a9a2
6 changed files with 459 additions and 181 deletions

View File

@ -1,3 +1,18 @@
Sun Dec 15 14:46:06 1996 Ian Lance Taylor <ian@cygnus.com>
* elfcode.h (elf_slurp_reloc_table): Add dynamic parameter.
* elf.c (_bfd_elf_canonicalize_reloc): Pass new argument to
slurp_reloc_table.
(_bfd_elf_get_dynamic_reloc_upper_bound): New function.
(_bfd_elf_canonicalize_dynamic_reloc): New function.
* elf-bfd.h (struct elf_size_info): Update declaration of
slurp_reloc_table.
(_bfd_elf_get_dynamic_reloc_upper_bound): Declare.
(_bfd_elf_canonicalize_dynamic_reloc): Declare.
* elfxx-target.h: Use new dynamic reloc routines by default.
* elf64-mips.c (mips_elf64_slurp_reloc_table): Add dynamic
parameter.
Fri Dec 13 13:18:49 1996 Dan Wilder <dan@gasboy.com>
* coffcode.h (coff_set_flags): Use MC68KBCSMAGIC for bfd_arch_m68k

View File

@ -110,6 +110,9 @@ struct elf_link_hash_entry
/* Symbol type (STT_NOTYPE, STT_OBJECT, etc.). */
char type;
/* Symbol st_other value. */
unsigned char other;
/* Some flags; legal values follow. */
unsigned char elf_link_hash_flags;
/* Symbol is referenced by a non-shared object. */
@ -193,7 +196,8 @@ struct elf_size_info {
boolean (*write_shdrs_and_ehdr) PARAMS ((bfd *));
void (*write_relocs) PARAMS ((bfd *, asection *, PTR));
void (*swap_symbol_out) PARAMS ((bfd *, const Elf_Internal_Sym *, PTR));
boolean (*slurp_reloc_table) PARAMS ((bfd *, asection *, asymbol **));
boolean (*slurp_reloc_table)
PARAMS ((bfd *, asection *, asymbol **, boolean));
long (*slurp_symbol_table) PARAMS ((bfd *, asymbol **, boolean));
void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *));
};
@ -698,6 +702,9 @@ extern long _bfd_elf_canonicalize_dynamic_symtab PARAMS ((bfd *, asymbol **));
extern long _bfd_elf_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
extern long _bfd_elf_canonicalize_reloc PARAMS ((bfd *, sec_ptr,
arelent **, asymbol **));
extern long _bfd_elf_get_dynamic_reloc_upper_bound PARAMS ((bfd *));
extern long _bfd_elf_canonicalize_dynamic_reloc PARAMS ((bfd *, arelent **,
asymbol **));
extern asymbol *_bfd_elf_make_empty_symbol PARAMS ((bfd *));
extern void _bfd_elf_get_symbol_info PARAMS ((bfd *, asymbol *,
symbol_info *));
@ -719,6 +726,7 @@ extern void _bfd_elf_no_info_to_howto PARAMS ((bfd *, arelent *,
Elf_Internal_Rela *));
extern boolean bfd_section_from_shdr PARAMS ((bfd *, unsigned int shindex));
extern boolean bfd_section_from_phdr PARAMS ((bfd *, Elf_Internal_Phdr *, int));
extern int _bfd_elf_symbol_from_bfd_symbol PARAMS ((bfd *, asymbol **));
@ -835,6 +843,8 @@ extern boolean bfd_elf32_add_dynamic_entry
PARAMS ((struct bfd_link_info *, bfd_vma, bfd_vma));
extern boolean bfd_elf32_link_create_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
extern Elf_Internal_Rela *_bfd_elf32_link_read_relocs
PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, boolean));
extern const bfd_target *bfd_elf64_object_p PARAMS ((bfd *));
extern const bfd_target *bfd_elf64_core_file_p PARAMS ((bfd *));
@ -876,6 +886,8 @@ extern boolean bfd_elf64_add_dynamic_entry
PARAMS ((struct bfd_link_info *, bfd_vma, bfd_vma));
extern boolean bfd_elf64_link_create_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
extern Elf_Internal_Rela *_bfd_elf64_link_read_relocs
PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, boolean));
#define bfd_elf32_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol
#define bfd_elf64_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol
@ -895,5 +907,23 @@ extern void _bfd_mips_elf_symbol_processing PARAMS ((bfd *, asymbol *));
extern boolean _bfd_mips_elf_read_ecoff_info
PARAMS ((bfd *, asection *, struct ecoff_debug_info *));
extern void _bfd_mips_elf_final_write_processing PARAMS ((bfd *, boolean));
extern bfd_reloc_status_type _bfd_mips_elf_hi16_reloc
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
extern bfd_reloc_status_type _bfd_mips_elf_lo16_reloc
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
extern bfd_reloc_status_type _bfd_mips_elf_gprel16_reloc
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
extern bfd_reloc_status_type _bfd_mips_elf_got16_reloc
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
extern bfd_reloc_status_type _bfd_mips_elf_gprel32_reloc
PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
extern boolean _bfd_mips_elf_set_private_flags PARAMS ((bfd *, flagword));
extern boolean _bfd_mips_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *));
extern boolean _bfd_mips_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
extern boolean _bfd_mips_elf_find_nearest_line
PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **,
const char **, unsigned int *));
extern boolean _bfd_mips_elf_set_section_contents
PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
#endif /* _LIBELF_H_ */

View File

@ -868,6 +868,7 @@ bfd_section_from_shdr (abfd, shindex)
if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
return false;
if (hdr->bfd_section != NULL
&& hdr->sh_info > 0
&& bfd_section_from_shdr (abfd, hdr->sh_info))
{
target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info);
@ -3249,7 +3250,10 @@ _bfd_elf_canonicalize_reloc (abfd, section, relptr, symbols)
arelent *tblptr;
unsigned int i;
if (! get_elf_backend_data (abfd)->s->slurp_reloc_table (abfd, section, symbols))
if (! get_elf_backend_data (abfd)->s->slurp_reloc_table (abfd,
section,
symbols,
false))
return -1;
tblptr = section->relocation;
@ -3281,6 +3285,86 @@ _bfd_elf_canonicalize_dynamic_symtab (abfd, alocation)
return get_elf_backend_data (abfd)->s->slurp_symbol_table (abfd, alocation, true);
}
/* Return the size required for the dynamic reloc entries. Any
section that was actually installed in the BFD, and has type
SHT_REL or SHT_RELA, and uses the dynamic symbol table, is
considered to be a dynamic reloc section. */
long
_bfd_elf_get_dynamic_reloc_upper_bound (abfd)
bfd *abfd;
{
long ret;
asection *s;
if (elf_dynsymtab (abfd) == 0)
{
bfd_set_error (bfd_error_invalid_operation);
return -1;
}
ret = sizeof (arelent *);
for (s = abfd->sections; s != NULL; s = s->next)
if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
&& (elf_section_data (s)->this_hdr.sh_type == SHT_REL
|| elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
ret += ((s->_raw_size / elf_section_data (s)->this_hdr.sh_entsize)
* sizeof (arelent *));
return ret;
}
/* Canonicalize the dynamic relocation entries. Note that we return
the dynamic relocations as a single block, although they are
actually associated with particular sections; the interface, which
was designed for SunOS style shared libraries, expects that there
is only one set of dynamic relocs. Any section that was actually
installed in the BFD, and has type SHT_REL or SHT_RELA, and uses
the dynamic symbol table, is considered to be a dynamic reloc
section. */
long
_bfd_elf_canonicalize_dynamic_reloc (abfd, storage, syms)
bfd *abfd;
arelent **storage;
asymbol **syms;
{
boolean (*slurp_relocs) PARAMS ((bfd *, asection *, asymbol **, boolean));
asection *s;
long ret;
if (elf_dynsymtab (abfd) == 0)
{
bfd_set_error (bfd_error_invalid_operation);
return -1;
}
slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
ret = 0;
for (s = abfd->sections; s != NULL; s = s->next)
{
if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
&& (elf_section_data (s)->this_hdr.sh_type == SHT_REL
|| elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
{
arelent *p;
long count, i;
if (! (*slurp_relocs) (abfd, s, syms, true))
return -1;
count = s->_raw_size / elf_section_data (s)->this_hdr.sh_entsize;
p = s->relocation;
for (i = 0; i < count; i++)
*storage++ = p++;
ret += count;
}
}
*storage = NULL;
return ret;
}
asymbol *
_bfd_elf_make_empty_symbol (abfd)
bfd *abfd;

View File

@ -22,11 +22,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
The MIPS 64-bit ELF ABI uses an unusual reloc format. This file
overrides the usual ELF reloc handling, and handles reading and
writing the relocations here. */
writing the relocations here.
The MIPS 64-bit ELF ABI also uses an unusual archive map format. */
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#include "aout/ar.h"
#include "bfdlink.h"
#include "genlink.h"
#include "elf-bfd.h"
@ -69,6 +72,9 @@ static boolean mips_elf64_section_from_shdr
PARAMS ((bfd *, Elf_Internal_Shdr *, char *));
static boolean mips_elf64_section_processing
PARAMS ((bfd *, Elf_Internal_Shdr *));
static boolean mips_elf64_slurp_armap PARAMS ((bfd *));
static boolean mips_elf64_write_armap
PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
/* The relocation types. */
@ -1537,13 +1543,20 @@ mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, rel_hdr)
associated with a single data section. */
static boolean
mips_elf64_slurp_reloc_table (abfd, asect, symbols)
mips_elf64_slurp_reloc_table (abfd, asect, symbols, dynamic)
bfd *abfd;
asection *asect;
asymbol **symbols;
boolean dynamic;
{
struct bfd_elf_section_data * const d = elf_section_data (asect);
if (dynamic)
{
bfd_set_error (bfd_error_invalid_operation);
return false;
}
if (asect->relocation != NULL
|| (asect->flags & SEC_RELOC) == 0
|| asect->reloc_count == 0)
@ -1720,47 +1733,6 @@ mips_elf64_write_relocs (abfd, sec, data)
== count);
}
/* The .MIPS.options section holds register information in an
Elf64_Reginfo structure. These routines swap them in and out.
They are globally visible because they are used outside of BFD. */
void
bfd_mips_elf64_swap_reginfo_in (abfd, ex, in)
bfd *abfd;
const Elf64_External_RegInfo *ex;
Elf64_Internal_RegInfo *in;
{
in->ri_gprmask = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_gprmask);
in->ri_pad = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_pad);
in->ri_cprmask[0] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[0]);
in->ri_cprmask[1] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[1]);
in->ri_cprmask[2] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[2]);
in->ri_cprmask[3] = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_cprmask[3]);
in->ri_gp_value = bfd_h_get_64 (abfd, (bfd_byte *) ex->ri_gp_value);
}
void
bfd_mips_elf64_swap_reginfo_out (abfd, in, ex)
bfd *abfd;
const Elf64_Internal_RegInfo *in;
Elf64_External_RegInfo *ex;
{
bfd_h_put_32 (abfd, (bfd_vma) in->ri_gprmask,
(bfd_byte *) ex->ri_gprmask);
bfd_h_put_32 (abfd, (bfd_vma) in->ri_pad,
(bfd_byte *) ex->ri_pad);
bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[0],
(bfd_byte *) ex->ri_cprmask[0]);
bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[1],
(bfd_byte *) ex->ri_cprmask[1]);
bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[2],
(bfd_byte *) ex->ri_cprmask[2]);
bfd_h_put_32 (abfd, (bfd_vma) in->ri_cprmask[3],
(bfd_byte *) ex->ri_cprmask[3]);
bfd_h_put_64 (abfd, (bfd_vma) in->ri_gp_value,
(bfd_byte *) ex->ri_gp_value);
}
/* Handle a 64-bit MIPS ELF specific section. */
static boolean
@ -1870,6 +1842,215 @@ mips_elf64_section_processing (abfd, hdr)
return _bfd_mips_elf_section_processing (abfd, hdr);
}
/* Irix 6 defines a brand new archive map format, so that they can
have archives more than 4 GB in size. */
/* Read an Irix 6 armap. */
static boolean
mips_elf64_slurp_armap (abfd)
bfd *abfd;
{
struct artdata *ardata = bfd_ardata (abfd);
char nextname[17];
file_ptr arhdrpos;
bfd_size_type i, parsed_size, nsymz, stringsize, carsym_size, ptrsize;
struct areltdata *mapdata;
bfd_byte int_buf[8];
char *stringbase;
bfd_byte *raw_armap = NULL;
carsym *carsyms;
ardata->symdefs = NULL;
/* Get the name of the first element. */
arhdrpos = bfd_tell (abfd);
i = bfd_read ((PTR) nextname, 1, 16, abfd);
if (i == 0)
return true;
if (i != 16)
return false;
if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0)
return false;
/* Archives with traditional armaps are still permitted. */
if (strncmp (nextname, "/ ", 16) == 0)
return bfd_slurp_armap (abfd);
if (strncmp (nextname, "/SYM64/ ", 16) != 0)
{
bfd_has_map (abfd) = false;
return true;
}
mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
if (mapdata == NULL)
return false;
parsed_size = mapdata->parsed_size;
bfd_release (abfd, (PTR) mapdata);
if (bfd_read (int_buf, 1, 8, abfd) != 8)
{
if (bfd_get_error () != bfd_error_system_call)
bfd_set_error (bfd_error_malformed_archive);
return false;
}
nsymz = bfd_getb64 (int_buf);
stringsize = parsed_size - 8 * nsymz - 8;
carsym_size = nsymz * sizeof (carsym);
ptrsize = 8 * nsymz;
ardata->symdefs = (carsym *) bfd_zalloc (abfd, carsym_size + stringsize + 1);
if (ardata->symdefs == NULL)
return false;
carsyms = ardata->symdefs;
stringbase = ((char *) ardata->symdefs) + carsym_size;
raw_armap = (bfd_byte *) bfd_alloc (abfd, ptrsize);
if (raw_armap == NULL)
goto error_return;
if (bfd_read (raw_armap, 1, ptrsize, abfd) != ptrsize
|| bfd_read (stringbase, 1, stringsize, abfd) != stringsize)
{
if (bfd_get_error () != bfd_error_system_call)
bfd_set_error (bfd_error_malformed_archive);
goto error_return;
}
for (i = 0; i < nsymz; i++)
{
carsyms->file_offset = bfd_getb64 (raw_armap + i * 8);
carsyms->name = stringbase;
stringbase += strlen (stringbase) + 1;
++carsyms;
}
*stringbase = '\0';
ardata->symdef_count = nsymz;
ardata->first_file_filepos = arhdrpos + sizeof (struct ar_hdr) + parsed_size;
bfd_has_map (abfd) = true;
bfd_release (abfd, raw_armap);
return true;
error_return:
if (raw_armap != NULL)
bfd_release (abfd, raw_armap);
if (ardata->symdefs != NULL)
bfd_release (abfd, ardata->symdefs);
return false;
}
/* Write out an Irix 6 armap. The Irix 6 tools are supposed to be
able to handle ordinary ELF armaps, but at least on Irix 6.2 the
linker crashes. */
static boolean
mips_elf64_write_armap (arch, elength, map, symbol_count, stridx)
bfd *arch;
unsigned int elength;
struct orl *map;
unsigned int symbol_count;
int stridx;
{
unsigned int ranlibsize = (symbol_count * 8) + 8;
unsigned int stringsize = stridx;
unsigned int mapsize = stringsize + ranlibsize;
file_ptr archive_member_file_ptr;
bfd *current = arch->archive_head;
unsigned int count;
struct ar_hdr hdr;
unsigned int i;
int padding;
bfd_byte buf[8];
padding = BFD_ALIGN (mapsize, 8) - mapsize;
mapsize += padding;
/* work out where the first object file will go in the archive */
archive_member_file_ptr = (mapsize
+ elength
+ sizeof (struct ar_hdr)
+ SARMAG);
memset ((char *) (&hdr), 0, sizeof (struct ar_hdr));
strcpy (hdr.ar_name, "/SYM64/");
sprintf (hdr.ar_size, "%-10d", (int) mapsize);
sprintf (hdr.ar_date, "%ld", (long) time (NULL));
/* This, at least, is what Intel coff sets the values to.: */
sprintf ((hdr.ar_uid), "%d", 0);
sprintf ((hdr.ar_gid), "%d", 0);
sprintf ((hdr.ar_mode), "%-7o", (unsigned) 0);
strncpy (hdr.ar_fmag, ARFMAG, 2);
for (i = 0; i < sizeof (struct ar_hdr); i++)
if (((char *) (&hdr))[i] == '\0')
(((char *) (&hdr))[i]) = ' ';
/* Write the ar header for this item and the number of symbols */
if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), arch)
!= sizeof (struct ar_hdr))
return false;
bfd_putb64 (symbol_count, buf);
if (bfd_write (buf, 1, 8, arch) != 8)
return false;
/* Two passes, first write the file offsets for each symbol -
remembering that each offset is on a two byte boundary. */
/* Write out the file offset for the file associated with each
symbol, and remember to keep the offsets padded out. */
current = arch->archive_head;
count = 0;
while (current != (bfd *) NULL && count < symbol_count)
{
/* For each symbol which is used defined in this object, write out
the object file's address in the archive */
while (((bfd *) (map[count]).pos) == current)
{
bfd_putb64 (archive_member_file_ptr, buf);
if (bfd_write (buf, 1, 8, arch) != 8)
return false;
count++;
}
/* Add size of this archive entry */
archive_member_file_ptr += (arelt_size (current)
+ sizeof (struct ar_hdr));
/* remember about the even alignment */
archive_member_file_ptr += archive_member_file_ptr % 2;
current = current->next;
}
/* now write the strings themselves */
for (count = 0; count < symbol_count; count++)
{
size_t len = strlen (*map[count].name) + 1;
if (bfd_write (*map[count].name, 1, len, arch) != len)
return false;
}
/* The spec says that this should be padded to an 8 byte boundary.
However, the Irix 6.2 tools do not appear to do this. */
while (padding != 0)
{
if (bfd_write ("", 1, 1, arch) != 1)
return false;
--padding;
}
return true;
}
/* ECOFF swapping routines. These are used when dealing with the
.mdebug section, which is in the ECOFF debugging format. */
static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
@ -1969,4 +2150,23 @@ const struct elf_size_info mips_elf64_size_info =
_bfd_mips_elf_merge_private_bfd_data
#define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
#define bfd_elf64_archive_functions
#define bfd_elf64_archive_slurp_armap mips_elf64_slurp_armap
#define bfd_elf64_archive_slurp_extended_name_table \
_bfd_archive_coff_slurp_extended_name_table
#define bfd_elf64_archive_construct_extended_name_table \
_bfd_archive_coff_construct_extended_name_table
#define bfd_elf64_archive_truncate_arname \
_bfd_archive_coff_truncate_arname
#define bfd_elf64_archive_write_armap mips_elf64_write_armap
#define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
#define bfd_elf64_archive_openr_next_archived_file \
_bfd_archive_coff_openr_next_archived_file
#define bfd_elf64_archive_get_elt_at_index \
_bfd_archive_coff_get_elt_at_index
#define bfd_elf64_archive_generic_stat_arch_elt \
_bfd_archive_coff_generic_stat_arch_elt
#define bfd_elf64_archive_update_armap_timestamp \
_bfd_archive_coff_update_armap_timestamp
#include "elf64-target.h"

View File

@ -154,21 +154,13 @@ static void elf_swap_shdr_out
#define elf_stringtab_init _bfd_elf_stringtab_init
extern struct bfd_strtab_hash *_bfd_elf_stringtab_init PARAMS ((void));
#define section_from_elf_index bfd_section_from_elf_index
extern boolean bfd_section_from_phdr PARAMS ((bfd *, Elf_Internal_Phdr *,
int));
static boolean elf_slurp_reloc_table PARAMS ((bfd *, asection *, asymbol **));
static boolean elf_slurp_reloc_table
PARAMS ((bfd *, asection *, asymbol **, boolean));
int _bfd_elf_symbol_from_bfd_symbol PARAMS ((bfd *,
struct symbol_cache_entry **));
static boolean validate_reloc PARAMS ((bfd *, arelent *));
static void write_relocs PARAMS ((bfd *, asection *, PTR));
boolean bfd_section_from_shdr PARAMS ((bfd *, unsigned int shindex));
#ifdef DEBUG
static void elf_debug_section PARAMS ((int, Elf_Internal_Shdr *));
static void elf_debug_file PARAMS ((Elf_Internal_Ehdr *));
@ -594,6 +586,15 @@ elf_object_p (abfd)
goto got_no_match;
elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex);
elf_elfsections (abfd)[shindex] = i_shdrp + shindex;
/* If the section is loaded, but not page aligned, clear
D_PAGED. */
if ((i_shdrp[shindex].sh_flags & SHF_ALLOC) != 0
&& i_shdrp[shindex].sh_type != SHT_NOBITS
&& (((i_shdrp[shindex].sh_addr - i_shdrp[shindex].sh_offset)
% ebd->maxpagesize)
!= 0))
abfd->flags &= ~D_PAGED;
}
if (i_ehdrp->e_shstrndx)
{
@ -676,104 +677,6 @@ got_no_match:
/* ELF .o/exec file writing */
/* Try to convert a non-ELF reloc into an ELF one. */
static boolean
validate_reloc (abfd, areloc)
bfd *abfd;
arelent *areloc;
{
/* Check whether we really have an ELF howto. */
if ((*areloc->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec)
{
bfd_reloc_code_real_type code;
reloc_howto_type *howto;
/* Alien reloc: Try to determine its type to replace it with an
equivalent ELF reloc. */
if (areloc->howto->pc_relative)
{
switch (areloc->howto->bitsize)
{
case 8:
code = BFD_RELOC_8_PCREL;
break;
case 12:
code = BFD_RELOC_12_PCREL;
break;
case 16:
code = BFD_RELOC_16_PCREL;
break;
case 24:
code = BFD_RELOC_24_PCREL;
break;
case 32:
code = BFD_RELOC_32_PCREL;
break;
case 64:
code = BFD_RELOC_64_PCREL;
break;
default:
goto fail;
}
howto = bfd_reloc_type_lookup (abfd, code);
if (areloc->howto->pcrel_offset != howto->pcrel_offset)
{
if (howto->pcrel_offset)
areloc->addend += areloc->address;
else
areloc->addend -= areloc->address; /* addend is unsigned!! */
}
}
else
{
switch (areloc->howto->bitsize)
{
case 8:
code = BFD_RELOC_8;
break;
case 14:
code = BFD_RELOC_14;
break;
case 16:
code = BFD_RELOC_16;
break;
case 26:
code = BFD_RELOC_26;
break;
case 32:
code = BFD_RELOC_32;
break;
case 64:
code = BFD_RELOC_64;
break;
default:
goto fail;
}
howto = bfd_reloc_type_lookup (abfd, code);
}
if (howto)
areloc->howto = howto;
else
goto fail;
}
return true;
fail:
(*_bfd_error_handler)
("%s: unsupported relocation type %s",
bfd_get_filename (abfd), areloc->howto->name);
bfd_set_error (bfd_error_bad_value);
return false;
}
/* Write out the relocs. */
static void
@ -842,6 +745,8 @@ write_relocs (abfd, sec, data)
sym = *ptr->sym_ptr_ptr;
if (sym == last_sym)
n = last_sym_idx;
else if (bfd_is_abs_section (sym->section) && sym->value == 0)
n = STN_UNDEF;
else
{
last_sym = sym;
@ -854,8 +759,9 @@ write_relocs (abfd, sec, data)
last_sym_idx = n;
}
if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
&& ! validate_reloc (abfd, ptr))
if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
&& (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
&& ! _bfd_elf_validate_reloc (abfd, ptr))
{
*failedp = true;
return;
@ -907,7 +813,7 @@ write_relocs (abfd, sec, data)
}
if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
&& ! validate_reloc (abfd, ptr))
&& ! _bfd_elf_validate_reloc (abfd, ptr))
{
*failedp = true;
return;
@ -1177,13 +1083,16 @@ error_return:
/* Read in and swap the external relocs. */
static boolean
elf_slurp_reloc_table (abfd, asect, symbols)
elf_slurp_reloc_table (abfd, asect, symbols, dynamic)
bfd *abfd;
asection *asect;
asymbol **symbols;
boolean dynamic;
{
struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
struct bfd_elf_section_data * const d = elf_section_data (asect);
Elf_Internal_Shdr *rel_hdr;
bfd_size_type reloc_count;
PTR allocated = NULL;
bfd_byte *native_relocs;
arelent *relents;
@ -1191,37 +1100,51 @@ elf_slurp_reloc_table (abfd, asect, symbols)
unsigned int i;
int entsize;
if (asect->relocation != NULL
|| (asect->flags & SEC_RELOC) == 0
|| asect->reloc_count == 0)
if (asect->relocation != NULL)
return true;
BFD_ASSERT (asect->rel_filepos == d->rel_hdr.sh_offset
&& (asect->reloc_count
== d->rel_hdr.sh_size / d->rel_hdr.sh_entsize));
if (! dynamic)
{
if ((asect->flags & SEC_RELOC) == 0
|| asect->reloc_count == 0)
return true;
allocated = (PTR) bfd_malloc ((size_t) d->rel_hdr.sh_size);
rel_hdr = &d->rel_hdr;
reloc_count = asect->reloc_count;
BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
&& reloc_count == rel_hdr->sh_size / rel_hdr->sh_entsize);
}
else
{
if (asect->_raw_size == 0)
return true;
rel_hdr = &d->this_hdr;
reloc_count = rel_hdr->sh_size / rel_hdr->sh_entsize;
}
allocated = (PTR) bfd_malloc ((size_t) rel_hdr->sh_size);
if (allocated == NULL)
goto error_return;
if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0
|| (bfd_read (allocated, 1, d->rel_hdr.sh_size, abfd)
!= d->rel_hdr.sh_size))
if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
|| (bfd_read (allocated, 1, rel_hdr->sh_size, abfd)
!= rel_hdr->sh_size))
goto error_return;
native_relocs = (bfd_byte *) allocated;
relents = ((arelent *)
bfd_alloc (abfd, asect->reloc_count * sizeof (arelent)));
relents = (arelent *) bfd_alloc (abfd, reloc_count * sizeof (arelent));
if (relents == NULL)
goto error_return;
entsize = d->rel_hdr.sh_entsize;
entsize = rel_hdr->sh_entsize;
BFD_ASSERT (entsize == sizeof (Elf_External_Rel)
|| entsize == sizeof (Elf_External_Rela));
for (i = 0, relent = relents;
i < asect->reloc_count;
i < reloc_count;
i++, relent++, native_relocs += entsize)
{
Elf_Internal_Rela rela;
@ -1239,8 +1162,9 @@ elf_slurp_reloc_table (abfd, asect, symbols)
/* The address of an ELF reloc is section relative for an object
file, and absolute for an executable file or shared library.
The address of a BFD reloc is always section relative. */
if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
The address of a normal BFD reloc is always section relative,
and the address of a dynamic reloc is absolute.. */
if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
relent->address = rela.r_offset;
else
relent->address = rela.r_offset - asect->vma;

View File

@ -40,7 +40,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define bfd_elfNN_minisymbol_to_symbol _bfd_elf_minisymbol_to_symbol
#define bfd_elfNN_get_dynamic_symtab_upper_bound _bfd_elf_get_dynamic_symtab_upper_bound
#define bfd_elfNN_get_lineno _bfd_elf_get_lineno
#ifndef bfd_elfNN_get_reloc_upper_bound
#define bfd_elfNN_get_reloc_upper_bound _bfd_elf_get_reloc_upper_bound
#endif
#define bfd_elfNN_get_symbol_info _bfd_elf_get_symbol_info
#define bfd_elfNN_get_symtab _bfd_elf_get_symtab
#define bfd_elfNN_get_symtab_upper_bound _bfd_elf_get_symtab_upper_bound
@ -78,7 +80,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
bfd_generic_get_relocated_section_contents
#endif
#ifndef bfd_elfNN_bfd_relax_section
#define bfd_elfNN_bfd_relax_section bfd_generic_relax_section
#endif
#define bfd_elfNN_bfd_make_debug_symbol \
((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
@ -113,11 +118,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef bfd_elfNN_get_dynamic_reloc_upper_bound
#define bfd_elfNN_get_dynamic_reloc_upper_bound \
_bfd_nodynamic_get_dynamic_reloc_upper_bound
_bfd_elf_get_dynamic_reloc_upper_bound
#endif
#ifndef bfd_elfNN_canonicalize_dynamic_reloc
#define bfd_elfNN_canonicalize_dynamic_reloc \
_bfd_nodynamic_canonicalize_dynamic_reloc
_bfd_elf_canonicalize_dynamic_reloc
#endif
#ifdef elf_backend_relocate_section
@ -141,6 +146,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define bfd_elfNN_bfd_link_split_section _bfd_generic_link_split_section
#endif
#ifndef bfd_elfNN_archive_p
#define bfd_elfNN_archive_p bfd_generic_archive_p
#endif
#ifndef bfd_elfNN_write_archive_contents
#define bfd_elfNN_write_archive_contents _bfd_write_archive_contents
#endif
#ifndef bfd_elfNN_mkarchive
#define bfd_elfNN_mkarchive _bfd_generic_mkarchive
#endif
#ifndef elf_symbol_leading_char
#define elf_symbol_leading_char 0
#endif
@ -340,28 +357,32 @@ const bfd_target TARGET_BIG_SYM =
/* bfd_check_format: check the format of a file being read */
{ _bfd_dummy_target, /* unknown format */
bfd_elfNN_object_p, /* assembler/linker output (object file) */
bfd_generic_archive_p, /* an archive */
bfd_elfNN_archive_p, /* an archive */
bfd_elfNN_core_file_p /* a core file */
},
/* bfd_set_format: set the format of a file being written */
{ bfd_false,
bfd_elf_mkobject,
_bfd_generic_mkarchive,
bfd_elfNN_mkarchive,
bfd_false
},
/* bfd_write_contents: write cached information into a file being written */
{ bfd_false,
bfd_elfNN_write_object_contents,
_bfd_write_archive_contents,
bfd_elfNN_write_archive_contents,
bfd_false
},
BFD_JUMP_TABLE_GENERIC (bfd_elfNN),
BFD_JUMP_TABLE_COPY (bfd_elfNN),
BFD_JUMP_TABLE_CORE (bfd_elfNN),
#ifdef bfd_elfNN_archive_functions
BFD_JUMP_TABLE_ARCHIVE (bfd_elfNN_archive),
#else
BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
#endif
BFD_JUMP_TABLE_SYMBOLS (bfd_elfNN),
BFD_JUMP_TABLE_RELOCS (bfd_elfNN),
BFD_JUMP_TABLE_WRITE (bfd_elfNN),
@ -424,28 +445,32 @@ const bfd_target TARGET_LITTLE_SYM =
/* bfd_check_format: check the format of a file being read */
{ _bfd_dummy_target, /* unknown format */
bfd_elfNN_object_p, /* assembler/linker output (object file) */
bfd_generic_archive_p, /* an archive */
bfd_elfNN_archive_p, /* an archive */
bfd_elfNN_core_file_p /* a core file */
},
/* bfd_set_format: set the format of a file being written */
{ bfd_false,
bfd_elf_mkobject,
_bfd_generic_mkarchive,
bfd_elfNN_mkarchive,
bfd_false
},
/* bfd_write_contents: write cached information into a file being written */
{ bfd_false,
bfd_elfNN_write_object_contents,
_bfd_write_archive_contents,
bfd_elfNN_write_archive_contents,
bfd_false
},
BFD_JUMP_TABLE_GENERIC (bfd_elfNN),
BFD_JUMP_TABLE_COPY (bfd_elfNN),
BFD_JUMP_TABLE_CORE (bfd_elfNN),
#ifdef bfd_elfNN_archive_functions
BFD_JUMP_TABLE_ARCHIVE (bfd_elfNN_archive),
#else
BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
#endif
BFD_JUMP_TABLE_SYMBOLS (bfd_elfNN),
BFD_JUMP_TABLE_RELOCS (bfd_elfNN),
BFD_JUMP_TABLE_WRITE (bfd_elfNN),