From 9d3f1c3a6777e560a4eec507fb98e8e726c2f346 Mon Sep 17 00:00:00 2001 From: Thiemo Seufer Date: Wed, 5 Dec 2001 22:46:21 +0000 Subject: * 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. --- bfd/ChangeLog | 18 ++++ bfd/Makefile.am | 20 +++-- bfd/archive.c | 7 +- bfd/archive64.c | 245 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ bfd/config.bfd | 12 ++- bfd/configure.in | 3 + bfd/elf64-mips.c | 224 ++------------------------------------------------ 7 files changed, 299 insertions(+), 230 deletions(-) create mode 100644 bfd/archive64.c diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5fd2dcdc47f..908afe9efbf 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,21 @@ +2001-12-05 Thiemo Seufer + + * 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 * config.bfd: Remove trailing blanks. diff --git a/bfd/Makefile.am b/bfd/Makefile.am index b6753685fae..62ba358bc15 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -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 diff --git a/bfd/archive.c b/bfd/archive.c index 04be6a90326..fc2ba4572c3 100644 --- a/bfd/archive.c +++ b/bfd/archive.c @@ -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; diff --git a/bfd/archive64.c b/bfd/archive64.c new file mode 100644 index 00000000000..ea94c6ae86e --- /dev/null +++ b/bfd/archive64.c @@ -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. + + +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; +} diff --git a/bfd/config.bfd b/bfd/config.bfd index 48beacf2e0f..62ddd75c72e 100644 --- a/bfd/config.bfd +++ b/bfd/config.bfd @@ -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" diff --git a/bfd/configure.in b/bfd/configure.in index b13b0d2f9a5..19242fd1204 100644 --- a/bfd/configure.in +++ b/bfd/configure.in @@ -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) diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c index 313c4ab6b2b..41ea9478bec 100644 --- a/bfd/elf64-mips.c +++ b/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 -- cgit v1.2.1