* 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:
parent
d31b72a314
commit
e35765a9a2
|
@ -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
|
||||
|
|
|
@ -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_ */
|
||||
|
|
86
bfd/elf.c
86
bfd/elf.c
|
@ -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;
|
||||
|
|
286
bfd/elf64-mips.c
286
bfd/elf64-mips.c
|
@ -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"
|
||||
|
|
180
bfd/elfcode.h
180
bfd/elfcode.h
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Reference in New Issue