* Makefile.am: split up BFD_LIBS like statements in BFD32_LIBS and
BFD64_LIBS, make the latter depending on the availability of BFD64. Add archive64.c source file. * archive64.c: New file implementing bfd_elf64_archive_slurp_armap and bfd_elf64_archive_write_armap, code from elf64-mips.c * archive.c (bfd_slurp_armap): Add ELF64 archive support. * config.bfd (mips*-*-irix6*): Allow with BFD64 only. (mips64*el-*-linux*): Likewise. (mips*el-*-linux*): Likewise. Reorder entries. * configure.in (bfd_libs): Define in dependency of BFD64 and AC_SUBST it. * elf64-mips.c (mips_elf64_slurp_armap): Remove, use bfd_elf64_archive_slurp_armap instead. (mips_elf64_write_armap): Remove, use bfd_elf64_archive_write_armap instead.
This commit is contained in:
parent
09227b3ec8
commit
36b4548250
@ -1,3 +1,21 @@
|
||||
2001-12-05 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
|
||||
|
||||
* Makefile.am: split up BFD_LIBS like statements in BFD32_LIBS and
|
||||
BFD64_LIBS, make the latter depending on the availability of BFD64.
|
||||
Add archive64.c source file.
|
||||
* archive64.c: New file implementing bfd_elf64_archive_slurp_armap
|
||||
and bfd_elf64_archive_write_armap, code from elf64-mips.c
|
||||
* archive.c (bfd_slurp_armap): Add ELF64 archive support.
|
||||
* config.bfd (mips*-*-irix6*): Allow with BFD64 only.
|
||||
(mips64*el-*-linux*): Likewise.
|
||||
(mips*el-*-linux*): Likewise. Reorder entries.
|
||||
* configure.in (bfd_libs): Define in dependency of BFD64 and
|
||||
AC_SUBST it.
|
||||
* elf64-mips.c (mips_elf64_slurp_armap): Remove, use
|
||||
bfd_elf64_archive_slurp_armap instead.
|
||||
(mips_elf64_write_armap): Remove, use bfd_elf64_archive_write_armap
|
||||
instead.
|
||||
|
||||
2001-12-04 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
|
||||
|
||||
* config.bfd: Remove trailing blanks.
|
||||
|
@ -25,20 +25,24 @@ BFD_H = bfd.h
|
||||
# for the debugger, so if you are downloading things as S-records you
|
||||
# need two copies of the executable, one to download and one for the
|
||||
# debugger).
|
||||
BFD_LIBS = \
|
||||
BFD32_LIBS = \
|
||||
archive.lo archures.lo bfd.lo cache.lo coffgen.lo corefile.lo \
|
||||
format.lo init.lo libbfd.lo opncls.lo reloc.lo \
|
||||
section.lo syms.lo targets.lo hash.lo linker.lo \
|
||||
srec.lo binary.lo tekhex.lo ihex.lo stabs.lo stab-syms.lo \
|
||||
merge.lo dwarf2.lo
|
||||
|
||||
BFD_LIBS_CFILES = \
|
||||
BFD64_LIBS = archive64.lo
|
||||
|
||||
BFD32_LIBS_CFILES = \
|
||||
archive.c archures.c bfd.c cache.c coffgen.c corefile.c \
|
||||
format.c init.c libbfd.c opncls.c reloc.c \
|
||||
section.c syms.c targets.c hash.c linker.c \
|
||||
srec.c binary.c tekhex.c ihex.c stabs.c stab-syms.c \
|
||||
merge.c dwarf2.c
|
||||
|
||||
BFD64_LIBS_CFILES = archive64.c
|
||||
|
||||
# This list is alphabetized to make it easier to keep in sync
|
||||
# with the decls and initializer in archures.c.
|
||||
ALL_MACHINES = \
|
||||
@ -486,6 +490,7 @@ OPTIONAL_BACKENDS_CFILES = \
|
||||
WORDSIZE = @wordsize@
|
||||
ALL_BACKENDS = @all_backends@
|
||||
BFD_BACKENDS = @bfd_backends@
|
||||
BFD_LIBS = @bfd_libs@
|
||||
BFD_MACHINES = @bfd_machines@
|
||||
TDEFAULTS = @tdefaults@
|
||||
|
||||
@ -493,7 +498,8 @@ INCLUDES = -D_GNU_SOURCE @HDEFINES@ @COREFLAG@ @TDEFINES@ $(CSEARCH) $(CSWITCHES
|
||||
|
||||
# C source files that correspond to .o's.
|
||||
SOURCE_CFILES = \
|
||||
$(BFD_LIBS_CFILES) \
|
||||
$(BFD32_LIBS_CFILES) \
|
||||
$(BFD64_LIBS_CFILES) \
|
||||
$(ALL_MACHINES_CFILES) \
|
||||
$(BFD32_BACKENDS_CFILES) \
|
||||
$(BFD64_BACKENDS_CFILES) \
|
||||
@ -564,7 +570,7 @@ stamp-ofiles: Makefile
|
||||
|
||||
ofiles: stamp-ofiles ; @true
|
||||
|
||||
libbfd_la_SOURCES = $(BFD_LIBS_CFILES)
|
||||
libbfd_la_SOURCES = $(BFD32_LIBS_CFILES) $(BFD64_LIBS_CFILES)
|
||||
libbfd_la_DEPENDENCIES = $(OFILES) ofiles
|
||||
libbfd_la_LIBADD = `cat ofiles` @WIN32LIBADD@
|
||||
libbfd_la_LDFLAGS = -release $(VERSION) @WIN32LDFLAGS@
|
||||
@ -637,7 +643,8 @@ pepigen.c : peXXigen.c
|
||||
|
||||
BFD_H_DEPS= $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h
|
||||
LOCAL_H_DEPS= libbfd.h sysdep.h config.h
|
||||
$(BFD_LIBS) \
|
||||
$(BFD32_LIBS) \
|
||||
$(BFD64_LIBS) \
|
||||
$(ALL_MACHINES) \
|
||||
$(BFD32_BACKENDS) \
|
||||
$(BFD64_BACKENDS) \
|
||||
@ -713,6 +720,7 @@ stmp-bfd-h: bfd-in3.h
|
||||
|
||||
BFD_H_FILES = bfd-in.h init.c opncls.c libbfd.c section.c archures.c \
|
||||
reloc.c syms.c bfd.c archive.c corefile.c targets.c format.c version.h
|
||||
BFD64_H_FILES = archive64.c
|
||||
LIBBFD_H_FILES = libbfd-in.h init.c libbfd.c cache.c reloc.c archures.c elf.c
|
||||
LIBCOFF_H_FILES = libcoff-in.h coffcode.h
|
||||
|
||||
@ -730,7 +738,7 @@ headers:
|
||||
# configured with --enable-maintainer-mode.
|
||||
|
||||
$(srcdir)/bfd-in2.h: @MAINT@ stmp-bin2-h ; @true
|
||||
stmp-bin2-h: $(BFD_H_FILES)
|
||||
stmp-bin2-h: $(BFD_H_FILES) $(BFD64_H_FILES)
|
||||
(cd $(docdir); $(MAKE) $(FLAGS_TO_PASS) bfd.h)
|
||||
cp $(docdir)/bfd.h bfd-in2.h-new
|
||||
$(SHELL) $(srcdir)/../move-if-change bfd-in2.h-new $(srcdir)/bfd-in2.h
|
||||
|
@ -164,6 +164,7 @@ static char *get_extended_arelt_filename PARAMS ((bfd *arch,
|
||||
const char *name));
|
||||
static boolean do_slurp_bsd_armap PARAMS ((bfd *abfd));
|
||||
static boolean do_slurp_coff_armap PARAMS ((bfd *abfd));
|
||||
boolean bfd_elf64_archive_slurp_armap PARAMS ((bfd *abfd));
|
||||
static const char *normalize PARAMS ((bfd *, const char *file));
|
||||
static struct areltdata *bfd_ar_hdr_from_filesystem PARAMS ((bfd *abfd,
|
||||
const char *,
|
||||
@ -934,9 +935,13 @@ bfd_slurp_armap (abfd)
|
||||
return do_slurp_coff_armap (abfd);
|
||||
else if (!strncmp (nextname, "/SYM64/ ", 16))
|
||||
{
|
||||
/* Irix 6 archive--must be recognized by code in elf64-mips.c. */
|
||||
/* 64bit ELF (Irix 6) archive. */
|
||||
#ifdef BFD64
|
||||
return bfd_elf64_archive_slurp_armap (abfd);
|
||||
#else
|
||||
bfd_set_error (bfd_error_wrong_format);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bfd_has_map (abfd) = false;
|
||||
|
245
bfd/archive64.c
Normal file
245
bfd/archive64.c
Normal file
@ -0,0 +1,245 @@
|
||||
/* MIPS-specific support for 64-bit ELF
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001
|
||||
Free Software Foundation, Inc.
|
||||
Ian Lance Taylor, Cygnus Support
|
||||
Linker support added by Mark Mitchell, CodeSourcery, LLC.
|
||||
<mark@codesourcery.com>
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* This file supports the 64-bit (MIPS) ELF archives. */
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
#include "aout/ar.h"
|
||||
|
||||
/* Irix 6 defines a 64bit archive map format, so that they can
|
||||
have archives more than 4 GB in size. */
|
||||
|
||||
boolean bfd_elf64_archive_slurp_armap PARAMS ((bfd *));
|
||||
boolean bfd_elf64_archive_write_armap
|
||||
PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
|
||||
|
||||
/* Read an Irix 6 armap. */
|
||||
|
||||
boolean
|
||||
bfd_elf64_archive_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;
|
||||
bfd_size_type amt;
|
||||
|
||||
ardata->symdefs = NULL;
|
||||
|
||||
/* Get the name of the first element. */
|
||||
arhdrpos = bfd_tell (abfd);
|
||||
i = bfd_bread ((PTR) nextname, (bfd_size_type) 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_bread (int_buf, (bfd_size_type) 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;
|
||||
|
||||
amt = carsym_size + stringsize + 1;
|
||||
ardata->symdefs = (carsym *) bfd_zalloc (abfd, amt);
|
||||
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 release_symdefs;
|
||||
|
||||
if (bfd_bread (raw_armap, ptrsize, abfd) != ptrsize
|
||||
|| bfd_bread (stringbase, stringsize, abfd) != stringsize)
|
||||
{
|
||||
if (bfd_get_error () != bfd_error_system_call)
|
||||
bfd_set_error (bfd_error_malformed_archive);
|
||||
goto release_raw_armap;
|
||||
}
|
||||
|
||||
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 = bfd_tell (abfd);
|
||||
/* Pad to an even boundary if you have to. */
|
||||
ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
|
||||
|
||||
bfd_has_map (abfd) = true;
|
||||
bfd_release (abfd, raw_armap);
|
||||
|
||||
return true;
|
||||
|
||||
release_raw_armap:
|
||||
bfd_release (abfd, raw_armap);
|
||||
release_symdefs:
|
||||
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. */
|
||||
|
||||
boolean
|
||||
bfd_elf64_archive_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_bwrite ((PTR) &hdr, (bfd_size_type) sizeof (struct ar_hdr), arch)
|
||||
!= sizeof (struct ar_hdr))
|
||||
return false;
|
||||
|
||||
bfd_putb64 ((bfd_vma) symbol_count, buf);
|
||||
if (bfd_bwrite (buf, (bfd_size_type) 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 (map[count].u.abfd == current)
|
||||
{
|
||||
bfd_putb64 ((bfd_vma) archive_member_file_ptr, buf);
|
||||
if (bfd_bwrite (buf, (bfd_size_type) 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_bwrite (*map[count].name, (bfd_size_type) 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_bwrite ("", (bfd_size_type) 1, arch) != 1)
|
||||
return false;
|
||||
--padding;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
@ -642,10 +642,12 @@ case "${targ}" in
|
||||
targ_defvec=ecoff_big_vec
|
||||
targ_selvecs=ecoff_little_vec
|
||||
;;
|
||||
#ifdef BFD64
|
||||
mips*-*-irix6*)
|
||||
targ_defvec=bfd_elf32_bigmips_vec
|
||||
targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec"
|
||||
;;
|
||||
#endif
|
||||
mips*-*-irix5*)
|
||||
targ_defvec=bfd_elf32_bigmips_vec
|
||||
targ_selvecs="bfd_elf32_littlemips_vec ecoff_big_vec ecoff_little_vec"
|
||||
@ -695,18 +697,20 @@ case "${targ}" in
|
||||
targ_defvec=bfd_elf32_bigmips_vec
|
||||
targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec ecoff_big_vec ecoff_little_vec"
|
||||
;;
|
||||
#ifdef BFD64
|
||||
mips64*el-*-linux*)
|
||||
targ_defvec=bfd_elf32_tradlittlemips_vec
|
||||
targ_selvecs="bfd_elf32_tradbigmips_vec bfd_elf64_tradlittlemips_vec bfd_elf64_tradbigmips_vec"
|
||||
;;
|
||||
mips*el-*-linux*)
|
||||
targ_defvec=bfd_elf32_tradlittlemips_vec
|
||||
targ_selvecs="bfd_elf32_tradbigmips_vec bfd_elf64_tradlittlemips_vec bfd_elf64_tradbigmips_vec ecoff_little_vec ecoff_big_vec"
|
||||
;;
|
||||
mips64*-*-linux*)
|
||||
targ_defvec=bfd_elf32_tradbigmips_vec
|
||||
targ_selvecs="bfd_elf32_tradlittlemips_vec bfd_elf64_tradbigmips_vec bfd_elf64_tradlittlemips_vec"
|
||||
;;
|
||||
#endif
|
||||
mips*el-*-linux*)
|
||||
targ_defvec=bfd_elf32_tradlittlemips_vec
|
||||
targ_selvecs="bfd_elf32_tradbigmips_vec bfd_elf64_tradlittlemips_vec bfd_elf64_tradbigmips_vec ecoff_little_vec ecoff_big_vec"
|
||||
;;
|
||||
mips*-*-linux*)
|
||||
targ_defvec=bfd_elf32_tradbigmips_vec
|
||||
targ_selvecs="bfd_elf32_tradlittlemips_vec bfd_elf64_tradbigmips_vec bfd_elf64_tradlittlemips_vec ecoff_big_vec ecoff_little_vec"
|
||||
|
@ -761,6 +761,7 @@ fi # all_targets is true
|
||||
case ${host64}-${target64}-${want64} in
|
||||
*true*)
|
||||
wordsize=64
|
||||
bfd_libs='$(BFD64_LIBS) $(BFD32_LIBS)'
|
||||
all_backends='$(BFD64_BACKENDS) $(BFD32_BACKENDS)'
|
||||
if test -z "$GCC" && test "$BFD_HOST_64BIT_LONG" = "0" && test "$BFD_HOST_64_BIT_DEFINED" = "0"; then
|
||||
AC_MSG_WARN([You have requested a 64 bit BFD configuration, but])
|
||||
@ -769,11 +770,13 @@ case ${host64}-${target64}-${want64} in
|
||||
;;
|
||||
false-false-false)
|
||||
wordsize=32
|
||||
bfd_libs='$(BFD32_LIBS)'
|
||||
all_backends='$(BFD32_BACKENDS)'
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(wordsize)
|
||||
AC_SUBST(bfd_libs)
|
||||
AC_SUBST(all_backends)
|
||||
AC_SUBST(bfd_backends)
|
||||
AC_SUBST(bfd_machines)
|
||||
|
224
bfd/elf64-mips.c
224
bfd/elf64-mips.c
@ -25,9 +25,7 @@ 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.
|
||||
|
||||
The MIPS 64-bit ELF ABI also uses an unusual archive map format. */
|
||||
writing the relocations here. */
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
@ -77,9 +75,6 @@ static boolean mips_elf64_slurp_one_reloc_table
|
||||
static boolean mips_elf64_slurp_reloc_table
|
||||
PARAMS ((bfd *, asection *, asymbol **, boolean));
|
||||
static void mips_elf64_write_relocs PARAMS ((bfd *, asection *, PTR));
|
||||
static boolean mips_elf64_slurp_armap PARAMS ((bfd *));
|
||||
static boolean mips_elf64_write_armap
|
||||
PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
|
||||
|
||||
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
|
||||
from smaller values. Start with zero, widen, *then* decrement. */
|
||||
@ -1768,217 +1763,6 @@ mips_elf64_write_relocs (abfd, sec, data)
|
||||
== (int) count);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
bfd_size_type amt;
|
||||
|
||||
ardata->symdefs = NULL;
|
||||
|
||||
/* Get the name of the first element. */
|
||||
arhdrpos = bfd_tell (abfd);
|
||||
i = bfd_bread ((PTR) nextname, (bfd_size_type) 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_bread (int_buf, (bfd_size_type) 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;
|
||||
|
||||
amt = carsym_size + stringsize + 1;
|
||||
ardata->symdefs = (carsym *) bfd_zalloc (abfd, amt);
|
||||
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_bread (raw_armap, ptrsize, abfd) != ptrsize
|
||||
|| bfd_bread (stringbase, 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_bwrite ((PTR) &hdr, (bfd_size_type) sizeof (struct ar_hdr), arch)
|
||||
!= sizeof (struct ar_hdr))
|
||||
return false;
|
||||
|
||||
bfd_putb64 ((bfd_vma) symbol_count, buf);
|
||||
if (bfd_bwrite (buf, (bfd_size_type) 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 (map[count].u.abfd == current)
|
||||
{
|
||||
bfd_putb64 ((bfd_vma) archive_member_file_ptr, buf);
|
||||
if (bfd_bwrite (buf, (bfd_size_type) 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_bwrite (*map[count].name, (bfd_size_type) 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_bwrite ("", (bfd_size_type) 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 =
|
||||
@ -2129,14 +1913,16 @@ const struct elf_size_info mips_elf64_size_info =
|
||||
#define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
|
||||
#define bfd_elf64_bfd_reloc_type_lookup mips_elf64_reloc_type_lookup
|
||||
#define bfd_elf64_archive_functions
|
||||
#define bfd_elf64_archive_slurp_armap mips_elf64_slurp_armap
|
||||
extern boolean bfd_elf64_archive_slurp_armap
|
||||
PARAMS((bfd *));
|
||||
extern boolean bfd_elf64_archive_write_armap
|
||||
PARAMS((bfd *, unsigned int, struct orl *, unsigned int, int));
|
||||
#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
|
||||
|
Loading…
Reference in New Issue
Block a user