* 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:
Thiemo Seufer 2001-12-05 22:46:21 +00:00
parent 09227b3ec8
commit 36b4548250
7 changed files with 299 additions and 230 deletions

View file

@ -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> 2001-12-04 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
* config.bfd: Remove trailing blanks. * config.bfd: Remove trailing blanks.

View file

@ -25,20 +25,24 @@ BFD_H = bfd.h
# for the debugger, so if you are downloading things as S-records you # 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 # need two copies of the executable, one to download and one for the
# debugger). # debugger).
BFD_LIBS = \ BFD32_LIBS = \
archive.lo archures.lo bfd.lo cache.lo coffgen.lo corefile.lo \ archive.lo archures.lo bfd.lo cache.lo coffgen.lo corefile.lo \
format.lo init.lo libbfd.lo opncls.lo reloc.lo \ format.lo init.lo libbfd.lo opncls.lo reloc.lo \
section.lo syms.lo targets.lo hash.lo linker.lo \ section.lo syms.lo targets.lo hash.lo linker.lo \
srec.lo binary.lo tekhex.lo ihex.lo stabs.lo stab-syms.lo \ srec.lo binary.lo tekhex.lo ihex.lo stabs.lo stab-syms.lo \
merge.lo dwarf2.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 \ archive.c archures.c bfd.c cache.c coffgen.c corefile.c \
format.c init.c libbfd.c opncls.c reloc.c \ format.c init.c libbfd.c opncls.c reloc.c \
section.c syms.c targets.c hash.c linker.c \ section.c syms.c targets.c hash.c linker.c \
srec.c binary.c tekhex.c ihex.c stabs.c stab-syms.c \ srec.c binary.c tekhex.c ihex.c stabs.c stab-syms.c \
merge.c dwarf2.c merge.c dwarf2.c
BFD64_LIBS_CFILES = archive64.c
# This list is alphabetized to make it easier to keep in sync # This list is alphabetized to make it easier to keep in sync
# with the decls and initializer in archures.c. # with the decls and initializer in archures.c.
ALL_MACHINES = \ ALL_MACHINES = \
@ -486,6 +490,7 @@ OPTIONAL_BACKENDS_CFILES = \
WORDSIZE = @wordsize@ WORDSIZE = @wordsize@
ALL_BACKENDS = @all_backends@ ALL_BACKENDS = @all_backends@
BFD_BACKENDS = @bfd_backends@ BFD_BACKENDS = @bfd_backends@
BFD_LIBS = @bfd_libs@
BFD_MACHINES = @bfd_machines@ BFD_MACHINES = @bfd_machines@
TDEFAULTS = @tdefaults@ TDEFAULTS = @tdefaults@
@ -493,7 +498,8 @@ INCLUDES = -D_GNU_SOURCE @HDEFINES@ @COREFLAG@ @TDEFINES@ $(CSEARCH) $(CSWITCHES
# C source files that correspond to .o's. # C source files that correspond to .o's.
SOURCE_CFILES = \ SOURCE_CFILES = \
$(BFD_LIBS_CFILES) \ $(BFD32_LIBS_CFILES) \
$(BFD64_LIBS_CFILES) \
$(ALL_MACHINES_CFILES) \ $(ALL_MACHINES_CFILES) \
$(BFD32_BACKENDS_CFILES) \ $(BFD32_BACKENDS_CFILES) \
$(BFD64_BACKENDS_CFILES) \ $(BFD64_BACKENDS_CFILES) \
@ -564,7 +570,7 @@ stamp-ofiles: Makefile
ofiles: stamp-ofiles ; @true 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_DEPENDENCIES = $(OFILES) ofiles
libbfd_la_LIBADD = `cat ofiles` @WIN32LIBADD@ libbfd_la_LIBADD = `cat ofiles` @WIN32LIBADD@
libbfd_la_LDFLAGS = -release $(VERSION) @WIN32LDFLAGS@ libbfd_la_LDFLAGS = -release $(VERSION) @WIN32LDFLAGS@
@ -637,7 +643,8 @@ pepigen.c : peXXigen.c
BFD_H_DEPS= $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h BFD_H_DEPS= $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h
LOCAL_H_DEPS= libbfd.h sysdep.h config.h LOCAL_H_DEPS= libbfd.h sysdep.h config.h
$(BFD_LIBS) \ $(BFD32_LIBS) \
$(BFD64_LIBS) \
$(ALL_MACHINES) \ $(ALL_MACHINES) \
$(BFD32_BACKENDS) \ $(BFD32_BACKENDS) \
$(BFD64_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 \ 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 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 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 LIBCOFF_H_FILES = libcoff-in.h coffcode.h
@ -730,7 +738,7 @@ headers:
# configured with --enable-maintainer-mode. # configured with --enable-maintainer-mode.
$(srcdir)/bfd-in2.h: @MAINT@ stmp-bin2-h ; @true $(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) (cd $(docdir); $(MAKE) $(FLAGS_TO_PASS) bfd.h)
cp $(docdir)/bfd.h bfd-in2.h-new cp $(docdir)/bfd.h bfd-in2.h-new
$(SHELL) $(srcdir)/../move-if-change bfd-in2.h-new $(srcdir)/bfd-in2.h $(SHELL) $(srcdir)/../move-if-change bfd-in2.h-new $(srcdir)/bfd-in2.h

View file

@ -164,6 +164,7 @@ static char *get_extended_arelt_filename PARAMS ((bfd *arch,
const char *name)); const char *name));
static boolean do_slurp_bsd_armap PARAMS ((bfd *abfd)); static boolean do_slurp_bsd_armap PARAMS ((bfd *abfd));
static boolean do_slurp_coff_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 const char *normalize PARAMS ((bfd *, const char *file));
static struct areltdata *bfd_ar_hdr_from_filesystem PARAMS ((bfd *abfd, static struct areltdata *bfd_ar_hdr_from_filesystem PARAMS ((bfd *abfd,
const char *, const char *,
@ -934,9 +935,13 @@ bfd_slurp_armap (abfd)
return do_slurp_coff_armap (abfd); return do_slurp_coff_armap (abfd);
else if (!strncmp (nextname, "/SYM64/ ", 16)) 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); bfd_set_error (bfd_error_wrong_format);
return false; return false;
#endif
} }
bfd_has_map (abfd) = false; bfd_has_map (abfd) = false;

245
bfd/archive64.c Normal file
View 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;
}

View file

@ -642,10 +642,12 @@ case "${targ}" in
targ_defvec=ecoff_big_vec targ_defvec=ecoff_big_vec
targ_selvecs=ecoff_little_vec targ_selvecs=ecoff_little_vec
;; ;;
#ifdef BFD64
mips*-*-irix6*) mips*-*-irix6*)
targ_defvec=bfd_elf32_bigmips_vec targ_defvec=bfd_elf32_bigmips_vec
targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec" targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec"
;; ;;
#endif
mips*-*-irix5*) mips*-*-irix5*)
targ_defvec=bfd_elf32_bigmips_vec targ_defvec=bfd_elf32_bigmips_vec
targ_selvecs="bfd_elf32_littlemips_vec ecoff_big_vec ecoff_little_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_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" 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*) mips64*el-*-linux*)
targ_defvec=bfd_elf32_tradlittlemips_vec targ_defvec=bfd_elf32_tradlittlemips_vec
targ_selvecs="bfd_elf32_tradbigmips_vec bfd_elf64_tradlittlemips_vec bfd_elf64_tradbigmips_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*) mips64*-*-linux*)
targ_defvec=bfd_elf32_tradbigmips_vec targ_defvec=bfd_elf32_tradbigmips_vec
targ_selvecs="bfd_elf32_tradlittlemips_vec bfd_elf64_tradbigmips_vec bfd_elf64_tradlittlemips_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*) mips*-*-linux*)
targ_defvec=bfd_elf32_tradbigmips_vec 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" targ_selvecs="bfd_elf32_tradlittlemips_vec bfd_elf64_tradbigmips_vec bfd_elf64_tradlittlemips_vec ecoff_big_vec ecoff_little_vec"

View file

@ -761,6 +761,7 @@ fi # all_targets is true
case ${host64}-${target64}-${want64} in case ${host64}-${target64}-${want64} in
*true*) *true*)
wordsize=64 wordsize=64
bfd_libs='$(BFD64_LIBS) $(BFD32_LIBS)'
all_backends='$(BFD64_BACKENDS) $(BFD32_BACKENDS)' all_backends='$(BFD64_BACKENDS) $(BFD32_BACKENDS)'
if test -z "$GCC" && test "$BFD_HOST_64BIT_LONG" = "0" && test "$BFD_HOST_64_BIT_DEFINED" = "0"; then 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]) AC_MSG_WARN([You have requested a 64 bit BFD configuration, but])
@ -769,11 +770,13 @@ case ${host64}-${target64}-${want64} in
;; ;;
false-false-false) false-false-false)
wordsize=32 wordsize=32
bfd_libs='$(BFD32_LIBS)'
all_backends='$(BFD32_BACKENDS)' all_backends='$(BFD32_BACKENDS)'
;; ;;
esac esac
AC_SUBST(wordsize) AC_SUBST(wordsize)
AC_SUBST(bfd_libs)
AC_SUBST(all_backends) AC_SUBST(all_backends)
AC_SUBST(bfd_backends) AC_SUBST(bfd_backends)
AC_SUBST(bfd_machines) AC_SUBST(bfd_machines)

View file

@ -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 The MIPS 64-bit ELF ABI uses an unusual reloc format. This file
overrides the usual ELF reloc handling, and handles reading and 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 "bfd.h"
#include "sysdep.h" #include "sysdep.h"
@ -77,9 +75,6 @@ static boolean mips_elf64_slurp_one_reloc_table
static boolean mips_elf64_slurp_reloc_table static boolean mips_elf64_slurp_reloc_table
PARAMS ((bfd *, asection *, asymbol **, boolean)); PARAMS ((bfd *, asection *, asymbol **, boolean));
static void mips_elf64_write_relocs PARAMS ((bfd *, asection *, PTR)); 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 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
from smaller values. Start with zero, widen, *then* decrement. */ from smaller values. Start with zero, widen, *then* decrement. */
@ -1768,217 +1763,6 @@ mips_elf64_write_relocs (abfd, sec, data)
== (int) count); == (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 /* ECOFF swapping routines. These are used when dealing with the
.mdebug section, which is in the ECOFF debugging format. */ .mdebug section, which is in the ECOFF debugging format. */
static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap = 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_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_bfd_reloc_type_lookup mips_elf64_reloc_type_lookup
#define bfd_elf64_archive_functions #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 \ #define bfd_elf64_archive_slurp_extended_name_table \
_bfd_archive_coff_slurp_extended_name_table _bfd_archive_coff_slurp_extended_name_table
#define bfd_elf64_archive_construct_extended_name_table \ #define bfd_elf64_archive_construct_extended_name_table \
_bfd_archive_coff_construct_extended_name_table _bfd_archive_coff_construct_extended_name_table
#define bfd_elf64_archive_truncate_arname \ #define bfd_elf64_archive_truncate_arname \
_bfd_archive_coff_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_read_ar_hdr _bfd_archive_coff_read_ar_hdr
#define bfd_elf64_archive_openr_next_archived_file \ #define bfd_elf64_archive_openr_next_archived_file \
_bfd_archive_coff_openr_next_archived_file _bfd_archive_coff_openr_next_archived_file