diff options
author | bde <bde@FreeBSD.org> | 1997-06-29 18:06:40 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1997-06-29 18:06:40 +0000 |
commit | 7965a88eb164a6fb02af818f73a4ccf054c51c7a (patch) | |
tree | 7273b38989f36249e4f73f92436f7c4824981ba4 | |
parent | b80172dfce576f6c2038cd44127d9c3ddaab9cb7 (diff) | |
download | FreeBSD-src-7965a88eb164a6fb02af818f73a4ccf054c51c7a.zip FreeBSD-src-7965a88eb164a6fb02af818f73a4ccf054c51c7a.tar.gz |
Removed unused files (about 8MB total).
148 files changed, 0 insertions, 92337 deletions
diff --git a/contrib/gdb/bfd/acconfig.h b/contrib/gdb/bfd/acconfig.h deleted file mode 100644 index 647798c..0000000 --- a/contrib/gdb/bfd/acconfig.h +++ /dev/null @@ -1,19 +0,0 @@ - -/* Whether malloc must be declared even if <stdlib.h> is included. */ -#undef NEED_DECLARATION_MALLOC - -/* Whether free must be declared even if <stdlib.h> is included. */ -#undef NEED_DECLARATION_FREE -@TOP@ - -/* Do we need to use the b modifier when opening binary files? */ -#undef USE_BINARY_FOPEN - -/* Name of host specific header file to include in trad-core.c. */ -#undef TRAD_HEADER - -/* Define only if <sys/procfs.h> is available *and* it defines prstatus_t. */ -#undef HAVE_SYS_PROCFS_H - -/* Do we really want to use mmap if it's available? */ -#undef USE_MMAP diff --git a/contrib/gdb/bfd/aix386-core.c b/contrib/gdb/bfd/aix386-core.c deleted file mode 100644 index 21ec9a6..0000000 --- a/contrib/gdb/bfd/aix386-core.c +++ /dev/null @@ -1,285 +0,0 @@ -/* BFD back-end for AIX on PS/2 core files. - This was based on trad-core.c, which was written by John Gilmore of - Cygnus Support. - Copyright 1988, 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Minh Tran-Le <TRANLE@INTELLICORP.COM>. - Converted to back end form by Ian Lance Taylor <ian@cygnus.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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/i386.h" -#include "coff/internal.h" -#include "libcoff.h" - -#include <stdio.h> -#include <stddef.h> -#include <signal.h> - -#include <errno.h> - -#if defined (_AIX) && defined (_I386) -#define NOCHECKS /* this is for coredump.h */ -#define _h_USER /* avoid including user.h from coredump.h */ -#include <uinfo.h> -#include <sys/i386/coredump.h> -#endif /* _AIX && _I386 */ - -/* maybe this could work on some other i386 but I have not tried it - * mtranle@paris - Tue Sep 24 12:49:35 1991 - */ - -#ifndef COR_MAGIC -# define COR_MAGIC "core" -#endif - -/* need this cast because ptr is really void * */ -#define core_hdr(bfd) \ - (((bfd->tdata.trad_core_data))->hdr) -#define core_section(bfd,n) \ - (((bfd)->tdata.trad_core_data)->sections[n]) -#define core_regsec(bfd) \ - (((bfd)->tdata.trad_core_data)->reg_section) -#define core_reg2sec(bfd) \ - (((bfd)->tdata.trad_core_data)->reg2_section) - -/* These are stored in the bfd's tdata */ -struct trad_core_struct { - struct corehdr *hdr; /* core file header */ - asection *reg_section; - asection *reg2_section; - asection *sections[MAX_CORE_SEGS]; -}; - -static const bfd_target * -aix386_core_file_p (abfd) - bfd *abfd; -{ - int i,n; - unsigned char longbuf[4]; /* Raw bytes of various header fields */ - int core_size = sizeof (struct corehdr); - struct corehdr *core; - struct mergem { - struct trad_core_struct coredata; - struct corehdr internal_core; - } *mergem; - - if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) != sizeof (longbuf)) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - if (strncmp(longbuf,COR_MAGIC,4)) return 0; - - if (bfd_seek (abfd, 0L, false) < 0) return 0; - - mergem = (struct mergem *)bfd_zalloc (abfd, sizeof (struct mergem)); - if (mergem == NULL) - return 0; - - core = &mergem->internal_core; - - if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - bfd_release (abfd, (char *)mergem); - return 0; - } - - set_tdata (abfd, &mergem->coredata); - core_hdr (abfd) = core; - - /* create the sections. This is raunchy, but bfd_close wants to reclaim - them */ - core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_regsec (abfd) == NULL) - { - loser: - bfd_release (abfd, (char *)mergem); - return 0; - } - core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_reg2sec (abfd) == NULL) - { - loser1: - bfd_release (abfd, core_regsec (abfd)); - goto loser; - } - - for (i=0, n=0 ; (i < MAX_CORE_SEGS) && (core->cd_segs[i].cs_type) ; i++) - { - if (core->cd_segs[i].cs_offset == 0) - continue; - core_section (abfd,n) = - (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_section (abfd,n) == NULL) - { - int j; - if (n > 0) - { - for (j=0; j < n; j++) - bfd_release (abfd, core_section(abfd, j)); - } - bfd_release (abfd, (char *)mergem); - goto loser1; - } - - switch (core->cd_segs[i].cs_type) - { - case COR_TYPE_DATA: - core_section (abfd, n)->name = ".data"; - core_section (abfd, n)->flags = (SEC_ALLOC + SEC_LOAD + - SEC_HAS_CONTENTS); - break; - case COR_TYPE_STACK: - core_section (abfd, n)->name = ".stack"; - core_section (abfd, n)->flags = (SEC_ALLOC + SEC_LOAD + - SEC_HAS_CONTENTS); - break; - case COR_TYPE_LIBDATA: - core_section (abfd, n)->name = ".libdata"; - core_section (abfd, n)->flags = (SEC_ALLOC + SEC_HAS_CONTENTS); - break; - case COR_TYPE_WRITE: - core_section (abfd, n)->name = ".writeable"; - core_section (abfd, n)->flags = (SEC_ALLOC + SEC_HAS_CONTENTS); - break; - case COR_TYPE_MSC: - core_section (abfd, n)->name = ".misc"; - core_section (abfd, n)->flags = (SEC_ALLOC + SEC_HAS_CONTENTS); - break; - default: - core_section (abfd, n)->name = ".unknown"; - core_section (abfd, n)->flags = (SEC_ALLOC + SEC_HAS_CONTENTS); - break; - } - core_section (abfd, n)->_raw_size = core->cd_segs[i].cs_len; - core_section (abfd, n)->vma = core->cd_segs[i].cs_address; - core_section (abfd, n)->filepos = core->cd_segs[i].cs_offset; - core_section (abfd, n)->alignment_power = 2; - core_section (abfd, n)->next = NULL; - if (n > 0) - core_section (abfd, (n-1))->next = core_section (abfd, n); - - abfd->section_count = ++n; - } - - core_regsec (abfd)->name = ".reg"; - core_reg2sec (abfd)->name = ".reg2"; - - core_regsec (abfd)->flags = SEC_HAS_CONTENTS; - core_reg2sec (abfd)->flags = SEC_HAS_CONTENTS; - - core_regsec (abfd)->_raw_size = sizeof(core->cd_regs); - core_reg2sec (abfd)->_raw_size = sizeof(core->cd_fpregs); - - core_regsec (abfd)->vma = -1; - core_reg2sec (abfd)->vma = -1; - - /* We'll access the regs afresh in the core file, like any section: */ - core_regsec (abfd)->filepos = (file_ptr)offsetof(struct corehdr,cd_regs[0]); - core_reg2sec (abfd)->filepos = (file_ptr)offsetof(struct corehdr, - cd_fpregs); - - /* add the 2 reg fake sections to abfd */ - abfd->section_count += 2; - abfd->sections = core_regsec (abfd); - core_regsec (abfd)->next = core_reg2sec (abfd); - core_reg2sec (abfd)->next = core_section (abfd, 0); - - return abfd->xvec; -} - -static char * -aix386_core_file_failing_command (abfd) - bfd *abfd; -{ - return core_hdr (abfd)->cd_comm; -} - -static int -aix386_core_file_failing_signal (abfd) - bfd *abfd; -{ - return core_hdr (abfd)->cd_cursig; -} - -static boolean -aix386_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd; - bfd *exec_bfd; -{ - return true; /* FIXME, We have no way of telling at this - point */ -} - -/* If somebody calls any byte-swapping routines, shoot them. */ -void -swap_abort() -{ - abort(); /* This way doesn't require any declaration for ANSI to fuck up */ -} -#define NO_GET ((PROTO(bfd_vma, (*), ( const bfd_byte *))) swap_abort ) -#define NO_GETS ((PROTO(bfd_signed_vma, (*), (const bfd_byte *))) swap_abort ) -#define NO_PUT ((PROTO(void, (*), (bfd_vma, bfd_byte *))) swap_abort ) - -const bfd_target aix386_core_vec = - { - "aix386-core", - bfd_target_unknown_flavour, - BFD_ENDIAN_BIG, /* target byte order */ - BFD_ENDIANG_BIG, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - NO_GET, NO_GETS, NO_PUT, - NO_GET, NO_GETS, NO_PUT, - NO_GET, NO_GETS, NO_PUT, /* data */ - NO_GET, NO_GETS, NO_PUT, - NO_GET, NO_GETS, NO_PUT, - NO_GET, NO_GETS, NO_PUT, /* hdrs */ - - {_bfd_dummy_target, _bfd_dummy_target, - _bfd_dummy_target, aix386_core_file_p}, - {bfd_false, bfd_false, /* bfd_create_object */ - bfd_false, bfd_false}, - {bfd_false, bfd_false, /* bfd_write_contents */ - bfd_false, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (aix386), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (_bfd_generic), - BFD_JUMP_TABLE_LINK (_bfd_nolink), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; diff --git a/contrib/gdb/bfd/aout-adobe.c b/contrib/gdb/bfd/aout-adobe.c deleted file mode 100644 index 36d230d..0000000 --- a/contrib/gdb/bfd/aout-adobe.c +++ /dev/null @@ -1,528 +0,0 @@ -/* BFD back-end for a.out.adobe binaries. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. Based on bout.c. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#include "aout/adobe.h" - -#include "aout/stab_gnu.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -extern const bfd_target a_out_adobe_vec; /* Forward decl */ - -static const bfd_target *aout_adobe_callback PARAMS ((bfd *)); - -extern boolean aout_32_slurp_symbol_table PARAMS ((bfd *abfd)); -extern boolean aout_32_write_syms PARAMS ((bfd *)); -static void aout_adobe_write_section PARAMS ((bfd *abfd, sec_ptr sect)); - -/* Swaps the information in an executable header taken from a raw byte - stream memory image, into the internal exec_header structure. */ - -void aout_adobe_swap_exec_header_in - PARAMS ((bfd *abfd, struct external_exec *raw_bytes, - struct internal_exec *execp)); - -void -aout_adobe_swap_exec_header_in (abfd, raw_bytes, execp) - bfd *abfd; - struct external_exec *raw_bytes; - struct internal_exec *execp; -{ - struct external_exec *bytes = (struct external_exec *)raw_bytes; - - /* Now fill in fields in the execp, from the bytes in the raw data. */ - execp->a_info = bfd_h_get_32 (abfd, bytes->e_info); - execp->a_text = GET_WORD (abfd, bytes->e_text); - execp->a_data = GET_WORD (abfd, bytes->e_data); - execp->a_bss = GET_WORD (abfd, bytes->e_bss); - execp->a_syms = GET_WORD (abfd, bytes->e_syms); - execp->a_entry = GET_WORD (abfd, bytes->e_entry); - execp->a_trsize = GET_WORD (abfd, bytes->e_trsize); - execp->a_drsize = GET_WORD (abfd, bytes->e_drsize); -} - -/* Swaps the information in an internal exec header structure into the - supplied buffer ready for writing to disk. */ - -PROTO(void, aout_adobe_swap_exec_header_out, - (bfd *abfd, - struct internal_exec *execp, - struct external_exec *raw_bytes)); -void -aout_adobe_swap_exec_header_out (abfd, execp, raw_bytes) - bfd *abfd; - struct internal_exec *execp; - struct external_exec *raw_bytes; -{ - struct external_exec *bytes = (struct external_exec *)raw_bytes; - - /* Now fill in fields in the raw data, from the fields in the exec struct. */ - bfd_h_put_32 (abfd, execp->a_info , bytes->e_info); - PUT_WORD (abfd, execp->a_text , bytes->e_text); - PUT_WORD (abfd, execp->a_data , bytes->e_data); - PUT_WORD (abfd, execp->a_bss , bytes->e_bss); - PUT_WORD (abfd, execp->a_syms , bytes->e_syms); - PUT_WORD (abfd, execp->a_entry , bytes->e_entry); - PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize); - PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize); -} - - -static const bfd_target * -aout_adobe_object_p (abfd) - bfd *abfd; -{ - struct internal_exec anexec; - struct external_exec exec_bytes; - char *targ; - - if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) - != EXEC_BYTES_SIZE) { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - anexec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info); - - /* Normally we just compare for the magic number. - However, a bunch of Adobe tools aren't fixed up yet; they generate - files using ZMAGIC(!). - If the environment variable GNUTARGET is set to "a.out.adobe", we will - take just about any a.out file as an Adobe a.out file. FIXME! */ - - if (N_BADMAG (anexec)) { - extern char *getenv (); - - targ = getenv ("GNUTARGET"); - if (targ && !strcmp (targ, a_out_adobe_vec.name)) - ; /* Just continue anyway, if specifically set to this format */ - else - { - bfd_set_error (bfd_error_wrong_format); - return 0; - } - } - - aout_adobe_swap_exec_header_in (abfd, &exec_bytes, &anexec); - return aout_32_some_aout_object_p (abfd, &anexec, aout_adobe_callback); -} - - -/* Finish up the opening of a b.out file for reading. Fill in all the - fields that are not handled by common code. */ - -static const bfd_target * -aout_adobe_callback (abfd) - bfd *abfd; -{ - struct internal_exec *execp = exec_hdr (abfd); - asection *sect; - struct external_segdesc ext[1]; - char *section_name; - char try_again[30]; /* name and number */ - char *newname; - int trynum; - flagword flags; - - /* Architecture and machine type -- unknown in this format. */ - bfd_set_arch_mach(abfd, bfd_arch_unknown, 0); - - /* The positions of the string table and symbol table. */ - obj_str_filepos (abfd) = N_STROFF (*execp); - obj_sym_filepos (abfd) = N_SYMOFF (*execp); - - /* Suck up the section information from the file, one section at a time. */ - - for (;;) { - if (bfd_read ((PTR) ext, 1, sizeof (*ext), abfd) != sizeof (*ext)) { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - switch (ext->e_type[0]) { - case N_TEXT: - section_name = ".text"; - flags = SEC_CODE | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS; - break; - - case N_DATA: - section_name = ".data"; - flags = SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS; - break; - - case N_BSS: - section_name = ".bss"; - flags = SEC_DATA | SEC_HAS_CONTENTS; - break; - - case 0: - goto no_more_sections; - - default: - (*_bfd_error_handler) - ("%s: Unknown section type in a.out.adobe file: %x\n", - bfd_get_filename (abfd), ext->e_type[0]); - goto no_more_sections; - } - - /* First one is called ".text" or whatever; subsequent ones are - ".text1", ".text2", ... */ - - bfd_set_error (bfd_error_no_error); - sect = bfd_make_section (abfd, section_name); - trynum = 0; - while (!sect) { - if (bfd_get_error () != bfd_error_no_error) - return 0; /* Some other error -- slide into the sunset */ - sprintf (try_again, "%s%d", section_name, ++trynum); - sect = bfd_make_section (abfd, try_again); - } - - /* Fix the name, if it is a sprintf'd name. */ - if (sect->name == try_again) { - newname = (char *) bfd_zalloc(abfd, strlen (sect->name)); - if (newname == NULL) - return 0; - strcpy (newname, sect->name); - sect->name = newname; - } - - /* Now set the section's attributes. */ - bfd_set_section_flags (abfd, sect, flags); - sect->_raw_size = ((ext->e_size[0] << 8) /* Assumed big-endian */ - | ext->e_size[1] << 8) - | ext->e_size[2]; - sect->_cooked_size = sect->_raw_size; - sect->vma = bfd_h_get_32 (abfd, ext->e_virtbase); - sect->filepos = bfd_h_get_32 (abfd, ext->e_filebase); - /* FIXME XXX alignment? */ - - /* Set relocation information for first section of each type. */ - if (trynum == 0) switch (ext->e_type[0]) { - case N_TEXT: - sect->rel_filepos = N_TRELOFF (*execp); - sect->reloc_count = execp->a_trsize; - break; - - case N_DATA: - sect->rel_filepos = N_DRELOFF (*execp); - sect->reloc_count = execp->a_drsize; - break; - } - } -no_more_sections: - - adata(abfd).reloc_entry_size = sizeof (struct reloc_std_external); - adata(abfd).symbol_entry_size = sizeof (struct external_nlist); - adata(abfd).page_size = 1; /* Not applicable. */ - adata(abfd).segment_size = 1; /* Not applicable. */ - adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE; - - return abfd->xvec; -} - -struct bout_data_struct { - struct aoutdata a; - struct internal_exec e; -}; - -static boolean -aout_adobe_mkobject (abfd) - bfd *abfd; -{ - struct bout_data_struct *rawptr; - - rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, sizeof (struct bout_data_struct)); - if (rawptr == NULL) - return false; - - abfd->tdata.bout_data = rawptr; - exec_hdr (abfd) = &rawptr->e; - - adata(abfd).reloc_entry_size = sizeof (struct reloc_std_external); - adata(abfd).symbol_entry_size = sizeof (struct external_nlist); - adata(abfd).page_size = 1; /* Not applicable. */ - adata(abfd).segment_size = 1; /* Not applicable. */ - adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE; - - return true; -} - - -static boolean -aout_adobe_write_object_contents (abfd) - bfd *abfd; -{ - struct external_exec swapped_hdr; - static struct external_segdesc sentinel[1]; /* Initialized to zero */ - asection *sect; - - exec_hdr (abfd)->a_info = ZMAGIC; - - /* Calculate text size as total of text sections, etc. */ - - exec_hdr (abfd)->a_text = 0; - exec_hdr (abfd)->a_data = 0; - exec_hdr (abfd)->a_bss = 0; - exec_hdr (abfd)->a_trsize = 0; - exec_hdr (abfd)->a_drsize = 0; - - for (sect = abfd->sections; sect; sect = sect->next) { - if (sect->flags & SEC_CODE) { - exec_hdr (abfd)->a_text += sect->_raw_size; - exec_hdr (abfd)->a_trsize += sect->reloc_count * - sizeof (struct reloc_std_external); - } else if (sect->flags & SEC_DATA) { - exec_hdr (abfd)->a_data += sect->_raw_size; - exec_hdr (abfd)->a_drsize += sect->reloc_count * - sizeof (struct reloc_std_external); - } else if (sect->flags & SEC_ALLOC && !(sect->flags & SEC_LOAD)) { - exec_hdr (abfd)->a_bss += sect->_raw_size; - } - } - - exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) - * sizeof (struct external_nlist); - exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd); - - aout_adobe_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr); - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || (bfd_write ((PTR) &swapped_hdr, 1, EXEC_BYTES_SIZE, abfd) - != EXEC_BYTES_SIZE)) - return false; - - /* Now write out the section information. Text first, data next, rest - afterward. */ - - for (sect = abfd->sections; sect; sect = sect->next) { - if (sect->flags & SEC_CODE) { - aout_adobe_write_section (abfd, sect); - } - } - for (sect = abfd->sections; sect; sect = sect->next) { - if (sect->flags & SEC_DATA) { - aout_adobe_write_section (abfd, sect); - } - } - for (sect = abfd->sections; sect; sect = sect->next) { - if (!(sect->flags & (SEC_CODE|SEC_DATA))) { - aout_adobe_write_section (abfd, sect); - } - } - - /* Write final `sentinel` section header (with type of 0). */ - if (bfd_write ((PTR) sentinel, 1, sizeof (*sentinel), abfd) - != sizeof (*sentinel)) - return false; - - /* Now write out reloc info, followed by syms and strings */ - if (bfd_get_symcount (abfd) != 0) - { - if (bfd_seek (abfd, (file_ptr)(N_SYMOFF(*exec_hdr(abfd))), SEEK_SET) - != 0) - return false; - - if (! aout_32_write_syms (abfd)) - return false; - - if (bfd_seek (abfd, (file_ptr)(N_TRELOFF(*exec_hdr(abfd))), SEEK_SET) - != 0) - return false; - - for (sect = abfd->sections; sect; sect = sect->next) { - if (sect->flags & SEC_CODE) { - if (!aout_32_squirt_out_relocs (abfd, sect)) - return false; - } - } - - if (bfd_seek (abfd, (file_ptr)(N_DRELOFF(*exec_hdr(abfd))), SEEK_SET) - != 0) - return false; - - for (sect = abfd->sections; sect; sect = sect->next) { - if (sect->flags & SEC_DATA) { - if (!aout_32_squirt_out_relocs (abfd, sect)) - return false; - } - } - } - return true; -} - -static void -aout_adobe_write_section (abfd, sect) - bfd *abfd; - sec_ptr sect; -{ - /* FIXME XXX */ -} - -static boolean -aout_adobe_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - asection *section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - file_ptr section_start; - sec_ptr sect; - - if (abfd->output_has_begun == false) { /* set by bfd.c handler */ - - /* Assign file offsets to sections. Text sections are first, and - are contiguous. Then data sections. Everything else at the end. */ - - section_start = N_TXTOFF (ignore<-->me); - - for (sect = abfd->sections; sect; sect = sect->next) { - if (sect->flags & SEC_CODE) { - sect->filepos = section_start; - /* FIXME: Round to alignment */ - section_start += sect->_raw_size; - } - } - - for (sect = abfd->sections; sect; sect = sect->next) { - if (sect->flags & SEC_DATA) { - sect->filepos = section_start; - /* FIXME: Round to alignment */ - section_start += sect->_raw_size; - } - } - - for (sect = abfd->sections; sect; sect = sect->next) { - if (sect->flags & SEC_HAS_CONTENTS && - !(sect->flags & (SEC_CODE|SEC_DATA))) { - sect->filepos = section_start; - /* FIXME: Round to alignment */ - section_start += sect->_raw_size; - } - } - } - - /* regardless, once we know what we're doing, we might as well get going */ - if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0) - return false; - - if (count != 0) { - return (bfd_write ((PTR)location, 1, count, abfd) == count) ?true:false; - } - return true; -} - -static boolean -aout_adobe_set_arch_mach (abfd, arch, machine) - bfd *abfd; - enum bfd_architecture arch; - unsigned long machine; -{ - if (! bfd_default_set_arch_mach (abfd, arch, machine)) - return false; - - if (arch == bfd_arch_unknown - || arch == bfd_arch_m68k) - return true; - - return false; -} - -static int -aout_adobe_sizeof_headers (ignore_abfd, ignore) - bfd *ignore_abfd; - boolean ignore; -{ - return sizeof(struct internal_exec); -} - - - - -/* Build the transfer vector for Adobe A.Out files. */ - -#define aout_32_close_and_cleanup aout_32_bfd_free_cached_info - -#define aout_32_bfd_make_debug_symbol \ - ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr) - -#define aout_32_bfd_reloc_type_lookup \ - ((reloc_howto_type *(*) \ - PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr) - -#define aout_32_set_arch_mach aout_adobe_set_arch_mach -#define aout_32_set_section_contents aout_adobe_set_section_contents - -#define aout_32_sizeof_headers aout_adobe_sizeof_headers -#define aout_32_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define aout_32_get_section_contents_in_window _bfd_generic_get_section_contents_in_window -#define aout_32_bfd_relax_section bfd_generic_relax_section -#define aout_32_bfd_link_hash_table_create \ - _bfd_generic_link_hash_table_create -#define aout_32_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define aout_32_bfd_final_link _bfd_generic_final_link -#define aout_32_bfd_link_split_section _bfd_generic_link_split_section - -const bfd_target a_out_adobe_vec = -{ - "a.out.adobe", /* name */ - bfd_target_aout_flavour, - BFD_ENDIAN_BIG, /* data byte order is unknown (big assumed) */ - BFD_ENDIAN_BIG, /* hdr byte order is big */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT ), - /* section flags */ - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_DATA | SEC_RELOC), - '_', /* symbol leading char */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - {_bfd_dummy_target, aout_adobe_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, aout_adobe_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, aout_adobe_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (aout_32), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd), - BFD_JUMP_TABLE_SYMBOLS (aout_32), - BFD_JUMP_TABLE_RELOCS (aout_32), - BFD_JUMP_TABLE_WRITE (aout_32), - BFD_JUMP_TABLE_LINK (aout_32), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; diff --git a/contrib/gdb/bfd/aout-arm.c b/contrib/gdb/bfd/aout-arm.c deleted file mode 100644 index 978664a..0000000 --- a/contrib/gdb/bfd/aout-arm.c +++ /dev/null @@ -1,548 +0,0 @@ -/* BFD back-end for raw ARM a.out binaries. - Copyright (C) 1994, 1995 Free Software Foundation, Inc. - Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) - -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. */ - - -#define N_TXTADDR(x) \ - ((N_MAGIC(x) == NMAGIC) ? 0x8000 : \ - (N_MAGIC(x) != ZMAGIC) ? 0 : \ - (N_SHARED_LIB(x)) ? ((x).a_entry & ~(TARGET_PAGE_SIZE - 1)) : \ - TEXT_START_ADDR) - -#define TEXT_START_ADDR 0x8000 -#define TARGET_PAGE_SIZE 0x8000 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define DEFAULT_ARCH bfd_arch_arm - -#define MY(OP) CAT(aoutarm_,OP) -#define N_BADMAG(x) ((((x).a_info & ~007200) != ZMAGIC) && \ - (((x).a_info & ~006000) != OMAGIC) && \ - ((x).a_info != NMAGIC)) -#define N_MAGIC(x) ((x).a_info & ~07200) - -#include "bfd.h" -#include "sysdep.h" -#include "assert.h" - -#define MYARM(OP) CAT(aoutarm_,OP) -reloc_howto_type *MYARM(bfd_reloc_type_lookup) - PARAMS((bfd *, bfd_reloc_code_real_type)); -static boolean MYARM(write_object_contents) PARAMS((bfd *)); - -/* Avoid multiple defininitions from aoutx if supporting standarad a.out - as well as our own. */ -#define NAME(x,y) CAT3(aoutarm,_32_,y) - -#define MY_bfd_reloc_type_lookup aoutarm_bfd_reloc_type_lookup - -#include "libaout.h" -#include "aout/aout64.h" - -static bfd_reloc_status_type -MY(fix_pcrel_26_done) PARAMS ((bfd *, arelent *, asymbol *, PTR, - asection *, bfd *, char **)); - -static bfd_reloc_status_type -MY(fix_pcrel_26) PARAMS ((bfd *, arelent *, asymbol *, PTR, - asection *, bfd *, char **)); -static void MY(swap_std_reloc_in) PARAMS ((bfd *, struct reloc_std_external *, - arelent *, asymbol **, - bfd_size_type)); -void MY(swap_std_reloc_out) PARAMS ((bfd *, arelent *, - struct reloc_std_external *)); - -reloc_howto_type MY(howto_table)[] = -{ - /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask - pcdone */ - HOWTO (0, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "8", true, - 0x000000ff, 0x000000ff, false), - HOWTO (1, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "16", true, - 0x0000ffff, 0x0000ffff, false), - HOWTO (2, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "32", true, - 0xffffffff, 0xffffffff, false), - HOWTO (3, 2, 2, 26, true, 0, complain_overflow_signed, MY(fix_pcrel_26), - "ARM26", true, 0x00ffffff, 0x00ffffff, true), - HOWTO (4, 0, 0, 8, true, 0, complain_overflow_signed, 0, "DISP8", true, - 0x000000ff, 0x000000ff, true), - HOWTO (5, 0, 1, 16, true, 0, complain_overflow_signed, 0, "DISP16", true, - 0x0000ffff, 0x0000ffff, true), - HOWTO (6, 0, 2, 32, true, 0, complain_overflow_signed, 0, "DISP32", true, - 0xffffffff, 0xffffffff, true), - HOWTO (7, 2, 2, 26, false, 0, complain_overflow_signed, - MY(fix_pcrel_26_done), "ARM26D", true, 0x0, 0x0, - false), - {-1}, - HOWTO (9, 0, -1, 16, false, 0, complain_overflow_bitfield, 0, "NEG16", true, - 0x0000ffff, 0x0000ffff, false), - HOWTO (10, 0, -2, 32, false, 0, complain_overflow_bitfield, 0, "NEG32", true, - 0xffffffff, 0xffffffff, false) -}; - -#define RELOC_ARM_BITS_NEG_BIG ((unsigned int) 0x08) -#define RELOC_ARM_BITS_NEG_LITTLE ((unsigned int) 0x10) - -reloc_howto_type * -MY(reloc_howto)(abfd, rel, r_index, r_extern, r_pcrel) - bfd *abfd; - struct reloc_std_external *rel; - int *r_index; - int *r_extern; - int *r_pcrel; -{ - unsigned int r_length; - unsigned int r_pcrel_done; - unsigned int r_neg; - int index; - - *r_pcrel = 0; - if (bfd_header_big_endian (abfd)) - { - *r_index = ((rel->r_index[0] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[2]); - *r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG)); - r_pcrel_done = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG)); - r_neg = (0 != (rel->r_type[0] & RELOC_ARM_BITS_NEG_BIG)); - r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) - >> RELOC_STD_BITS_LENGTH_SH_BIG); - } - else - { - *r_index = ((rel->r_index[2] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[0]); - *r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE)); - r_pcrel_done = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE)); - r_neg = (0 != (rel->r_type[0] & RELOC_ARM_BITS_NEG_LITTLE)); - r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) - >> RELOC_STD_BITS_LENGTH_SH_LITTLE); - } - index = r_length + 4 * r_pcrel_done + 8 * r_neg; - if (index == 3) - *r_pcrel = 1; - - return MY(howto_table) + index; -} - -#define MY_reloc_howto(BFD, REL, IN, EX, PC) \ - MY(reloc_howto) (BFD, REL, &IN, &EX, &PC) - -void -MY(put_reloc)(abfd, r_extern, r_index, value, howto, reloc) - bfd *abfd; - int r_extern; - int r_index; - long value; - reloc_howto_type *howto; - struct reloc_std_external *reloc; -{ - unsigned int r_length; - int r_pcrel; - int r_neg; - - PUT_WORD (abfd, value, reloc->r_address); - r_length = howto->size ; /* Size as a power of two */ - - /* Special case for branch relocations. */ - if (howto->type == 3 || howto->type == 7) - r_length = 3; - - r_pcrel = howto->type & 4; /* PC Relative done? */ - r_neg = howto->type & 8; /* Negative relocation */ - if (bfd_header_big_endian (abfd)) - { - reloc->r_index[0] = r_index >> 16; - reloc->r_index[1] = r_index >> 8; - reloc->r_index[2] = r_index; - reloc->r_type[0] = - ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0) - | (r_neg ? RELOC_ARM_BITS_NEG_BIG : 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG)); - } - else - { - reloc->r_index[2] = r_index >> 16; - reloc->r_index[1] = r_index >> 8; - reloc->r_index[0] = r_index; - reloc->r_type[0] = - ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0) - | (r_neg ? RELOC_ARM_BITS_NEG_LITTLE : 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE)); - } -} - -#define MY_put_reloc(BFD, EXT, IDX, VAL, HOWTO, RELOC) \ - MY(put_reloc)(BFD, EXT, IDX, VAL, HOWTO, RELOC) - -void -MY(relocatable_reloc)(howto, abfd, reloc, amount, r_addr) - reloc_howto_type *howto; - bfd *abfd; - struct reloc_std_external *reloc; - bfd_vma *amount; - bfd_vma r_addr; -{ - if (howto->type == 3) - { - if (reloc->r_type[0] - & (bfd_header_big_endian (abfd) - ? RELOC_STD_BITS_EXTERN_BIG : RELOC_STD_BITS_EXTERN_LITTLE)) - { - /* The reloc is still external, so don't modify anything. */ - *amount = 0; - } - else - { - *amount -= r_addr; - /* Change the r_pcrel value -- on the ARM, this bit is set once the - relocation is done. */ - if (bfd_header_big_endian (abfd)) - reloc->r_type[0] |= RELOC_STD_BITS_PCREL_BIG; - else - reloc->r_type[0] |= RELOC_STD_BITS_PCREL_LITTLE; - } - } - else if (howto->type == 7) - *amount = 0; -} - -#define MY_relocatable_reloc(HOW, BFD, REL, AMOUNT, ADDR) \ - MY(relocatable_reloc)(HOW, BFD, REL, &(AMOUNT), ADDR) - -static bfd_reloc_status_type -MY(fix_pcrel_26_done) (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - /* This is dead simple at present. */ - return bfd_reloc_ok; -} - -static bfd_reloc_status_type -MY(fix_pcrel_26) (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_vma relocation; - bfd_size_type addr = reloc_entry->address; - long target = bfd_get_32 (abfd, (bfd_byte *) data + addr); - bfd_reloc_status_type flag = bfd_reloc_ok; - - /* If this is an undefined symbol, return error */ - if (symbol->section == &bfd_und_section - && (symbol->flags & BSF_WEAK) == 0) - return output_bfd ? bfd_reloc_ok : bfd_reloc_undefined; - - /* If the sections are different, and we are doing a partial relocation, - just ignore it for now. */ - if (symbol->section->name != input_section->name - && output_bfd != (bfd *)NULL) - return bfd_reloc_ok; - - relocation = (target & 0x00ffffff) << 2; - relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend */ - relocation += symbol->value; - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - relocation -= input_section->output_section->vma; - relocation -= input_section->output_offset; - relocation -= addr; - if (relocation & 3) - return bfd_reloc_overflow; - - /* Check for overflow */ - if (relocation & 0x02000000) - { - if ((relocation & ~0x03ffffff) != ~0x03ffffff) - flag = bfd_reloc_overflow; - } - else if (relocation & ~0x03ffffff) - flag = bfd_reloc_overflow; - - target &= ~0x00ffffff; - target |= (relocation >> 2) & 0x00ffffff; - bfd_put_32 (abfd, target, (bfd_byte *) data + addr); - - /* Now the ARM magic... Change the reloc type so that it is marked as done. - Strictly this is only necessary if we are doing a partial relocation. */ - reloc_entry->howto = &MY(howto_table)[7]; - - return flag; -} - -reloc_howto_type * -MY(bfd_reloc_type_lookup)(abfd,code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ -#define ASTD(i,j) case i: return &MY(howto_table)[j] - if (code == BFD_RELOC_CTOR) - switch (bfd_get_arch_info (abfd)->bits_per_address) - { - case 32: - code = BFD_RELOC_32; - break; - default: return (CONST struct reloc_howto_struct *) 0; - } - - switch (code) - { - ASTD (BFD_RELOC_16, 1); - ASTD (BFD_RELOC_32, 2); - ASTD (BFD_RELOC_ARM_PCREL_BRANCH, 3); - ASTD (BFD_RELOC_8_PCREL, 4); - ASTD (BFD_RELOC_16_PCREL, 5); - ASTD (BFD_RELOC_32_PCREL, 6); - default: return (CONST struct reloc_howto_struct *) 0; - } -} - -#define MY_swap_std_reloc_in MY(swap_std_reloc_in) -#define MY_swap_std_reloc_out MY(swap_std_reloc_out) -#define MY_get_section_contents _bfd_generic_get_section_contents -/* #define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create */ -/* #define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols */ -/* #define MY_bfd_final_link _bfd_generic_final_link */ - -#include "aoutx.h" - -static void -MY_swap_std_reloc_in (abfd, bytes, cache_ptr, symbols, symcount) - bfd *abfd; - struct reloc_std_external *bytes; - arelent *cache_ptr; - asymbol **symbols; - bfd_size_type symcount; -{ - int r_index; - int r_extern; - unsigned int r_length; - int r_pcrel; - struct aoutdata *su = &(abfd->tdata.aout_data->a); - - cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address); - - cache_ptr->howto = MY_reloc_howto (abfd, bytes, r_index, r_extern, r_pcrel); - - MOVE_ADDRESS (0); -} - -void -MY_swap_std_reloc_out (abfd, g, natptr) - bfd *abfd; - arelent *g; - struct reloc_std_external *natptr; -{ - int r_index; - asymbol *sym = *(g->sym_ptr_ptr); - int r_extern; - int r_length; - int r_pcrel; - int r_neg = 0; /* Negative relocs use the BASEREL bit. */ - asection *output_section = sym->section->output_section; - - PUT_WORD(abfd, g->address, natptr->r_address); - - r_length = g->howto->size ; /* Size as a power of two */ - if (r_length < 0) - { - r_length = -r_length; - r_neg = 1; - } - - r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */ - - /* For RISC iX, in pc-relative relocs the r_pcrel bit means that the - relocation has been done already (Only for the 26-bit one I think)???!!! - */ - - if (g->howto->type == 3) - { - r_length = 3; - r_pcrel = 0; - } - else if (g->howto->type == 7) - { - r_length = 3; - r_pcrel = 1; - } - - -#if 0 - /* For a standard reloc, the addend is in the object file. */ - r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; -#endif - - /* name was clobbered by aout_write_syms to be symbol index */ - - /* If this relocation is relative to a symbol then set the - r_index to the symbols index, and the r_extern bit. - - Absolute symbols can come in in two ways, either as an offset - from the abs section, or as a symbol which has an abs value. - check for that here - */ - - if (bfd_is_com_section (output_section) - || output_section == &bfd_abs_section - || output_section == &bfd_und_section) - { - if (bfd_abs_section.symbol == sym) - { - /* Whoops, looked like an abs symbol, but is really an offset - from the abs section */ - r_index = 0; - r_extern = 0; - } - else - { - /* Fill in symbol */ - r_extern = 1; - r_index = (*(g->sym_ptr_ptr))->KEEPIT; - } - } - else - { - /* Just an ordinary section */ - r_extern = 0; - r_index = output_section->target_index; - } - - /* now the fun stuff */ - if (bfd_header_big_endian (abfd)) - { - natptr->r_index[0] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[2] = r_index; - natptr->r_type[0] = - ( (r_extern ? RELOC_STD_BITS_EXTERN_BIG: 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG: 0) - | (r_neg ? RELOC_ARM_BITS_NEG_BIG: 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG)); - } - else - { - natptr->r_index[2] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[0] = r_index; - natptr->r_type[0] = - ( (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE: 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE: 0) - | (r_neg ? RELOC_ARM_BITS_NEG_LITTLE: 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE)); - } -} - -#define MY_BFD_TARGET - -#include "aout-target.h" - -const bfd_target aout_arm_little_vec = -{ - "a.out-arm-little", /* name */ - bfd_target_aout_flavour, - BFD_ENDIAN_LITTLE, /* target byte order (little) */ - BFD_ENDIAN_LITTLE, /* target headers byte order (little) */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - MY_symbol_leading_char, - AR_PAD_CHAR, /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - {_bfd_dummy_target, MY_object_p, /* bfd_check_format */ - bfd_generic_archive_p, MY_core_file_p}, - {bfd_false, MY_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, MY_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (MY), - BFD_JUMP_TABLE_COPY (MY), - BFD_JUMP_TABLE_CORE (MY), - BFD_JUMP_TABLE_ARCHIVE (MY), - BFD_JUMP_TABLE_SYMBOLS (MY), - BFD_JUMP_TABLE_RELOCS (MY), - BFD_JUMP_TABLE_WRITE (MY), - BFD_JUMP_TABLE_LINK (MY), - BFD_JUMP_TABLE_DYNAMIC (MY), - - (PTR) MY_backend_data, -}; - -const bfd_target aout_arm_big_vec = -{ - "a.out-arm-big", /* name */ - bfd_target_aout_flavour, - BFD_ENDIAN_BIG, /* target byte order (big) */ - BFD_ENDIAN_BIG, /* target headers byte order (big) */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - MY_symbol_leading_char, - AR_PAD_CHAR, /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - {_bfd_dummy_target, MY_object_p, /* bfd_check_format */ - bfd_generic_archive_p, MY_core_file_p}, - {bfd_false, MY_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, MY_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (MY), - BFD_JUMP_TABLE_COPY (MY), - BFD_JUMP_TABLE_CORE (MY), - BFD_JUMP_TABLE_ARCHIVE (MY), - BFD_JUMP_TABLE_SYMBOLS (MY), - BFD_JUMP_TABLE_RELOCS (MY), - BFD_JUMP_TABLE_WRITE (MY), - BFD_JUMP_TABLE_LINK (MY), - BFD_JUMP_TABLE_DYNAMIC (MY), - - (PTR) MY_backend_data, -}; diff --git a/contrib/gdb/bfd/aout-encap.c b/contrib/gdb/bfd/aout-encap.c deleted file mode 100644 index c25f903..0000000 --- a/contrib/gdb/bfd/aout-encap.c +++ /dev/null @@ -1,236 +0,0 @@ -/* BFD back-end for a.out files encapsulated with COFF headers. - Copyright (C) 1990, 1991 Free Software Foundation, Inc. - -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 MODULE IS NOT FINISHED. IT PROBABLY DOESN'T EVEN COMPILE. */ - -#if 0 -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define TEXT_START_ADDR 0 -#define BYTES_IN_WORD 4 -#endif - -#include "bfd.h" -#include <sysdep.h> -#include "libbfd.h" -#include <aout/aout64.h> -#include "aout/stab_gnu.h" -#include "aout/ar.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -const bfd_target *encap_real_callback (); - -const bfd_target * -encap_object_p (abfd) - bfd *abfd; -{ - unsigned char magicbuf[4]; /* Raw bytes of magic number from file */ - unsigned long magic; /* Swapped magic number */ - short coff_magic; - struct external_exec exec_bytes; - struct internal_exec exec; - - if (bfd_read ((PTR)magicbuf, 1, sizeof (magicbuf), abfd) != - sizeof (magicbuf)) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - coff_magic = bfd_h_get_16 (abfd, magicbuf); - if (coff_magic != COFF_MAGIC) - return 0; /* Not an encap coff file */ - - __header_offset_temp==COFF_MAGIC ? sizeof(struct coffheader) : 0) - (fseek ((f), HEADER_OFFSET((f)), 1)) - - magic = bfd_h_get_32 (abfd, magicbuf); - - if (N_BADMAG (*((struct internal_exec *) &magic))) return 0; - - struct external_exec exec_bytes; - if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) - != EXEC_BYTES_SIZE) { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, &exec); - - return aout_32_some_aout_object_p (abfd, &exec, encap_realcallback); -} - -/* Finish up the reading of a encapsulated-coff a.out file header */ -const bfd_target * -encap_real_callback (abfd) - bfd *abfd; -{ - struct internal_exec *execp = exec_hdr (abfd); - - MY(callback)(abfd, execp); - - /* If we have a coff header, it can give us better values for - text_start and exec_data_start. This is particularly useful - for remote debugging of embedded systems. */ - if (N_FLAGS(exec_aouthdr) & N_FLAGS_COFF_ENCAPSULATE) - { - struct coffheader ch; - int val; - val = lseek (execchan, -(sizeof (AOUTHDR) + sizeof (ch)), 1); - if (val == -1) - perror_with_name (filename); - val = myread (execchan, &ch, sizeof (ch)); - if (val < 0) - perror_with_name (filename); - text_start = ch.text_start; - exec_data_start = ch.data_start; - } else - { - text_start = - IS_OBJECT_FILE (exec_aouthdr) ? 0 : N_TXTADDR (exec_aouthdr); - exec_data_start = IS_OBJECT_FILE (exec_aouthdr) - ? exec_aouthdr.a_text : N_DATADDR (exec_aouthdr); - } - - /* Determine the architecture and machine type of the object file. */ - bfd_default_set_arch_mach(abfd, bfd_arch_m68k, 0); /* FIXME */ - - return abfd->xvec; -} - -/* Write an object file in Encapsulated COFF format. - Section contents have already been written. We write the - file header, symbols, and relocation. */ - -boolean -encap_write_object_contents (abfd) - bfd *abfd; -{ - bfd_size_type data_pad = 0; - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - -/****** FIXME: Fragments from the old GNU LD program for dealing with - encap coff. */ -struct coffheader coffheader; -int need_coff_header; - - /* Determine whether to count the header as part of - the text size, and initialize the text size accordingly. - This depends on the kind of system and on the output format selected. */ - - N_SET_MAGIC (outheader, magic); -#ifdef INITIALIZE_HEADER - INITIALIZE_HEADER; -#endif - - text_size = sizeof (struct exec); -#ifdef COFF_ENCAPSULATE - if (relocatable_output == 0 && file_table[0].just_syms_flag == 0) - { - need_coff_header = 1; - /* set this flag now, since it will change the values of N_TXTOFF, etc */ - N_SET_FLAGS (outheader, aout_backend_info (abfd)->exec_hdr_flags); - text_size += sizeof (struct coffheader); - } -#endif - -#ifdef COFF_ENCAPSULATE - if (need_coff_header) - { - /* We are encapsulating BSD format within COFF format. */ - struct coffscn *tp, *dp, *bp; - - tp = &coffheader.scns[0]; - dp = &coffheader.scns[1]; - bp = &coffheader.scns[2]; - - strcpy (tp->s_name, ".text"); - tp->s_paddr = text_start; - tp->s_vaddr = text_start; - tp->s_size = text_size; - tp->s_scnptr = sizeof (struct coffheader) + sizeof (struct exec); - tp->s_relptr = 0; - tp->s_lnnoptr = 0; - tp->s_nreloc = 0; - tp->s_nlnno = 0; - tp->s_flags = 0x20; - strcpy (dp->s_name, ".data"); - dp->s_paddr = data_start; - dp->s_vaddr = data_start; - dp->s_size = data_size; - dp->s_scnptr = tp->s_scnptr + tp->s_size; - dp->s_relptr = 0; - dp->s_lnnoptr = 0; - dp->s_nreloc = 0; - dp->s_nlnno = 0; - dp->s_flags = 0x40; - strcpy (bp->s_name, ".bss"); - bp->s_paddr = dp->s_vaddr + dp->s_size; - bp->s_vaddr = bp->s_paddr; - bp->s_size = bss_size; - bp->s_scnptr = 0; - bp->s_relptr = 0; - bp->s_lnnoptr = 0; - bp->s_nreloc = 0; - bp->s_nlnno = 0; - bp->s_flags = 0x80; - - coffheader.f_magic = COFF_MAGIC; - coffheader.f_nscns = 3; - /* store an unlikely time so programs can - * tell that there is a bsd header - */ - coffheader.f_timdat = 1; - coffheader.f_symptr = 0; - coffheader.f_nsyms = 0; - coffheader.f_opthdr = 28; - coffheader.f_flags = 0x103; - /* aouthdr */ - coffheader.magic = ZMAGIC; - coffheader.vstamp = 0; - coffheader.tsize = tp->s_size; - coffheader.dsize = dp->s_size; - coffheader.bsize = bp->s_size; - coffheader.entry = outheader.a_entry; - coffheader.text_start = tp->s_vaddr; - coffheader.data_start = dp->s_vaddr; - } -#endif - -#ifdef COFF_ENCAPSULATE - if (need_coff_header) - mywrite (&coffheader, sizeof coffheader, 1, outdesc); -#endif - -#ifndef COFF_ENCAPSULATE - padfile (N_TXTOFF (outheader) - sizeof outheader, outdesc); -#endif - - text_size -= N_TXTOFF (outheader); - WRITE_HEADERS(abfd, execp); - return true; -} - -#define MY_write_object_content encap_write_object_contents -#define MY_object_p encap_object_p -#define MY_exec_hdr_flags N_FLAGS_COFF_ENCAPSULATE - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/aout-ns32k.c b/contrib/gdb/bfd/aout-ns32k.c deleted file mode 100644 index 269e053..0000000 --- a/contrib/gdb/bfd/aout-ns32k.c +++ /dev/null @@ -1,399 +0,0 @@ -/* BFD back-end for ns32k a.out-ish binaries. - Copyright (C) 1990, 1991, 1992, 1994, 1995 Free Software Foundation, Inc. - Contributed by Ian Dall (idall@eleceng.adelaide.edu.au). - -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. */ - -#define BYTES_IN_WORD 4 - -#include "bfd.h" -#include "aout/aout64.h" - -#define MYNS(OP) CAT(ns32kaout_,OP) -reloc_howto_type * -MYNS(bfd_reloc_type_lookup) - PARAMS((bfd *abfd AND - bfd_reloc_code_real_type code)); - -boolean -MYNS(write_object_contents) - PARAMS((bfd *abfd)); - -/* Avoid multiple definitions from aoutx if supporting standard a.out format(s) - * as well as this one - */ -#define NAME(x,y) CAT3(ns32kaout,_32_,y) - -void bfd_ns32k_arch PARAMS ((void)); -long ns32k_get_displacement PARAMS ((bfd_byte *buffer, long offset, long size)); -int ns32k_put_displacement PARAMS ((long value, bfd_byte *buffer, long offset, long size)); -long ns32k_get_immediate PARAMS ((bfd_byte *buffer, long offset, long size)); -int ns32k_put_immediate PARAMS ((long value, bfd_byte *buffer, long offset, long size)); -bfd_reloc_status_type - ns32k_reloc_disp PARAMS ((bfd *abfd, arelent *reloc_entry, - struct symbol_cache_entry *symbol, - PTR data, - asection *input_section, - bfd *output_bfd, - char **error_message)); -bfd_reloc_status_type - ns32k_reloc_imm PARAMS ((bfd *abfd, - arelent *reloc_entry, - struct symbol_cache_entry *symbol, - PTR data, - asection *input_section, - bfd *output_bfd, - char **error_message)); -bfd_reloc_status_type - ns32k_final_link_relocate PARAMS ((reloc_howto_type *howto, - bfd *input_bfd, - asection *input_section, - bfd_byte *contents, - bfd_vma address, - bfd_vma value, - bfd_vma addend )); -bfd_reloc_status_type - ns32k_relocate_contents PARAMS ((reloc_howto_type *howto, - bfd *input_bfd, - bfd_vma relocation, - bfd_byte *location)); - -#include "libaout.h" - -#define MY(OP) MYNS(OP) - -#define MY_swap_std_reloc_in MY(swap_std_reloc_in) -#define MY_swap_std_reloc_out MY(swap_std_reloc_out) - -static void -MY_swap_std_reloc_in PARAMS ((bfd *abfd, struct reloc_std_external *bytes, - arelent *cache_ptr, asymbol **symbols, - bfd_size_type symcount)); - -static void -MY_swap_std_reloc_out PARAMS ((bfd *abfd, arelent *g, - struct reloc_std_external *natptr)); - -/* The ns32k series is ah, unusual, when it comes to relocation. - * There are three storage methods for relocateable objects. There - * are displacements, immediate operands and ordinary twos complement - * data. Of these, only the last fits into the standard relocation - * scheme. Immediate operands are stored huffman encoded and - * immediate operands are stored big endian (where as the natural byte - * order is little endian for this achitecture). - - * Note that the ns32k displacement storage method is orthogonal to - * whether the relocation is pc relative or not. The "displacement" - * storage scheme is used for essentially all address constants. The - * displacement can be relative to zero (absolute displacement), - * relative to the pc (pc relative), the stack pointer, the frame - * pointer, the static base register and general purpose register etc. - - * For example: - * - * sym1: .long . # pc relative 2's complement - * sym1: .long foo # 2's complement not pc relative - * - * self: movd @self, r0 # pc relative displacement - * movd foo, r0 # non pc relative displacement - * - * self: movd self, r0 # pc relative immediate - * movd foo, r0 # non pc relative immediate - * - * In addition, for historical reasons the encoding of the relocation types - * in the a.out format relocation entries is such that even the relocation - * methods which are standard are not encoded the standard way. - * - */ - -reloc_howto_type MY(howto_table)[] = -{ -/* ns32k immediate operands */ -HOWTO(BFD_RELOC_NS32K_IMM_8, 0, 0, 8, false, 0, true, - ns32k_reloc_imm, "NS32K_IMM_8", - true, 0x000000ff,0x000000ff, false), -HOWTO(BFD_RELOC_NS32K_IMM_16, 0, 1, 16, false, 0, true, - ns32k_reloc_imm, "NS32K_IMM_16", - true, 0x0000ffff,0x0000ffff, false), -HOWTO(BFD_RELOC_NS32K_IMM_32, 0, 2, 32, false, 0, true, - ns32k_reloc_imm, "NS32K_IMM_32", - true, 0xffffffff,0xffffffff, false), -HOWTO(BFD_RELOC_NS32K_IMM_8_PCREL, 0, 0, 8, true, 0, false, - ns32k_reloc_imm, "PCREL_NS32K_IMM_8", - true, 0x000000ff, 0x000000ff, false), -HOWTO(BFD_RELOC_NS32K_IMM_16_PCREL, 0, 1, 16, true, 0, false, - ns32k_reloc_imm, "PCREL_NS32K_IMM_16", - true, 0x0000ffff,0x0000ffff, false), -HOWTO(BFD_RELOC_NS32K_IMM_32_PCREL, 0, 2, 32, true, 0, false, - ns32k_reloc_imm, "PCREL_NS32K_IMM_32", - true, 0xffffffff,0xffffffff, false), - -/* ns32k displacements */ -HOWTO(BFD_RELOC_NS32K_DISP_8, 0, 0, 8, false, 0, true, - ns32k_reloc_disp, "NS32K_DISP_8", - true, 0x000000ff,0x000000ff, false), -HOWTO(BFD_RELOC_NS32K_DISP_16, 0, 1, 16, false, 0, true, - ns32k_reloc_disp, "NS32K_DISP_16", - true, 0x0000ffff, 0x0000ffff, false), -HOWTO(BFD_RELOC_NS32K_DISP_32, 0, 2, 32, false, 0, true, - ns32k_reloc_disp, "NS32K_DISP_32", - true, 0xffffffff, 0xffffffff, false), -HOWTO(BFD_RELOC_NS32K_DISP_8_PCREL, 0, 0, 8, true, 0, false, - ns32k_reloc_disp, "PCREL_NS32K_DISP_8", - true, 0x000000ff,0x000000ff, false), -HOWTO(BFD_RELOC_NS32K_DISP_16_PCREL, 0, 1, 16, true, 0, false, - ns32k_reloc_disp, "PCREL_NS32K_DISP_16", - true, 0x0000ffff,0x0000ffff, false), -HOWTO(BFD_RELOC_NS32K_DISP_32_PCREL, 0, 2, 32, true, 0, false, - ns32k_reloc_disp, "PCREL_NS32K_DISP_32", - true, 0xffffffff,0xffffffff, false), - -/* Normal 2's complement */ -HOWTO(BFD_RELOC_8, 0, 0, 8, false, 0, complain_overflow_bitfield,0, - "8", true, 0x000000ff,0x000000ff, false), -HOWTO(BFD_RELOC_16, 0, 1, 16, false, 0, complain_overflow_bitfield,0, - "16", true, 0x0000ffff,0x0000ffff, false), -HOWTO(BFD_RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield,0, - "32", true, 0xffffffff,0xffffffff, false), -HOWTO(BFD_RELOC_8_PCREL, 0, 0, 8, true, 0, complain_overflow_signed, 0, - "PCREL_8", true, 0x000000ff,0x000000ff, false), -HOWTO(BFD_RELOC_16_PCREL, 0, 1, 16, true, 0, complain_overflow_signed, 0, - "PCREL_16", true, 0x0000ffff,0x0000ffff, false), -HOWTO(BFD_RELOC_32_PCREL, 0, 2, 32, true, 0, complain_overflow_signed, 0, - "PCREL_32", true, 0xffffffff,0xffffffff, false), -}; - - -#define CTOR_TABLE_RELOC_HOWTO(BFD) (MY(howto_table) + 14) - -#define RELOC_STD_BITS_NS32K_TYPE_BIG 0x06 -#define RELOC_STD_BITS_NS32K_TYPE_LITTLE 0x60 -#define RELOC_STD_BITS_NS32K_TYPE_SH_BIG 1 -#define RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE 5 - -reloc_howto_type * -MY(reloc_howto)(abfd, rel, r_index, r_extern, r_pcrel) - bfd *abfd; - struct reloc_std_external *rel; - int *r_index; - int *r_extern; - int *r_pcrel; -{ - unsigned int r_length; - int r_ns32k_type; -/* BFD_ASSERT(bfd_header_little_endian (abfd)); */ - *r_index = ((rel->r_index[2] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[0] ); - *r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE)); - *r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE)); - r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) - >> RELOC_STD_BITS_LENGTH_SH_LITTLE); - r_ns32k_type = ((rel->r_type[0] & RELOC_STD_BITS_NS32K_TYPE_LITTLE) - >> RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE); - return (MY(howto_table) + r_length + 3 * (*r_pcrel) + 6 * r_ns32k_type); -} - -#define MY_reloc_howto(BFD,REL,IN,EX,PC) MY(reloc_howto)(BFD, REL, &IN, &EX, &PC) - -void -MY(put_reloc)(abfd, r_extern, r_index, value, howto, reloc) - bfd *abfd; - int r_extern; - int r_index; - long value; - reloc_howto_type *howto; - struct reloc_std_external *reloc; -{ - unsigned int r_length; - int r_pcrel; - int r_ns32k_type; - PUT_WORD (abfd, value, reloc->r_address); - r_length = howto->size ; /* Size as a power of two */ - r_pcrel = (int) howto->pc_relative; /* Relative to PC? */ - r_ns32k_type = (howto - MY(howto_table) )/6; -/* BFD_ASSERT (bfd_header_little_endian (abfd)); */ - reloc->r_index[2] = r_index >> 16; - reloc->r_index[1] = r_index >> 8; - reloc->r_index[0] = r_index; - reloc->r_type[0] = - (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0) - | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE) - | (r_ns32k_type << RELOC_STD_BITS_NS32K_TYPE_SH_LITTLE); -} - -#define MY_put_reloc(BFD, EXT, IDX, VAL, HOWTO, RELOC) \ - MY(put_reloc)(BFD, EXT, IDX, VAL, HOWTO, RELOC) - -#define STAT_FOR_EXEC - -#define MY_final_link_relocate ns32k_final_link_relocate -#define MY_relocate_contents ns32k_relocate_contents - -#include <aoutx.h> - -reloc_howto_type * - MY(bfd_reloc_type_lookup)(abfd,code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - -#define ENTRY(i,j) case i: return &MY(howto_table)[j] - - int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE; - - BFD_ASSERT(ext == 0); - if (code == BFD_RELOC_CTOR) - switch (bfd_get_arch_info (abfd)->bits_per_address) - { - case 32: - code = BFD_RELOC_32; - break; - } - switch (code) - { - ENTRY(BFD_RELOC_NS32K_IMM_8, 0); - ENTRY(BFD_RELOC_NS32K_IMM_16, 1); - ENTRY(BFD_RELOC_NS32K_IMM_32, 2); - ENTRY(BFD_RELOC_NS32K_IMM_8_PCREL, 3); - ENTRY(BFD_RELOC_NS32K_IMM_16_PCREL, 4); - ENTRY(BFD_RELOC_NS32K_IMM_32_PCREL, 5); - ENTRY(BFD_RELOC_NS32K_DISP_8, 6); - ENTRY(BFD_RELOC_NS32K_DISP_16, 7); - ENTRY(BFD_RELOC_NS32K_DISP_32, 8); - ENTRY(BFD_RELOC_NS32K_DISP_8_PCREL, 9); - ENTRY(BFD_RELOC_NS32K_DISP_16_PCREL, 10); - ENTRY(BFD_RELOC_NS32K_DISP_32_PCREL, 11); - ENTRY(BFD_RELOC_8, 12); - ENTRY(BFD_RELOC_16, 13); - ENTRY(BFD_RELOC_32, 14); - ENTRY(BFD_RELOC_8_PCREL, 15); - ENTRY(BFD_RELOC_16_PCREL, 16); - ENTRY(BFD_RELOC_32_PCREL, 17); - default: return (reloc_howto_type *) NULL; - } -#undef ENTRY -} - - -static void -MY_swap_std_reloc_in (abfd, bytes, cache_ptr, symbols, symcount) - bfd *abfd; - struct reloc_std_external *bytes; - arelent *cache_ptr; - asymbol **symbols; - bfd_size_type symcount; -{ - int r_index; - int r_extern; - int r_pcrel; - struct aoutdata *su = &(abfd->tdata.aout_data->a); - - cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address); - - /* now the fun stuff */ - - cache_ptr->howto = MY_reloc_howto(abfd, bytes, r_index, r_extern, r_pcrel); - - MOVE_ADDRESS(0); -} - -static void -MY_swap_std_reloc_out (abfd, g, natptr) - bfd *abfd; - arelent *g; - struct reloc_std_external *natptr; -{ - int r_index; - asymbol *sym = *(g->sym_ptr_ptr); - int r_extern; - unsigned int r_addend; - asection *output_section = sym->section->output_section; - - r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; - - /* name was clobbered by aout_write_syms to be symbol index */ - - /* If this relocation is relative to a symbol then set the - r_index to the symbols index, and the r_extern bit. - - Absolute symbols can come in in two ways, either as an offset - from the abs section, or as a symbol which has an abs value. - Check for that here. */ - - if (bfd_is_com_section (output_section) - || output_section == &bfd_abs_section - || output_section == &bfd_und_section) - { - if (bfd_abs_section.symbol == sym) - { - /* Whoops, looked like an abs symbol, but is really an offset - from the abs section */ - r_index = 0; - r_extern = 0; - } - else - { - /* Fill in symbol */ - r_extern = 1; -#undef KEEPIT -#define KEEPIT udata.i - r_index = (*(g->sym_ptr_ptr))->KEEPIT; -#undef KEEPIT - } - } - else - { - /* Just an ordinary section */ - r_extern = 0; - r_index = output_section->target_index; - } - - MY_put_reloc (abfd, r_extern, r_index, g->address, g->howto, natptr); -} - -bfd_reloc_status_type -ns32k_relocate_contents (howto, input_bfd, relocation, location) - reloc_howto_type *howto; - bfd *input_bfd; - bfd_vma relocation; - bfd_byte *location; -{ - int r_ns32k_type = (howto - MY(howto_table)) / 6; - long (*get_data)(); - int (*put_data)(); - - switch (r_ns32k_type) - { - case 0: - get_data = ns32k_get_immediate; - put_data = ns32k_put_immediate; - break; - case 1: - get_data = ns32k_get_displacement; - put_data = ns32k_put_displacement; - break; - case 2: - return _bfd_relocate_contents (howto, input_bfd, relocation, - location); - /* NOT REACHED */ - break; - } - return do_ns32k_reloc_contents (howto, input_bfd, relocation, - location, get_data, put_data); -} diff --git a/contrib/gdb/bfd/aout0.c b/contrib/gdb/bfd/aout0.c deleted file mode 100644 index 5bc7ae0..0000000 --- a/contrib/gdb/bfd/aout0.c +++ /dev/null @@ -1,32 +0,0 @@ -/* BFD backend for SunOS style a.out with flags set to 0 - Copyright (C) 1990, 91, 92, 93, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - -#define TARGETNAME "a.out-zero-big" -#define MY(OP) CAT(aout0_big_,OP) - -#include "bfd.h" - -#define MY_exec_hdr_flags 0 - -#define MACHTYPE_OK(mtype) \ - ((mtype) == M_UNKNOWN || (mtype) == M_68010 || (mtype) == M_68020) - -/* Include the usual a.out support. */ -#include "aoutf1.h" diff --git a/contrib/gdb/bfd/aout64.c b/contrib/gdb/bfd/aout64.c deleted file mode 100644 index 84036c8..0000000 --- a/contrib/gdb/bfd/aout64.c +++ /dev/null @@ -1,31 +0,0 @@ -/* BFD back-end for 64-bit a.out files. - Copyright 1990, 1991, 1992 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - -#define ARCH_SIZE 64 - -/* aoutx.h requires definitions for BMAGIC and QMAGIC. */ -#ifndef BMAGIC -#define BMAGIC 0 -#endif -#ifndef QMAGIC -#define QMAGIC 0 -#endif - -#include "aoutx.h" diff --git a/contrib/gdb/bfd/aoutf1.h b/contrib/gdb/bfd/aoutf1.h deleted file mode 100644 index 690d528..0000000 --- a/contrib/gdb/bfd/aoutf1.h +++ /dev/null @@ -1,788 +0,0 @@ -/* A.out "format 1" file handling code for BFD. - Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#include "aout/sun4.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -#include "aout/aout64.h" -#include "aout/stab_gnu.h" -#include "aout/ar.h" - -/* This is needed to reject a NewsOS file, e.g. in - gdb/testsuite/gdb.t10/crossload.exp. <kingdon@cygnus.com> - I needed to add M_UNKNOWN to recognize a 68000 object, so this will - probably no longer reject a NewsOS object. <ian@cygnus.com>. */ -#ifndef MACHTYPE_OK -#define MACHTYPE_OK(mtype) \ - (((mtype) == M_SPARC && bfd_lookup_arch (bfd_arch_sparc, 0) != NULL) \ - || (((mtype) == M_UNKNOWN || (mtype) == M_68010 || (mtype) == M_68020) \ - && bfd_lookup_arch (bfd_arch_m68k, 0) != NULL)) -#endif - -/* -The file @code{aoutf1.h} contains the code for BFD's -a.out back end. Control over the generated back end is given by these -two preprocessor names: -@table @code -@item ARCH_SIZE -This value should be either 32 or 64, depending upon the size of an -int in the target format. It changes the sizes of the structs which -perform the memory/disk mapping of structures. - -The 64 bit backend may only be used if the host compiler supports 64 -ints (eg long long with gcc), by defining the name @code{BFD_HOST_64_BIT} in @code{bfd.h}. -With this name defined, @emph{all} bfd operations are performed with 64bit -arithmetic, not just those to a 64bit target. - -@item TARGETNAME -The name put into the target vector. -@item -@end table - -*/ - -/*SUPPRESS558*/ -/*SUPPRESS529*/ - -static void -#if ARCH_SIZE == 64 -sunos_64_set_arch_mach -#else -sunos_32_set_arch_mach -#endif - (abfd, machtype) - bfd *abfd; - int machtype; -{ - /* Determine the architecture and machine type of the object file. */ - enum bfd_architecture arch; - long machine; - switch (machtype) - { - - case M_UNKNOWN: - /* Some Sun3s make magic numbers without cpu types in them, so - we'll default to the 68000. */ - arch = bfd_arch_m68k; - machine = 68000; - break; - - case M_68010: - case M_HP200: - arch = bfd_arch_m68k; - machine = 68010; - break; - - case M_68020: - case M_HP300: - arch = bfd_arch_m68k; - machine = 68020; - break; - - case M_SPARC: - arch = bfd_arch_sparc; - machine = 0; - break; - - case M_386: - case M_386_DYNIX: - arch = bfd_arch_i386; - machine = 0; - break; - - case M_29K: - arch = bfd_arch_a29k; - machine = 0; - break; - - case M_HPUX: - arch = bfd_arch_m68k; - machine = 0; - break; - - default: - arch = bfd_arch_obscure; - machine = 0; - break; - } - bfd_set_arch_mach (abfd, arch, machine); -} - -#define SET_ARCH_MACH(ABFD, EXEC) \ - NAME(sunos,set_arch_mach)(ABFD, N_MACHTYPE (EXEC)); \ - choose_reloc_size(ABFD); - -/* Determine the size of a relocation entry, based on the architecture */ -static void -choose_reloc_size (abfd) - bfd *abfd; -{ - switch (bfd_get_arch (abfd)) - { - case bfd_arch_sparc: - case bfd_arch_a29k: - obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE; - break; - default: - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - break; - } -} - -/* Write an object file in SunOS format. - Section contents have already been written. We write the - file header, symbols, and relocation. */ - -static boolean -#if ARCH_SIZE == 64 -aout_64_sunos4_write_object_contents -#else -aout_32_sunos4_write_object_contents -#endif - (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - - /* Magic number, maestro, please! */ - switch (bfd_get_arch (abfd)) - { - case bfd_arch_m68k: - switch (bfd_get_mach (abfd)) - { - case 68000: - N_SET_MACHTYPE (*execp, M_UNKNOWN); - break; - case 68010: - N_SET_MACHTYPE (*execp, M_68010); - break; - default: - case 68020: - N_SET_MACHTYPE (*execp, M_68020); - break; - } - break; - case bfd_arch_sparc: - N_SET_MACHTYPE (*execp, M_SPARC); - break; - case bfd_arch_i386: - N_SET_MACHTYPE (*execp, M_386); - break; - case bfd_arch_a29k: - N_SET_MACHTYPE (*execp, M_29K); - break; - default: - N_SET_MACHTYPE (*execp, M_UNKNOWN); - } - - choose_reloc_size (abfd); - - N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags); - - N_SET_DYNAMIC (*execp, bfd_get_file_flags (abfd) & DYNAMIC); - - WRITE_HEADERS (abfd, execp); - - return true; -} - -/* core files */ - -#define CORE_MAGIC 0x080456 -#define CORE_NAMELEN 16 - -/* The core structure is taken from the Sun documentation. - Unfortunately, they don't document the FPA structure, or at least I - can't find it easily. Fortunately the core header contains its own - length. So this shouldn't cause problems, except for c_ucode, which - so far we don't use but is easy to find with a little arithmetic. */ - -/* But the reg structure can be gotten from the SPARC processor handbook. - This really should be in a GNU include file though so that gdb can use - the same info. */ -struct regs -{ - int r_psr; - int r_pc; - int r_npc; - int r_y; - int r_g1; - int r_g2; - int r_g3; - int r_g4; - int r_g5; - int r_g6; - int r_g7; - int r_o0; - int r_o1; - int r_o2; - int r_o3; - int r_o4; - int r_o5; - int r_o6; - int r_o7; -}; - -/* Taken from Sun documentation: */ - -/* FIXME: It's worse than we expect. This struct contains TWO substructs - neither of whose size we know, WITH STUFF IN BETWEEN THEM! We can't - even portably access the stuff in between! */ - -struct external_sparc_core - { - int c_magic; /* Corefile magic number */ - int c_len; /* Sizeof (struct core) */ -#define SPARC_CORE_LEN 432 - int c_regs[19]; /* General purpose registers -- MACHDEP SIZE */ - struct external_exec c_aouthdr; /* A.out header */ - int c_signo; /* Killing signal, if any */ - int c_tsize; /* Text size (bytes) */ - int c_dsize; /* Data size (bytes) */ - int c_ssize; /* Stack size (bytes) */ - char c_cmdname[CORE_NAMELEN + 1]; /* Command name */ - double fp_stuff[1]; /* external FPU state (size unknown by us) */ - /* The type "double" is critical here, for alignment. - SunOS declares a struct here, but the struct's alignment - is double since it contains doubles. */ - int c_ucode; /* Exception no. from u_code */ - /* (this member is not accessible by name since we don't - portably know the size of fp_stuff.) */ - }; - -/* Core files generated by the BCP (the part of Solaris which allows - it to run SunOS4 a.out files). */ -struct external_solaris_bcp_core - { - int c_magic; /* Corefile magic number */ - int c_len; /* Sizeof (struct core) */ -#define SOLARIS_BCP_CORE_LEN 456 - int c_regs[19]; /* General purpose registers -- MACHDEP SIZE */ - int c_exdata_vp; /* exdata structure */ - int c_exdata_tsize; - int c_exdata_dsize; - int c_exdata_bsize; - int c_exdata_lsize; - int c_exdata_nshlibs; - short c_exdata_mach; - short c_exdata_mag; - int c_exdata_toffset; - int c_exdata_doffset; - int c_exdata_loffset; - int c_exdata_txtorg; - int c_exdata_datorg; - int c_exdata_entloc; - int c_signo; /* Killing signal, if any */ - int c_tsize; /* Text size (bytes) */ - int c_dsize; /* Data size (bytes) */ - int c_ssize; /* Stack size (bytes) */ - char c_cmdname[CORE_NAMELEN + 1]; /* Command name */ - double fp_stuff[1]; /* external FPU state (size unknown by us) */ - /* The type "double" is critical here, for alignment. - SunOS declares a struct here, but the struct's alignment - is double since it contains doubles. */ - int c_ucode; /* Exception no. from u_code */ - /* (this member is not accessible by name since we don't - portably know the size of fp_stuff.) */ - }; - -struct external_sun3_core - { - int c_magic; /* Corefile magic number */ - int c_len; /* Sizeof (struct core) */ -#define SUN3_CORE_LEN 826 /* As of SunOS 4.1.1 */ - int c_regs[18]; /* General purpose registers -- MACHDEP SIZE */ - struct external_exec c_aouthdr; /* A.out header */ - int c_signo; /* Killing signal, if any */ - int c_tsize; /* Text size (bytes) */ - int c_dsize; /* Data size (bytes) */ - int c_ssize; /* Stack size (bytes) */ - char c_cmdname[CORE_NAMELEN + 1]; /* Command name */ - double fp_stuff[1]; /* external FPU state (size unknown by us) */ - /* The type "double" is critical here, for alignment. - SunOS declares a struct here, but the struct's alignment - is double since it contains doubles. */ - int c_ucode; /* Exception no. from u_code */ - /* (this member is not accessible by name since we don't - portably know the size of fp_stuff.) */ - }; - -struct internal_sunos_core - { - int c_magic; /* Corefile magic number */ - int c_len; /* Sizeof (struct core) */ - long c_regs_pos; /* file offset of General purpose registers */ - int c_regs_size; /* size of General purpose registers */ - struct internal_exec c_aouthdr; /* A.out header */ - int c_signo; /* Killing signal, if any */ - int c_tsize; /* Text size (bytes) */ - int c_dsize; /* Data size (bytes) */ - bfd_vma c_data_addr; /* Data start (address) */ - int c_ssize; /* Stack size (bytes) */ - bfd_vma c_stacktop; /* Stack top (address) */ - char c_cmdname[CORE_NAMELEN + 1]; /* Command name */ - long fp_stuff_pos; /* file offset of external FPU state (regs) */ - int fp_stuff_size; /* Size of it */ - int c_ucode; /* Exception no. from u_code */ - }; - -/* byte-swap in the Sun-3 core structure */ -static void -swapcore_sun3 (abfd, ext, intcore) - bfd *abfd; - char *ext; - struct internal_sunos_core *intcore; -{ - struct external_sun3_core *extcore = (struct external_sun3_core *) ext; - - intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_magic); - intcore->c_len = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_len); - intcore->c_regs_pos = (long) (((struct external_sun3_core *) 0)->c_regs); - intcore->c_regs_size = sizeof (extcore->c_regs); -#if ARCH_SIZE == 64 - aout_64_swap_exec_header_in -#else - aout_32_swap_exec_header_in -#endif - (abfd, &extcore->c_aouthdr, &intcore->c_aouthdr); - intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_signo); - intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_tsize); - intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_dsize); - intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr); - intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_ssize); - memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname)); - intcore->fp_stuff_pos = (long) (((struct external_sun3_core *) 0)->fp_stuff); - /* FP stuff takes up whole rest of struct, except c_ucode. */ - intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) - - (file_ptr) (((struct external_sun3_core *) 0)->fp_stuff); - /* Ucode is the last thing in the struct -- just before the end */ - intcore->c_ucode = - bfd_h_get_32 (abfd, - intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *) extcore); - intcore->c_stacktop = 0x0E000000; /* By experimentation */ -} - - -/* byte-swap in the Sparc core structure */ -static void -swapcore_sparc (abfd, ext, intcore) - bfd *abfd; - char *ext; - struct internal_sunos_core *intcore; -{ - struct external_sparc_core *extcore = (struct external_sparc_core *) ext; - - intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_magic); - intcore->c_len = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_len); - intcore->c_regs_pos = (long) (((struct external_sparc_core *) 0)->c_regs); - intcore->c_regs_size = sizeof (extcore->c_regs); -#if ARCH_SIZE == 64 - aout_64_swap_exec_header_in -#else - aout_32_swap_exec_header_in -#endif - (abfd, &extcore->c_aouthdr, &intcore->c_aouthdr); - intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_signo); - intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_tsize); - intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_dsize); - intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr); - intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_ssize); - memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname)); - intcore->fp_stuff_pos = (long) (((struct external_sparc_core *) 0)->fp_stuff); - /* FP stuff takes up whole rest of struct, except c_ucode. */ - intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) - - (file_ptr) (((struct external_sparc_core *) 0)->fp_stuff); - /* Ucode is the last thing in the struct -- just before the end */ - intcore->c_ucode = - bfd_h_get_32 (abfd, - intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *) extcore); - - /* Supposedly the user stack grows downward from the bottom of kernel memory. - Presuming that this remains true, this definition will work. */ - /* Now sun has provided us with another challenge. The value is different - for sparc2 and sparc10 (both running SunOS 4.1.3). We pick one or - the other based on the current value of the stack pointer. This - loses (a) if the stack pointer has been clobbered, or (b) if the stack - is larger than 128 megabytes. - - It's times like these you're glad they're switching to ELF. - - Note that using include files or nlist on /vmunix would be wrong, - because we want the value for this core file, no matter what kind of - machine we were compiled on or are running on. */ -#define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000) -#define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000) - { - bfd_vma sp = bfd_h_get_32 - (abfd, (unsigned char *) &((struct regs *) &extcore->c_regs[0])->r_o6); - if (sp < SPARC_USRSTACK_SPARC10) - intcore->c_stacktop = SPARC_USRSTACK_SPARC10; - else - intcore->c_stacktop = SPARC_USRSTACK_SPARC2; - } -} - -/* byte-swap in the Solaris BCP core structure */ -static void -swapcore_solaris_bcp (abfd, ext, intcore) - bfd *abfd; - char *ext; - struct internal_sunos_core *intcore; -{ - struct external_solaris_bcp_core *extcore = - (struct external_solaris_bcp_core *) ext; - - intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_magic); - intcore->c_len = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_len); - intcore->c_regs_pos = (long) (((struct external_solaris_bcp_core *) 0)->c_regs); - intcore->c_regs_size = sizeof (extcore->c_regs); - - /* The Solaris BCP exdata structure does not contain an a_syms field, - so we are unable to synthesize an internal exec header. - Luckily we are able to figure out the start address of the data section, - which is the only thing needed from the internal exec header, - from the exdata structure. - - As of Solaris 2.3, BCP core files for statically linked executables - are buggy. The exdata structure is not properly filled in, and - the data section is written from address zero instead of the data - start address. */ - memset ((PTR) &intcore->c_aouthdr, 0, sizeof (struct internal_exec)); - intcore->c_data_addr = - bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_exdata_datorg); - intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_signo); - intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_tsize); - intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_dsize); - intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_ssize); - memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname)); - intcore->fp_stuff_pos = - (long) (((struct external_solaris_bcp_core *) 0)->fp_stuff); - /* FP stuff takes up whole rest of struct, except c_ucode. */ - intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) - - (file_ptr) (((struct external_solaris_bcp_core *) 0)->fp_stuff); - /* Ucode is the last thing in the struct -- just before the end */ - intcore->c_ucode = - bfd_h_get_32 (abfd, - intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *) extcore); - - /* Supposedly the user stack grows downward from the bottom of kernel memory. - Presuming that this remains true, this definition will work. */ - /* Now sun has provided us with another challenge. The value is different - for sparc2 and sparc10 (both running SunOS 4.1.3). We pick one or - the other based on the current value of the stack pointer. This - loses (a) if the stack pointer has been clobbered, or (b) if the stack - is larger than 128 megabytes. - - It's times like these you're glad they're switching to ELF. - - Note that using include files or nlist on /vmunix would be wrong, - because we want the value for this core file, no matter what kind of - machine we were compiled on or are running on. */ -#define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000) -#define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000) - { - bfd_vma sp = bfd_h_get_32 - (abfd, (unsigned char *) &((struct regs *) &extcore->c_regs[0])->r_o6); - if (sp < SPARC_USRSTACK_SPARC10) - intcore->c_stacktop = SPARC_USRSTACK_SPARC10; - else - intcore->c_stacktop = SPARC_USRSTACK_SPARC2; - } -} - -/* need this cast because ptr is really void * */ -#define core_hdr(bfd) ((bfd)->tdata.sun_core_data) -#define core_datasec(bfd) (core_hdr(bfd)->data_section) -#define core_stacksec(bfd) (core_hdr(bfd)->stack_section) -#define core_regsec(bfd) (core_hdr(bfd)->reg_section) -#define core_reg2sec(bfd) (core_hdr(bfd)->reg2_section) - -/* These are stored in the bfd's tdata */ -struct sun_core_struct -{ - struct internal_sunos_core *hdr; /* core file header */ - asection *data_section; - asection *stack_section; - asection *reg_section; - asection *reg2_section; -}; - -static const bfd_target * -sunos4_core_file_p (abfd) - bfd *abfd; -{ - unsigned char longbuf[4]; /* Raw bytes of various header fields */ - bfd_size_type core_size; - unsigned long core_mag; - struct internal_sunos_core *core; - char *extcore; - struct mergem - { - struct sun_core_struct suncoredata; - struct internal_sunos_core internal_sunos_core; - char external_core[1]; - } - *mergem; - - if (bfd_read ((PTR) longbuf, 1, sizeof (longbuf), abfd) != - sizeof (longbuf)) - return 0; - core_mag = bfd_h_get_32 (abfd, longbuf); - - if (core_mag != CORE_MAGIC) - return 0; - - /* SunOS core headers can vary in length; second word is size; */ - if (bfd_read ((PTR) longbuf, 1, sizeof (longbuf), abfd) != - sizeof (longbuf)) - return 0; - core_size = bfd_h_get_32 (abfd, longbuf); - /* Sanity check */ - if (core_size > 20000) - return 0; - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) < 0) - return 0; - - mergem = (struct mergem *) bfd_zalloc (abfd, core_size + sizeof (struct mergem)); - if (mergem == NULL) - return 0; - - extcore = mergem->external_core; - - if ((bfd_read ((PTR) extcore, 1, core_size, abfd)) != core_size) - { - bfd_release (abfd, (char *) mergem); - return 0; - } - - /* Validate that it's a core file we know how to handle, due to sun - botching the positioning of registers and other fields in a machine - dependent way. */ - core = &mergem->internal_sunos_core; - switch (core_size) - { - case SPARC_CORE_LEN: - swapcore_sparc (abfd, extcore, core); - break; - case SUN3_CORE_LEN: - swapcore_sun3 (abfd, extcore, core); - break; - case SOLARIS_BCP_CORE_LEN: - swapcore_solaris_bcp (abfd, extcore, core); - break; - default: - bfd_set_error (bfd_error_system_call); /* FIXME */ - bfd_release (abfd, (char *) mergem); - return 0; - } - - abfd->tdata.sun_core_data = &mergem->suncoredata; - abfd->tdata.sun_core_data->hdr = core; - - /* create the sections. This is raunchy, but bfd_close wants to reclaim - them */ - core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_stacksec (abfd) == NULL) - { - loser: - bfd_release (abfd, (char *) mergem); - return 0; - } - core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_datasec (abfd) == NULL) - { - loser1: - bfd_release (abfd, core_stacksec (abfd)); - goto loser; - } - core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_regsec (abfd) == NULL) - { - loser2: - bfd_release (abfd, core_datasec (abfd)); - goto loser1; - } - core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_reg2sec (abfd) == NULL) - { - bfd_release (abfd, core_regsec (abfd)); - goto loser2; - } - - core_stacksec (abfd)->name = ".stack"; - core_datasec (abfd)->name = ".data"; - core_regsec (abfd)->name = ".reg"; - core_reg2sec (abfd)->name = ".reg2"; - - core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - core_regsec (abfd)->flags = SEC_HAS_CONTENTS; - core_reg2sec (abfd)->flags = SEC_HAS_CONTENTS; - - core_stacksec (abfd)->_raw_size = core->c_ssize; - core_datasec (abfd)->_raw_size = core->c_dsize; - core_regsec (abfd)->_raw_size = core->c_regs_size; - core_reg2sec (abfd)->_raw_size = core->fp_stuff_size; - - core_stacksec (abfd)->vma = (core->c_stacktop - core->c_ssize); - core_datasec (abfd)->vma = core->c_data_addr; - core_regsec (abfd)->vma = 0; - core_reg2sec (abfd)->vma = 0; - - core_stacksec (abfd)->filepos = core->c_len + core->c_dsize; - core_datasec (abfd)->filepos = core->c_len; - /* We'll access the regs afresh in the core file, like any section: */ - core_regsec (abfd)->filepos = (file_ptr) core->c_regs_pos; - core_reg2sec (abfd)->filepos = (file_ptr) core->fp_stuff_pos; - - /* Align to word at least */ - core_stacksec (abfd)->alignment_power = 2; - core_datasec (abfd)->alignment_power = 2; - core_regsec (abfd)->alignment_power = 2; - core_reg2sec (abfd)->alignment_power = 2; - - abfd->sections = core_stacksec (abfd); - core_stacksec (abfd)->next = core_datasec (abfd); - core_datasec (abfd)->next = core_regsec (abfd); - core_regsec (abfd)->next = core_reg2sec (abfd); - - abfd->section_count = 4; - - return abfd->xvec; -} - -static char * -sunos4_core_file_failing_command (abfd) - bfd *abfd; -{ - return core_hdr (abfd)->hdr->c_cmdname; -} - -static int -sunos4_core_file_failing_signal (abfd) - bfd *abfd; -{ - return core_hdr (abfd)->hdr->c_signo; -} - -static boolean -sunos4_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd; - bfd *exec_bfd; -{ - if (core_bfd->xvec != exec_bfd->xvec) - { - bfd_set_error (bfd_error_system_call); - return false; - } - - /* Solaris core files do not include an aouthdr. */ - if ((core_hdr (core_bfd)->hdr)->c_len == SOLARIS_BCP_CORE_LEN) - return true; - - return (memcmp ((char *) &((core_hdr (core_bfd)->hdr)->c_aouthdr), - (char *) exec_hdr (exec_bfd), - sizeof (struct internal_exec)) == 0) ? true : false; -} - -#define MY_set_sizes sunos4_set_sizes -static boolean -sunos4_set_sizes (abfd) - bfd *abfd; -{ - switch (bfd_get_arch (abfd)) - { - default: - return false; - case bfd_arch_sparc: - adata (abfd).page_size = 0x2000; - adata (abfd).segment_size = 0x2000; - adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE; - return true; - case bfd_arch_m68k: - adata (abfd).page_size = 0x2000; - adata (abfd).segment_size = 0x20000; - adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE; - return true; - } -} - -/* We default to setting the toolversion field to 1, as is required by - SunOS. */ -#ifndef MY_exec_hdr_flags -#define MY_exec_hdr_flags 1 -#endif - -#ifndef MY_add_dynamic_symbols -#define MY_add_dynamic_symbols 0 -#endif -#ifndef MY_add_one_symbol -#define MY_add_one_symbol 0 -#endif -#ifndef MY_link_dynamic_object -#define MY_link_dynamic_object 0 -#endif -#ifndef MY_write_dynamic_symbol -#define MY_write_dynamic_symbol 0 -#endif -#ifndef MY_check_dynamic_reloc -#define MY_check_dynamic_reloc 0 -#endif -#ifndef MY_finish_dynamic_link -#define MY_finish_dynamic_link 0 -#endif - -static CONST struct aout_backend_data sunos4_aout_backend = -{ - 0, /* zmagic files are not contiguous */ - 1, /* text includes header */ - MY_exec_hdr_flags, - 0, /* default text vma */ - sunos4_set_sizes, - 0, /* header is counted in zmagic text */ - MY_add_dynamic_symbols, - MY_add_one_symbol, - MY_link_dynamic_object, - MY_write_dynamic_symbol, - MY_check_dynamic_reloc, - MY_finish_dynamic_link -}; - -#define MY_core_file_failing_command sunos4_core_file_failing_command -#define MY_core_file_failing_signal sunos4_core_file_failing_signal -#define MY_core_file_matches_executable_p sunos4_core_file_matches_executable_p - -#define MY_bfd_debug_info_start bfd_void -#define MY_bfd_debug_info_end bfd_void -#define MY_bfd_debug_info_accumulate \ - (void (*) PARAMS ((bfd *, struct sec *))) bfd_void -#define MY_core_file_p sunos4_core_file_p -#define MY_write_object_contents NAME(aout,sunos4_write_object_contents) -#define MY_backend_data &sunos4_aout_backend - -#define TARGET_IS_BIG_ENDIAN_P - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/bfd-in2.h b/contrib/gdb/bfd/bfd-in2.h deleted file mode 100644 index d238d5a..0000000 --- a/contrib/gdb/bfd/bfd-in2.h +++ /dev/null @@ -1,2479 +0,0 @@ -/* Main header file for the bfd library -- portable access to object files. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Contributed by Cygnus Support. - -** NOTE: bfd.h and bfd-in2.h are GENERATED files. Don't change them; -** instead, change bfd-in.h or the other BFD source files processed to -** generate these files. - -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. */ - -/* bfd.h -- The only header file required by users of the bfd library - -The bfd.h file is generated from bfd-in.h and various .c files; if you -change it, your changes will probably be lost. - -All the prototypes and definitions following the comment "THE FOLLOWING -IS EXTRACTED FROM THE SOURCE" are extracted from the source files for -BFD. If you change it, someone oneday will extract it from the source -again, and your changes will be lost. To save yourself from this bind, -change the definitions in the source in the bfd directory. Type "make -docs" and then "make headers" in that directory, and magically this file -will change to reflect your changes. - -If you don't have the tools to perform the extraction, then you are -safe from someone on your system trampling over your header files. -You should still maintain the equivalence between the source and this -file though; every change you make to the .c file should be reflected -here. */ - -#ifndef __BFD_H_SEEN__ -#define __BFD_H_SEEN__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "ansidecl.h" -#include "obstack.h" - -/* These two lines get substitutions done by commands in Makefile.in. */ -#define BFD_VERSION "@VERSION@" -#define BFD_ARCH_SIZE @WORDSIZE@ -#define BFD_HOST_64BIT_LONG @BFD_HOST_64BIT_LONG@ - -#if BFD_ARCH_SIZE >= 64 -#define BFD64 -#endif - -#ifndef INLINE -#if __GNUC__ >= 2 -#define INLINE __inline__ -#else -#define INLINE -#endif -#endif - -/* forward declaration */ -typedef struct _bfd bfd; - -/* To squelch erroneous compiler warnings ("illegal pointer - combination") from the SVR3 compiler, we would like to typedef - boolean to int (it doesn't like functions which return boolean. - Making sure they are never implicitly declared to return int - doesn't seem to help). But this file is not configured based on - the host. */ -/* General rules: functions which are boolean return true on success - and false on failure (unless they're a predicate). -- bfd.doc */ -/* I'm sure this is going to break something and someone is going to - force me to change it. */ -/* typedef enum boolean {false, true} boolean; */ -/* Yup, SVR4 has a "typedef enum boolean" in <sys/types.h> -fnf */ -/* It gets worse if the host also defines a true/false enum... -sts */ -/* And even worse if your compiler has built-in boolean types... -law */ -#if defined (__GNUG__) && (__GNUC_MINOR__ > 5) -#define TRUE_FALSE_ALREADY_DEFINED -#endif -#ifdef MPW -/* Pre-emptive strike - get the file with the enum. */ -#include <Types.h> -#define TRUE_FALSE_ALREADY_DEFINED -#endif /* MPW */ -#ifndef TRUE_FALSE_ALREADY_DEFINED -typedef enum bfd_boolean {false, true} boolean; -#define BFD_TRUE_FALSE -#else -/* Use enum names that will appear nowhere else. */ -typedef enum bfd_boolean {bfd_fffalse, bfd_tttrue} boolean; -#endif - -/* A pointer to a position in a file. */ -/* FIXME: This should be using off_t from <sys/types.h>. - For now, try to avoid breaking stuff by not including <sys/types.h> here. - This will break on systems with 64-bit file offsets (e.g. 4.4BSD). - Probably the best long-term answer is to avoid using file_ptr AND off_t - in this header file, and to handle this in the BFD implementation - rather than in its interface. */ -/* typedef off_t file_ptr; */ -typedef long int file_ptr; - -/* Support for different sizes of target format ints and addresses. - If the type `long' is at least 64 bits, BFD_HOST_64BIT_LONG will be - set to 1 above. Otherwise, if gcc is being used, this code will - use gcc's "long long" type. Otherwise, the compilation will fail - if 64-bit targets are requested. */ - -#ifdef BFD64 - -#ifndef BFD_HOST_64_BIT -#if BFD_HOST_64BIT_LONG -#define BFD_HOST_64_BIT long -#else -#ifdef __GNUC__ -#define BFD_HOST_64_BIT long long -#endif /* defined (__GNUC__) */ -#endif /* ! BFD_HOST_64BIT_LONG */ -#endif /* ! defined (BFD_HOST_64_BIT) */ - -typedef unsigned BFD_HOST_64_BIT bfd_vma; -typedef BFD_HOST_64_BIT bfd_signed_vma; -typedef unsigned BFD_HOST_64_BIT bfd_size_type; -typedef unsigned BFD_HOST_64_BIT symvalue; - -#ifndef fprintf_vma -#if BFD_HOST_64BIT_LONG -#define sprintf_vma(s,x) sprintf (s, "%016lx", x) -#define fprintf_vma(f,x) fprintf (f, "%016lx", x) -#else -#define _bfd_int64_low(x) ((unsigned long) (((x) & 0xffffffff))) -#define _bfd_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff)) -#define fprintf_vma(s,x) \ - fprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x)) -#define sprintf_vma(s,x) \ - sprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x)) -#endif -#endif - -#else /* not BFD64 */ - -/* Represent a target address. Also used as a generic unsigned type - which is guaranteed to be big enough to hold any arithmetic types - we need to deal with. */ -typedef unsigned long bfd_vma; - -/* A generic signed type which is guaranteed to be big enough to hold any - arithmetic types we need to deal with. Can be assumed to be compatible - with bfd_vma in the same way that signed and unsigned ints are compatible - (as parameters, in assignment, etc). */ -typedef long bfd_signed_vma; - -typedef unsigned long symvalue; -typedef unsigned long bfd_size_type; - -/* Print a bfd_vma x on stream s. */ -#define fprintf_vma(s,x) fprintf(s, "%08lx", x) -#define sprintf_vma(s,x) sprintf(s, "%08lx", x) -#endif /* not BFD64 */ -#define printf_vma(x) fprintf_vma(stdout,x) - -typedef unsigned int flagword; /* 32 bits of flags */ -typedef unsigned char bfd_byte; - -/** File formats */ - -typedef enum bfd_format { - bfd_unknown = 0, /* file format is unknown */ - bfd_object, /* linker/assember/compiler output */ - bfd_archive, /* object archive file */ - bfd_core, /* core dump */ - bfd_type_end} /* marks the end; don't use it! */ - bfd_format; - -/* Values that may appear in the flags field of a BFD. These also - appear in the object_flags field of the bfd_target structure, where - they indicate the set of flags used by that backend (not all flags - are meaningful for all object file formats) (FIXME: at the moment, - the object_flags values have mostly just been copied from backend - to another, and are not necessarily correct). */ - -/* No flags. */ -#define NO_FLAGS 0x00 - -/* BFD contains relocation entries. */ -#define HAS_RELOC 0x01 - -/* BFD is directly executable. */ -#define EXEC_P 0x02 - -/* BFD has line number information (basically used for F_LNNO in a - COFF header). */ -#define HAS_LINENO 0x04 - -/* BFD has debugging information. */ -#define HAS_DEBUG 0x08 - -/* BFD has symbols. */ -#define HAS_SYMS 0x10 - -/* BFD has local symbols (basically used for F_LSYMS in a COFF - header). */ -#define HAS_LOCALS 0x20 - -/* BFD is a dynamic object. */ -#define DYNAMIC 0x40 - -/* Text section is write protected (if D_PAGED is not set, this is - like an a.out NMAGIC file) (the linker sets this by default, but - clears it for -r or -N). */ -#define WP_TEXT 0x80 - -/* BFD is dynamically paged (this is like an a.out ZMAGIC file) (the - linker sets this by default, but clears it for -r or -n or -N). */ -#define D_PAGED 0x100 - -/* BFD is relaxable (this means that bfd_relax_section may be able to - do something) (sometimes bfd_relax_section can do something even if - this is not set). */ -#define BFD_IS_RELAXABLE 0x200 - -/* This may be set before writing out a BFD to request using a - traditional format. For example, this is used to request that when - writing out an a.out object the symbols not be hashed to eliminate - duplicates. */ -#define BFD_TRADITIONAL_FORMAT 0x400 - -/* This flag indicates that the BFD contents are actually cached in - memory. If this is set, iostream points to a bfd_in_memory struct. */ -#define BFD_IN_MEMORY 0x800 - -/* symbols and relocation */ - -/* A count of carsyms (canonical archive symbols). */ -typedef unsigned long symindex; - -/* How to perform a relocation. */ -typedef const struct reloc_howto_struct reloc_howto_type; - -#define BFD_NO_MORE_SYMBOLS ((symindex) ~0) - -/* General purpose part of a symbol X; - target specific parts are in libcoff.h, libaout.h, etc. */ - -#define bfd_get_section(x) ((x)->section) -#define bfd_get_output_section(x) ((x)->section->output_section) -#define bfd_set_section(x,y) ((x)->section) = (y) -#define bfd_asymbol_base(x) ((x)->section->vma) -#define bfd_asymbol_value(x) (bfd_asymbol_base(x) + (x)->value) -#define bfd_asymbol_name(x) ((x)->name) -/*Perhaps future: #define bfd_asymbol_bfd(x) ((x)->section->owner)*/ -#define bfd_asymbol_bfd(x) ((x)->the_bfd) -#define bfd_asymbol_flavour(x) (bfd_asymbol_bfd(x)->xvec->flavour) - -/* A canonical archive symbol. */ -/* This is a type pun with struct ranlib on purpose! */ -typedef struct carsym { - char *name; - file_ptr file_offset; /* look here to find the file */ -} carsym; /* to make these you call a carsymogen */ - - -/* Used in generating armaps (archive tables of contents). - Perhaps just a forward definition would do? */ -struct orl { /* output ranlib */ - char **name; /* symbol name */ - file_ptr pos; /* bfd* or file position */ - int namidx; /* index into string table */ -}; - - -/* Linenumber stuff */ -typedef struct lineno_cache_entry { - unsigned int line_number; /* Linenumber from start of function*/ - union { - struct symbol_cache_entry *sym; /* Function name */ - unsigned long offset; /* Offset into section */ - } u; -} alent; - -/* object and core file sections */ - -#define align_power(addr, align) \ - ( ((addr) + ((1<<(align))-1)) & (-1 << (align))) - -typedef struct sec *sec_ptr; - -#define bfd_get_section_name(bfd, ptr) ((ptr)->name + 0) -#define bfd_get_section_vma(bfd, ptr) ((ptr)->vma + 0) -#define bfd_get_section_alignment(bfd, ptr) ((ptr)->alignment_power + 0) -#define bfd_section_name(bfd, ptr) ((ptr)->name) -#define bfd_section_size(bfd, ptr) (bfd_get_section_size_before_reloc(ptr)) -#define bfd_section_vma(bfd, ptr) ((ptr)->vma) -#define bfd_section_alignment(bfd, ptr) ((ptr)->alignment_power) -#define bfd_get_section_flags(bfd, ptr) ((ptr)->flags + 0) -#define bfd_get_section_userdata(bfd, ptr) ((ptr)->userdata) - -#define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0) - -#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma= (val)), ((ptr)->user_set_vma = (boolean)true), true) -#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),true) -#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),true) - -typedef struct stat stat_type; - -typedef enum bfd_print_symbol -{ - bfd_print_symbol_name, - bfd_print_symbol_more, - bfd_print_symbol_all -} bfd_print_symbol_type; - -/* Information about a symbol that nm needs. */ - -typedef struct _symbol_info -{ - symvalue value; - char type; - CONST char *name; /* Symbol name. */ - unsigned char stab_type; /* Stab type. */ - char stab_other; /* Stab other. */ - short stab_desc; /* Stab desc. */ - CONST char *stab_name; /* String for stab type. */ -} symbol_info; - -/* Get the name of a stabs type code. */ - -extern const char *bfd_get_stab_name PARAMS ((int)); - -/* Hash table routines. There is no way to free up a hash table. */ - -/* An element in the hash table. Most uses will actually use a larger - structure, and an instance of this will be the first field. */ - -struct bfd_hash_entry -{ - /* Next entry for this hash code. */ - struct bfd_hash_entry *next; - /* String being hashed. */ - const char *string; - /* Hash code. This is the full hash code, not the index into the - table. */ - unsigned long hash; -}; - -/* A hash table. */ - -struct bfd_hash_table -{ - /* The hash array. */ - struct bfd_hash_entry **table; - /* The number of slots in the hash table. */ - unsigned int size; - /* A function used to create new elements in the hash table. The - first entry is itself a pointer to an element. When this - function is first invoked, this pointer will be NULL. However, - having the pointer permits a hierarchy of method functions to be - built each of which calls the function in the superclass. Thus - each function should be written to allocate a new block of memory - only if the argument is NULL. */ - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); - /* An obstack for this hash table. */ - struct obstack memory; -}; - -/* Initialize a hash table. */ -extern boolean bfd_hash_table_init - PARAMS ((struct bfd_hash_table *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *))); - -/* Initialize a hash table specifying a size. */ -extern boolean bfd_hash_table_init_n - PARAMS ((struct bfd_hash_table *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *), - unsigned int size)); - -/* Free up a hash table. */ -extern void bfd_hash_table_free PARAMS ((struct bfd_hash_table *)); - -/* Look up a string in a hash table. If CREATE is true, a new entry - will be created for this string if one does not already exist. The - COPY argument must be true if this routine should copy the string - into newly allocated memory when adding an entry. */ -extern struct bfd_hash_entry *bfd_hash_lookup - PARAMS ((struct bfd_hash_table *, const char *, boolean create, - boolean copy)); - -/* Replace an entry in a hash table. */ -extern void bfd_hash_replace - PARAMS ((struct bfd_hash_table *, struct bfd_hash_entry *old, - struct bfd_hash_entry *nw)); - -/* Base method for creating a hash table entry. */ -extern struct bfd_hash_entry *bfd_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, - const char *)); - -/* Grab some space for a hash table entry. */ -extern PTR bfd_hash_allocate PARAMS ((struct bfd_hash_table *, - unsigned int)); - -/* Traverse a hash table in a random order, calling a function on each - element. If the function returns false, the traversal stops. The - INFO argument is passed to the function. */ -extern void bfd_hash_traverse PARAMS ((struct bfd_hash_table *, - boolean (*) (struct bfd_hash_entry *, - PTR), - PTR info)); - -/* Semi-portable string concatenation in cpp. - The CAT4 hack is to avoid a problem with some strict ANSI C preprocessors. - The problem is, "32_" is not a valid preprocessing token, and we don't - want extra underscores (e.g., "nlm_32_"). The XCAT2 macro will cause the - inner CAT macros to be evaluated first, producing still-valid pp-tokens. - Then the final concatenation can be done. (Sigh.) */ -#ifndef CAT -#ifdef SABER -#define CAT(a,b) a##b -#define CAT3(a,b,c) a##b##c -#define CAT4(a,b,c,d) a##b##c##d -#else -#if defined(__STDC__) || defined(ALMOST_STDC) -#define CAT(a,b) a##b -#define CAT3(a,b,c) a##b##c -#define XCAT2(a,b) CAT(a,b) -#define CAT4(a,b,c,d) XCAT2(CAT(a,b),CAT(c,d)) -#else -#define CAT(a,b) a/**/b -#define CAT3(a,b,c) a/**/b/**/c -#define CAT4(a,b,c,d) a/**/b/**/c/**/d -#endif -#endif -#endif - -#define COFF_SWAP_TABLE (PTR) &bfd_coff_std_swap_table - -/* User program access to BFD facilities */ - -/* Direct I/O routines, for programs which know more about the object - file than BFD does. Use higher level routines if possible. */ - -extern bfd_size_type bfd_read - PARAMS ((PTR, bfd_size_type size, bfd_size_type nitems, bfd *abfd)); -extern bfd_size_type bfd_write - PARAMS ((const PTR, bfd_size_type size, bfd_size_type nitems, bfd *abfd)); -extern int bfd_seek PARAMS ((bfd *abfd, file_ptr fp, int direction)); -extern long bfd_tell PARAMS ((bfd *abfd)); -extern int bfd_flush PARAMS ((bfd *abfd)); -extern int bfd_stat PARAMS ((bfd *abfd, struct stat *)); - - -/* Cast from const char * to char * so that caller can assign to - a char * without a warning. */ -#define bfd_get_filename(abfd) ((char *) (abfd)->filename) -#define bfd_get_cacheable(abfd) ((abfd)->cacheable) -#define bfd_get_format(abfd) ((abfd)->format) -#define bfd_get_target(abfd) ((abfd)->xvec->name) -#define bfd_get_flavour(abfd) ((abfd)->xvec->flavour) -#define bfd_big_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_BIG) -#define bfd_little_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_LITTLE) -#define bfd_header_big_endian(abfd) \ - ((abfd)->xvec->header_byteorder == BFD_ENDIAN_BIG) -#define bfd_header_little_endian(abfd) \ - ((abfd)->xvec->header_byteorder == BFD_ENDIAN_LITTLE) -#define bfd_get_file_flags(abfd) ((abfd)->flags) -#define bfd_applicable_file_flags(abfd) ((abfd)->xvec->object_flags) -#define bfd_applicable_section_flags(abfd) ((abfd)->xvec->section_flags) -#define bfd_my_archive(abfd) ((abfd)->my_archive) -#define bfd_has_map(abfd) ((abfd)->has_armap) - -#define bfd_valid_reloc_types(abfd) ((abfd)->xvec->valid_reloc_types) -#define bfd_usrdata(abfd) ((abfd)->usrdata) - -#define bfd_get_start_address(abfd) ((abfd)->start_address) -#define bfd_get_symcount(abfd) ((abfd)->symcount) -#define bfd_get_outsymbols(abfd) ((abfd)->outsymbols) -#define bfd_count_sections(abfd) ((abfd)->section_count) - -#define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char) - -#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = (boolean)(bool)), true) - -extern boolean bfd_record_phdr - PARAMS ((bfd *, unsigned long, boolean, flagword, boolean, bfd_vma, - boolean, boolean, unsigned int, struct sec **)); - -/* Byte swapping routines. */ - -bfd_vma bfd_getb64 PARAMS ((const unsigned char *)); -bfd_vma bfd_getl64 PARAMS ((const unsigned char *)); -bfd_signed_vma bfd_getb_signed_64 PARAMS ((const unsigned char *)); -bfd_signed_vma bfd_getl_signed_64 PARAMS ((const unsigned char *)); -bfd_vma bfd_getb32 PARAMS ((const unsigned char *)); -bfd_vma bfd_getl32 PARAMS ((const unsigned char *)); -bfd_signed_vma bfd_getb_signed_32 PARAMS ((const unsigned char *)); -bfd_signed_vma bfd_getl_signed_32 PARAMS ((const unsigned char *)); -bfd_vma bfd_getb16 PARAMS ((const unsigned char *)); -bfd_vma bfd_getl16 PARAMS ((const unsigned char *)); -bfd_signed_vma bfd_getb_signed_16 PARAMS ((const unsigned char *)); -bfd_signed_vma bfd_getl_signed_16 PARAMS ((const unsigned char *)); -void bfd_putb64 PARAMS ((bfd_vma, unsigned char *)); -void bfd_putl64 PARAMS ((bfd_vma, unsigned char *)); -void bfd_putb32 PARAMS ((bfd_vma, unsigned char *)); -void bfd_putl32 PARAMS ((bfd_vma, unsigned char *)); -void bfd_putb16 PARAMS ((bfd_vma, unsigned char *)); -void bfd_putl16 PARAMS ((bfd_vma, unsigned char *)); - -/* Externally visible ECOFF routines. */ - -#if defined(__STDC__) || defined(ALMOST_STDC) -struct ecoff_debug_info; -struct ecoff_debug_swap; -struct ecoff_extr; -struct symbol_cache_entry; -struct bfd_link_info; -struct bfd_link_hash_entry; -#endif -extern bfd_vma bfd_ecoff_get_gp_value PARAMS ((bfd * abfd)); -extern boolean bfd_ecoff_set_gp_value PARAMS ((bfd *abfd, bfd_vma gp_value)); -extern boolean bfd_ecoff_set_regmasks - PARAMS ((bfd *abfd, unsigned long gprmask, unsigned long fprmask, - unsigned long *cprmask)); -extern PTR bfd_ecoff_debug_init - PARAMS ((bfd *output_bfd, struct ecoff_debug_info *output_debug, - const struct ecoff_debug_swap *output_swap, - struct bfd_link_info *)); -extern void bfd_ecoff_debug_free - PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, - const struct ecoff_debug_swap *output_swap, - struct bfd_link_info *)); -extern boolean bfd_ecoff_debug_accumulate - PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, - const struct ecoff_debug_swap *output_swap, - bfd *input_bfd, struct ecoff_debug_info *input_debug, - const struct ecoff_debug_swap *input_swap, - struct bfd_link_info *)); -extern boolean bfd_ecoff_debug_accumulate_other - PARAMS ((PTR handle, bfd *output_bfd, struct ecoff_debug_info *output_debug, - const struct ecoff_debug_swap *output_swap, bfd *input_bfd, - struct bfd_link_info *)); -extern boolean bfd_ecoff_debug_externals - PARAMS ((bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap, - boolean relocateable, - boolean (*get_extr) (struct symbol_cache_entry *, - struct ecoff_extr *), - void (*set_index) (struct symbol_cache_entry *, - bfd_size_type))); -extern boolean bfd_ecoff_debug_one_external - PARAMS ((bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap, - const char *name, struct ecoff_extr *esym)); -extern bfd_size_type bfd_ecoff_debug_size - PARAMS ((bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap)); -extern boolean bfd_ecoff_write_debug - PARAMS ((bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap, file_ptr where)); -extern boolean bfd_ecoff_write_accumulated_debug - PARAMS ((PTR handle, bfd *abfd, struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap, - struct bfd_link_info *info, file_ptr where)); -extern boolean bfd_mips_ecoff_create_embedded_relocs - PARAMS ((bfd *, struct bfd_link_info *, struct sec *, struct sec *, - char **)); - -/* Externally visible ELF routines. */ - -struct bfd_link_needed_list -{ - struct bfd_link_needed_list *next; - bfd *by; - const char *name; -}; - -extern boolean bfd_elf32_record_link_assignment - PARAMS ((bfd *, struct bfd_link_info *, const char *, boolean)); -extern boolean bfd_elf64_record_link_assignment - PARAMS ((bfd *, struct bfd_link_info *, const char *, boolean)); -extern struct bfd_link_needed_list *bfd_elf_get_needed_list - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean bfd_elf32_size_dynamic_sections - PARAMS ((bfd *, const char *, const char *, boolean, - struct bfd_link_info *, struct sec **)); -extern boolean bfd_elf64_size_dynamic_sections - PARAMS ((bfd *, const char *, const char *, boolean, - struct bfd_link_info *, struct sec **)); -extern void bfd_elf_set_dt_needed_name PARAMS ((bfd *, const char *)); -extern const char *bfd_elf_get_dt_soname PARAMS ((bfd *)); - -/* SunOS shared library support routines for the linker. */ - -extern struct bfd_link_needed_list *bfd_sunos_get_needed_list - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean bfd_sunos_record_link_assignment - PARAMS ((bfd *, struct bfd_link_info *, const char *)); -extern boolean bfd_sunos_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *, struct sec **, struct sec **, - struct sec **)); - -/* Linux shared library support routines for the linker. */ - -extern boolean bfd_i386linux_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean bfd_m68klinux_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); - -/* mmap hacks */ - -struct _bfd_window_internal; -typedef struct _bfd_window_internal bfd_window_internal; - -typedef struct _bfd_window { - /* What the user asked for. */ - PTR data; - bfd_size_type size; - /* The actual window used by BFD. Small user-requested read-only - regions sharing a page may share a single window into the object - file. Read-write versions shouldn't until I've fixed things to - keep track of which portions have been claimed by the - application; don't want to give the same region back when the - application wants two writable copies! */ - struct _bfd_window_internal *i; -} bfd_window; - -extern void bfd_init_window PARAMS ((bfd_window *)); -extern void bfd_free_window PARAMS ((bfd_window *)); -extern boolean bfd_get_file_window - PARAMS ((bfd *, file_ptr, bfd_size_type, bfd_window *, boolean)); - -/* XCOFF support routines for the linker. */ - -extern boolean bfd_xcoff_link_record_set - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, - bfd_size_type)); -extern boolean bfd_xcoff_import_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, - bfd_vma, const char *, const char *, const char *)); -extern boolean bfd_xcoff_export_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, - boolean)); -extern boolean bfd_xcoff_link_count_reloc - PARAMS ((bfd *, struct bfd_link_info *, const char *)); -extern boolean bfd_xcoff_record_link_assignment - PARAMS ((bfd *, struct bfd_link_info *, const char *)); -extern boolean bfd_xcoff_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *, const char *, const char *, - unsigned long, unsigned long, unsigned long, boolean, - int, boolean, boolean, struct sec **)); - -/* And more from the source. */ -void -bfd_init PARAMS ((void)); - -bfd * -bfd_openr PARAMS ((CONST char *filename, CONST char *target)); - -bfd * -bfd_fdopenr PARAMS ((CONST char *filename, CONST char *target, int fd)); - -bfd * -bfd_openstreamr PARAMS (()); - -bfd * -bfd_openw PARAMS ((CONST char *filename, CONST char *target)); - -boolean -bfd_close PARAMS ((bfd *abfd)); - -boolean -bfd_close_all_done PARAMS ((bfd *)); - -bfd_size_type -bfd_alloc_size PARAMS ((bfd *abfd)); - -bfd * -bfd_create PARAMS ((CONST char *filename, bfd *templ)); - - - /* Byte swapping macros for user section data. */ - -#define bfd_put_8(abfd, val, ptr) \ - (*((unsigned char *)(ptr)) = (unsigned char)(val)) -#define bfd_put_signed_8 \ - bfd_put_8 -#define bfd_get_8(abfd, ptr) \ - (*(unsigned char *)(ptr)) -#define bfd_get_signed_8(abfd, ptr) \ - ((*(unsigned char *)(ptr) ^ 0x80) - 0x80) - -#define bfd_put_16(abfd, val, ptr) \ - BFD_SEND(abfd, bfd_putx16, ((val),(ptr))) -#define bfd_put_signed_16 \ - bfd_put_16 -#define bfd_get_16(abfd, ptr) \ - BFD_SEND(abfd, bfd_getx16, (ptr)) -#define bfd_get_signed_16(abfd, ptr) \ - BFD_SEND (abfd, bfd_getx_signed_16, (ptr)) - -#define bfd_put_32(abfd, val, ptr) \ - BFD_SEND(abfd, bfd_putx32, ((val),(ptr))) -#define bfd_put_signed_32 \ - bfd_put_32 -#define bfd_get_32(abfd, ptr) \ - BFD_SEND(abfd, bfd_getx32, (ptr)) -#define bfd_get_signed_32(abfd, ptr) \ - BFD_SEND(abfd, bfd_getx_signed_32, (ptr)) - -#define bfd_put_64(abfd, val, ptr) \ - BFD_SEND(abfd, bfd_putx64, ((val), (ptr))) -#define bfd_put_signed_64 \ - bfd_put_64 -#define bfd_get_64(abfd, ptr) \ - BFD_SEND(abfd, bfd_getx64, (ptr)) -#define bfd_get_signed_64(abfd, ptr) \ - BFD_SEND(abfd, bfd_getx_signed_64, (ptr)) - - - /* Byte swapping macros for file header data. */ - -#define bfd_h_put_8(abfd, val, ptr) \ - bfd_put_8 (abfd, val, ptr) -#define bfd_h_put_signed_8(abfd, val, ptr) \ - bfd_put_8 (abfd, val, ptr) -#define bfd_h_get_8(abfd, ptr) \ - bfd_get_8 (abfd, ptr) -#define bfd_h_get_signed_8(abfd, ptr) \ - bfd_get_signed_8 (abfd, ptr) - -#define bfd_h_put_16(abfd, val, ptr) \ - BFD_SEND(abfd, bfd_h_putx16,(val,ptr)) -#define bfd_h_put_signed_16 \ - bfd_h_put_16 -#define bfd_h_get_16(abfd, ptr) \ - BFD_SEND(abfd, bfd_h_getx16,(ptr)) -#define bfd_h_get_signed_16(abfd, ptr) \ - BFD_SEND(abfd, bfd_h_getx_signed_16, (ptr)) - -#define bfd_h_put_32(abfd, val, ptr) \ - BFD_SEND(abfd, bfd_h_putx32,(val,ptr)) -#define bfd_h_put_signed_32 \ - bfd_h_put_32 -#define bfd_h_get_32(abfd, ptr) \ - BFD_SEND(abfd, bfd_h_getx32,(ptr)) -#define bfd_h_get_signed_32(abfd, ptr) \ - BFD_SEND(abfd, bfd_h_getx_signed_32, (ptr)) - -#define bfd_h_put_64(abfd, val, ptr) \ - BFD_SEND(abfd, bfd_h_putx64,(val, ptr)) -#define bfd_h_put_signed_64 \ - bfd_h_put_64 -#define bfd_h_get_64(abfd, ptr) \ - BFD_SEND(abfd, bfd_h_getx64,(ptr)) -#define bfd_h_get_signed_64(abfd, ptr) \ - BFD_SEND(abfd, bfd_h_getx_signed_64, (ptr)) - -typedef struct sec -{ - /* The name of the section; the name isn't a copy, the pointer is - the same as that passed to bfd_make_section. */ - - CONST char *name; - - /* Which section is it; 0..nth. */ - - int index; - - /* The next section in the list belonging to the BFD, or NULL. */ - - struct sec *next; - - /* The field flags contains attributes of the section. Some - flags are read in from the object file, and some are - synthesized from other information. */ - - flagword flags; - -#define SEC_NO_FLAGS 0x000 - - /* Tells the OS to allocate space for this section when loading. - This is clear for a section containing debug information - only. */ -#define SEC_ALLOC 0x001 - - /* Tells the OS to load the section from the file when loading. - This is clear for a .bss section. */ -#define SEC_LOAD 0x002 - - /* The section contains data still to be relocated, so there is - some relocation information too. */ -#define SEC_RELOC 0x004 - -#if 0 /* Obsolete ? */ -#define SEC_BALIGN 0x008 -#endif - - /* A signal to the OS that the section contains read only - data. */ -#define SEC_READONLY 0x010 - - /* The section contains code only. */ -#define SEC_CODE 0x020 - - /* The section contains data only. */ -#define SEC_DATA 0x040 - - /* The section will reside in ROM. */ -#define SEC_ROM 0x080 - - /* The section contains constructor information. This section - type is used by the linker to create lists of constructors and - destructors used by <<g++>>. When a back end sees a symbol - which should be used in a constructor list, it creates a new - section for the type of name (e.g., <<__CTOR_LIST__>>), attaches - the symbol to it, and builds a relocation. To build the lists - of constructors, all the linker has to do is catenate all the - sections called <<__CTOR_LIST__>> and relocate the data - contained within - exactly the operations it would peform on - standard data. */ -#define SEC_CONSTRUCTOR 0x100 - - /* The section is a constuctor, and should be placed at the - end of the text, data, or bss section(?). */ -#define SEC_CONSTRUCTOR_TEXT 0x1100 -#define SEC_CONSTRUCTOR_DATA 0x2100 -#define SEC_CONSTRUCTOR_BSS 0x3100 - - /* The section has contents - a data section could be - <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>; a debug section could be - <<SEC_HAS_CONTENTS>> */ -#define SEC_HAS_CONTENTS 0x200 - - /* An instruction to the linker to not output the section - even if it has information which would normally be written. */ -#define SEC_NEVER_LOAD 0x400 - - /* The section is a COFF shared library section. This flag is - only for the linker. If this type of section appears in - the input file, the linker must copy it to the output file - without changing the vma or size. FIXME: Although this - was originally intended to be general, it really is COFF - specific (and the flag was renamed to indicate this). It - might be cleaner to have some more general mechanism to - allow the back end to control what the linker does with - sections. */ -#define SEC_COFF_SHARED_LIBRARY 0x800 - - /* The section is a common section (symbols may be defined - multiple times, the value of a symbol is the amount of - space it requires, and the largest symbol value is the one - used). Most targets have exactly one of these (which we - translate to bfd_com_section_ptr), but ECOFF has two. */ -#define SEC_IS_COMMON 0x8000 - - /* The section contains only debugging information. For - example, this is set for ELF .debug and .stab sections. - strip tests this flag to see if a section can be - discarded. */ -#define SEC_DEBUGGING 0x10000 - - /* The contents of this section are held in memory pointed to - by the contents field. This is checked by - bfd_get_section_contents, and the data is retrieved from - memory if appropriate. */ -#define SEC_IN_MEMORY 0x20000 - - /* The contents of this section are to be excluded by the - linker for executable and shared objects unless those - objects are to be further relocated. */ -#define SEC_EXCLUDE 0x40000 - - /* The contents of this section are to be sorted by the - based on the address specified in the associated symbol - table. */ -#define SEC_SORT_ENTRIES 0x80000 - - /* End of section flags. */ - - /* The virtual memory address of the section - where it will be - at run time. The symbols are relocated against this. The - user_set_vma flag is maintained by bfd; if it's not set, the - backend can assign addresses (for example, in <<a.out>>, where - the default address for <<.data>> is dependent on the specific - target and various flags). */ - - bfd_vma vma; - boolean user_set_vma; - - /* The load address of the section - where it would be in a - rom image; really only used for writing section header - information. */ - - bfd_vma lma; - - /* The size of the section in bytes, as it will be output. - contains a value even if the section has no contents (e.g., the - size of <<.bss>>). This will be filled in after relocation */ - - bfd_size_type _cooked_size; - - /* The original size on disk of the section, in bytes. Normally this - value is the same as the size, but if some relaxing has - been done, then this value will be bigger. */ - - bfd_size_type _raw_size; - - /* If this section is going to be output, then this value is the - offset into the output section of the first byte in the input - section. E.g., if this was going to start at the 100th byte in - the output section, this value would be 100. */ - - bfd_vma output_offset; - - /* The output section through which to map on output. */ - - struct sec *output_section; - - /* The alignment requirement of the section, as an exponent of 2 - - e.g., 3 aligns to 2^3 (or 8). */ - - unsigned int alignment_power; - - /* If an input section, a pointer to a vector of relocation - records for the data in this section. */ - - struct reloc_cache_entry *relocation; - - /* If an output section, a pointer to a vector of pointers to - relocation records for the data in this section. */ - - struct reloc_cache_entry **orelocation; - - /* The number of relocation records in one of the above */ - - unsigned reloc_count; - - /* Information below is back end specific - and not always used - or updated. */ - - /* File position of section data */ - - file_ptr filepos; - - /* File position of relocation info */ - - file_ptr rel_filepos; - - /* File position of line data */ - - file_ptr line_filepos; - - /* Pointer to data for applications */ - - PTR userdata; - - /* If the SEC_IN_MEMORY flag is set, this points to the actual - contents. */ - unsigned char *contents; - - /* Attached line number information */ - - alent *lineno; - - /* Number of line number records */ - - unsigned int lineno_count; - - /* When a section is being output, this value changes as more - linenumbers are written out */ - - file_ptr moving_line_filepos; - - /* What the section number is in the target world */ - - int target_index; - - PTR used_by_bfd; - - /* If this is a constructor section then here is a list of the - relocations created to relocate items within it. */ - - struct relent_chain *constructor_chain; - - /* The BFD which owns the section. */ - - bfd *owner; - - boolean reloc_done; - /* A symbol which points at this section only */ - struct symbol_cache_entry *symbol; - struct symbol_cache_entry **symbol_ptr_ptr; - - struct bfd_link_order *link_order_head; - struct bfd_link_order *link_order_tail; -} asection ; - - /* These sections are global, and are managed by BFD. The application - and target back end are not permitted to change the values in - these sections. New code should use the section_ptr macros rather - than referring directly to the const sections. The const sections - may eventually vanish. */ -#define BFD_ABS_SECTION_NAME "*ABS*" -#define BFD_UND_SECTION_NAME "*UND*" -#define BFD_COM_SECTION_NAME "*COM*" -#define BFD_IND_SECTION_NAME "*IND*" - - /* the absolute section */ -extern const asection bfd_abs_section; -#define bfd_abs_section_ptr ((asection *) &bfd_abs_section) -#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr) - /* Pointer to the undefined section */ -extern const asection bfd_und_section; -#define bfd_und_section_ptr ((asection *) &bfd_und_section) -#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr) - /* Pointer to the common section */ -extern const asection bfd_com_section; -#define bfd_com_section_ptr ((asection *) &bfd_com_section) - /* Pointer to the indirect section */ -extern const asection bfd_ind_section; -#define bfd_ind_section_ptr ((asection *) &bfd_ind_section) -#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr) - -extern const struct symbol_cache_entry * const bfd_abs_symbol; -extern const struct symbol_cache_entry * const bfd_com_symbol; -extern const struct symbol_cache_entry * const bfd_und_symbol; -extern const struct symbol_cache_entry * const bfd_ind_symbol; -#define bfd_get_section_size_before_reloc(section) \ - (section->reloc_done ? (abort(),1): (section)->_raw_size) -#define bfd_get_section_size_after_reloc(section) \ - ((section->reloc_done) ? (section)->_cooked_size: (abort(),1)) -asection * -bfd_get_section_by_name PARAMS ((bfd *abfd, CONST char *name)); - -asection * -bfd_make_section_old_way PARAMS ((bfd *abfd, CONST char *name)); - -asection * -bfd_make_section_anyway PARAMS ((bfd *abfd, CONST char *name)); - -asection * -bfd_make_section PARAMS ((bfd *, CONST char *name)); - -boolean -bfd_set_section_flags PARAMS ((bfd *abfd, asection *sec, flagword flags)); - -void -bfd_map_over_sections PARAMS ((bfd *abfd, - void (*func)(bfd *abfd, - asection *sect, - PTR obj), - PTR obj)); - -boolean -bfd_set_section_size PARAMS ((bfd *abfd, asection *sec, bfd_size_type val)); - -boolean -bfd_set_section_contents - PARAMS ((bfd *abfd, - asection *section, - PTR data, - file_ptr offset, - bfd_size_type count)); - -boolean -bfd_get_section_contents - PARAMS ((bfd *abfd, asection *section, PTR location, - file_ptr offset, bfd_size_type count)); - -boolean -bfd_copy_private_section_data PARAMS ((bfd *ibfd, asection *isec, bfd *obfd, asection *osec)); - -#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \ - BFD_SEND (ibfd, _bfd_copy_private_section_data, \ - (ibfd, isection, obfd, osection)) -enum bfd_architecture -{ - bfd_arch_unknown, /* File arch not known */ - bfd_arch_obscure, /* Arch known, not one of these */ - bfd_arch_m68k, /* Motorola 68xxx */ - bfd_arch_vax, /* DEC Vax */ - bfd_arch_i960, /* Intel 960 */ - /* The order of the following is important. - lower number indicates a machine type that - only accepts a subset of the instructions - available to machines with higher numbers. - The exception is the "ca", which is - incompatible with all other machines except - "core". */ - -#define bfd_mach_i960_core 1 -#define bfd_mach_i960_ka_sa 2 -#define bfd_mach_i960_kb_sb 3 -#define bfd_mach_i960_mc 4 -#define bfd_mach_i960_xa 5 -#define bfd_mach_i960_ca 6 -#define bfd_mach_i960_jx 7 -#define bfd_mach_i960_hx 8 - - bfd_arch_a29k, /* AMD 29000 */ - bfd_arch_sparc, /* SPARC */ -#define bfd_mach_sparc 1 - /* The difference between v8plus and v9 is that v9 is a true 64 bit env. */ -#define bfd_mach_sparc_v8plus 2 -#define bfd_mach_sparc_v8plusa 3 /* with ultrasparc add'ns */ -#define bfd_mach_sparc_v9 4 -#define bfd_mach_sparc_v9a 5 /* with ultrasparc add'ns */ - /* Nonzero if MACH has the v9 instruction set. */ -#define bfd_mach_sparc_v9_p(mach) ((mach) != bfd_mach_sparc) - bfd_arch_mips, /* MIPS Rxxxx */ - bfd_arch_i386, /* Intel 386 */ - bfd_arch_we32k, /* AT&T WE32xxx */ - bfd_arch_tahoe, /* CCI/Harris Tahoe */ - bfd_arch_i860, /* Intel 860 */ - bfd_arch_romp, /* IBM ROMP PC/RT */ - bfd_arch_alliant, /* Alliant */ - bfd_arch_convex, /* Convex */ - bfd_arch_m88k, /* Motorola 88xxx */ - bfd_arch_pyramid, /* Pyramid Technology */ - bfd_arch_h8300, /* Hitachi H8/300 */ -#define bfd_mach_h8300 1 -#define bfd_mach_h8300h 2 - bfd_arch_powerpc, /* PowerPC */ - bfd_arch_rs6000, /* IBM RS/6000 */ - bfd_arch_hppa, /* HP PA RISC */ - bfd_arch_z8k, /* Zilog Z8000 */ -#define bfd_mach_z8001 1 -#define bfd_mach_z8002 2 - bfd_arch_h8500, /* Hitachi H8/500 */ - bfd_arch_sh, /* Hitachi SH */ - bfd_arch_alpha, /* Dec Alpha */ - bfd_arch_arm, /* Advanced Risc Machines ARM */ - bfd_arch_ns32k, /* National Semiconductors ns32000 */ - bfd_arch_w65, /* WDC 65816 */ - bfd_arch_last - }; - -typedef struct bfd_arch_info -{ - int bits_per_word; - int bits_per_address; - int bits_per_byte; - enum bfd_architecture arch; - unsigned long mach; - const char *arch_name; - const char *printable_name; - unsigned int section_align_power; - /* true if this is the default machine for the architecture */ - boolean the_default; - const struct bfd_arch_info * (*compatible) - PARAMS ((const struct bfd_arch_info *a, - const struct bfd_arch_info *b)); - - boolean (*scan) PARAMS ((const struct bfd_arch_info *, const char *)); - - const struct bfd_arch_info *next; -} bfd_arch_info_type; -const char * -bfd_printable_name PARAMS ((bfd *abfd)); - -const bfd_arch_info_type * -bfd_scan_arch PARAMS ((const char *string)); - -const bfd_arch_info_type * -bfd_arch_get_compatible PARAMS (( - const bfd *abfd, - const bfd *bbfd)); - -void -bfd_set_arch_info PARAMS ((bfd *abfd, const bfd_arch_info_type *arg)); - -enum bfd_architecture -bfd_get_arch PARAMS ((bfd *abfd)); - -unsigned long -bfd_get_mach PARAMS ((bfd *abfd)); - -unsigned int -bfd_arch_bits_per_byte PARAMS ((bfd *abfd)); - -unsigned int -bfd_arch_bits_per_address PARAMS ((bfd *abfd)); - -const bfd_arch_info_type * -bfd_get_arch_info PARAMS ((bfd *abfd)); - -const bfd_arch_info_type * -bfd_lookup_arch - PARAMS ((enum bfd_architecture - arch, - unsigned long machine)); - -const char * -bfd_printable_arch_mach - PARAMS ((enum bfd_architecture arch, unsigned long machine)); - -typedef enum bfd_reloc_status -{ - /* No errors detected */ - bfd_reloc_ok, - - /* The relocation was performed, but there was an overflow. */ - bfd_reloc_overflow, - - /* The address to relocate was not within the section supplied. */ - bfd_reloc_outofrange, - - /* Used by special functions */ - bfd_reloc_continue, - - /* Unsupported relocation size requested. */ - bfd_reloc_notsupported, - - /* Unused */ - bfd_reloc_other, - - /* The symbol to relocate against was undefined. */ - bfd_reloc_undefined, - - /* The relocation was performed, but may not be ok - presently - generated only when linking i960 coff files with i960 b.out - symbols. If this type is returned, the error_message argument - to bfd_perform_relocation will be set. */ - bfd_reloc_dangerous - } - bfd_reloc_status_type; - - -typedef struct reloc_cache_entry -{ - /* A pointer into the canonical table of pointers */ - struct symbol_cache_entry **sym_ptr_ptr; - - /* offset in section */ - bfd_size_type address; - - /* addend for relocation value */ - bfd_vma addend; - - /* Pointer to how to perform the required relocation */ - reloc_howto_type *howto; - -} arelent; -enum complain_overflow -{ - /* Do not complain on overflow. */ - complain_overflow_dont, - - /* Complain if the bitfield overflows, whether it is considered - as signed or unsigned. */ - complain_overflow_bitfield, - - /* Complain if the value overflows when considered as signed - number. */ - complain_overflow_signed, - - /* Complain if the value overflows when considered as an - unsigned number. */ - complain_overflow_unsigned -}; - -struct reloc_howto_struct -{ - /* The type field has mainly a documetary use - the back end can - do what it wants with it, though normally the back end's - external idea of what a reloc number is stored - in this field. For example, a PC relative word relocation - in a coff environment has the type 023 - because that's - what the outside world calls a R_PCRWORD reloc. */ - unsigned int type; - - /* The value the final relocation is shifted right by. This drops - unwanted data from the relocation. */ - unsigned int rightshift; - - /* The size of the item to be relocated. This is *not* a - power-of-two measure. To get the number of bytes operated - on by a type of relocation, use bfd_get_reloc_size. */ - int size; - - /* The number of bits in the item to be relocated. This is used - when doing overflow checking. */ - unsigned int bitsize; - - /* Notes that the relocation is relative to the location in the - data section of the addend. The relocation function will - subtract from the relocation value the address of the location - being relocated. */ - boolean pc_relative; - - /* The bit position of the reloc value in the destination. - The relocated value is left shifted by this amount. */ - unsigned int bitpos; - - /* What type of overflow error should be checked for when - relocating. */ - enum complain_overflow complain_on_overflow; - - /* If this field is non null, then the supplied function is - called rather than the normal function. This allows really - strange relocation methods to be accomodated (e.g., i960 callj - instructions). */ - bfd_reloc_status_type (*special_function) - PARAMS ((bfd *abfd, - arelent *reloc_entry, - struct symbol_cache_entry *symbol, - PTR data, - asection *input_section, - bfd *output_bfd, - char **error_message)); - - /* The textual name of the relocation type. */ - char *name; - - /* When performing a partial link, some formats must modify the - relocations rather than the data - this flag signals this.*/ - boolean partial_inplace; - - /* The src_mask selects which parts of the read in data - are to be used in the relocation sum. E.g., if this was an 8 bit - bit of data which we read and relocated, this would be - 0x000000ff. When we have relocs which have an addend, such as - sun4 extended relocs, the value in the offset part of a - relocating field is garbage so we never use it. In this case - the mask would be 0x00000000. */ - bfd_vma src_mask; - - /* The dst_mask selects which parts of the instruction are replaced - into the instruction. In most cases src_mask == dst_mask, - except in the above special case, where dst_mask would be - 0x000000ff, and src_mask would be 0x00000000. */ - bfd_vma dst_mask; - - /* When some formats create PC relative instructions, they leave - the value of the pc of the place being relocated in the offset - slot of the instruction, so that a PC relative relocation can - be made just by adding in an ordinary offset (e.g., sun3 a.out). - Some formats leave the displacement part of an instruction - empty (e.g., m88k bcs); this flag signals the fact.*/ - boolean pcrel_offset; - -}; -#define HOWTO(C, R,S,B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \ - {(unsigned)C,R,S,B, P, BI, O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC} -#define NEWHOWTO( FUNCTION, NAME,SIZE,REL,IN) HOWTO(0,0,SIZE,0,REL,0,complain_overflow_dont,FUNCTION, NAME,false,0,0,IN) - -#define HOWTO_PREPARE(relocation, symbol) \ - { \ - if (symbol != (asymbol *)NULL) { \ - if (bfd_is_com_section (symbol->section)) { \ - relocation = 0; \ - } \ - else { \ - relocation = symbol->value; \ - } \ - } \ -} -int -bfd_get_reloc_size PARAMS ((reloc_howto_type *)); - -typedef struct relent_chain { - arelent relent; - struct relent_chain *next; -} arelent_chain; -bfd_reloc_status_type - -bfd_perform_relocation - PARAMS ((bfd *abfd, - arelent *reloc_entry, - PTR data, - asection *input_section, - bfd *output_bfd, - char **error_message)); - -bfd_reloc_status_type - -bfd_install_relocation - PARAMS ((bfd *abfd, - arelent *reloc_entry, - PTR data, bfd_vma data_start, - asection *input_section, - char **error_message)); - -enum bfd_reloc_code_real { - _dummy_first_bfd_reloc_code_real, - - -/* Basic absolute relocations of N bits. */ - BFD_RELOC_64, - BFD_RELOC_32, - BFD_RELOC_26, - BFD_RELOC_16, - BFD_RELOC_14, - BFD_RELOC_8, - -/* PC-relative relocations. Sometimes these are relative to the address -of the relocation itself; sometimes they are relative to the start of -the section containing the relocation. It depends on the specific target. - -The 24-bit relocation is used in some Intel 960 configurations. */ - BFD_RELOC_64_PCREL, - BFD_RELOC_32_PCREL, - BFD_RELOC_24_PCREL, - BFD_RELOC_16_PCREL, - BFD_RELOC_12_PCREL, - BFD_RELOC_8_PCREL, - -/* For ELF. */ - BFD_RELOC_32_GOT_PCREL, - BFD_RELOC_16_GOT_PCREL, - BFD_RELOC_8_GOT_PCREL, - BFD_RELOC_32_GOTOFF, - BFD_RELOC_16_GOTOFF, - BFD_RELOC_LO16_GOTOFF, - BFD_RELOC_HI16_GOTOFF, - BFD_RELOC_HI16_S_GOTOFF, - BFD_RELOC_8_GOTOFF, - BFD_RELOC_32_PLT_PCREL, - BFD_RELOC_24_PLT_PCREL, - BFD_RELOC_16_PLT_PCREL, - BFD_RELOC_8_PLT_PCREL, - BFD_RELOC_32_PLTOFF, - BFD_RELOC_16_PLTOFF, - BFD_RELOC_LO16_PLTOFF, - BFD_RELOC_HI16_PLTOFF, - BFD_RELOC_HI16_S_PLTOFF, - BFD_RELOC_8_PLTOFF, - -/* Relocations used by 68K ELF. */ - BFD_RELOC_68K_GLOB_DAT, - BFD_RELOC_68K_JMP_SLOT, - BFD_RELOC_68K_RELATIVE, - -/* Linkage-table relative. */ - BFD_RELOC_32_BASEREL, - BFD_RELOC_16_BASEREL, - BFD_RELOC_LO16_BASEREL, - BFD_RELOC_HI16_BASEREL, - BFD_RELOC_HI16_S_BASEREL, - BFD_RELOC_8_BASEREL, - BFD_RELOC_RVA, - -/* Absolute 8-bit relocation, but used to form an address like 0xFFnn. */ - BFD_RELOC_8_FFnn, - -/* These PC-relative relocations are stored as word displacements -- -i.e., byte displacements shifted right two bits. The 30-bit word -displacement (<<32_PCREL_S2>> -- 32 bits, shifted 2) is used on the -SPARC. (SPARC tools generally refer to this as <<WDISP30>>.) The -signed 16-bit displacement is used on the MIPS, and the 23-bit -displacement is used on the Alpha. */ - BFD_RELOC_32_PCREL_S2, - BFD_RELOC_16_PCREL_S2, - BFD_RELOC_23_PCREL_S2, - -/* High 22 bits and low 10 bits of 32-bit value, placed into lower bits of -the target word. These are used on the SPARC. */ - BFD_RELOC_HI22, - BFD_RELOC_LO10, - -/* For systems that allocate a Global Pointer register, these are -displacements off that register. These relocation types are -handled specially, because the value the register will have is -decided relatively late. */ - BFD_RELOC_GPREL16, - BFD_RELOC_GPREL32, - -/* Reloc types used for i960/b.out. */ - BFD_RELOC_I960_CALLJ, - -/* SPARC ELF relocations. There is probably some overlap with other -relocation types already defined. */ - BFD_RELOC_NONE, - BFD_RELOC_SPARC_WDISP22, - BFD_RELOC_SPARC22, - BFD_RELOC_SPARC13, - BFD_RELOC_SPARC_GOT10, - BFD_RELOC_SPARC_GOT13, - BFD_RELOC_SPARC_GOT22, - BFD_RELOC_SPARC_PC10, - BFD_RELOC_SPARC_PC22, - BFD_RELOC_SPARC_WPLT30, - BFD_RELOC_SPARC_COPY, - BFD_RELOC_SPARC_GLOB_DAT, - BFD_RELOC_SPARC_JMP_SLOT, - BFD_RELOC_SPARC_RELATIVE, - BFD_RELOC_SPARC_UA32, - -/* I think these are specific to SPARC a.out (e.g., Sun 4). */ - BFD_RELOC_SPARC_BASE13, - BFD_RELOC_SPARC_BASE22, - -/* Some relocations we're using for SPARC V9 -- subject to change. */ -#define BFD_RELOC_SPARC_64 BFD_RELOC_64 - BFD_RELOC_SPARC_10, - BFD_RELOC_SPARC_11, - BFD_RELOC_SPARC_OLO10, - BFD_RELOC_SPARC_HH22, - BFD_RELOC_SPARC_HM10, - BFD_RELOC_SPARC_LM22, - BFD_RELOC_SPARC_PC_HH22, - BFD_RELOC_SPARC_PC_HM10, - BFD_RELOC_SPARC_PC_LM22, - BFD_RELOC_SPARC_WDISP16, - BFD_RELOC_SPARC_WDISP19, - BFD_RELOC_SPARC_GLOB_JMP, - BFD_RELOC_SPARC_7, - BFD_RELOC_SPARC_6, - BFD_RELOC_SPARC_5, - -/* Alpha ECOFF relocations. Some of these treat the symbol or "addend" -in some special way. -For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when -writing; when reading, it will be the absolute section symbol. The -addend is the displacement in bytes of the "lda" instruction from -the "ldah" instruction (which is at the address of this reloc). */ - BFD_RELOC_ALPHA_GPDISP_HI16, - -/* For GPDISP_LO16 ("ignore") relocations, the symbol is handled as -with GPDISP_HI16 relocs. The addend is ignored when writing the -relocations out, and is filled in with the file's GP value on -reading, for convenience. */ - BFD_RELOC_ALPHA_GPDISP_LO16, - -/* The Alpha LITERAL/LITUSE relocs are produced by a symbol reference; -the assembler turns it into a LDQ instruction to load the address of -the symbol, and then fills in a register in the real instruction. - -The LITERAL reloc, at the LDQ instruction, refers to the .lita -section symbol. The addend is ignored when writing, but is filled -in with the file's GP value on reading, for convenience, as with the -GPDISP_LO16 reloc. - -The LITUSE reloc, on the instruction using the loaded address, gives -information to the linker that it might be able to use to optimize -away some literal section references. The symbol is ignored (read -as the absolute section symbol), and the "addend" indicates the type -of instruction using the register: -1 - "memory" fmt insn -2 - byte-manipulation (byte offset reg) -3 - jsr (target of branch) - -The GNU linker currently doesn't do any of this optimizing. */ - BFD_RELOC_ALPHA_LITERAL, - BFD_RELOC_ALPHA_LITUSE, - -/* The HINT relocation indicates a value that should be filled into the -"hint" field of a jmp/jsr/ret instruction, for possible branch- -prediction logic which may be provided on some processors. */ - BFD_RELOC_ALPHA_HINT, - -/* Bits 27..2 of the relocation address shifted right 2 bits; -simple reloc otherwise. */ - BFD_RELOC_MIPS_JMP, - -/* High 16 bits of 32-bit value; simple reloc. */ - BFD_RELOC_HI16, - -/* High 16 bits of 32-bit value but the low 16 bits will be sign -extended and added to form the final result. If the low 16 -bits form a negative number, we need to add one to the high value -to compensate for the borrow when the low bits are added. */ - BFD_RELOC_HI16_S, - -/* Low 16 bits. */ - BFD_RELOC_LO16, - -/* Like BFD_RELOC_HI16_S, but PC relative. */ - BFD_RELOC_PCREL_HI16_S, - -/* Like BFD_RELOC_LO16, but PC relative. */ - BFD_RELOC_PCREL_LO16, - -/* Relocation relative to the global pointer. */ -#define BFD_RELOC_MIPS_GPREL BFD_RELOC_GPREL16 - -/* Relocation against a MIPS literal section. */ - BFD_RELOC_MIPS_LITERAL, - -/* MIPS ELF relocations. */ - BFD_RELOC_MIPS_GOT16, - BFD_RELOC_MIPS_CALL16, -#define BFD_RELOC_MIPS_GPREL32 BFD_RELOC_GPREL32 - BFD_RELOC_MIPS_GOT_HI16, - BFD_RELOC_MIPS_GOT_LO16, - BFD_RELOC_MIPS_CALL_HI16, - BFD_RELOC_MIPS_CALL_LO16, - -/* i386/elf relocations */ - BFD_RELOC_386_GOT32, - BFD_RELOC_386_PLT32, - BFD_RELOC_386_COPY, - BFD_RELOC_386_GLOB_DAT, - BFD_RELOC_386_JUMP_SLOT, - BFD_RELOC_386_RELATIVE, - BFD_RELOC_386_GOTOFF, - BFD_RELOC_386_GOTPC, - -/* ns32k relocations */ - BFD_RELOC_NS32K_IMM_8, - BFD_RELOC_NS32K_IMM_16, - BFD_RELOC_NS32K_IMM_32, - BFD_RELOC_NS32K_IMM_8_PCREL, - BFD_RELOC_NS32K_IMM_16_PCREL, - BFD_RELOC_NS32K_IMM_32_PCREL, - BFD_RELOC_NS32K_DISP_8, - BFD_RELOC_NS32K_DISP_16, - BFD_RELOC_NS32K_DISP_32, - BFD_RELOC_NS32K_DISP_8_PCREL, - BFD_RELOC_NS32K_DISP_16_PCREL, - BFD_RELOC_NS32K_DISP_32_PCREL, - -/* Power(rs6000) and PowerPC relocations. */ - BFD_RELOC_PPC_B26, - BFD_RELOC_PPC_BA26, - BFD_RELOC_PPC_TOC16, - BFD_RELOC_PPC_B16, - BFD_RELOC_PPC_B16_BRTAKEN, - BFD_RELOC_PPC_B16_BRNTAKEN, - BFD_RELOC_PPC_BA16, - BFD_RELOC_PPC_BA16_BRTAKEN, - BFD_RELOC_PPC_BA16_BRNTAKEN, - BFD_RELOC_PPC_COPY, - BFD_RELOC_PPC_GLOB_DAT, - BFD_RELOC_PPC_JMP_SLOT, - BFD_RELOC_PPC_RELATIVE, - BFD_RELOC_PPC_LOCAL24PC, - BFD_RELOC_PPC_EMB_NADDR32, - BFD_RELOC_PPC_EMB_NADDR16, - BFD_RELOC_PPC_EMB_NADDR16_LO, - BFD_RELOC_PPC_EMB_NADDR16_HI, - BFD_RELOC_PPC_EMB_NADDR16_HA, - BFD_RELOC_PPC_EMB_SDAI16, - BFD_RELOC_PPC_EMB_SDA2I16, - BFD_RELOC_PPC_EMB_SDA2REL, - BFD_RELOC_PPC_EMB_SDA21, - BFD_RELOC_PPC_EMB_MRKREF, - BFD_RELOC_PPC_EMB_RELSEC16, - BFD_RELOC_PPC_EMB_RELST_LO, - BFD_RELOC_PPC_EMB_RELST_HI, - BFD_RELOC_PPC_EMB_RELST_HA, - BFD_RELOC_PPC_EMB_BIT_FLD, - BFD_RELOC_PPC_EMB_RELSDA, - -/* The type of reloc used to build a contructor table - at the moment -probably a 32 bit wide absolute relocation, but the target can choose. -It generally does map to one of the other relocation types. */ - BFD_RELOC_CTOR, - -/* ARM 26 bit pc-relative branch. The lowest two bits must be zero and are -not stored in the instruction. */ - BFD_RELOC_ARM_PCREL_BRANCH, - -/* These relocs are only used within the ARM assembler. They are not -(at present) written to any object files. */ - BFD_RELOC_ARM_IMMEDIATE, - BFD_RELOC_ARM_OFFSET_IMM, - BFD_RELOC_ARM_SHIFT_IMM, - BFD_RELOC_ARM_SWI, - BFD_RELOC_ARM_MULTI, - BFD_RELOC_ARM_CP_OFF_IMM, - BFD_RELOC_ARM_ADR_IMM, - BFD_RELOC_ARM_LDR_IMM, - BFD_RELOC_ARM_LITERAL, - BFD_RELOC_ARM_IN_POOL, - BFD_RELOC_UNUSED }; -typedef enum bfd_reloc_code_real bfd_reloc_code_real_type; -reloc_howto_type * - -bfd_reloc_type_lookup PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); - -const char * -bfd_get_reloc_code_name PARAMS ((bfd_reloc_code_real_type code)); - - -typedef struct symbol_cache_entry -{ - /* A pointer to the BFD which owns the symbol. This information - is necessary so that a back end can work out what additional - information (invisible to the application writer) is carried - with the symbol. - - This field is *almost* redundant, since you can use section->owner - instead, except that some symbols point to the global sections - bfd_{abs,com,und}_section. This could be fixed by making - these globals be per-bfd (or per-target-flavor). FIXME. */ - - struct _bfd *the_bfd; /* Use bfd_asymbol_bfd(sym) to access this field. */ - - /* The text of the symbol. The name is left alone, and not copied; the - application may not alter it. */ - CONST char *name; - - /* The value of the symbol. This really should be a union of a - numeric value with a pointer, since some flags indicate that - a pointer to another symbol is stored here. */ - symvalue value; - - /* Attributes of a symbol: */ - -#define BSF_NO_FLAGS 0x00 - - /* The symbol has local scope; <<static>> in <<C>>. The value - is the offset into the section of the data. */ -#define BSF_LOCAL 0x01 - - /* The symbol has global scope; initialized data in <<C>>. The - value is the offset into the section of the data. */ -#define BSF_GLOBAL 0x02 - - /* The symbol has global scope and is exported. The value is - the offset into the section of the data. */ -#define BSF_EXPORT BSF_GLOBAL /* no real difference */ - - /* A normal C symbol would be one of: - <<BSF_LOCAL>>, <<BSF_FORT_COMM>>, <<BSF_UNDEFINED>> or - <<BSF_GLOBAL>> */ - - /* The symbol is a debugging record. The value has an arbitary - meaning. */ -#define BSF_DEBUGGING 0x08 - - /* The symbol denotes a function entry point. Used in ELF, - perhaps others someday. */ -#define BSF_FUNCTION 0x10 - - /* Used by the linker. */ -#define BSF_KEEP 0x20 -#define BSF_KEEP_G 0x40 - - /* A weak global symbol, overridable without warnings by - a regular global symbol of the same name. */ -#define BSF_WEAK 0x80 - - /* This symbol was created to point to a section, e.g. ELF's - STT_SECTION symbols. */ -#define BSF_SECTION_SYM 0x100 - - /* The symbol used to be a common symbol, but now it is - allocated. */ -#define BSF_OLD_COMMON 0x200 - - /* The default value for common data. */ -#define BFD_FORT_COMM_DEFAULT_VALUE 0 - - /* In some files the type of a symbol sometimes alters its - location in an output file - ie in coff a <<ISFCN>> symbol - which is also <<C_EXT>> symbol appears where it was - declared and not at the end of a section. This bit is set - by the target BFD part to convey this information. */ - -#define BSF_NOT_AT_END 0x400 - - /* Signal that the symbol is the label of constructor section. */ -#define BSF_CONSTRUCTOR 0x800 - - /* Signal that the symbol is a warning symbol. The name is a - warning. The name of the next symbol is the one to warn about; - if a reference is made to a symbol with the same name as the next - symbol, a warning is issued by the linker. */ -#define BSF_WARNING 0x1000 - - /* Signal that the symbol is indirect. This symbol is an indirect - pointer to the symbol with the same name as the next symbol. */ -#define BSF_INDIRECT 0x2000 - - /* BSF_FILE marks symbols that contain a file name. This is used - for ELF STT_FILE symbols. */ -#define BSF_FILE 0x4000 - - /* Symbol is from dynamic linking information. */ -#define BSF_DYNAMIC 0x8000 - - /* The symbol denotes a data object. Used in ELF, and perhaps - others someday. */ -#define BSF_OBJECT 0x10000 - - flagword flags; - - /* A pointer to the section to which this symbol is - relative. This will always be non NULL, there are special - sections for undefined and absolute symbols. */ - struct sec *section; - - /* Back end special data. */ - union - { - PTR p; - bfd_vma i; - } udata; - -} asymbol; -#define bfd_get_symtab_upper_bound(abfd) \ - BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd)) -boolean -bfd_is_local_label PARAMS ((bfd *abfd, asymbol *sym)); - -#define bfd_is_local_label(abfd, sym) \ - BFD_SEND (abfd, _bfd_is_local_label,(abfd, sym)) -#define bfd_canonicalize_symtab(abfd, location) \ - BFD_SEND (abfd, _bfd_canonicalize_symtab,\ - (abfd, location)) -boolean -bfd_set_symtab PARAMS ((bfd *abfd, asymbol **location, unsigned int count)); - -void -bfd_print_symbol_vandf PARAMS ((PTR file, asymbol *symbol)); - -#define bfd_make_empty_symbol(abfd) \ - BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd)) -#define bfd_make_debug_symbol(abfd,ptr,size) \ - BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size)) -int -bfd_decode_symclass PARAMS ((asymbol *symbol)); - -void -bfd_symbol_info PARAMS ((asymbol *symbol, symbol_info *ret)); - -boolean -bfd_copy_private_symbol_data PARAMS ((bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym)); - -#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \ - BFD_SEND (ibfd, _bfd_copy_private_symbol_data, \ - (ibfd, isymbol, obfd, osymbol)) -struct _bfd -{ - /* The filename the application opened the BFD with. */ - CONST char *filename; - - /* A pointer to the target jump table. */ - const struct bfd_target *xvec; - - /* To avoid dragging too many header files into every file that - includes `<<bfd.h>>', IOSTREAM has been declared as a "char - *", and MTIME as a "long". Their correct types, to which they - are cast when used, are "FILE *" and "time_t". The iostream - is the result of an fopen on the filename. However, if the - BFD_IN_MEMORY flag is set, then iostream is actually a pointer - to a bfd_in_memory struct. */ - PTR iostream; - - /* Is the file descriptor being cached? That is, can it be closed as - needed, and re-opened when accessed later? */ - - boolean cacheable; - - /* Marks whether there was a default target specified when the - BFD was opened. This is used to select which matching algorithm - to use to choose the back end. */ - - boolean target_defaulted; - - /* The caching routines use these to maintain a - least-recently-used list of BFDs */ - - struct _bfd *lru_prev, *lru_next; - - /* When a file is closed by the caching routines, BFD retains - state information on the file here: */ - - file_ptr where; - - /* and here: (``once'' means at least once) */ - - boolean opened_once; - - /* Set if we have a locally maintained mtime value, rather than - getting it from the file each time: */ - - boolean mtime_set; - - /* File modified time, if mtime_set is true: */ - - long mtime; - - /* Reserved for an unimplemented file locking extension.*/ - - int ifd; - - /* The format which belongs to the BFD. (object, core, etc.) */ - - bfd_format format; - - /* The direction the BFD was opened with*/ - - enum bfd_direction {no_direction = 0, - read_direction = 1, - write_direction = 2, - both_direction = 3} direction; - - /* Format_specific flags*/ - - flagword flags; - - /* Currently my_archive is tested before adding origin to - anything. I believe that this can become always an add of - origin, with origin set to 0 for non archive files. */ - - file_ptr origin; - - /* Remember when output has begun, to stop strange things - from happening. */ - boolean output_has_begun; - - /* Pointer to linked list of sections*/ - struct sec *sections; - - /* The number of sections */ - unsigned int section_count; - - /* Stuff only useful for object files: - The start address. */ - bfd_vma start_address; - - /* Used for input and output*/ - unsigned int symcount; - - /* Symbol table for output BFD (with symcount entries) */ - struct symbol_cache_entry **outsymbols; - - /* Pointer to structure which contains architecture information*/ - const struct bfd_arch_info *arch_info; - - /* Stuff only useful for archives:*/ - PTR arelt_data; - struct _bfd *my_archive; /* The containing archive BFD. */ - struct _bfd *next; /* The next BFD in the archive. */ - struct _bfd *archive_head; /* The first BFD in the archive. */ - boolean has_armap; - - /* A chain of BFD structures involved in a link. */ - struct _bfd *link_next; - - /* A field used by _bfd_generic_link_add_archive_symbols. This will - be used only for archive elements. */ - int archive_pass; - - /* Used by the back end to hold private data. */ - - union - { - struct aout_data_struct *aout_data; - struct artdata *aout_ar_data; - struct _oasys_data *oasys_obj_data; - struct _oasys_ar_data *oasys_ar_data; - struct coff_tdata *coff_obj_data; - struct pe_tdata *pe_obj_data; - struct xcoff_tdata *xcoff_obj_data; - struct ecoff_tdata *ecoff_obj_data; - struct ieee_data_struct *ieee_data; - struct ieee_ar_data_struct *ieee_ar_data; - struct srec_data_struct *srec_data; - struct ihex_data_struct *ihex_data; - struct tekhex_data_struct *tekhex_data; - struct elf_obj_tdata *elf_obj_data; - struct nlm_obj_tdata *nlm_obj_data; - struct bout_data_struct *bout_data; - struct sun_core_struct *sun_core_data; - struct trad_core_struct *trad_core_data; - struct som_data_struct *som_data; - struct hpux_core_struct *hpux_core_data; - struct hppabsd_core_struct *hppabsd_core_data; - struct sgi_core_struct *sgi_core_data; - struct lynx_core_struct *lynx_core_data; - struct osf_core_struct *osf_core_data; - struct cisco_core_struct *cisco_core_data; - struct versados_data_struct *versados_data; - struct netbsd_core_struct *netbsd_core_data; - PTR any; - } tdata; - - /* Used by the application to hold private data*/ - PTR usrdata; - - /* Where all the allocated stuff under this BFD goes */ - struct obstack memory; -}; - -typedef enum bfd_error -{ - bfd_error_no_error = 0, - bfd_error_system_call, - bfd_error_invalid_target, - bfd_error_wrong_format, - bfd_error_invalid_operation, - bfd_error_no_memory, - bfd_error_no_symbols, - bfd_error_no_armap, - bfd_error_no_more_archived_files, - bfd_error_malformed_archive, - bfd_error_file_not_recognized, - bfd_error_file_ambiguously_recognized, - bfd_error_no_contents, - bfd_error_nonrepresentable_section, - bfd_error_no_debug_section, - bfd_error_bad_value, - bfd_error_file_truncated, - bfd_error_file_too_big, - bfd_error_invalid_error_code -} bfd_error_type; - -bfd_error_type -bfd_get_error PARAMS ((void)); - -void -bfd_set_error PARAMS ((bfd_error_type error_tag)); - -CONST char * -bfd_errmsg PARAMS ((bfd_error_type error_tag)); - -void -bfd_perror PARAMS ((CONST char *message)); - -typedef void (*bfd_error_handler_type) PARAMS ((const char *, ...)); - -bfd_error_handler_type -bfd_set_error_handler PARAMS ((bfd_error_handler_type)); - -void -bfd_set_error_program_name PARAMS ((const char *)); - -long -bfd_get_reloc_upper_bound PARAMS ((bfd *abfd, asection *sect)); - -long -bfd_canonicalize_reloc - PARAMS ((bfd *abfd, - asection *sec, - arelent **loc, - asymbol **syms)); - -void -bfd_set_reloc - PARAMS ((bfd *abfd, asection *sec, arelent **rel, unsigned int count) - - ); - -boolean -bfd_set_file_flags PARAMS ((bfd *abfd, flagword flags)); - -boolean -bfd_set_start_address PARAMS ((bfd *abfd, bfd_vma vma)); - -long -bfd_get_mtime PARAMS ((bfd *abfd)); - -long -bfd_get_size PARAMS ((bfd *abfd)); - -int -bfd_get_gp_size PARAMS ((bfd *abfd)); - -void -bfd_set_gp_size PARAMS ((bfd *abfd, int i)); - -bfd_vma -bfd_scan_vma PARAMS ((CONST char *string, CONST char **end, int base)); - -boolean -bfd_copy_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd)); - -#define bfd_copy_private_bfd_data(ibfd, obfd) \ - BFD_SEND (ibfd, _bfd_copy_private_bfd_data, \ - (ibfd, obfd)) -boolean -bfd_merge_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd)); - -#define bfd_merge_private_bfd_data(ibfd, obfd) \ - BFD_SEND (ibfd, _bfd_merge_private_bfd_data, \ - (ibfd, obfd)) -boolean -bfd_set_private_flags PARAMS ((bfd *abfd, flagword flags)); - -#define bfd_set_private_flags(abfd, flags) \ - BFD_SEND (abfd, _bfd_set_private_flags, \ - (abfd, flags)) -#define bfd_sizeof_headers(abfd, reloc) \ - BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc)) - -#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \ - BFD_SEND (abfd, _bfd_find_nearest_line, (abfd, sec, syms, off, file, func, line)) - - /* Do these three do anything useful at all, for any back end? */ -#define bfd_debug_info_start(abfd) \ - BFD_SEND (abfd, _bfd_debug_info_start, (abfd)) - -#define bfd_debug_info_end(abfd) \ - BFD_SEND (abfd, _bfd_debug_info_end, (abfd)) - -#define bfd_debug_info_accumulate(abfd, section) \ - BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section)) - - -#define bfd_stat_arch_elt(abfd, stat) \ - BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat)) - -#define bfd_update_armap_timestamp(abfd) \ - BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd)) - -#define bfd_set_arch_mach(abfd, arch, mach)\ - BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach)) - -#define bfd_relax_section(abfd, section, link_info, again) \ - BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again)) - -#define bfd_link_hash_table_create(abfd) \ - BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd)) - -#define bfd_link_add_symbols(abfd, info) \ - BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info)) - -#define bfd_final_link(abfd, info) \ - BFD_SEND (abfd, _bfd_final_link, (abfd, info)) - -#define bfd_free_cached_info(abfd) \ - BFD_SEND (abfd, _bfd_free_cached_info, (abfd)) - -#define bfd_get_dynamic_symtab_upper_bound(abfd) \ - BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd)) - -#define bfd_print_private_bfd_data(abfd, file)\ - BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file)) - -#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \ - BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols)) - -#define bfd_get_dynamic_reloc_upper_bound(abfd) \ - BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd)) - -#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \ - BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms)) - -extern bfd_byte *bfd_get_relocated_section_contents - PARAMS ((bfd *, struct bfd_link_info *, - struct bfd_link_order *, bfd_byte *, - boolean, asymbol **)); - -symindex -bfd_get_next_mapent PARAMS ((bfd *abfd, symindex previous, carsym **sym)); - -boolean -bfd_set_archive_head PARAMS ((bfd *output, bfd *new_head)); - -bfd * -bfd_openr_next_archived_file PARAMS ((bfd *archive, bfd *previous)); - -CONST char * -bfd_core_file_failing_command PARAMS ((bfd *abfd)); - -int -bfd_core_file_failing_signal PARAMS ((bfd *abfd)); - -boolean -core_file_matches_executable_p - PARAMS ((bfd *core_bfd, bfd *exec_bfd)); - -#define BFD_SEND(bfd, message, arglist) \ - ((*((bfd)->xvec->message)) arglist) - -#ifdef DEBUG_BFD_SEND -#undef BFD_SEND -#define BFD_SEND(bfd, message, arglist) \ - (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ - ((*((bfd)->xvec->message)) arglist) : \ - (bfd_assert (__FILE__,__LINE__), NULL)) -#endif -#define BFD_SEND_FMT(bfd, message, arglist) \ - (((bfd)->xvec->message[(int)((bfd)->format)]) arglist) - -#ifdef DEBUG_BFD_SEND -#undef BFD_SEND_FMT -#define BFD_SEND_FMT(bfd, message, arglist) \ - (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ - (((bfd)->xvec->message[(int)((bfd)->format)]) arglist) : \ - (bfd_assert (__FILE__,__LINE__), NULL)) -#endif -enum bfd_flavour { - bfd_target_unknown_flavour, - bfd_target_aout_flavour, - bfd_target_coff_flavour, - bfd_target_ecoff_flavour, - bfd_target_elf_flavour, - bfd_target_ieee_flavour, - bfd_target_nlm_flavour, - bfd_target_oasys_flavour, - bfd_target_tekhex_flavour, - bfd_target_srec_flavour, - bfd_target_ihex_flavour, - bfd_target_som_flavour, - bfd_target_os9k_flavour, - bfd_target_versados_flavour, - bfd_target_msdos_flavour -}; - -enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN }; - - /* Forward declaration. */ -typedef struct bfd_link_info _bfd_link_info; - -typedef struct bfd_target -{ - char *name; - enum bfd_flavour flavour; - enum bfd_endian byteorder; - enum bfd_endian header_byteorder; - flagword object_flags; - flagword section_flags; - char symbol_leading_char; - char ar_pad_char; - unsigned short ar_max_namelen; - bfd_vma (*bfd_getx64) PARAMS ((const bfd_byte *)); - bfd_signed_vma (*bfd_getx_signed_64) PARAMS ((const bfd_byte *)); - void (*bfd_putx64) PARAMS ((bfd_vma, bfd_byte *)); - bfd_vma (*bfd_getx32) PARAMS ((const bfd_byte *)); - bfd_signed_vma (*bfd_getx_signed_32) PARAMS ((const bfd_byte *)); - void (*bfd_putx32) PARAMS ((bfd_vma, bfd_byte *)); - bfd_vma (*bfd_getx16) PARAMS ((const bfd_byte *)); - bfd_signed_vma (*bfd_getx_signed_16) PARAMS ((const bfd_byte *)); - void (*bfd_putx16) PARAMS ((bfd_vma, bfd_byte *)); - bfd_vma (*bfd_h_getx64) PARAMS ((const bfd_byte *)); - bfd_signed_vma (*bfd_h_getx_signed_64) PARAMS ((const bfd_byte *)); - void (*bfd_h_putx64) PARAMS ((bfd_vma, bfd_byte *)); - bfd_vma (*bfd_h_getx32) PARAMS ((const bfd_byte *)); - bfd_signed_vma (*bfd_h_getx_signed_32) PARAMS ((const bfd_byte *)); - void (*bfd_h_putx32) PARAMS ((bfd_vma, bfd_byte *)); - bfd_vma (*bfd_h_getx16) PARAMS ((const bfd_byte *)); - bfd_signed_vma (*bfd_h_getx_signed_16) PARAMS ((const bfd_byte *)); - void (*bfd_h_putx16) PARAMS ((bfd_vma, bfd_byte *)); - const struct bfd_target *(*_bfd_check_format[bfd_type_end]) PARAMS ((bfd *)); - boolean (*_bfd_set_format[bfd_type_end]) PARAMS ((bfd *)); - boolean (*_bfd_write_contents[bfd_type_end]) PARAMS ((bfd *)); - - /* Generic entry points. */ -#define BFD_JUMP_TABLE_GENERIC(NAME)\ -CAT(NAME,_close_and_cleanup),\ -CAT(NAME,_bfd_free_cached_info),\ -CAT(NAME,_new_section_hook),\ -CAT(NAME,_get_section_contents),\ -CAT(NAME,_get_section_contents_in_window) - - /* Called when the BFD is being closed to do any necessary cleanup. */ - boolean (*_close_and_cleanup) PARAMS ((bfd *)); - /* Ask the BFD to free all cached information. */ - boolean (*_bfd_free_cached_info) PARAMS ((bfd *)); - /* Called when a new section is created. */ - boolean (*_new_section_hook) PARAMS ((bfd *, sec_ptr)); - /* Read the contents of a section. */ - boolean (*_bfd_get_section_contents) PARAMS ((bfd *, sec_ptr, PTR, - file_ptr, bfd_size_type)); - boolean (*_bfd_get_section_contents_in_window) - PARAMS ((bfd *, sec_ptr, bfd_window *, - file_ptr, bfd_size_type)); - - /* Entry points to copy private data. */ -#define BFD_JUMP_TABLE_COPY(NAME)\ -CAT(NAME,_bfd_copy_private_bfd_data),\ -CAT(NAME,_bfd_merge_private_bfd_data),\ -CAT(NAME,_bfd_copy_private_section_data),\ -CAT(NAME,_bfd_copy_private_symbol_data),\ -CAT(NAME,_bfd_set_private_flags),\ -CAT(NAME,_bfd_print_private_bfd_data)\ - /* Called to copy BFD general private data from one object file - to another. */ - boolean (*_bfd_copy_private_bfd_data) PARAMS ((bfd *, bfd *)); - /* Called to merge BFD general private data from one object file - to a common output file when linking. */ - boolean (*_bfd_merge_private_bfd_data) PARAMS ((bfd *, bfd *)); - /* Called to copy BFD private section data from one object file - to another. */ - boolean (*_bfd_copy_private_section_data) PARAMS ((bfd *, sec_ptr, - bfd *, sec_ptr)); - /* Called to copy BFD private symbol data from one symbol - to another. */ - boolean (*_bfd_copy_private_symbol_data) PARAMS ((bfd *, asymbol *, - bfd *, asymbol *)); - /* Called to set private backend flags */ - boolean (*_bfd_set_private_flags) PARAMS ((bfd *, flagword)); - - /* Called to print private BFD data */ - boolean (*_bfd_print_private_bfd_data) PARAMS ((bfd *, PTR)); - - /* Core file entry points. */ -#define BFD_JUMP_TABLE_CORE(NAME)\ -CAT(NAME,_core_file_failing_command),\ -CAT(NAME,_core_file_failing_signal),\ -CAT(NAME,_core_file_matches_executable_p) - char * (*_core_file_failing_command) PARAMS ((bfd *)); - int (*_core_file_failing_signal) PARAMS ((bfd *)); - boolean (*_core_file_matches_executable_p) PARAMS ((bfd *, bfd *)); - - /* Archive entry points. */ -#define BFD_JUMP_TABLE_ARCHIVE(NAME)\ -CAT(NAME,_slurp_armap),\ -CAT(NAME,_slurp_extended_name_table),\ -CAT(NAME,_construct_extended_name_table),\ -CAT(NAME,_truncate_arname),\ -CAT(NAME,_write_armap),\ -CAT(NAME,_read_ar_hdr),\ -CAT(NAME,_openr_next_archived_file),\ -CAT(NAME,_get_elt_at_index),\ -CAT(NAME,_generic_stat_arch_elt),\ -CAT(NAME,_update_armap_timestamp) - boolean (*_bfd_slurp_armap) PARAMS ((bfd *)); - boolean (*_bfd_slurp_extended_name_table) PARAMS ((bfd *)); - boolean (*_bfd_construct_extended_name_table) - PARAMS ((bfd *, char **, bfd_size_type *, const char **)); - void (*_bfd_truncate_arname) PARAMS ((bfd *, CONST char *, char *)); - boolean (*write_armap) PARAMS ((bfd *arch, - unsigned int elength, - struct orl *map, - unsigned int orl_count, - int stridx)); - PTR (*_bfd_read_ar_hdr_fn) PARAMS ((bfd *)); - bfd * (*openr_next_archived_file) PARAMS ((bfd *arch, bfd *prev)); -#define bfd_get_elt_at_index(b,i) BFD_SEND(b, _bfd_get_elt_at_index, (b,i)) - bfd * (*_bfd_get_elt_at_index) PARAMS ((bfd *, symindex)); - int (*_bfd_stat_arch_elt) PARAMS ((bfd *, struct stat *)); - boolean (*_bfd_update_armap_timestamp) PARAMS ((bfd *)); - - /* Entry points used for symbols. */ -#define BFD_JUMP_TABLE_SYMBOLS(NAME)\ -CAT(NAME,_get_symtab_upper_bound),\ -CAT(NAME,_get_symtab),\ -CAT(NAME,_make_empty_symbol),\ -CAT(NAME,_print_symbol),\ -CAT(NAME,_get_symbol_info),\ -CAT(NAME,_bfd_is_local_label),\ -CAT(NAME,_get_lineno),\ -CAT(NAME,_find_nearest_line),\ -CAT(NAME,_bfd_make_debug_symbol),\ -CAT(NAME,_read_minisymbols),\ -CAT(NAME,_minisymbol_to_symbol) - long (*_bfd_get_symtab_upper_bound) PARAMS ((bfd *)); - long (*_bfd_canonicalize_symtab) PARAMS ((bfd *, - struct symbol_cache_entry **)); - struct symbol_cache_entry * - (*_bfd_make_empty_symbol) PARAMS ((bfd *)); - void (*_bfd_print_symbol) PARAMS ((bfd *, PTR, - struct symbol_cache_entry *, - bfd_print_symbol_type)); -#define bfd_print_symbol(b,p,s,e) BFD_SEND(b, _bfd_print_symbol, (b,p,s,e)) - void (*_bfd_get_symbol_info) PARAMS ((bfd *, - struct symbol_cache_entry *, - symbol_info *)); -#define bfd_get_symbol_info(b,p,e) BFD_SEND(b, _bfd_get_symbol_info, (b,p,e)) - boolean (*_bfd_is_local_label) PARAMS ((bfd *, asymbol *)); - - alent * (*_get_lineno) PARAMS ((bfd *, struct symbol_cache_entry *)); - boolean (*_bfd_find_nearest_line) PARAMS ((bfd *abfd, - struct sec *section, struct symbol_cache_entry **symbols, - bfd_vma offset, CONST char **file, CONST char **func, - unsigned int *line)); - /* Back-door to allow format-aware applications to create debug symbols - while using BFD for everything else. Currently used by the assembler - when creating COFF files. */ - asymbol * (*_bfd_make_debug_symbol) PARAMS (( - bfd *abfd, - void *ptr, - unsigned long size)); -#define bfd_read_minisymbols(b, d, m, s) \ - BFD_SEND (b, _read_minisymbols, (b, d, m, s)) - long (*_read_minisymbols) PARAMS ((bfd *, boolean, PTR *, - unsigned int *)); -#define bfd_minisymbol_to_symbol(b, d, m, f) \ - BFD_SEND (b, _minisymbol_to_symbol, (b, d, m, f)) - asymbol *(*_minisymbol_to_symbol) PARAMS ((bfd *, boolean, const PTR, - asymbol *)); - - /* Routines for relocs. */ -#define BFD_JUMP_TABLE_RELOCS(NAME)\ -CAT(NAME,_get_reloc_upper_bound),\ -CAT(NAME,_canonicalize_reloc),\ -CAT(NAME,_bfd_reloc_type_lookup) - long (*_get_reloc_upper_bound) PARAMS ((bfd *, sec_ptr)); - long (*_bfd_canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **, - struct symbol_cache_entry **)); - /* See documentation on reloc types. */ - reloc_howto_type * - (*reloc_type_lookup) PARAMS ((bfd *abfd, - bfd_reloc_code_real_type code)); - - /* Routines used when writing an object file. */ -#define BFD_JUMP_TABLE_WRITE(NAME)\ -CAT(NAME,_set_arch_mach),\ -CAT(NAME,_set_section_contents) - boolean (*_bfd_set_arch_mach) PARAMS ((bfd *, enum bfd_architecture, - unsigned long)); - boolean (*_bfd_set_section_contents) PARAMS ((bfd *, sec_ptr, PTR, - file_ptr, bfd_size_type)); - - /* Routines used by the linker. */ -#define BFD_JUMP_TABLE_LINK(NAME)\ -CAT(NAME,_sizeof_headers),\ -CAT(NAME,_bfd_get_relocated_section_contents),\ -CAT(NAME,_bfd_relax_section),\ -CAT(NAME,_bfd_link_hash_table_create),\ -CAT(NAME,_bfd_link_add_symbols),\ -CAT(NAME,_bfd_final_link),\ -CAT(NAME,_bfd_link_split_section) - int (*_bfd_sizeof_headers) PARAMS ((bfd *, boolean)); - bfd_byte * (*_bfd_get_relocated_section_contents) PARAMS ((bfd *, - struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *data, boolean relocateable, - struct symbol_cache_entry **)); - - boolean (*_bfd_relax_section) PARAMS ((bfd *, struct sec *, - struct bfd_link_info *, boolean *again)); - - /* Create a hash table for the linker. Different backends store - different information in this table. */ - struct bfd_link_hash_table *(*_bfd_link_hash_table_create) PARAMS ((bfd *)); - - /* Add symbols from this object file into the hash table. */ - boolean (*_bfd_link_add_symbols) PARAMS ((bfd *, struct bfd_link_info *)); - - /* Do a link based on the link_order structures attached to each - section of the BFD. */ - boolean (*_bfd_final_link) PARAMS ((bfd *, struct bfd_link_info *)); - - /* Should this section be split up into smaller pieces during linking. */ - boolean (*_bfd_link_split_section) PARAMS ((bfd *, struct sec *)); - - /* Routines to handle dynamic symbols and relocs. */ -#define BFD_JUMP_TABLE_DYNAMIC(NAME)\ -CAT(NAME,_get_dynamic_symtab_upper_bound),\ -CAT(NAME,_canonicalize_dynamic_symtab),\ -CAT(NAME,_get_dynamic_reloc_upper_bound),\ -CAT(NAME,_canonicalize_dynamic_reloc) - /* Get the amount of memory required to hold the dynamic symbols. */ - long (*_bfd_get_dynamic_symtab_upper_bound) PARAMS ((bfd *)); - /* Read in the dynamic symbols. */ - long (*_bfd_canonicalize_dynamic_symtab) - PARAMS ((bfd *, struct symbol_cache_entry **)); - /* Get the amount of memory required to hold the dynamic relocs. */ - long (*_bfd_get_dynamic_reloc_upper_bound) PARAMS ((bfd *)); - /* Read in the dynamic relocs. */ - long (*_bfd_canonicalize_dynamic_reloc) - PARAMS ((bfd *, arelent **, struct symbol_cache_entry **)); - - PTR backend_data; -} bfd_target; -const bfd_target * -bfd_find_target PARAMS ((CONST char *target_name, bfd *abfd)); - -const char ** -bfd_target_list PARAMS ((void)); - -boolean -bfd_check_format PARAMS ((bfd *abfd, bfd_format format)); - -boolean -bfd_check_format_matches PARAMS ((bfd *abfd, bfd_format format, char ***matching)); - -boolean -bfd_set_format PARAMS ((bfd *abfd, bfd_format format)); - -CONST char * -bfd_format_string PARAMS ((bfd_format format)); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/contrib/gdb/bfd/bout.c b/contrib/gdb/bfd/bout.c deleted file mode 100644 index 9da4b82..0000000 --- a/contrib/gdb/bfd/bout.c +++ /dev/null @@ -1,1471 +0,0 @@ -/* BFD back-end for Intel 960 b.out binaries. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "genlink.h" -#include "bout.h" - -#include "aout/stab_gnu.h" -#include "libaout.h" /* BFD a.out internal data structures */ - - -static int aligncode PARAMS ((bfd *abfd, asection *input_section, - arelent *r, unsigned int shrink)); -static void perform_slip PARAMS ((bfd *abfd, unsigned int slip, - asection *input_section, bfd_vma value)); -static boolean b_out_squirt_out_relocs PARAMS ((bfd *abfd, asection *section)); -static const bfd_target *b_out_callback PARAMS ((bfd *)); -static bfd_reloc_status_type calljx_callback - PARAMS ((bfd *, struct bfd_link_info *, arelent *, PTR src, PTR dst, - asection *)); -static bfd_reloc_status_type callj_callback - PARAMS ((bfd *, struct bfd_link_info *, arelent *, PTR data, - unsigned int srcidx, unsigned int dstidx, asection *, boolean)); -static bfd_vma get_value PARAMS ((arelent *, struct bfd_link_info *, - asection *)); -static int abs32code PARAMS ((bfd *, asection *, arelent *, - unsigned int, struct bfd_link_info *)); -static boolean b_out_bfd_relax_section PARAMS ((bfd *, asection *, - struct bfd_link_info *, - boolean *)); -static bfd_byte *b_out_bfd_get_relocated_section_contents - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *, boolean, asymbol **)); - -/* Swaps the information in an executable header taken from a raw byte - stream memory image, into the internal exec_header structure. */ - -void -bout_swap_exec_header_in (abfd, raw_bytes, execp) - bfd *abfd; - struct external_exec *raw_bytes; - struct internal_exec *execp; -{ - struct external_exec *bytes = (struct external_exec *)raw_bytes; - - /* Now fill in fields in the execp, from the bytes in the raw data. */ - execp->a_info = bfd_h_get_32 (abfd, bytes->e_info); - execp->a_text = GET_WORD (abfd, bytes->e_text); - execp->a_data = GET_WORD (abfd, bytes->e_data); - execp->a_bss = GET_WORD (abfd, bytes->e_bss); - execp->a_syms = GET_WORD (abfd, bytes->e_syms); - execp->a_entry = GET_WORD (abfd, bytes->e_entry); - execp->a_trsize = GET_WORD (abfd, bytes->e_trsize); - execp->a_drsize = GET_WORD (abfd, bytes->e_drsize); - execp->a_tload = GET_WORD (abfd, bytes->e_tload); - execp->a_dload = GET_WORD (abfd, bytes->e_dload); - execp->a_talign = bytes->e_talign[0]; - execp->a_dalign = bytes->e_dalign[0]; - execp->a_balign = bytes->e_balign[0]; - execp->a_relaxable = bytes->e_relaxable[0]; -} - -/* Swaps the information in an internal exec header structure into the - supplied buffer ready for writing to disk. */ - -PROTO(void, bout_swap_exec_header_out, - (bfd *abfd, - struct internal_exec *execp, - struct external_exec *raw_bytes)); -void -bout_swap_exec_header_out (abfd, execp, raw_bytes) - bfd *abfd; - struct internal_exec *execp; - struct external_exec *raw_bytes; -{ - struct external_exec *bytes = (struct external_exec *)raw_bytes; - - /* Now fill in fields in the raw data, from the fields in the exec struct. */ - bfd_h_put_32 (abfd, execp->a_info , bytes->e_info); - PUT_WORD (abfd, execp->a_text , bytes->e_text); - PUT_WORD (abfd, execp->a_data , bytes->e_data); - PUT_WORD (abfd, execp->a_bss , bytes->e_bss); - PUT_WORD (abfd, execp->a_syms , bytes->e_syms); - PUT_WORD (abfd, execp->a_entry , bytes->e_entry); - PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize); - PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize); - PUT_WORD (abfd, execp->a_tload , bytes->e_tload); - PUT_WORD (abfd, execp->a_dload , bytes->e_dload); - bytes->e_talign[0] = execp->a_talign; - bytes->e_dalign[0] = execp->a_dalign; - bytes->e_balign[0] = execp->a_balign; - bytes->e_relaxable[0] = execp->a_relaxable; -} - - -static const bfd_target * -b_out_object_p (abfd) - bfd *abfd; -{ - struct internal_exec anexec; - struct external_exec exec_bytes; - - if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) - != EXEC_BYTES_SIZE) { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - anexec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info); - - if (N_BADMAG (anexec)) { - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - bout_swap_exec_header_in (abfd, &exec_bytes, &anexec); - return aout_32_some_aout_object_p (abfd, &anexec, b_out_callback); -} - - -/* Finish up the opening of a b.out file for reading. Fill in all the - fields that are not handled by common code. */ - -static const bfd_target * -b_out_callback (abfd) - bfd *abfd; -{ - struct internal_exec *execp = exec_hdr (abfd); - unsigned long bss_start; - - /* Architecture and machine type */ - bfd_set_arch_mach(abfd, - bfd_arch_i960, /* B.out only used on i960 */ - bfd_mach_i960_core /* Default */ - ); - - /* The positions of the string table and symbol table. */ - obj_str_filepos (abfd) = N_STROFF (*execp); - obj_sym_filepos (abfd) = N_SYMOFF (*execp); - - /* The alignments of the sections */ - obj_textsec (abfd)->alignment_power = execp->a_talign; - obj_datasec (abfd)->alignment_power = execp->a_dalign; - obj_bsssec (abfd)->alignment_power = execp->a_balign; - - /* The starting addresses of the sections. */ - obj_textsec (abfd)->vma = execp->a_tload; - obj_datasec (abfd)->vma = execp->a_dload; - - /* And reload the sizes, since the aout module zaps them */ - obj_textsec (abfd)->_raw_size = execp->a_text; - - bss_start = execp->a_dload + execp->a_data; /* BSS = end of data section */ - obj_bsssec (abfd)->vma = align_power (bss_start, execp->a_balign); - - /* The file positions of the sections */ - obj_textsec (abfd)->filepos = N_TXTOFF(*execp); - obj_datasec (abfd)->filepos = N_DATOFF(*execp); - - /* The file positions of the relocation info */ - obj_textsec (abfd)->rel_filepos = N_TROFF(*execp); - obj_datasec (abfd)->rel_filepos = N_DROFF(*execp); - - adata(abfd).page_size = 1; /* Not applicable. */ - adata(abfd).segment_size = 1; /* Not applicable. */ - adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE; - - if (execp->a_relaxable) - abfd->flags |= BFD_IS_RELAXABLE; - return abfd->xvec; -} - -struct bout_data_struct { - struct aoutdata a; - struct internal_exec e; -}; - -static boolean -b_out_mkobject (abfd) - bfd *abfd; -{ - struct bout_data_struct *rawptr; - - rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, sizeof (struct bout_data_struct)); - if (rawptr == NULL) - return false; - - abfd->tdata.bout_data = rawptr; - exec_hdr (abfd) = &rawptr->e; - - obj_textsec (abfd) = (asection *)NULL; - obj_datasec (abfd) = (asection *)NULL; - obj_bsssec (abfd) = (asection *)NULL; - - return true; -} - -static boolean -b_out_write_object_contents (abfd) - bfd *abfd; -{ - struct external_exec swapped_hdr; - - if (! aout_32_make_sections (abfd)) - return false; - - exec_hdr (abfd)->a_info = BMAGIC; - - exec_hdr (abfd)->a_text = obj_textsec (abfd)->_raw_size; - exec_hdr (abfd)->a_data = obj_datasec (abfd)->_raw_size; - exec_hdr (abfd)->a_bss = obj_bsssec (abfd)->_raw_size; - exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist); - exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd); - exec_hdr (abfd)->a_trsize = ((obj_textsec (abfd)->reloc_count) * - sizeof (struct relocation_info)); - exec_hdr (abfd)->a_drsize = ((obj_datasec (abfd)->reloc_count) * - sizeof (struct relocation_info)); - - exec_hdr (abfd)->a_talign = obj_textsec (abfd)->alignment_power; - exec_hdr (abfd)->a_dalign = obj_datasec (abfd)->alignment_power; - exec_hdr (abfd)->a_balign = obj_bsssec (abfd)->alignment_power; - - exec_hdr (abfd)->a_tload = obj_textsec (abfd)->vma; - exec_hdr (abfd)->a_dload = obj_datasec (abfd)->vma; - - bout_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr); - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || (bfd_write ((PTR) &swapped_hdr, 1, EXEC_BYTES_SIZE, abfd) - != EXEC_BYTES_SIZE)) - return false; - - /* Now write out reloc info, followed by syms and strings */ - if (bfd_get_symcount (abfd) != 0) - { - if (bfd_seek (abfd, (file_ptr)(N_SYMOFF(*exec_hdr(abfd))), SEEK_SET) - != 0) - return false; - - if (! aout_32_write_syms (abfd)) - return false; - - if (bfd_seek (abfd, (file_ptr)(N_TROFF(*exec_hdr(abfd))), SEEK_SET) != 0) - return false; - - if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd))) return false; - if (bfd_seek (abfd, (file_ptr)(N_DROFF(*exec_hdr(abfd))), SEEK_SET) - != 0) - return false; - - if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd))) return false; - } - return true; -} - -/** Some reloc hackery */ - -#define CALLS 0x66003800 /* Template for 'calls' instruction */ -#define BAL 0x0b000000 /* Template for 'bal' instruction */ -#define BALX 0x85000000 /* Template for 'balx' instruction */ -#define BAL_MASK 0x00ffffff -#define CALL 0x09000000 -#define PCREL13_MASK 0x1fff - - -#define output_addr(sec) ((sec)->output_offset+(sec)->output_section->vma) - -/* Magic to turn callx into calljx */ -static bfd_reloc_status_type -calljx_callback (abfd, link_info, reloc_entry, src, dst, input_section) - bfd *abfd; - struct bfd_link_info *link_info; - arelent *reloc_entry; - PTR src; - PTR dst; - asection *input_section; -{ - int word = bfd_get_32 (abfd, src); - asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr); - aout_symbol_type *symbol = aout_symbol (symbol_in); - bfd_vma value; - - value = get_value (reloc_entry, link_info, input_section); - - if (IS_CALLNAME (symbol->other)) - { - aout_symbol_type *balsym = symbol+1; - int inst = bfd_get_32 (abfd, (bfd_byte *) src-4); - /* The next symbol should be an N_BALNAME */ - BFD_ASSERT (IS_BALNAME (balsym->other)); - inst &= BAL_MASK; - inst |= BALX; - bfd_put_32 (abfd, inst, (bfd_byte *) dst-4); - symbol = balsym; - value = (symbol->symbol.value - + output_addr (symbol->symbol.section)); - } - - word += value + reloc_entry->addend; - - bfd_put_32(abfd, word, dst); - return bfd_reloc_ok; -} - - -/* Magic to turn call into callj */ -static bfd_reloc_status_type -callj_callback (abfd, link_info, reloc_entry, data, srcidx, dstidx, - input_section, shrinking) - bfd *abfd; - struct bfd_link_info *link_info; - arelent *reloc_entry; - PTR data; - unsigned int srcidx; - unsigned int dstidx; - asection *input_section; - boolean shrinking; -{ - int word = bfd_get_32 (abfd, (bfd_byte *) data + srcidx); - asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr); - aout_symbol_type *symbol = aout_symbol (symbol_in); - bfd_vma value; - - value = get_value (reloc_entry, link_info, input_section); - - if (IS_OTHER(symbol->other)) - { - /* Call to a system procedure - replace code with system - procedure number. */ - word = CALLS | (symbol->other - 1); - } - else if (IS_CALLNAME(symbol->other)) - { - aout_symbol_type *balsym = symbol+1; - - /* The next symbol should be an N_BALNAME. */ - BFD_ASSERT(IS_BALNAME(balsym->other)); - - /* We are calling a leaf, so replace the call instruction with a - bal. */ - word = BAL | ((word - + output_addr (balsym->symbol.section) - + balsym->symbol.value + reloc_entry->addend - - dstidx - - output_addr (input_section)) - & BAL_MASK); - } - else if ((symbol->symbol.flags & BSF_SECTION_SYM) != 0) - { - /* A callj against a symbol in the same section is a fully - resolved relative call. We don't need to do anything here. - If the symbol is not in the same section, I'm not sure what - to do; fortunately, this case will probably never arise. */ - BFD_ASSERT (! shrinking); - BFD_ASSERT (symbol->symbol.section == input_section); - } - else - { - word = CALL | (((word & BAL_MASK) - + value - + reloc_entry->addend - - (shrinking ? dstidx : 0) - - output_addr (input_section)) - & BAL_MASK); - } - bfd_put_32(abfd, word, (bfd_byte *) data + dstidx); - return bfd_reloc_ok; -} - -/* type rshift size bitsize pcrel bitpos absolute overflow check*/ - -#define ABS32CODE 0 -#define ABS32CODE_SHRUNK 1 -#define PCREL24 2 -#define CALLJ 3 -#define ABS32 4 -#define PCREL13 5 -#define ABS32_MAYBE_RELAXABLE 1 -#define ABS32_WAS_RELAXABLE 2 - -#define ALIGNER 10 -#define ALIGNDONE 11 -static reloc_howto_type howto_reloc_callj = -HOWTO(CALLJ, 0, 2, 24, true, 0, complain_overflow_signed, 0,"callj", true, 0x00ffffff, 0x00ffffff,false); -static reloc_howto_type howto_reloc_abs32 = -HOWTO(ABS32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"abs32", true, 0xffffffff,0xffffffff,false); -static reloc_howto_type howto_reloc_pcrel24 = -HOWTO(PCREL24, 0, 2, 24, true, 0, complain_overflow_signed,0,"pcrel24", true, 0x00ffffff,0x00ffffff,false); - -static reloc_howto_type howto_reloc_pcrel13 = -HOWTO(PCREL13, 0, 2, 13, true, 0, complain_overflow_signed,0,"pcrel13", true, 0x00001fff,0x00001fff,false); - - -static reloc_howto_type howto_reloc_abs32codeshrunk = -HOWTO(ABS32CODE_SHRUNK, 0, 2, 24, true, 0, complain_overflow_signed, 0,"callx->callj", true, 0x00ffffff, 0x00ffffff,false); - -static reloc_howto_type howto_reloc_abs32code = -HOWTO(ABS32CODE, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"callx", true, 0xffffffff,0xffffffff,false); - -static reloc_howto_type howto_align_table[] = { - HOWTO (ALIGNER, 0, 0x1, 0, false, 0, complain_overflow_dont, 0, "align16", false, 0, 0, false), - HOWTO (ALIGNER, 0, 0x3, 0, false, 0, complain_overflow_dont, 0, "align32", false, 0, 0, false), - HOWTO (ALIGNER, 0, 0x7, 0, false, 0, complain_overflow_dont, 0, "align64", false, 0, 0, false), - HOWTO (ALIGNER, 0, 0xf, 0, false, 0, complain_overflow_dont, 0, "align128", false, 0, 0, false), -}; - -static reloc_howto_type howto_done_align_table[] = { - HOWTO (ALIGNDONE, 0x1, 0x1, 0, false, 0, complain_overflow_dont, 0, "donealign16", false, 0, 0, false), - HOWTO (ALIGNDONE, 0x3, 0x3, 0, false, 0, complain_overflow_dont, 0, "donealign32", false, 0, 0, false), - HOWTO (ALIGNDONE, 0x7, 0x7, 0, false, 0, complain_overflow_dont, 0, "donealign64", false, 0, 0, false), - HOWTO (ALIGNDONE, 0xf, 0xf, 0, false, 0, complain_overflow_dont, 0, "donealign128", false, 0, 0, false), -}; - -static reloc_howto_type * -b_out_bfd_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - switch (code) - { - default: - return 0; - case BFD_RELOC_I960_CALLJ: - return &howto_reloc_callj; - case BFD_RELOC_32: - case BFD_RELOC_CTOR: - return &howto_reloc_abs32; - case BFD_RELOC_24_PCREL: - return &howto_reloc_pcrel24; - } -} - -/* Allocate enough room for all the reloc entries, plus pointers to them all */ - -static boolean -b_out_slurp_reloc_table (abfd, asect, symbols) - bfd *abfd; - sec_ptr asect; - asymbol **symbols; -{ - register struct relocation_info *rptr; - unsigned int counter ; - arelent *cache_ptr ; - int extern_mask, pcrel_mask, callj_mask, length_shift; - int incode_mask; - int size_mask; - bfd_vma prev_addr = 0; - unsigned int count; - size_t reloc_size; - struct relocation_info *relocs; - arelent *reloc_cache; - - if (asect->relocation) - return true; - if (!aout_32_slurp_symbol_table (abfd)) - return false; - - if (asect == obj_datasec (abfd)) { - reloc_size = exec_hdr(abfd)->a_drsize; - goto doit; - } - - if (asect == obj_textsec (abfd)) { - reloc_size = exec_hdr(abfd)->a_trsize; - goto doit; - } - - if (asect == obj_bsssec (abfd)) { - reloc_size = 0; - goto doit; - } - - bfd_set_error (bfd_error_invalid_operation); - return false; - - doit: - if (bfd_seek (abfd, (file_ptr)(asect->rel_filepos), SEEK_SET) != 0) - return false; - count = reloc_size / sizeof (struct relocation_info); - - relocs = (struct relocation_info *) bfd_malloc (reloc_size); - if (!relocs && reloc_size != 0) - return false; - reloc_cache = (arelent *) bfd_malloc ((count+1) * sizeof (arelent)); - if (!reloc_cache) { - if (relocs != NULL) - free ((char*)relocs); - return false; - } - - if (bfd_read ((PTR) relocs, 1, reloc_size, abfd) != reloc_size) { - free (reloc_cache); - if (relocs != NULL) - free (relocs); - return false; - } - - - - if (bfd_header_big_endian (abfd)) { - /* big-endian bit field allocation order */ - pcrel_mask = 0x80; - extern_mask = 0x10; - incode_mask = 0x08; - callj_mask = 0x02; - size_mask = 0x20; - length_shift = 5; - } else { - /* little-endian bit field allocation order */ - pcrel_mask = 0x01; - extern_mask = 0x08; - incode_mask = 0x10; - callj_mask = 0x40; - size_mask = 0x02; - length_shift = 1; - } - - for (rptr = relocs, cache_ptr = reloc_cache, counter = 0; - counter < count; - counter++, rptr++, cache_ptr++) - { - unsigned char *raw = (unsigned char *)rptr; - unsigned int symnum; - cache_ptr->address = bfd_h_get_32 (abfd, raw + 0); - cache_ptr->howto = 0; - if (bfd_header_big_endian (abfd)) - { - symnum = (raw[4] << 16) | (raw[5] << 8) | raw[6]; - } - else - { - symnum = (raw[6] << 16) | (raw[5] << 8) | raw[4]; - } - - if (raw[7] & extern_mask) - { - /* if this is set then the r_index is a index into the symbol table; - * if the bit is not set then r_index contains a section map. - * we either fill in the sym entry with a pointer to the symbol, - * or point to the correct section - */ - cache_ptr->sym_ptr_ptr = symbols + symnum; - cache_ptr->addend = 0; - } else - { - /* in a.out symbols are relative to the beginning of the - * file rather than sections ? - * (look in translate_from_native_sym_flags) - * the reloc entry addend has added to it the offset into the - * file of the data, so subtract the base to make the reloc - * section relative */ - int s; - { - /* sign-extend symnum from 24 bits to whatever host uses */ - s = symnum; - if (s & (1 << 23)) - s |= (~0) << 24; - } - cache_ptr->sym_ptr_ptr = (asymbol **)NULL; - switch (s) - { - case N_TEXT: - case N_TEXT | N_EXT: - cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; - cache_ptr->addend = - obj_textsec(abfd)->vma; - break; - case N_DATA: - case N_DATA | N_EXT: - cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; - cache_ptr->addend = - obj_datasec(abfd)->vma; - break; - case N_BSS: - case N_BSS | N_EXT: - cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; - cache_ptr->addend = - obj_bsssec(abfd)->vma; - break; - case N_ABS: - case N_ABS | N_EXT: - cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; - cache_ptr->addend = 0; - break; - case -2: /* .align */ - if (raw[7] & pcrel_mask) - { - cache_ptr->howto = &howto_align_table[(raw[7] >> length_shift) & 3]; - cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - } - else - { - /* .org? */ - abort (); - } - cache_ptr->addend = 0; - break; - default: - BFD_ASSERT(0); - break; - } - - } - - /* the i960 only has a few relocation types: - abs 32-bit and pcrel 24bit. except for callj's! */ - if (cache_ptr->howto != 0) - ; - else if (raw[7] & callj_mask) - { - cache_ptr->howto = &howto_reloc_callj; - } - else if ( raw[7] & pcrel_mask) - { - if (raw[7] & size_mask) - cache_ptr->howto = &howto_reloc_pcrel13; - else - cache_ptr->howto = &howto_reloc_pcrel24; - } - else - { - if (raw[7] & incode_mask) - { - cache_ptr->howto = &howto_reloc_abs32code; - } - else - { - cache_ptr->howto = &howto_reloc_abs32; - } - } - if (cache_ptr->address < prev_addr) - { - /* Ouch! this reloc is out of order, insert into the right place - */ - arelent tmp; - arelent *cursor = cache_ptr-1; - bfd_vma stop = cache_ptr->address; - tmp = *cache_ptr; - while (cursor->address > stop && cursor >= reloc_cache) - { - cursor[1] = cursor[0]; - cursor--; - } - cursor[1] = tmp; - } - else - { - prev_addr = cache_ptr->address; - } - } - - - if (relocs != NULL) - free (relocs); - asect->relocation = reloc_cache; - asect->reloc_count = count; - - - return true; -} - - -static boolean -b_out_squirt_out_relocs (abfd, section) - bfd *abfd; - asection *section; -{ - arelent **generic; - int r_extern = 0; - int r_idx; - int incode_mask; - int len_1; - unsigned int count = section->reloc_count; - struct relocation_info *native, *natptr; - size_t natsize = count * sizeof (struct relocation_info); - int extern_mask, pcrel_mask, len_2, callj_mask; - if (count == 0) return true; - generic = section->orelocation; - native = ((struct relocation_info *) bfd_malloc (natsize)); - if (!native && natsize != 0) - return false; - - if (bfd_header_big_endian (abfd)) - { - /* Big-endian bit field allocation order */ - pcrel_mask = 0x80; - extern_mask = 0x10; - len_2 = 0x40; - len_1 = 0x20; - callj_mask = 0x02; - incode_mask = 0x08; - } - else - { - /* Little-endian bit field allocation order */ - pcrel_mask = 0x01; - extern_mask = 0x08; - len_2 = 0x04; - len_1 = 0x02; - callj_mask = 0x40; - incode_mask = 0x10; - } - - for (natptr = native; count > 0; --count, ++natptr, ++generic) - { - arelent *g = *generic; - unsigned char *raw = (unsigned char *)natptr; - asymbol *sym = *(g->sym_ptr_ptr); - - asection *output_section = sym->section->output_section; - - bfd_h_put_32(abfd, g->address, raw); - /* Find a type in the output format which matches the input howto - - * at the moment we assume input format == output format FIXME!! - */ - r_idx = 0; - /* FIXME: Need callj stuff here, and to check the howto entries to - be sure they are real for this architecture. */ - if (g->howto== &howto_reloc_callj) - { - raw[7] = callj_mask + pcrel_mask + len_2; - } - else if (g->howto == &howto_reloc_pcrel24) - { - raw[7] = pcrel_mask + len_2; - } - else if (g->howto == &howto_reloc_pcrel13) - { - raw[7] = pcrel_mask + len_1; - } - else if (g->howto == &howto_reloc_abs32code) - { - raw[7] = len_2 + incode_mask; - } - else if (g->howto >= howto_align_table - && g->howto <= (howto_align_table - + sizeof (howto_align_table) / sizeof (howto_align_table[0]) - - 1)) - { - /* symnum == -2; extern_mask not set, pcrel_mask set */ - r_idx = -2; - r_extern = 0; - raw[7] = (pcrel_mask - | ((g->howto - howto_align_table) << 1)); - } - else { - raw[7] = len_2; - } - - if (r_idx != 0) - /* already mucked with r_extern, r_idx */; - else if (bfd_is_com_section (output_section) - || bfd_is_abs_section (output_section) - || bfd_is_und_section (output_section)) - { - - if (bfd_abs_section_ptr->symbol == sym) - { - /* Whoops, looked like an abs symbol, but is really an offset - from the abs section */ - r_idx = 0; - r_extern = 0; - } - else - { - /* Fill in symbol */ - - r_extern = 1; - r_idx = (*g->sym_ptr_ptr)->udata.i; - } - } - else - { - /* Just an ordinary section */ - r_extern = 0; - r_idx = output_section->target_index; - } - - if (bfd_header_big_endian (abfd)) { - raw[4] = (unsigned char) (r_idx >> 16); - raw[5] = (unsigned char) (r_idx >> 8); - raw[6] = (unsigned char) (r_idx ); - } else { - raw[6] = (unsigned char) (r_idx >> 16); - raw[5] = (unsigned char) (r_idx>> 8); - raw[4] = (unsigned char) (r_idx ); - } - if (r_extern) - raw[7] |= extern_mask; - } - - if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize) { - free((PTR)native); - return false; - } - free ((PTR)native); - - return true; -} - -/* This is stupid. This function should be a boolean predicate */ -static long -b_out_canonicalize_reloc (abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - arelent *tblptr; - unsigned int count; - - if ((section->flags & SEC_CONSTRUCTOR) != 0) - { - arelent_chain *chain = section->constructor_chain; - for (count = 0; count < section->reloc_count; count++) - { - *relptr++ = &chain->relent; - chain = chain->next; - } - } - else - { - if (section->relocation == NULL - && ! b_out_slurp_reloc_table (abfd, section, symbols)) - return -1; - - tblptr = section->relocation; - for (count = 0; count++ < section->reloc_count;) - *relptr++ = tblptr++; - } - - *relptr = NULL; - - return section->reloc_count; -} - -static long -b_out_get_reloc_upper_bound (abfd, asect) - bfd *abfd; - sec_ptr asect; -{ - if (bfd_get_format (abfd) != bfd_object) { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - - if (asect->flags & SEC_CONSTRUCTOR) - return sizeof (arelent *) * (asect->reloc_count + 1); - - if (asect == obj_datasec (abfd)) - return (sizeof (arelent *) * - ((exec_hdr(abfd)->a_drsize / sizeof (struct relocation_info)) - +1)); - - if (asect == obj_textsec (abfd)) - return (sizeof (arelent *) * - ((exec_hdr(abfd)->a_trsize / sizeof (struct relocation_info)) - +1)); - - if (asect == obj_bsssec (abfd)) - return 0; - - bfd_set_error (bfd_error_invalid_operation); - return -1; -} - -static boolean -b_out_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - asection *section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - - if (abfd->output_has_begun == false) { /* set by bfd.c handler */ - if (! aout_32_make_sections (abfd)) - return false; - - obj_textsec (abfd)->filepos = sizeof(struct internal_exec); - obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos - + obj_textsec (abfd)->_raw_size; - - } - /* regardless, once we know what we're doing, we might as well get going */ - if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0) - return false; - - if (count != 0) { - return (bfd_write ((PTR)location, 1, count, abfd) == count) ?true:false; - } - return true; -} - -static boolean -b_out_set_arch_mach (abfd, arch, machine) - bfd *abfd; - enum bfd_architecture arch; - unsigned long machine; -{ - bfd_default_set_arch_mach(abfd, arch, machine); - - if (arch == bfd_arch_unknown) /* Unknown machine arch is OK */ - return true; - if (arch == bfd_arch_i960) /* i960 default is OK */ - switch (machine) { - case bfd_mach_i960_core: - case bfd_mach_i960_kb_sb: - case bfd_mach_i960_mc: - case bfd_mach_i960_xa: - case bfd_mach_i960_ca: - case bfd_mach_i960_ka_sa: - case bfd_mach_i960_jx: - case bfd_mach_i960_hx: - case 0: - return true; - default: - return false; - } - - return false; -} - -static int -b_out_sizeof_headers (ignore_abfd, ignore) - bfd *ignore_abfd; - boolean ignore; -{ - return sizeof(struct internal_exec); -} - - - -/************************************************************************/ -static bfd_vma -get_value (reloc, link_info, input_section) - arelent *reloc; - struct bfd_link_info *link_info; - asection *input_section; -{ - bfd_vma value; - asymbol *symbol = *(reloc->sym_ptr_ptr); - - /* A symbol holds a pointer to a section, and an offset from the - base of the section. To relocate, we find where the section will - live in the output and add that in */ - - if (bfd_is_und_section (symbol->section)) - { - struct bfd_link_hash_entry *h; - - /* The symbol is undefined in this BFD. Look it up in the - global linker hash table. FIXME: This should be changed when - we convert b.out to use a specific final_link function and - change the interface to bfd_relax_section to not require the - generic symbols. */ - h = bfd_wrapped_link_hash_lookup (input_section->owner, link_info, - bfd_asymbol_name (symbol), - false, false, true); - if (h != (struct bfd_link_hash_entry *) NULL - && (h->type == bfd_link_hash_defined - || h->type == bfd_link_hash_defweak)) - value = h->u.def.value + output_addr (h->u.def.section); - else if (h != (struct bfd_link_hash_entry *) NULL - && h->type == bfd_link_hash_common) - value = h->u.c.size; - else - { - if (! ((*link_info->callbacks->undefined_symbol) - (link_info, bfd_asymbol_name (symbol), - input_section->owner, input_section, reloc->address))) - abort (); - value = 0; - } - } - else - { - value = symbol->value + output_addr (symbol->section); - } - - /* Add the value contained in the relocation */ - value += reloc->addend; - - return value; -} - -static void -perform_slip (abfd, slip, input_section, value) - bfd *abfd; - unsigned int slip; - asection *input_section; - bfd_vma value; -{ - asymbol **s; - - s = _bfd_generic_link_get_symbols (abfd); - BFD_ASSERT (s != (asymbol **) NULL); - - /* Find all symbols past this point, and make them know - what's happened */ - while (*s) - { - asymbol *p = *s; - if (p->section == input_section) - { - /* This was pointing into this section, so mangle it */ - if (p->value > value) - { - p->value -=slip; - if (p->udata.p != NULL) - { - struct generic_link_hash_entry *h; - - h = (struct generic_link_hash_entry *) p->udata.p; - BFD_ASSERT (h->root.type == bfd_link_hash_defined); - h->root.u.def.value -= slip; - BFD_ASSERT (h->root.u.def.value == p->value); - } - } - } - s++; - - } -} - -/* This routine works out if the thing we want to get to can be - reached with a 24bit offset instead of a 32 bit one. - If it can, then it changes the amode */ - -static int -abs32code (abfd, input_section, r, shrink, link_info) - bfd *abfd; - asection *input_section; - arelent *r; - unsigned int shrink; - struct bfd_link_info *link_info; -{ - bfd_vma value = get_value (r, link_info, input_section); - bfd_vma dot = output_addr (input_section) + r->address; - bfd_vma gap; - - /* See if the address we're looking at within 2^23 bytes of where - we are, if so then we can use a small branch rather than the - jump we were going to */ - - gap = value - (dot - shrink); - - - if (-1<<23 < (long)gap && (long)gap < 1<<23 ) - { - /* Change the reloc type from 32bitcode possible 24, to 24bit - possible 32 */ - - r->howto = &howto_reloc_abs32codeshrunk; - /* The place to relc moves back by four bytes */ - r->address -=4; - - /* This will be four bytes smaller in the long run */ - shrink += 4 ; - perform_slip (abfd, 4, input_section, r->address-shrink + 4); - } - return shrink; -} - -static int -aligncode (abfd, input_section, r, shrink) - bfd *abfd; - asection *input_section; - arelent *r; - unsigned int shrink; -{ - bfd_vma dot = output_addr (input_section) + r->address; - bfd_vma gap; - bfd_vma old_end; - bfd_vma new_end; - int shrink_delta; - int size = r->howto->size; - - /* Reduce the size of the alignment so that it's still aligned but - smaller - the current size is already the same size as or bigger - than the alignment required. */ - - /* calculate the first byte following the padding before we optimize */ - old_end = ((dot + size ) & ~size) + size+1; - /* work out where the new end will be - remember that we're smaller - than we used to be */ - new_end = ((dot - shrink + size) & ~size); - - /* This is the new end */ - gap = old_end - ((dot + size) & ~size); - - shrink_delta = (old_end - new_end) - shrink; - - if (shrink_delta) - { - /* Change the reloc so that it knows how far to align to */ - r->howto = howto_done_align_table + (r->howto - howto_align_table); - - /* Encode the stuff into the addend - for future use we need to - know how big the reloc used to be */ - r->addend = old_end - dot + r->address; - - /* This will be N bytes smaller in the long run, adjust all the symbols */ - perform_slip (abfd, shrink_delta, input_section, r->address - shrink); - shrink += shrink_delta; - } - return shrink; -} - -static boolean -b_out_bfd_relax_section (abfd, i, link_info, again) - bfd *abfd; - asection *i; - struct bfd_link_info *link_info; - boolean *again; -{ - /* Get enough memory to hold the stuff */ - bfd *input_bfd = i->owner; - asection *input_section = i; - int shrink = 0 ; - arelent **reloc_vector = NULL; - long reloc_size = bfd_get_reloc_upper_bound(input_bfd, - input_section); - - if (reloc_size < 0) - return false; - - /* We only run this relaxation once. It might work to run it - multiple times, but it hasn't been tested. */ - *again = false; - - if (reloc_size) - { - long reloc_count; - - reloc_vector = (arelent **) bfd_malloc (reloc_size); - if (reloc_vector == NULL && reloc_size != 0) - goto error_return; - - /* Get the relocs and think about them */ - reloc_count = - bfd_canonicalize_reloc (input_bfd, input_section, reloc_vector, - _bfd_generic_link_get_symbols (input_bfd)); - if (reloc_count < 0) - goto error_return; - if (reloc_count > 0) - { - arelent **parent; - for (parent = reloc_vector; *parent; parent++) - { - arelent *r = *parent; - switch (r->howto->type) - { - case ALIGNER: - /* An alignment reloc */ - shrink = aligncode (abfd, input_section, r, shrink); - break; - case ABS32CODE: - /* A 32bit reloc in an addressing mode */ - shrink = abs32code (input_bfd, input_section, r, shrink, - link_info); - break; - case ABS32CODE_SHRUNK: - shrink+=4; - break; - } - } - } - } - input_section->_cooked_size = input_section->_raw_size - shrink; - - if (reloc_vector != NULL) - free (reloc_vector); - return true; - error_return: - if (reloc_vector != NULL) - free (reloc_vector); - return false; -} - -static bfd_byte * -b_out_bfd_get_relocated_section_contents (in_abfd, link_info, link_order, - data, relocateable, symbols) - bfd *in_abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - bfd_byte *data; - boolean relocateable; - asymbol **symbols; -{ - /* Get enough memory to hold the stuff */ - bfd *input_bfd = link_order->u.indirect.section->owner; - asection *input_section = link_order->u.indirect.section; - long reloc_size = bfd_get_reloc_upper_bound(input_bfd, - input_section); - arelent **reloc_vector = NULL; - long reloc_count; - - if (reloc_size < 0) - goto error_return; - - /* If producing relocateable output, don't bother to relax. */ - if (relocateable) - return bfd_generic_get_relocated_section_contents (in_abfd, link_info, - link_order, - data, relocateable, - symbols); - - reloc_vector = (arelent **) bfd_malloc (reloc_size); - if (reloc_vector == NULL && reloc_size != 0) - goto error_return; - - input_section->reloc_done = 1; - - /* read in the section */ - BFD_ASSERT (true == bfd_get_section_contents(input_bfd, - input_section, - data, - 0, - input_section->_raw_size)); - - reloc_count = bfd_canonicalize_reloc (input_bfd, - input_section, - reloc_vector, - symbols); - if (reloc_count < 0) - goto error_return; - if (reloc_count > 0) - { - arelent **parent = reloc_vector; - arelent *reloc ; - - unsigned int dst_address = 0; - unsigned int src_address = 0; - unsigned int run; - unsigned int idx; - - /* Find how long a run we can do */ - while (dst_address < link_order->size) - { - reloc = *parent; - if (reloc) - { - /* Note that the relaxing didn't tie up the addresses in the - relocation, so we use the original address to work out the - run of non-relocated data */ - BFD_ASSERT (reloc->address >= src_address); - run = reloc->address - src_address; - parent++; - } - else - { - run = link_order->size - dst_address; - } - /* Copy the bytes */ - for (idx = 0; idx < run; idx++) - { - data[dst_address++] = data[src_address++]; - } - - /* Now do the relocation */ - - if (reloc) - { - switch (reloc->howto->type) - { - case ABS32CODE: - calljx_callback (in_abfd, link_info, reloc, - src_address + data, dst_address + data, - input_section); - src_address+=4; - dst_address+=4; - break; - case ABS32: - bfd_put_32(in_abfd, - (bfd_get_32 (in_abfd, data+src_address) - + get_value (reloc, link_info, input_section)), - data+dst_address); - src_address+=4; - dst_address+=4; - break; - case CALLJ: - callj_callback (in_abfd, link_info, reloc, data, src_address, - dst_address, input_section, false); - src_address+=4; - dst_address+=4; - break; - case ALIGNDONE: - BFD_ASSERT (reloc->addend >= src_address); - BFD_ASSERT (reloc->addend <= input_section->_raw_size); - src_address = reloc->addend; - dst_address = ((dst_address + reloc->howto->size) - & ~reloc->howto->size); - break; - case ABS32CODE_SHRUNK: - /* This used to be a callx, but we've found out that a - callj will reach, so do the right thing. */ - callj_callback (in_abfd, link_info, reloc, data, - src_address + 4, dst_address, input_section, - true); - dst_address+=4; - src_address+=8; - break; - case PCREL24: - { - long int word = bfd_get_32(in_abfd, data+src_address); - bfd_vma value; - - value = get_value (reloc, link_info, input_section); - word = ((word & ~BAL_MASK) - | (((word & BAL_MASK) - + value - - output_addr (input_section) - + reloc->addend) - & BAL_MASK)); - - bfd_put_32(in_abfd,word, data+dst_address); - dst_address+=4; - src_address+=4; - - } - break; - - case PCREL13: - { - long int word = bfd_get_32(in_abfd, data+src_address); - bfd_vma value; - - value = get_value (reloc, link_info, input_section); - word = ((word & ~PCREL13_MASK) - | (((word & PCREL13_MASK) - + value - + reloc->addend - - output_addr (input_section)) - & PCREL13_MASK)); - - bfd_put_32(in_abfd,word, data+dst_address); - dst_address+=4; - src_address+=4; - - } - break; - - default: - abort(); - } - } - } - } - if (reloc_vector != NULL) - free (reloc_vector); - return data; - error_return: - if (reloc_vector != NULL) - free (reloc_vector); - return NULL; -} -/***********************************************************************/ - -/* Build the transfer vectors for Big and Little-Endian B.OUT files. */ - -#define aout_32_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define aout_32_close_and_cleanup aout_32_bfd_free_cached_info - -#define b_out_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define b_out_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define b_out_bfd_final_link _bfd_generic_final_link -#define b_out_bfd_link_split_section _bfd_generic_link_split_section - -#define aout_32_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -const bfd_target b_out_vec_big_host = -{ - "b.out.big", /* name */ - bfd_target_aout_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_BIG, /* hdr byte order is big */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* symbol leading char */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, b_out_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, b_out_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (aout_32), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd), - BFD_JUMP_TABLE_SYMBOLS (aout_32), - BFD_JUMP_TABLE_RELOCS (b_out), - BFD_JUMP_TABLE_WRITE (b_out), - BFD_JUMP_TABLE_LINK (b_out), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0, -}; - - -const bfd_target b_out_vec_little_host = -{ - "b.out.little", /* name */ - bfd_target_aout_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* symbol leading char */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - - {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, b_out_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, b_out_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (aout_32), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd), - BFD_JUMP_TABLE_SYMBOLS (aout_32), - BFD_JUMP_TABLE_RELOCS (b_out), - BFD_JUMP_TABLE_WRITE (b_out), - BFD_JUMP_TABLE_LINK (b_out), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; diff --git a/contrib/gdb/bfd/cf-i386lynx.c b/contrib/gdb/bfd/cf-i386lynx.c deleted file mode 100644 index 2a14bde..0000000 --- a/contrib/gdb/bfd/cf-i386lynx.c +++ /dev/null @@ -1,31 +0,0 @@ -/* BFD back-end for Intel 386 COFF LynxOS files. - Copyright 1993, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" - -#define TARGET_SYM i386lynx_coff_vec -#define TARGET_NAME "coff-i386-lynx" - -#define LYNXOS - -#define COFF_LONG_FILENAMES - -#include "coff-i386.c" diff --git a/contrib/gdb/bfd/cf-m68klynx.c b/contrib/gdb/bfd/cf-m68klynx.c deleted file mode 100644 index 8149dc6..0000000 --- a/contrib/gdb/bfd/cf-m68klynx.c +++ /dev/null @@ -1,223 +0,0 @@ -/* BFD back-end for Motorola M68K COFF LynxOS files. - Copyright 1993, 1994, 1995 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - -#define TARGET_SYM m68klynx_coff_vec -#define TARGET_NAME "coff-m68k-lynx" - -#define LYNXOS - -#define COFF_LONG_FILENAMES - -#define _bfd_m68kcoff_howto_table _bfd_m68klynx_howto_table -#define _bfd_m68kcoff_rtype2howto _bfd_m68klynx_rtype2howto -#define _bfd_m68kcoff_howto2rtype _bfd_m68klynx_howto2rtype -#define _bfd_m68kcoff_reloc_type_lookup _bfd_m68klynx_reloc_type_lookup - -#define LYNX_SPECIAL_FN _bfd_m68klynx_special_fn - -#include "bfd.h" -#include "sysdep.h" - -#ifdef ANSI_PROTOTYPES -struct internal_reloc; -struct coff_link_hash_entry; -struct internal_syment; -#endif - -static bfd_reloc_status_type _bfd_m68klynx_special_fn - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static reloc_howto_type *coff_m68k_lynx_rtype_to_howto - PARAMS ((bfd *, asection *, struct internal_reloc *, - struct coff_link_hash_entry *, struct internal_syment *, - bfd_vma *)); - -/* For some reason when using m68k COFF the value stored in the .text - section for a reference to a common symbol is the value itself plus - any desired offset. (taken from work done by Ian Taylor, Cygnus Support, - for I386 COFF). */ - -/* If we are producing relocateable output, we need to do some - adjustments to the object file that are not done by the - bfd_perform_relocation function. This function is called by every - reloc type to make any required adjustments. */ - -static bfd_reloc_status_type -_bfd_m68klynx_special_fn (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - symvalue diff; - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - if (bfd_is_com_section (symbol->section)) - { - /* We are relocating a common symbol. The current value in the - object file is ORIG + OFFSET, where ORIG is the value of the - common symbol as seen by the object file when it was compiled - (this may be zero if the symbol was undefined) and OFFSET is - the offset into the common symbol (normally zero, but may be - non-zero when referring to a field in a common structure). - ORIG is the negative of reloc_entry->addend, which is set by - the CALC_ADDEND macro below. We want to replace the value in - the object file with NEW + OFFSET, where NEW is the value of - the common symbol which we are going to put in the final - object file. NEW is symbol->value. */ - diff = symbol->value + reloc_entry->addend; - } - else - { - /* For some reason bfd_perform_relocation always effectively - ignores the addend for a COFF target when producing - relocateable output. This seems to be always wrong for 386 - COFF, so we handle the addend here instead. */ - diff = reloc_entry->addend; - } - -#define DOIT(x) \ - x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) - - if (diff != 0) - { - reloc_howto_type *howto = reloc_entry->howto; - unsigned char *addr = (unsigned char *) data + reloc_entry->address; - - switch (howto->size) - { - case 0: - { - char x = bfd_get_8 (abfd, addr); - DOIT (x); - bfd_put_8 (abfd, x, addr); - } - break; - - case 1: - { - short x = bfd_get_16 (abfd, addr); - DOIT (x); - bfd_put_16 (abfd, x, addr); - } - break; - - case 2: - { - long x = bfd_get_32 (abfd, addr); - DOIT (x); - bfd_put_32 (abfd, x, addr); - } - break; - - default: - abort (); - } - } - - /* Now let bfd_perform_relocation finish everything up. */ - return bfd_reloc_continue; -} -/* Compute the addend of a reloc. If the reloc is to a common symbol, - the object file contains the value of the common symbol. By the - time this is called, the linker may be using a different symbol - from a different object file with a different value. Therefore, we - hack wildly to locate the original symbol from this file so that we - can make the correct adjustment. This macro sets coffsym to the - symbol from the original file, and uses it to set the addend value - correctly. If this is not a common symbol, the usual addend - calculation is done, except that an additional tweak is needed for - PC relative relocs. - FIXME: This macro refers to symbols and asect; these are from the - calling function, not the macro arguments. */ - -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ - { \ - coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ - if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ - coffsym = (obj_symbols (abfd) \ - + (cache_ptr->sym_ptr_ptr - symbols)); \ - else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ - if (coffsym != (coff_symbol_type *) NULL \ - && coffsym->native->u.syment.n_scnum == 0) \ - cache_ptr->addend = - coffsym->native->u.syment.n_value; \ - else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ - && ptr->section != (asection *) NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ - else \ - cache_ptr->addend = 0; \ - if (ptr && (reloc.r_type == R_PCRBYTE \ - || reloc.r_type == R_PCRWORD \ - || reloc.r_type == R_PCRLONG)) \ - cache_ptr->addend += asect->vma; \ - } - -#define coff_rtype_to_howto coff_m68k_lynx_rtype_to_howto - -#include "coff-m68k.c" - -/* coff-m68k.c uses the special COFF backend linker. We need to - adjust common symbols. - - We can't define this function until after we have included - coff-m68k.c, because it uses RTYPE2HOWTO. */ - -/*ARGSUSED*/ -static reloc_howto_type * -coff_m68k_lynx_rtype_to_howto (abfd, sec, rel, h, sym, addendp) - bfd *abfd; - asection *sec; - struct internal_reloc *rel; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma *addendp; -{ - arelent relent; - reloc_howto_type *howto; - - RTYPE2HOWTO (&relent, rel); - - howto = relent.howto; - - if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) - { - /* This is a common symbol. The section contents include the - size (sym->n_value) as an addend. The relocate_section - function will be adding in the final value of the symbol. We - need to subtract out the current size in order to get the - correct result. */ - BFD_ASSERT (h != NULL); - *addendp -= sym->n_value; - } - - /* If the output symbol is common (in which case this must be a - relocateable link), we need to add in the final size of the - common symbol. */ - if (h != NULL && h->root.type == bfd_link_hash_common) - *addendp += h->root.u.c.size; - - return howto; -} diff --git a/contrib/gdb/bfd/cf-sparclynx.c b/contrib/gdb/bfd/cf-sparclynx.c deleted file mode 100644 index 774a099..0000000 --- a/contrib/gdb/bfd/cf-sparclynx.c +++ /dev/null @@ -1,28 +0,0 @@ -/* BFD back-end for Sparc COFF LynxOS files. - Copyright 1993 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - -#define TARGET_SYM sparclynx_coff_vec -#define TARGET_NAME "coff-sparc-lynx" - -#define LYNXOS - -#define COFF_LONG_FILENAMES - -#include "coff-sparc.c" diff --git a/contrib/gdb/bfd/cisco-core.c b/contrib/gdb/bfd/cisco-core.c deleted file mode 100644 index a25115c..0000000 --- a/contrib/gdb/bfd/cisco-core.c +++ /dev/null @@ -1,313 +0,0 @@ -/* BFD back-end for CISCO crash dumps. - -Copyright 1994 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -/* core_file_failing_signal returns a host signal (this probably should - be fixed). */ -#include <signal.h> - -#define CRASH_INFO (0xffc) -#define CRASH_MAGIC 0xdead1234 - -typedef enum { - CRASH_REASON_NOTCRASHED = 0, - CRASH_REASON_EXCEPTION = 1, - CRASH_REASON_CORRUPT = 2, - } crashreason; - -struct crashinfo_external -{ - char magic[4]; /* Magic number */ - char version[4]; /* Version number */ - char reason[4]; /* Crash reason */ - char cpu_vector[4]; /* CPU vector for exceptions */ - char registers[4]; /* Pointer to saved registers */ - char rambase[4]; /* Base of RAM (not in V1 crash info) */ -}; - -struct cisco_core_struct -{ - int sig; -}; - -static const bfd_target * -cisco_core_file_p (abfd) - bfd *abfd; -{ - char buf[4]; - unsigned int crashinfo_offset; - struct crashinfo_external crashinfo; - int nread; - unsigned int rambase; - sec_ptr asect; - struct stat statbuf; - - if (bfd_seek (abfd, CRASH_INFO, SEEK_SET) != 0) - return NULL; - - nread = bfd_read (buf, 1, 4, abfd); - if (nread != 4) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - crashinfo_offset = bfd_get_32 (abfd, buf); - - if (bfd_seek (abfd, crashinfo_offset, SEEK_SET) != 0) - return NULL; - - nread = bfd_read (&crashinfo, 1, sizeof (crashinfo), abfd); - if (nread != sizeof (crashinfo)) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - if (bfd_stat (abfd, &statbuf) < 0) - { - bfd_set_error (bfd_error_system_call); - return NULL; - } - - if (bfd_get_32 (abfd, crashinfo.magic) != CRASH_MAGIC) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - switch (bfd_get_32 (abfd, crashinfo.version)) - { - case 0: - bfd_set_error (bfd_error_wrong_format); - return NULL; - case 1: - rambase = 0; - break; - default: - case 2: - rambase = bfd_get_32 (abfd, crashinfo.rambase); - break; - } - - /* OK, we believe you. You're a core file. */ - - abfd->tdata.cisco_core_data = - ((struct cisco_core_struct *) - bfd_zmalloc (sizeof (struct cisco_core_struct))); - if (abfd->tdata.cisco_core_data == NULL) - return NULL; - - switch ((crashreason) bfd_get_32 (abfd, crashinfo.reason)) - { - case CRASH_REASON_NOTCRASHED: - /* Crash file probably came from write core. */ - abfd->tdata.cisco_core_data->sig = 0; - break; - case CRASH_REASON_CORRUPT: - /* The crash context area was corrupt -- proceed with caution. - We have no way of passing this information back to the caller. */ - abfd->tdata.cisco_core_data->sig = 0; - break; - case CRASH_REASON_EXCEPTION: - /* Crash occured due to CPU exception. */ - - /* This is 68k-specific; for MIPS we'll need to interpret - cpu_vector differently based on the target configuration - (since CISCO core files don't seem to have the processor - encoded in them). */ - - switch (bfd_get_32 (abfd, crashinfo.cpu_vector)) - { - /* bus error */ - case 2 : abfd->tdata.cisco_core_data->sig = SIGBUS; break; - /* address error */ - case 3 : abfd->tdata.cisco_core_data->sig = SIGBUS; break; - /* illegal instruction */ - case 4 : abfd->tdata.cisco_core_data->sig = SIGILL; break; - /* zero divide */ - case 5 : abfd->tdata.cisco_core_data->sig = SIGFPE; break; - /* chk instruction */ - case 6 : abfd->tdata.cisco_core_data->sig = SIGFPE; break; - /* trapv instruction */ - case 7 : abfd->tdata.cisco_core_data->sig = SIGFPE; break; - /* privilege violation */ - case 8 : abfd->tdata.cisco_core_data->sig = SIGSEGV; break; - /* trace trap */ - case 9 : abfd->tdata.cisco_core_data->sig = SIGTRAP; break; - /* line 1010 emulator */ - case 10: abfd->tdata.cisco_core_data->sig = SIGILL; break; - /* line 1111 emulator */ - case 11: abfd->tdata.cisco_core_data->sig = SIGILL; break; - - /* Coprocessor protocol violation. Using a standard MMU or FPU - this cannot be triggered by software. Call it a SIGBUS. */ - case 13: abfd->tdata.cisco_core_data->sig = SIGBUS; break; - - /* interrupt */ - case 31: abfd->tdata.cisco_core_data->sig = SIGINT; break; - /* breakpoint */ - case 33: abfd->tdata.cisco_core_data->sig = SIGTRAP; break; - - /* floating point err */ - case 48: abfd->tdata.cisco_core_data->sig = SIGFPE; break; - /* floating point err */ - case 49: abfd->tdata.cisco_core_data->sig = SIGFPE; break; - /* zero divide */ - case 50: abfd->tdata.cisco_core_data->sig = SIGFPE; break; - /* underflow */ - case 51: abfd->tdata.cisco_core_data->sig = SIGFPE; break; - /* operand error */ - case 52: abfd->tdata.cisco_core_data->sig = SIGFPE; break; - /* overflow */ - case 53: abfd->tdata.cisco_core_data->sig = SIGFPE; break; - /* NAN */ - case 54: abfd->tdata.cisco_core_data->sig = SIGFPE; break; - default: - /* "software generated"*/ - abfd->tdata.cisco_core_data->sig = SIGEMT; - } - break; - default: - /* Unknown crash reason. */ - abfd->tdata.cisco_core_data->sig = 0; - break; - } - - abfd->sections = NULL; - abfd->section_count = 0; - - asect = (asection *) bfd_zmalloc (sizeof (asection)); - if (asect == NULL) - goto error_return; - asect->name = ".reg"; - asect->flags = SEC_HAS_CONTENTS; - /* This can be bigger than the real size. Set it to the size of the whole - core file. */ - asect->_raw_size = statbuf.st_size; - asect->vma = 0; - asect->filepos = bfd_get_32 (abfd, crashinfo.registers) - rambase; - asect->next = abfd->sections; - abfd->sections = asect; - ++abfd->section_count; - - /* There is only one section containing data from the target system's RAM. - We call it .data. */ - asect = (asection *) bfd_zmalloc (sizeof (asection)); - if (asect == NULL) - goto error_return; - asect->name = ".data"; - asect->flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS; - /* The size of memory is the size of the core file itself. */ - asect->_raw_size = statbuf.st_size; - asect->vma = rambase; - asect->filepos = 0; - asect->next = abfd->sections; - abfd->sections = asect; - ++abfd->section_count; - - return abfd->xvec; - - error_return: - { - sec_ptr nextsect; - for (asect = abfd->sections; asect != NULL;) - { - nextsect = asect->next; - free (asect); - asect = nextsect; - } - free (abfd->tdata.cisco_core_data); - return NULL; - } -} - -char * -cisco_core_file_failing_command (abfd) - bfd *abfd; -{ - return NULL; -} - -int -cisco_core_file_failing_signal (abfd) - bfd *abfd; -{ - return abfd->tdata.cisco_core_data->sig; -} - -boolean -cisco_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd; - bfd *exec_bfd; -{ - return true; -} - -const bfd_target cisco_core_vec = - { - "trad-core", - bfd_target_unknown_flavour, - BFD_ENDIAN_BIG, /* target byte order */ - BFD_ENDIAN_BIG, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* symbol prefix */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - { /* bfd_check_format */ - _bfd_dummy_target, /* unknown format */ - _bfd_dummy_target, /* object file */ - _bfd_dummy_target, /* archive */ - cisco_core_file_p /* a core file */ - }, - { /* bfd_set_format */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - { /* bfd_write_contents */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (cisco), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (_bfd_generic), - BFD_JUMP_TABLE_LINK (_bfd_nolink), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 /* backend_data */ -}; diff --git a/contrib/gdb/bfd/coff-a29k.c b/contrib/gdb/bfd/coff-a29k.c deleted file mode 100644 index 3ceabfb..0000000 --- a/contrib/gdb/bfd/coff-a29k.c +++ /dev/null @@ -1,641 +0,0 @@ -/* BFD back-end for AMD 29000 COFF binaries. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Contributed by David Wood at New York University 7/8/91. - -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. */ - -#define A29K 1 - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/a29k.h" -#include "coff/internal.h" -#include "libcoff.h" - -static long get_symbol_value PARAMS ((asymbol *)); -static bfd_reloc_status_type a29k_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static boolean coff_a29k_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - struct internal_reloc *, struct internal_syment *, asection **)); -static boolean coff_a29k_adjust_symndx - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, - struct internal_reloc *, boolean *)); - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) - -#define INSERT_HWORD(WORD,HWORD) \ - (((WORD) & 0xff00ff00) | (((HWORD) & 0xff00) << 8) | ((HWORD)& 0xff)) -#define EXTRACT_HWORD(WORD) \ - ((((WORD) & 0x00ff0000) >> 8) | ((WORD)& 0xff)) -#define SIGN_EXTEND_HWORD(HWORD) \ - ((HWORD) & 0x8000 ? (HWORD)|(~0xffffL) : (HWORD)) - -/* Provided the symbol, returns the value reffed */ -static long -get_symbol_value (symbol) - asymbol *symbol; -{ - long relocation = 0; - - if (bfd_is_com_section (symbol->section)) - { - relocation = 0; - } - else - { - relocation = symbol->value + - symbol->section->output_section->vma + - symbol->section->output_offset; - } - - return(relocation); -} - -/* this function is in charge of performing all the 29k relocations */ - -static bfd_reloc_status_type -a29k_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol_in; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - /* the consth relocation comes in two parts, we have to remember - the state between calls, in these variables */ - static boolean part1_consth_active = false; - static unsigned long part1_consth_value; - - unsigned long insn; - unsigned long sym_value; - unsigned long unsigned_value; - unsigned short r_type; - long signed_value; - - unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/ - bfd_byte *hit_data =addr + (bfd_byte *)(data); - - r_type = reloc_entry->howto->type; - - if (output_bfd) { - /* Partial linking - do nothing */ - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - - } - - if (symbol_in != NULL - && bfd_is_und_section (symbol_in->section)) - { - /* Keep the state machine happy in case we're called again */ - if (r_type == R_IHIHALF) - { - part1_consth_active = true; - part1_consth_value = 0; - } - return(bfd_reloc_undefined); - } - - if ((part1_consth_active) && (r_type != R_IHCONST)) - { - part1_consth_active = false; - *error_message = (char *) "Missing IHCONST"; - return(bfd_reloc_dangerous); - } - - - sym_value = get_symbol_value(symbol_in); - - switch (r_type) - { - case R_IREL: - insn = bfd_get_32(abfd, hit_data); - /* Take the value in the field and sign extend it */ - signed_value = EXTRACT_HWORD(insn); - signed_value = SIGN_EXTEND_HWORD(signed_value); - signed_value <<= 2; - - /* See the note on the R_IREL reloc in coff_a29k_relocate_section. */ - if (signed_value == - (long) reloc_entry->address) - signed_value = 0; - - signed_value += sym_value + reloc_entry->addend; - if ((signed_value & ~0x3ffff) == 0) - { /* Absolute jmp/call */ - insn |= (1<<24); /* Make it absolute */ - /* FIXME: Should we change r_type to R_IABS */ - } - else - { - /* Relative jmp/call, so subtract from the value the - address of the place we're coming from */ - signed_value -= (reloc_entry->address - + input_section->output_section->vma - + input_section->output_offset); - if (signed_value>0x1ffff || signed_value<-0x20000) - return(bfd_reloc_overflow); - } - signed_value >>= 2; - insn = INSERT_HWORD(insn, signed_value); - bfd_put_32(abfd, insn ,hit_data); - break; - case R_ILOHALF: - insn = bfd_get_32(abfd, hit_data); - unsigned_value = EXTRACT_HWORD(insn); - unsigned_value += sym_value + reloc_entry->addend; - insn = INSERT_HWORD(insn, unsigned_value); - bfd_put_32(abfd, insn, hit_data); - break; - case R_IHIHALF: - insn = bfd_get_32(abfd, hit_data); - /* consth, part 1 - Just get the symbol value that is referenced */ - part1_consth_active = true; - part1_consth_value = sym_value + reloc_entry->addend; - /* Don't modify insn until R_IHCONST */ - break; - case R_IHCONST: - insn = bfd_get_32(abfd, hit_data); - /* consth, part 2 - Now relocate the reference */ - if (part1_consth_active == false) { - *error_message = (char *) "Missing IHIHALF"; - return(bfd_reloc_dangerous); - } - /* sym_ptr_ptr = r_symndx, in coff_slurp_reloc_table() */ - unsigned_value = 0; /*EXTRACT_HWORD(insn) << 16;*/ - unsigned_value += reloc_entry->addend; /* r_symndx */ - unsigned_value += part1_consth_value; - unsigned_value = unsigned_value >> 16; - insn = INSERT_HWORD(insn, unsigned_value); - part1_consth_active = false; - bfd_put_32(abfd, insn, hit_data); - break; - case R_BYTE: - insn = bfd_get_8(abfd, hit_data); - unsigned_value = insn + sym_value + reloc_entry->addend; - if (unsigned_value & 0xffffff00) - return(bfd_reloc_overflow); - bfd_put_8(abfd, unsigned_value, hit_data); - break; - case R_HWORD: - insn = bfd_get_16(abfd, hit_data); - unsigned_value = insn + sym_value + reloc_entry->addend; - if (unsigned_value & 0xffff0000) - return(bfd_reloc_overflow); - bfd_put_16(abfd, insn, hit_data); - break; - case R_WORD: - insn = bfd_get_32(abfd, hit_data); - insn += sym_value + reloc_entry->addend; - bfd_put_32(abfd, insn, hit_data); - break; - default: - *error_message = "Unrecognized reloc"; - return (bfd_reloc_dangerous); - } - - - return(bfd_reloc_ok); -} - -/* type rightshift - size - bitsize - pc-relative - bitpos - absolute - complain_on_overflow - special_function - relocation name - partial_inplace - src_mask -*/ - -/*FIXME: I'm not real sure about this table */ -static reloc_howto_type howto_table[] = -{ - {R_ABS, 0, 3, 32, false, 0, complain_overflow_bitfield,a29k_reloc,"ABS", true, 0xffffffff,0xffffffff, false}, - {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, - {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20}, - {21}, {22}, {23}, - {R_IREL, 0, 3, 32, true, 0, complain_overflow_signed,a29k_reloc,"IREL", true, 0xffffffff,0xffffffff, false}, - {R_IABS, 0, 3, 32, false, 0, complain_overflow_bitfield, a29k_reloc,"IABS", true, 0xffffffff,0xffffffff, false}, - {R_ILOHALF, 0, 3, 16, true, 0, complain_overflow_signed, a29k_reloc,"ILOHALF", true, 0x0000ffff,0x0000ffff, false}, - {R_IHIHALF, 0, 3, 16, true, 16, complain_overflow_signed, a29k_reloc,"IHIHALF", true, 0xffff0000,0xffff0000, false}, - {R_IHCONST, 0, 3, 16, true, 0, complain_overflow_signed, a29k_reloc,"IHCONST", true, 0xffff0000,0xffff0000, false}, - {R_BYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, a29k_reloc,"BYTE", true, 0x000000ff,0x000000ff, false}, - {R_HWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, a29k_reloc,"HWORD", true, 0x0000ffff,0x0000ffff, false}, - {R_WORD, 0, 2, 32, false, 0, complain_overflow_bitfield, a29k_reloc,"WORD", true, 0xffffffff,0xffffffff, false}, -}; - -#define BADMAG(x) A29KBADMAG(x) - -#define RELOC_PROCESSING(relent, reloc, symbols, abfd, section) \ - reloc_processing(relent, reloc, symbols, abfd, section) - -static void -reloc_processing (relent,reloc, symbols, abfd, section) - arelent *relent; - struct internal_reloc *reloc; - asymbol **symbols; - bfd *abfd; - asection *section; -{ - static bfd_vma ihihalf_vaddr = (bfd_vma) -1; - - relent->address = reloc->r_vaddr; - relent->howto = howto_table + reloc->r_type; - if (reloc->r_type == R_IHCONST) - { - /* The address of an R_IHCONST should always be the address of - the immediately preceding R_IHIHALF. relocs generated by gas - are correct, but relocs generated by High C are different (I - can't figure out what the address means for High C). We can - handle both gas and High C by ignoring the address here, and - simply reusing the address saved for R_IHIHALF. */ - if (ihihalf_vaddr == (bfd_vma) -1) - abort (); - relent->address = ihihalf_vaddr; - ihihalf_vaddr = (bfd_vma) -1; - relent->addend = reloc->r_symndx; - relent->sym_ptr_ptr= bfd_abs_section_ptr->symbol_ptr_ptr; - } - else - { - asymbol *ptr; - relent->sym_ptr_ptr = symbols + obj_convert(abfd)[reloc->r_symndx]; - - ptr = *(relent->sym_ptr_ptr); - - if (ptr - && bfd_asymbol_bfd(ptr) == abfd - - && ((ptr->flags & BSF_OLD_COMMON)== 0)) - { - relent->addend = 0; - } - else - { - relent->addend = 0; - } - relent->address-= section->vma; - if (reloc->r_type == R_IHIHALF) - ihihalf_vaddr = relent->address; - else if (ihihalf_vaddr != (bfd_vma) -1) - abort (); - } -} - -/* The reloc processing routine for the optimized COFF linker. */ - -static boolean -coff_a29k_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, syms, sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - struct internal_reloc *relocs; - struct internal_syment *syms; - asection **sections; -{ - struct internal_reloc *rel; - struct internal_reloc *relend; - boolean hihalf; - bfd_vma hihalf_val; - - /* If we are performing a relocateable link, we don't need to do a - thing. The caller will take care of adjusting the reloc - addresses and symbol indices. */ - if (info->relocateable) - return true; - - hihalf = false; - hihalf_val = 0; - - rel = relocs; - relend = rel + input_section->reloc_count; - for (; rel < relend; rel++) - { - long symndx; - bfd_byte *loc; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - asection *sec; - bfd_vma val; - boolean overflow; - unsigned long insn; - long signed_value; - unsigned long unsigned_value; - bfd_reloc_status_type rstat; - - symndx = rel->r_symndx; - loc = contents + rel->r_vaddr - input_section->vma; - - if (symndx == -1) - h = NULL; - else - h = obj_coff_sym_hashes (input_bfd)[symndx]; - - sym = NULL; - sec = NULL; - val = 0; - - /* An R_IHCONST reloc does not have a symbol. Instead, the - symbol index is an addend. R_IHCONST is always used in - conjunction with R_IHHALF. */ - if (rel->r_type != R_IHCONST) - { - if (h == NULL) - { - if (symndx == -1) - sec = bfd_abs_section_ptr; - else - { - sym = syms + symndx; - sec = sections[symndx]; - val = (sec->output_section->vma - + sec->output_offset - + sym->n_value - - sec->vma); - } - } - else - { - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - val = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return false; - } - } - - if (hihalf) - { - if (! ((*info->callbacks->reloc_dangerous) - (info, "missing IHCONST reloc", input_bfd, - input_section, rel->r_vaddr - input_section->vma))) - return false; - hihalf = false; - } - } - - overflow = false; - - switch (rel->r_type) - { - default: - bfd_set_error (bfd_error_bad_value); - return false; - - case R_IREL: - insn = bfd_get_32 (input_bfd, loc); - - /* Extract the addend. */ - signed_value = EXTRACT_HWORD (insn); - signed_value = SIGN_EXTEND_HWORD (signed_value); - signed_value <<= 2; - - /* Unfortunately, there are two different versions of COFF - a29k. In the original AMD version, the value stored in - the field for the R_IREL reloc is a simple addend. In - the GNU version, the value is the negative of the address - of the reloc within section. We try to cope here by - assuming the AMD version, unless the addend is exactly - the negative of the address; in the latter case we assume - the GNU version. This means that something like - .text - nop - jmp i-4 - will fail, because the addend of -4 will happen to equal - the negative of the address within the section. The - compiler will never generate code like this. - - At some point in the future we may want to take out this - check. */ - - if (signed_value == - (long) (rel->r_vaddr - input_section->vma)) - signed_value = 0; - - /* Determine the destination of the jump. */ - signed_value += val; - - if ((signed_value & ~0x3ffff) == 0) - { - /* We can use an absolute jump. */ - insn |= (1 << 24); - } - else - { - /* Make the destination PC relative. */ - signed_value -= (input_section->output_section->vma - + input_section->output_offset - + (rel->r_vaddr - input_section->vma)); - if (signed_value > 0x1ffff || signed_value < - 0x20000) - { - overflow = true; - signed_value = 0; - } - } - - /* Put the adjusted value back into the instruction. */ - signed_value >>= 2; - insn = INSERT_HWORD (insn, signed_value); - - bfd_put_32 (input_bfd, (bfd_vma) insn, loc); - - break; - - case R_ILOHALF: - insn = bfd_get_32 (input_bfd, loc); - unsigned_value = EXTRACT_HWORD (insn); - unsigned_value += val; - insn = INSERT_HWORD (insn, unsigned_value); - bfd_put_32 (input_bfd, insn, loc); - break; - - case R_IHIHALF: - /* Save the value for the R_IHCONST reloc. */ - hihalf = true; - hihalf_val = val; - break; - - case R_IHCONST: - if (! hihalf) - { - if (! ((*info->callbacks->reloc_dangerous) - (info, "missing IHIHALF reloc", input_bfd, - input_section, rel->r_vaddr - input_section->vma))) - return false; - hihalf_val = 0; - } - - insn = bfd_get_32 (input_bfd, loc); - unsigned_value = rel->r_symndx + hihalf_val; - unsigned_value >>= 16; - insn = INSERT_HWORD (insn, unsigned_value); - bfd_put_32 (input_bfd, (bfd_vma) insn, loc); - - hihalf = false; - - break; - - case R_BYTE: - case R_HWORD: - case R_WORD: - rstat = _bfd_relocate_contents (howto_table + rel->r_type, - input_bfd, val, loc); - if (rstat == bfd_reloc_overflow) - overflow = true; - else if (rstat != bfd_reloc_ok) - abort (); - break; - } - - if (overflow) - { - const char *name; - char buf[SYMNMLEN + 1]; - - if (symndx == -1) - name = "*ABS*"; - else if (h != NULL) - name = h->root.root.string; - else if (sym == NULL) - name = "*unknown*"; - else if (sym->_n._n_n._n_zeroes == 0 - && sym->_n._n_n._n_offset != 0) - name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset; - else - { - strncpy (buf, sym->_n._n_name, SYMNMLEN); - buf[SYMNMLEN] = '\0'; - name = buf; - } - - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto_table[rel->r_type].name, (bfd_vma) 0, - input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return false; - } - } - - return true; -} - -#define coff_relocate_section coff_a29k_relocate_section - -/* We don't want to change the symndx of a R_IHCONST reloc, since it - is actually an addend, not a symbol index at all. */ - -/*ARGSUSED*/ -static boolean -coff_a29k_adjust_symndx (obfd, info, ibfd, sec, irel, adjustedp) - bfd *obfd; - struct bfd_link_info *info; - bfd *ibfd; - asection *sec; - struct internal_reloc *irel; - boolean *adjustedp; -{ - if (irel->r_type == R_IHCONST) - *adjustedp = true; - else - *adjustedp = false; - return true; -} - -#define coff_adjust_symndx coff_a29k_adjust_symndx - -#include "coffcode.h" - -const bfd_target a29kcoff_big_vec = -{ - "coff-a29k-big", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC /* section flags */ - | SEC_LOAD | SEC_RELOC - | SEC_READONLY ), - '_', /* leading underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - /* hdrs */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - - { - - _bfd_dummy_target, - coff_object_p, - bfd_generic_archive_p, - _bfd_dummy_target - }, - { - bfd_false, - coff_mkobject, - _bfd_generic_mkarchive, - bfd_false - }, - { - bfd_false, - coff_write_object_contents, - _bfd_write_archive_contents, - bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE - }; diff --git a/contrib/gdb/bfd/coff-alpha.c b/contrib/gdb/bfd/coff-alpha.c deleted file mode 100644 index b14f3ef..0000000 --- a/contrib/gdb/bfd/coff-alpha.c +++ /dev/null @@ -1,2390 +0,0 @@ -/* BFD back-end for ALPHA Extended-Coff files. - Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - Modified from coff-mips.c by Steve Chamberlain <sac@cygnus.com> and - Ian Lance Taylor <ian@cygnus.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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "coff/internal.h" -#include "coff/sym.h" -#include "coff/symconst.h" -#include "coff/ecoff.h" -#include "coff/alpha.h" -#include "aout/ar.h" -#include "libcoff.h" -#include "libecoff.h" - -/* Prototypes for static functions. */ - -static const bfd_target *alpha_ecoff_object_p PARAMS ((bfd *)); -static boolean alpha_ecoff_bad_format_hook PARAMS ((bfd *abfd, PTR filehdr)); -static PTR alpha_ecoff_mkobject_hook PARAMS ((bfd *, PTR filehdr, PTR aouthdr)); -static void alpha_ecoff_swap_reloc_in PARAMS ((bfd *, PTR, - struct internal_reloc *)); -static void alpha_ecoff_swap_reloc_out PARAMS ((bfd *, - const struct internal_reloc *, - PTR)); -static void alpha_adjust_reloc_in PARAMS ((bfd *, - const struct internal_reloc *, - arelent *)); -static void alpha_adjust_reloc_out PARAMS ((bfd *, const arelent *, - struct internal_reloc *)); -static bfd_byte *alpha_ecoff_get_relocated_section_contents - PARAMS ((bfd *abfd, struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *data, boolean relocateable, asymbol **symbols)); -static bfd_vma alpha_convert_external_reloc - PARAMS ((bfd *, struct bfd_link_info *, bfd *, struct external_reloc *, - struct ecoff_link_hash_entry *)); -static boolean alpha_relocate_section PARAMS ((bfd *, struct bfd_link_info *, - bfd *, asection *, - bfd_byte *, PTR)); -static boolean alpha_adjust_headers - PARAMS ((bfd *, struct internal_filehdr *, struct internal_aouthdr *)); -static PTR alpha_ecoff_read_ar_hdr PARAMS ((bfd *)); -static bfd *alpha_ecoff_get_elt_at_filepos PARAMS ((bfd *, file_ptr)); -static bfd *alpha_ecoff_openr_next_archived_file PARAMS ((bfd *, bfd *)); -static bfd *alpha_ecoff_get_elt_at_index PARAMS ((bfd *, symindex)); - -/* ECOFF has COFF sections, but the debugging information is stored in - a completely different format. ECOFF targets use some of the - swapping routines from coffswap.h, and some of the generic COFF - routines in coffgen.c, but, unlike the real COFF targets, do not - use coffcode.h itself. - - Get the generic COFF swapping routines, except for the reloc, - symbol, and lineno ones. Give them ecoff names. Define some - accessor macros for the large sizes used for Alpha ECOFF. */ - -#define GET_FILEHDR_SYMPTR bfd_h_get_64 -#define PUT_FILEHDR_SYMPTR bfd_h_put_64 -#define GET_AOUTHDR_TSIZE bfd_h_get_64 -#define PUT_AOUTHDR_TSIZE bfd_h_put_64 -#define GET_AOUTHDR_DSIZE bfd_h_get_64 -#define PUT_AOUTHDR_DSIZE bfd_h_put_64 -#define GET_AOUTHDR_BSIZE bfd_h_get_64 -#define PUT_AOUTHDR_BSIZE bfd_h_put_64 -#define GET_AOUTHDR_ENTRY bfd_h_get_64 -#define PUT_AOUTHDR_ENTRY bfd_h_put_64 -#define GET_AOUTHDR_TEXT_START bfd_h_get_64 -#define PUT_AOUTHDR_TEXT_START bfd_h_put_64 -#define GET_AOUTHDR_DATA_START bfd_h_get_64 -#define PUT_AOUTHDR_DATA_START bfd_h_put_64 -#define GET_SCNHDR_PADDR bfd_h_get_64 -#define PUT_SCNHDR_PADDR bfd_h_put_64 -#define GET_SCNHDR_VADDR bfd_h_get_64 -#define PUT_SCNHDR_VADDR bfd_h_put_64 -#define GET_SCNHDR_SIZE bfd_h_get_64 -#define PUT_SCNHDR_SIZE bfd_h_put_64 -#define GET_SCNHDR_SCNPTR bfd_h_get_64 -#define PUT_SCNHDR_SCNPTR bfd_h_put_64 -#define GET_SCNHDR_RELPTR bfd_h_get_64 -#define PUT_SCNHDR_RELPTR bfd_h_put_64 -#define GET_SCNHDR_LNNOPTR bfd_h_get_64 -#define PUT_SCNHDR_LNNOPTR bfd_h_put_64 - -#define ALPHAECOFF - -#define NO_COFF_RELOCS -#define NO_COFF_SYMBOLS -#define NO_COFF_LINENOS -#define coff_swap_filehdr_in alpha_ecoff_swap_filehdr_in -#define coff_swap_filehdr_out alpha_ecoff_swap_filehdr_out -#define coff_swap_aouthdr_in alpha_ecoff_swap_aouthdr_in -#define coff_swap_aouthdr_out alpha_ecoff_swap_aouthdr_out -#define coff_swap_scnhdr_in alpha_ecoff_swap_scnhdr_in -#define coff_swap_scnhdr_out alpha_ecoff_swap_scnhdr_out -#include "coffswap.h" - -/* Get the ECOFF swapping routines. */ -#define ECOFF_64 -#include "ecoffswap.h" - -/* How to process the various reloc types. */ - -static bfd_reloc_status_type -reloc_nil PARAMS ((bfd *, arelent *, asymbol *, PTR, - asection *, bfd *, char **)); - -static bfd_reloc_status_type -reloc_nil (abfd, reloc, sym, data, sec, output_bfd, error_message) - bfd *abfd; - arelent *reloc; - asymbol *sym; - PTR data; - asection *sec; - bfd *output_bfd; - char **error_message; -{ - return bfd_reloc_ok; -} - -/* In case we're on a 32-bit machine, construct a 64-bit "-1" value - from smaller values. Start with zero, widen, *then* decrement. */ -#define MINUS_ONE (((bfd_vma)0) - 1) - -static reloc_howto_type alpha_howto_table[] = -{ - /* Reloc type 0 is ignored by itself. However, it appears after a - GPDISP reloc to identify the location where the low order 16 bits - of the gp register are loaded. */ - HOWTO (ALPHA_R_IGNORE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - reloc_nil, /* special_function */ - "IGNORE", /* name */ - true, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - true), /* pcrel_offset */ - - /* A 32 bit reference to a symbol. */ - HOWTO (ALPHA_R_REFLONG, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "REFLONG", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 64 bit reference to a symbol. */ - HOWTO (ALPHA_R_REFQUAD, /* type */ - 0, /* rightshift */ - 4, /* size (0 = byte, 1 = short, 2 = long) */ - 64, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "REFQUAD", /* name */ - true, /* partial_inplace */ - MINUS_ONE, /* src_mask */ - MINUS_ONE, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 32 bit GP relative offset. This is just like REFLONG except - that when the value is used the value of the gp register will be - added in. */ - HOWTO (ALPHA_R_GPREL32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "GPREL32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Used for an instruction that refers to memory off the GP - register. The offset is 16 bits of the 32 bit instruction. This - reloc always seems to be against the .lita section. */ - HOWTO (ALPHA_R_LITERAL, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "LITERAL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* This reloc only appears immediately following a LITERAL reloc. - It identifies a use of the literal. It seems that the linker can - use this to eliminate a portion of the .lita section. The symbol - index is special: 1 means the literal address is in the base - register of a memory format instruction; 2 means the literal - address is in the byte offset register of a byte-manipulation - instruction; 3 means the literal address is in the target - register of a jsr instruction. This does not actually do any - relocation. */ - HOWTO (ALPHA_R_LITUSE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - reloc_nil, /* special_function */ - "LITUSE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Load the gp register. This is always used for a ldah instruction - which loads the upper 16 bits of the gp register. The next reloc - will be an IGNORE reloc which identifies the location of the lda - instruction which loads the lower 16 bits. The symbol index of - the GPDISP instruction appears to actually be the number of bytes - between the ldah and lda instructions. This gives two different - ways to determine where the lda instruction is; I don't know why - both are used. The value to use for the relocation is the - difference between the GP value and the current location; the - load will always be done against a register holding the current - address. */ - HOWTO (ALPHA_R_GPDISP, /* type */ - 16, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - reloc_nil, /* special_function */ - "GPDISP", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - true), /* pcrel_offset */ - - /* A 21 bit branch. The native assembler generates these for - branches within the text segment, and also fills in the PC - relative offset in the instruction. */ - HOWTO (ALPHA_R_BRADDR, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 21, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "BRADDR", /* name */ - true, /* partial_inplace */ - 0x1fffff, /* src_mask */ - 0x1fffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A hint for a jump to a register. */ - HOWTO (ALPHA_R_HINT, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 14, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "HINT", /* name */ - true, /* partial_inplace */ - 0x3fff, /* src_mask */ - 0x3fff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit PC relative offset. */ - HOWTO (ALPHA_R_SREL16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "SREL16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32 bit PC relative offset. */ - HOWTO (ALPHA_R_SREL32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "SREL32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 64 bit PC relative offset. */ - HOWTO (ALPHA_R_SREL64, /* type */ - 0, /* rightshift */ - 4, /* size (0 = byte, 1 = short, 2 = long) */ - 64, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "SREL64", /* name */ - true, /* partial_inplace */ - MINUS_ONE, /* src_mask */ - MINUS_ONE, /* dst_mask */ - false), /* pcrel_offset */ - - /* Push a value on the reloc evaluation stack. */ - HOWTO (ALPHA_R_OP_PUSH, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "OP_PUSH", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Store the value from the stack at the given address. Store it in - a bitfield of size r_size starting at bit position r_offset. */ - HOWTO (ALPHA_R_OP_STORE, /* type */ - 0, /* rightshift */ - 4, /* size (0 = byte, 1 = short, 2 = long) */ - 64, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "OP_STORE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - MINUS_ONE, /* dst_mask */ - false), /* pcrel_offset */ - - /* Subtract the reloc address from the value on the top of the - relocation stack. */ - HOWTO (ALPHA_R_OP_PSUB, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "OP_PSUB", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Shift the value on the top of the relocation stack right by the - given value. */ - HOWTO (ALPHA_R_OP_PRSHIFT, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "OP_PRSHIFT", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Adjust the GP value for a new range in the object file. */ - HOWTO (ALPHA_R_GPVALUE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "GPVALUE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false) /* pcrel_offset */ -}; - -/* Recognize an Alpha ECOFF file. */ - -static const bfd_target * -alpha_ecoff_object_p (abfd) - bfd *abfd; -{ - static const bfd_target *ret; - - ret = coff_object_p (abfd); - - if (ret != NULL) - { - asection *sec; - - /* Alpha ECOFF has a .pdata section. The lnnoptr field of the - .pdata section is the number of entries it contains. Each - entry takes up 8 bytes. The number of entries is required - since the section is aligned to a 16 byte boundary. When we - link .pdata sections together, we do not want to include the - alignment bytes. We handle this on input by faking the size - of the .pdata section to remove the unwanted alignment bytes. - On output we will set the lnnoptr field and force the - alignment. */ - sec = bfd_get_section_by_name (abfd, _PDATA); - if (sec != (asection *) NULL) - { - bfd_size_type size; - - size = sec->line_filepos * 8; - BFD_ASSERT (size == bfd_section_size (abfd, sec) - || size + 8 == bfd_section_size (abfd, sec)); - if (! bfd_set_section_size (abfd, sec, size)) - return NULL; - } - } - - return ret; -} - -/* See whether the magic number matches. */ - -static boolean -alpha_ecoff_bad_format_hook (abfd, filehdr) - bfd *abfd; - PTR filehdr; -{ - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; - - if (ALPHA_ECOFF_BADMAG (*internal_f)) - return false; - - return true; -} - -/* This is a hook called by coff_real_object_p to create any backend - specific information. */ - -static PTR -alpha_ecoff_mkobject_hook (abfd, filehdr, aouthdr) - bfd *abfd; - PTR filehdr; - PTR aouthdr; -{ - PTR ecoff; - - ecoff = _bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr); - - if (ecoff != NULL) - { - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; - - /* Set additional BFD flags according to the object type from the - machine specific file header flags. */ - switch (internal_f->f_flags & F_ALPHA_OBJECT_TYPE_MASK) - { - case F_ALPHA_SHARABLE: - abfd->flags |= DYNAMIC; - break; - case F_ALPHA_CALL_SHARED: - /* Always executable if using shared libraries as the run time - loader might resolve undefined references. */ - abfd->flags |= (DYNAMIC | EXEC_P); - break; - } - } - return ecoff; -} - -/* Reloc handling. */ - -/* Swap a reloc in. */ - -static void -alpha_ecoff_swap_reloc_in (abfd, ext_ptr, intern) - bfd *abfd; - PTR ext_ptr; - struct internal_reloc *intern; -{ - const RELOC *ext = (RELOC *) ext_ptr; - - intern->r_vaddr = bfd_h_get_64 (abfd, (bfd_byte *) ext->r_vaddr); - intern->r_symndx = bfd_h_get_32 (abfd, (bfd_byte *) ext->r_symndx); - - BFD_ASSERT (bfd_header_little_endian (abfd)); - - intern->r_type = ((ext->r_bits[0] & RELOC_BITS0_TYPE_LITTLE) - >> RELOC_BITS0_TYPE_SH_LITTLE); - intern->r_extern = (ext->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0; - intern->r_offset = ((ext->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE) - >> RELOC_BITS1_OFFSET_SH_LITTLE); - /* Ignored the reserved bits. */ - intern->r_size = ((ext->r_bits[3] & RELOC_BITS3_SIZE_LITTLE) - >> RELOC_BITS3_SIZE_SH_LITTLE); - - if (intern->r_type == ALPHA_R_LITUSE - || intern->r_type == ALPHA_R_GPDISP) - { - /* Handle the LITUSE and GPDISP relocs specially. Its symndx - value is not actually a symbol index, but is instead a - special code. We put the code in the r_size field, and - clobber the symndx. */ - if (intern->r_size != 0) - abort (); - intern->r_size = intern->r_symndx; - intern->r_symndx = RELOC_SECTION_NONE; - } - else if (intern->r_type == ALPHA_R_IGNORE) - { - /* The IGNORE reloc generally follows a GPDISP reloc, and is - against the .lita section. The section is irrelevant. */ - if (! intern->r_extern && - intern->r_symndx == RELOC_SECTION_ABS) - abort (); - if (! intern->r_extern && intern->r_symndx == RELOC_SECTION_LITA) - intern->r_symndx = RELOC_SECTION_ABS; - } -} - -/* Swap a reloc out. */ - -static void -alpha_ecoff_swap_reloc_out (abfd, intern, dst) - bfd *abfd; - const struct internal_reloc *intern; - PTR dst; -{ - RELOC *ext = (RELOC *) dst; - long symndx; - unsigned char size; - - /* Undo the hackery done in swap_reloc_in. */ - if (intern->r_type == ALPHA_R_LITUSE - || intern->r_type == ALPHA_R_GPDISP) - { - symndx = intern->r_size; - size = 0; - } - else if (intern->r_type == ALPHA_R_IGNORE - && ! intern->r_extern - && intern->r_symndx == RELOC_SECTION_ABS) - { - symndx = RELOC_SECTION_LITA; - size = intern->r_size; - } - else - { - symndx = intern->r_symndx; - size = intern->r_size; - } - - BFD_ASSERT (intern->r_extern - || (intern->r_symndx >= 0 && intern->r_symndx <= 14)); - - bfd_h_put_64 (abfd, intern->r_vaddr, (bfd_byte *) ext->r_vaddr); - bfd_h_put_32 (abfd, symndx, (bfd_byte *) ext->r_symndx); - - BFD_ASSERT (bfd_header_little_endian (abfd)); - - ext->r_bits[0] = ((intern->r_type << RELOC_BITS0_TYPE_SH_LITTLE) - & RELOC_BITS0_TYPE_LITTLE); - ext->r_bits[1] = ((intern->r_extern ? RELOC_BITS1_EXTERN_LITTLE : 0) - | ((intern->r_offset << RELOC_BITS1_OFFSET_SH_LITTLE) - & RELOC_BITS1_OFFSET_LITTLE)); - ext->r_bits[2] = 0; - ext->r_bits[3] = ((size << RELOC_BITS3_SIZE_SH_LITTLE) - & RELOC_BITS3_SIZE_LITTLE); -} - -/* Finish canonicalizing a reloc. Part of this is generic to all - ECOFF targets, and that part is in ecoff.c. The rest is done in - this backend routine. It must fill in the howto field. */ - -static void -alpha_adjust_reloc_in (abfd, intern, rptr) - bfd *abfd; - const struct internal_reloc *intern; - arelent *rptr; -{ - if (intern->r_type > ALPHA_R_GPVALUE) - abort (); - - switch (intern->r_type) - { - case ALPHA_R_BRADDR: - case ALPHA_R_SREL16: - case ALPHA_R_SREL32: - case ALPHA_R_SREL64: - /* The PC relative relocs do not seem to use the section VMA as - a negative addend. */ - rptr->addend = 0; - break; - - case ALPHA_R_GPREL32: - case ALPHA_R_LITERAL: - /* Copy the gp value for this object file into the addend, to - ensure that we are not confused by the linker. */ - if (! intern->r_extern) - rptr->addend += ecoff_data (abfd)->gp; - break; - - case ALPHA_R_LITUSE: - case ALPHA_R_GPDISP: - /* The LITUSE and GPDISP relocs do not use a symbol, or an - addend, but they do use a special code. Put this code in the - addend field. */ - rptr->addend = intern->r_size; - break; - - case ALPHA_R_OP_STORE: - /* The STORE reloc needs the size and offset fields. We store - them in the addend. */ - BFD_ASSERT (intern->r_offset <= 256 && intern->r_size <= 256); - rptr->addend = (intern->r_offset << 8) + intern->r_size; - break; - - case ALPHA_R_OP_PUSH: - case ALPHA_R_OP_PSUB: - case ALPHA_R_OP_PRSHIFT: - /* The PUSH, PSUB and PRSHIFT relocs do not actually use an - address. I believe that the address supplied is really an - addend. */ - rptr->addend = intern->r_vaddr; - break; - - case ALPHA_R_GPVALUE: - /* Set the addend field to the new GP value. */ - rptr->addend = intern->r_symndx + ecoff_data (abfd)->gp; - break; - - case ALPHA_R_IGNORE: - /* If the type is ALPHA_R_IGNORE, make sure this is a reference - to the absolute section so that the reloc is ignored. For - some reason the address of this reloc type is not adjusted by - the section vma. We record the gp value for this object file - here, for convenience when doing the GPDISP relocation. */ - rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - rptr->address = intern->r_vaddr; - rptr->addend = ecoff_data (abfd)->gp; - break; - - default: - break; - } - - rptr->howto = &alpha_howto_table[intern->r_type]; -} - -/* When writing out a reloc we need to pull some values back out of - the addend field into the reloc. This is roughly the reverse of - alpha_adjust_reloc_in, except that there are several changes we do - not need to undo. */ - -static void -alpha_adjust_reloc_out (abfd, rel, intern) - bfd *abfd; - const arelent *rel; - struct internal_reloc *intern; -{ - switch (intern->r_type) - { - case ALPHA_R_LITUSE: - case ALPHA_R_GPDISP: - intern->r_size = rel->addend; - break; - - case ALPHA_R_OP_STORE: - intern->r_size = rel->addend & 0xff; - intern->r_offset = (rel->addend >> 8) & 0xff; - break; - - case ALPHA_R_OP_PUSH: - case ALPHA_R_OP_PSUB: - case ALPHA_R_OP_PRSHIFT: - intern->r_vaddr = rel->addend; - break; - - case ALPHA_R_IGNORE: - intern->r_vaddr = rel->address; - break; - - default: - break; - } -} - -/* The size of the stack for the relocation evaluator. */ -#define RELOC_STACKSIZE (10) - -/* Alpha ECOFF relocs have a built in expression evaluator as well as - other interdependencies. Rather than use a bunch of special - functions and global variables, we use a single routine to do all - the relocation for a section. I haven't yet worked out how the - assembler is going to handle this. */ - -static bfd_byte * -alpha_ecoff_get_relocated_section_contents (abfd, link_info, link_order, - data, relocateable, symbols) - bfd *abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - bfd_byte *data; - boolean relocateable; - asymbol **symbols; -{ - bfd *input_bfd = link_order->u.indirect.section->owner; - asection *input_section = link_order->u.indirect.section; - long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); - arelent **reloc_vector = NULL; - long reloc_count; - bfd *output_bfd = relocateable ? abfd : (bfd *) NULL; - bfd_vma gp; - boolean gp_undefined; - bfd_vma stack[RELOC_STACKSIZE]; - int tos = 0; - - if (reloc_size < 0) - goto error_return; - reloc_vector = (arelent **) bfd_malloc (reloc_size); - if (reloc_vector == NULL && reloc_size != 0) - goto error_return; - - if (! bfd_get_section_contents (input_bfd, input_section, data, - (file_ptr) 0, input_section->_raw_size)) - goto error_return; - - /* The section size is not going to change. */ - input_section->_cooked_size = input_section->_raw_size; - input_section->reloc_done = true; - - reloc_count = bfd_canonicalize_reloc (input_bfd, input_section, - reloc_vector, symbols); - if (reloc_count < 0) - goto error_return; - if (reloc_count == 0) - goto successful_return; - - /* Get the GP value for the output BFD. */ - gp_undefined = false; - gp = _bfd_get_gp_value (abfd); - if (gp == 0) - { - if (relocateable != false) - { - asection *sec; - bfd_vma lo; - - /* Make up a value. */ - lo = (bfd_vma) -1; - for (sec = abfd->sections; sec != NULL; sec = sec->next) - { - if (sec->vma < lo - && (strcmp (sec->name, ".sbss") == 0 - || strcmp (sec->name, ".sdata") == 0 - || strcmp (sec->name, ".lit4") == 0 - || strcmp (sec->name, ".lit8") == 0 - || strcmp (sec->name, ".lita") == 0)) - lo = sec->vma; - } - gp = lo + 0x8000; - _bfd_set_gp_value (abfd, gp); - } - else - { - struct bfd_link_hash_entry *h; - - h = bfd_link_hash_lookup (link_info->hash, "_gp", false, false, - true); - if (h == (struct bfd_link_hash_entry *) NULL - || h->type != bfd_link_hash_defined) - gp_undefined = true; - else - { - gp = (h->u.def.value - + h->u.def.section->output_section->vma - + h->u.def.section->output_offset); - _bfd_set_gp_value (abfd, gp); - } - } - } - - for (; *reloc_vector != (arelent *) NULL; reloc_vector++) - { - arelent *rel; - bfd_reloc_status_type r; - char *err; - - rel = *reloc_vector; - r = bfd_reloc_ok; - switch (rel->howto->type) - { - case ALPHA_R_IGNORE: - rel->address += input_section->output_offset; - break; - - case ALPHA_R_REFLONG: - case ALPHA_R_REFQUAD: - case ALPHA_R_BRADDR: - case ALPHA_R_HINT: - case ALPHA_R_SREL16: - case ALPHA_R_SREL32: - case ALPHA_R_SREL64: - if (relocateable - && ((*rel->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0) - { - rel->address += input_section->output_offset; - break; - } - r = bfd_perform_relocation (input_bfd, rel, data, input_section, - output_bfd, &err); - break; - - case ALPHA_R_GPREL32: - /* This relocation is used in a switch table. It is a 32 - bit offset from the current GP value. We must adjust it - by the different between the original GP value and the - current GP value. The original GP value is stored in the - addend. We adjust the addend and let - bfd_perform_relocation finish the job. */ - rel->addend -= gp; - r = bfd_perform_relocation (input_bfd, rel, data, input_section, - output_bfd, &err); - if (r == bfd_reloc_ok && gp_undefined) - { - r = bfd_reloc_dangerous; - err = (char *) "GP relative relocation used when GP not defined"; - } - break; - - case ALPHA_R_LITERAL: - /* This is a reference to a literal value, generally - (always?) in the .lita section. This is a 16 bit GP - relative relocation. Sometimes the subsequent reloc is a - LITUSE reloc, which indicates how this reloc is used. - This sometimes permits rewriting the two instructions - referred to by the LITERAL and the LITUSE into different - instructions which do not refer to .lita. This can save - a memory reference, and permits removing a value from - .lita thus saving GP relative space. - - We do not these optimizations. To do them we would need - to arrange to link the .lita section first, so that by - the time we got here we would know the final values to - use. This would not be particularly difficult, but it is - not currently implemented. */ - - { - unsigned long insn; - - /* I believe that the LITERAL reloc will only apply to a - ldq or ldl instruction, so check my assumption. */ - insn = bfd_get_32 (input_bfd, data + rel->address); - BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29 - || ((insn >> 26) & 0x3f) == 0x28); - - rel->addend -= gp; - r = bfd_perform_relocation (input_bfd, rel, data, input_section, - output_bfd, &err); - if (r == bfd_reloc_ok && gp_undefined) - { - r = bfd_reloc_dangerous; - err = - (char *) "GP relative relocation used when GP not defined"; - } - } - break; - - case ALPHA_R_LITUSE: - /* See ALPHA_R_LITERAL above for the uses of this reloc. It - does not cause anything to happen, itself. */ - rel->address += input_section->output_offset; - break; - - case ALPHA_R_GPDISP: - /* This marks the ldah of an ldah/lda pair which loads the - gp register with the difference of the gp value and the - current location. The second of the pair is r_size bytes - ahead; it used to be marked with an ALPHA_R_IGNORE reloc, - but that no longer happens in OSF/1 3.2. */ - { - unsigned long insn1, insn2; - bfd_vma addend; - - /* Get the two instructions. */ - insn1 = bfd_get_32 (input_bfd, data + rel->address); - insn2 = bfd_get_32 (input_bfd, data + rel->address + rel->addend); - - BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */ - BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */ - - /* Get the existing addend. We must account for the sign - extension done by lda and ldah. */ - addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff); - if (insn1 & 0x8000) - { - addend -= 0x80000000; - addend -= 0x80000000; - } - if (insn2 & 0x8000) - addend -= 0x10000; - - /* The existing addend includes the different between the - gp of the input BFD and the address in the input BFD. - Subtract this out. */ - addend -= (ecoff_data (input_bfd)->gp - - (input_section->vma + rel->address)); - - /* Now add in the final gp value, and subtract out the - final address. */ - addend += (gp - - (input_section->output_section->vma - + input_section->output_offset - + rel->address)); - - /* Change the instructions, accounting for the sign - extension, and write them out. */ - if (addend & 0x8000) - addend += 0x10000; - insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff); - insn2 = (insn2 & 0xffff0000) | (addend & 0xffff); - - bfd_put_32 (input_bfd, (bfd_vma) insn1, data + rel->address); - bfd_put_32 (input_bfd, (bfd_vma) insn2, - data + rel->address + rel->addend); - - rel->address += input_section->output_offset; - } - break; - - case ALPHA_R_OP_PUSH: - /* Push a value on the reloc evaluation stack. */ - { - asymbol *symbol; - bfd_vma relocation; - - if (relocateable) - { - rel->address += input_section->output_offset; - break; - } - - /* Figure out the relocation of this symbol. */ - symbol = *rel->sym_ptr_ptr; - - if (bfd_is_und_section (symbol->section)) - r = bfd_reloc_undefined; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += rel->addend; - - if (tos >= RELOC_STACKSIZE) - abort (); - - stack[tos++] = relocation; - } - break; - - case ALPHA_R_OP_STORE: - /* Store a value from the reloc stack into a bitfield. */ - { - bfd_vma val; - int offset, size; - - if (relocateable) - { - rel->address += input_section->output_offset; - break; - } - - if (tos == 0) - abort (); - - /* The offset and size for this reloc are encoded into the - addend field by alpha_adjust_reloc_in. */ - offset = (rel->addend >> 8) & 0xff; - size = rel->addend & 0xff; - - val = bfd_get_64 (abfd, data + rel->address); - val &=~ (((1 << size) - 1) << offset); - val |= (stack[--tos] & ((1 << size) - 1)) << offset; - bfd_put_64 (abfd, val, data + rel->address); - } - break; - - case ALPHA_R_OP_PSUB: - /* Subtract a value from the top of the stack. */ - { - asymbol *symbol; - bfd_vma relocation; - - if (relocateable) - { - rel->address += input_section->output_offset; - break; - } - - /* Figure out the relocation of this symbol. */ - symbol = *rel->sym_ptr_ptr; - - if (bfd_is_und_section (symbol->section)) - r = bfd_reloc_undefined; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += rel->addend; - - if (tos == 0) - abort (); - - stack[tos - 1] -= relocation; - } - break; - - case ALPHA_R_OP_PRSHIFT: - /* Shift the value on the top of the stack. */ - { - asymbol *symbol; - bfd_vma relocation; - - if (relocateable) - { - rel->address += input_section->output_offset; - break; - } - - /* Figure out the relocation of this symbol. */ - symbol = *rel->sym_ptr_ptr; - - if (bfd_is_und_section (symbol->section)) - r = bfd_reloc_undefined; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += rel->addend; - - if (tos == 0) - abort (); - - stack[tos - 1] >>= relocation; - } - break; - - case ALPHA_R_GPVALUE: - /* I really don't know if this does the right thing. */ - gp = rel->addend; - gp_undefined = false; - break; - - default: - abort (); - } - - if (relocateable) - { - asection *os = input_section->output_section; - - /* A partial link, so keep the relocs. */ - os->orelocation[os->reloc_count] = rel; - os->reloc_count++; - } - - if (r != bfd_reloc_ok) - { - switch (r) - { - case bfd_reloc_undefined: - if (! ((*link_info->callbacks->undefined_symbol) - (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr), - input_bfd, input_section, rel->address))) - goto error_return; - break; - case bfd_reloc_dangerous: - if (! ((*link_info->callbacks->reloc_dangerous) - (link_info, err, input_bfd, input_section, - rel->address))) - goto error_return; - break; - case bfd_reloc_overflow: - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*rel->sym_ptr_ptr), - rel->howto->name, rel->addend, input_bfd, - input_section, rel->address))) - goto error_return; - break; - case bfd_reloc_outofrange: - default: - abort (); - break; - } - } - } - - if (tos != 0) - abort (); - - successful_return: - if (reloc_vector != NULL) - free (reloc_vector); - return data; - - error_return: - if (reloc_vector != NULL) - free (reloc_vector); - return NULL; -} - -/* Get the howto structure for a generic reloc type. */ - -static reloc_howto_type * -alpha_bfd_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - int alpha_type; - - switch (code) - { - case BFD_RELOC_32: - alpha_type = ALPHA_R_REFLONG; - break; - case BFD_RELOC_64: - case BFD_RELOC_CTOR: - alpha_type = ALPHA_R_REFQUAD; - break; - case BFD_RELOC_GPREL32: - alpha_type = ALPHA_R_GPREL32; - break; - case BFD_RELOC_ALPHA_LITERAL: - alpha_type = ALPHA_R_LITERAL; - break; - case BFD_RELOC_ALPHA_LITUSE: - alpha_type = ALPHA_R_LITUSE; - break; - case BFD_RELOC_ALPHA_GPDISP_HI16: - alpha_type = ALPHA_R_GPDISP; - break; - case BFD_RELOC_ALPHA_GPDISP_LO16: - alpha_type = ALPHA_R_IGNORE; - break; - case BFD_RELOC_23_PCREL_S2: - alpha_type = ALPHA_R_BRADDR; - break; - case BFD_RELOC_ALPHA_HINT: - alpha_type = ALPHA_R_HINT; - break; - case BFD_RELOC_16_PCREL: - alpha_type = ALPHA_R_SREL16; - break; - case BFD_RELOC_32_PCREL: - alpha_type = ALPHA_R_SREL32; - break; - case BFD_RELOC_64_PCREL: - alpha_type = ALPHA_R_SREL64; - break; -#if 0 - case ???: - alpha_type = ALPHA_R_OP_PUSH; - break; - case ???: - alpha_type = ALPHA_R_OP_STORE; - break; - case ???: - alpha_type = ALPHA_R_OP_PSUB; - break; - case ???: - alpha_type = ALPHA_R_OP_PRSHIFT; - break; - case ???: - alpha_type = ALPHA_R_GPVALUE; - break; -#endif - default: - return (reloc_howto_type *) NULL; - } - - return &alpha_howto_table[alpha_type]; -} - -/* A helper routine for alpha_relocate_section which converts an - external reloc when generating relocateable output. Returns the - relocation amount. */ - -static bfd_vma -alpha_convert_external_reloc (output_bfd, info, input_bfd, ext_rel, h) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - struct external_reloc *ext_rel; - struct ecoff_link_hash_entry *h; -{ - unsigned long r_symndx; - bfd_vma relocation; - - BFD_ASSERT (info->relocateable); - - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - asection *hsec; - const char *name; - - /* This symbol is defined in the output. Convert the reloc from - being against the symbol to being against the section. */ - - /* Clear the r_extern bit. */ - ext_rel->r_bits[1] &=~ RELOC_BITS1_EXTERN_LITTLE; - - /* Compute a new r_symndx value. */ - hsec = h->root.u.def.section; - name = bfd_get_section_name (output_bfd, hsec->output_section); - - r_symndx = -1; - switch (name[1]) - { - case 'A': - if (strcmp (name, "*ABS*") == 0) - r_symndx = RELOC_SECTION_ABS; - break; - case 'b': - if (strcmp (name, ".bss") == 0) - r_symndx = RELOC_SECTION_BSS; - break; - case 'd': - if (strcmp (name, ".data") == 0) - r_symndx = RELOC_SECTION_DATA; - break; - case 'f': - if (strcmp (name, ".fini") == 0) - r_symndx = RELOC_SECTION_FINI; - break; - case 'i': - if (strcmp (name, ".init") == 0) - r_symndx = RELOC_SECTION_INIT; - break; - case 'l': - if (strcmp (name, ".lita") == 0) - r_symndx = RELOC_SECTION_LITA; - else if (strcmp (name, ".lit8") == 0) - r_symndx = RELOC_SECTION_LIT8; - else if (strcmp (name, ".lit4") == 0) - r_symndx = RELOC_SECTION_LIT4; - break; - case 'p': - if (strcmp (name, ".pdata") == 0) - r_symndx = RELOC_SECTION_PDATA; - break; - case 'r': - if (strcmp (name, ".rdata") == 0) - r_symndx = RELOC_SECTION_RDATA; - else if (strcmp (name, ".rconst") == 0) - r_symndx = RELOC_SECTION_RCONST; - break; - case 's': - if (strcmp (name, ".sdata") == 0) - r_symndx = RELOC_SECTION_SDATA; - else if (strcmp (name, ".sbss") == 0) - r_symndx = RELOC_SECTION_SBSS; - break; - case 't': - if (strcmp (name, ".text") == 0) - r_symndx = RELOC_SECTION_TEXT; - break; - case 'x': - if (strcmp (name, ".xdata") == 0) - r_symndx = RELOC_SECTION_XDATA; - break; - } - - if (r_symndx == -1) - abort (); - - /* Add the section VMA and the symbol value. */ - relocation = (h->root.u.def.value - + hsec->output_section->vma - + hsec->output_offset); - } - else - { - /* Change the symndx value to the right one for - the output BFD. */ - r_symndx = h->indx; - if (r_symndx == -1) - { - /* Caller must give an error. */ - r_symndx = 0; - } - relocation = 0; - } - - /* Write out the new r_symndx value. */ - bfd_h_put_32 (input_bfd, (bfd_vma) r_symndx, - (bfd_byte *) ext_rel->r_symndx); - - return relocation; -} - -/* Relocate a section while linking an Alpha ECOFF file. This is - quite similar to get_relocated_section_contents. Perhaps they - could be combined somehow. */ - -static boolean -alpha_relocate_section (output_bfd, info, input_bfd, input_section, - contents, external_relocs) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - PTR external_relocs; -{ - asection **symndx_to_section, *lita_sec; - struct ecoff_link_hash_entry **sym_hashes; - bfd_vma gp; - boolean gp_undefined; - bfd_vma stack[RELOC_STACKSIZE]; - int tos = 0; - struct external_reloc *ext_rel; - struct external_reloc *ext_rel_end; - - /* We keep a table mapping the symndx found in an internal reloc to - the appropriate section. This is faster than looking up the - section by name each time. */ - symndx_to_section = ecoff_data (input_bfd)->symndx_to_section; - if (symndx_to_section == (asection **) NULL) - { - symndx_to_section = ((asection **) - bfd_alloc (input_bfd, - (NUM_RELOC_SECTIONS - * sizeof (asection *)))); - if (!symndx_to_section) - return false; - - symndx_to_section[RELOC_SECTION_NONE] = NULL; - symndx_to_section[RELOC_SECTION_TEXT] = - bfd_get_section_by_name (input_bfd, ".text"); - symndx_to_section[RELOC_SECTION_RDATA] = - bfd_get_section_by_name (input_bfd, ".rdata"); - symndx_to_section[RELOC_SECTION_DATA] = - bfd_get_section_by_name (input_bfd, ".data"); - symndx_to_section[RELOC_SECTION_SDATA] = - bfd_get_section_by_name (input_bfd, ".sdata"); - symndx_to_section[RELOC_SECTION_SBSS] = - bfd_get_section_by_name (input_bfd, ".sbss"); - symndx_to_section[RELOC_SECTION_BSS] = - bfd_get_section_by_name (input_bfd, ".bss"); - symndx_to_section[RELOC_SECTION_INIT] = - bfd_get_section_by_name (input_bfd, ".init"); - symndx_to_section[RELOC_SECTION_LIT8] = - bfd_get_section_by_name (input_bfd, ".lit8"); - symndx_to_section[RELOC_SECTION_LIT4] = - bfd_get_section_by_name (input_bfd, ".lit4"); - symndx_to_section[RELOC_SECTION_XDATA] = - bfd_get_section_by_name (input_bfd, ".xdata"); - symndx_to_section[RELOC_SECTION_PDATA] = - bfd_get_section_by_name (input_bfd, ".pdata"); - symndx_to_section[RELOC_SECTION_FINI] = - bfd_get_section_by_name (input_bfd, ".fini"); - symndx_to_section[RELOC_SECTION_LITA] = - bfd_get_section_by_name (input_bfd, ".lita"); - symndx_to_section[RELOC_SECTION_ABS] = bfd_abs_section_ptr; - symndx_to_section[RELOC_SECTION_RCONST] = - bfd_get_section_by_name (input_bfd, ".rconst"); - - ecoff_data (input_bfd)->symndx_to_section = symndx_to_section; - } - - sym_hashes = ecoff_data (input_bfd)->sym_hashes; - - /* On the Alpha, the .lita section must be addressable by the global - pointer. To support large programs, we need to allow multiple - global pointers. This works as long as each input .lita section - is <64KB big. This implies that when producing relocatable - output, the .lita section is limited to 64KB. . */ - - lita_sec = symndx_to_section[RELOC_SECTION_LITA]; - gp = _bfd_get_gp_value (output_bfd); - if (! info->relocateable && lita_sec != NULL) - { - struct ecoff_section_tdata *lita_sec_data; - - /* Make sure we have a section data structure to which we can - hang on to the gp value we pick for the section. */ - lita_sec_data = ecoff_section_data (input_bfd, lita_sec); - if (lita_sec_data == NULL) - { - lita_sec_data = ((struct ecoff_section_tdata *) - bfd_zalloc (input_bfd, - sizeof (struct ecoff_section_tdata))); - ecoff_section_data (input_bfd, lita_sec) = lita_sec_data; - } - - if (lita_sec_data->gp != 0) - { - /* If we already assigned a gp to this section, we better - stick with that value. */ - gp = lita_sec_data->gp; - } - else - { - bfd_vma lita_vma; - bfd_size_type lita_size; - - lita_vma = lita_sec->output_offset + lita_sec->output_section->vma; - lita_size = lita_sec->_cooked_size; - if (lita_size == 0) - lita_size = lita_sec->_raw_size; - - if (gp == 0 - || lita_vma < gp - 0x8000 - || lita_vma + lita_size >= gp + 0x8000) - { - /* Either gp hasn't been set at all or the current gp - cannot address this .lita section. In both cases we - reset the gp to point into the "middle" of the - current input .lita section. */ - if (gp && !ecoff_data (output_bfd)->issued_multiple_gp_warning) - { - (*info->callbacks->warning) (info, - "using multiple gp values", - (char *) NULL, output_bfd, - (asection *) NULL, (bfd_vma) 0); - ecoff_data (output_bfd)->issued_multiple_gp_warning = true; - } - if (lita_vma < gp - 0x8000) - gp = lita_vma + lita_size - 0x8000; - else - gp = lita_vma + 0x8000; - - } - - lita_sec_data->gp = gp; - } - - _bfd_set_gp_value (output_bfd, gp); - } - - gp_undefined = (gp == 0); - - BFD_ASSERT (bfd_header_little_endian (output_bfd)); - BFD_ASSERT (bfd_header_little_endian (input_bfd)); - - ext_rel = (struct external_reloc *) external_relocs; - ext_rel_end = ext_rel + input_section->reloc_count; - for (; ext_rel < ext_rel_end; ext_rel++) - { - bfd_vma r_vaddr; - unsigned long r_symndx; - int r_type; - int r_extern; - int r_offset; - int r_size; - boolean relocatep; - boolean adjust_addrp; - boolean gp_usedp; - bfd_vma addend; - - r_vaddr = bfd_h_get_64 (input_bfd, (bfd_byte *) ext_rel->r_vaddr); - r_symndx = bfd_h_get_32 (input_bfd, (bfd_byte *) ext_rel->r_symndx); - - r_type = ((ext_rel->r_bits[0] & RELOC_BITS0_TYPE_LITTLE) - >> RELOC_BITS0_TYPE_SH_LITTLE); - r_extern = (ext_rel->r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0; - r_offset = ((ext_rel->r_bits[1] & RELOC_BITS1_OFFSET_LITTLE) - >> RELOC_BITS1_OFFSET_SH_LITTLE); - /* Ignored the reserved bits. */ - r_size = ((ext_rel->r_bits[3] & RELOC_BITS3_SIZE_LITTLE) - >> RELOC_BITS3_SIZE_SH_LITTLE); - - relocatep = false; - adjust_addrp = true; - gp_usedp = false; - addend = 0; - - switch (r_type) - { - default: - abort (); - - case ALPHA_R_IGNORE: - /* This reloc appears after a GPDISP reloc. On earlier - versions of OSF/1, It marked the position of the second - instruction to be altered by the GPDISP reloc, but it is - not otherwise used for anything. For some reason, the - address of the relocation does not appear to include the - section VMA, unlike the other relocation types. */ - if (info->relocateable) - bfd_h_put_64 (input_bfd, - input_section->output_offset + r_vaddr, - (bfd_byte *) ext_rel->r_vaddr); - adjust_addrp = false; - break; - - case ALPHA_R_REFLONG: - case ALPHA_R_REFQUAD: - case ALPHA_R_BRADDR: - case ALPHA_R_HINT: - case ALPHA_R_SREL16: - case ALPHA_R_SREL32: - case ALPHA_R_SREL64: - relocatep = true; - break; - - case ALPHA_R_GPREL32: - /* This relocation is used in a switch table. It is a 32 - bit offset from the current GP value. We must adjust it - by the different between the original GP value and the - current GP value. */ - relocatep = true; - addend = ecoff_data (input_bfd)->gp - gp; - gp_usedp = true; - break; - - case ALPHA_R_LITERAL: - /* This is a reference to a literal value, generally - (always?) in the .lita section. This is a 16 bit GP - relative relocation. Sometimes the subsequent reloc is a - LITUSE reloc, which indicates how this reloc is used. - This sometimes permits rewriting the two instructions - referred to by the LITERAL and the LITUSE into different - instructions which do not refer to .lita. This can save - a memory reference, and permits removing a value from - .lita thus saving GP relative space. - - We do not these optimizations. To do them we would need - to arrange to link the .lita section first, so that by - the time we got here we would know the final values to - use. This would not be particularly difficult, but it is - not currently implemented. */ - - /* I believe that the LITERAL reloc will only apply to a ldq - or ldl instruction, so check my assumption. */ - { - unsigned long insn; - - insn = bfd_get_32 (input_bfd, - contents + r_vaddr - input_section->vma); - BFD_ASSERT (((insn >> 26) & 0x3f) == 0x29 - || ((insn >> 26) & 0x3f) == 0x28); - } - - relocatep = true; - addend = ecoff_data (input_bfd)->gp - gp; - gp_usedp = true; - break; - - case ALPHA_R_LITUSE: - /* See ALPHA_R_LITERAL above for the uses of this reloc. It - does not cause anything to happen, itself. */ - break; - - case ALPHA_R_GPDISP: - /* This marks the ldah of an ldah/lda pair which loads the - gp register with the difference of the gp value and the - current location. The second of the pair is r_symndx - bytes ahead. It used to be marked with an ALPHA_R_IGNORE - reloc, but OSF/1 3.2 no longer does that. */ - { - unsigned long insn1, insn2; - - /* Get the two instructions. */ - insn1 = bfd_get_32 (input_bfd, - contents + r_vaddr - input_section->vma); - insn2 = bfd_get_32 (input_bfd, - (contents - + r_vaddr - - input_section->vma - + r_symndx)); - - BFD_ASSERT (((insn1 >> 26) & 0x3f) == 0x09); /* ldah */ - BFD_ASSERT (((insn2 >> 26) & 0x3f) == 0x08); /* lda */ - - /* Get the existing addend. We must account for the sign - extension done by lda and ldah. */ - addend = ((insn1 & 0xffff) << 16) + (insn2 & 0xffff); - if (insn1 & 0x8000) - { - /* This is addend -= 0x100000000 without causing an - integer overflow on a 32 bit host. */ - addend -= 0x80000000; - addend -= 0x80000000; - } - if (insn2 & 0x8000) - addend -= 0x10000; - - /* The existing addend includes the difference between the - gp of the input BFD and the address in the input BFD. - We want to change this to the difference between the - final GP and the final address. */ - addend += (gp - - ecoff_data (input_bfd)->gp - + input_section->vma - - (input_section->output_section->vma - + input_section->output_offset)); - - /* Change the instructions, accounting for the sign - extension, and write them out. */ - if (addend & 0x8000) - addend += 0x10000; - insn1 = (insn1 & 0xffff0000) | ((addend >> 16) & 0xffff); - insn2 = (insn2 & 0xffff0000) | (addend & 0xffff); - - bfd_put_32 (input_bfd, (bfd_vma) insn1, - contents + r_vaddr - input_section->vma); - bfd_put_32 (input_bfd, (bfd_vma) insn2, - contents + r_vaddr - input_section->vma + r_symndx); - - gp_usedp = true; - } - break; - - case ALPHA_R_OP_PUSH: - case ALPHA_R_OP_PSUB: - case ALPHA_R_OP_PRSHIFT: - /* Manipulate values on the reloc evaluation stack. The - r_vaddr field is not an address in input_section, it is - the current value (including any addend) of the object - being used. */ - if (! r_extern) - { - asection *s; - - s = symndx_to_section[r_symndx]; - if (s == (asection *) NULL) - abort (); - addend = s->output_section->vma + s->output_offset - s->vma; - } - else - { - struct ecoff_link_hash_entry *h; - - h = sym_hashes[r_symndx]; - if (h == (struct ecoff_link_hash_entry *) NULL) - abort (); - - if (! info->relocateable) - { - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - addend = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - else - { - /* Note that we pass the address as 0, since we - do not have a meaningful number for the - location within the section that is being - relocated. */ - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, (bfd_vma) 0))) - return false; - addend = 0; - } - } - else - { - if (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak - && h->indx == -1) - { - /* This symbol is not being written out. Pass - the address as 0, as with undefined_symbol, - above. */ - if (! ((*info->callbacks->unattached_reloc) - (info, h->root.root.string, input_bfd, - input_section, (bfd_vma) 0))) - return false; - } - - addend = alpha_convert_external_reloc (output_bfd, info, - input_bfd, - ext_rel, h); - } - } - - addend += r_vaddr; - - if (info->relocateable) - { - /* Adjust r_vaddr by the addend. */ - bfd_h_put_64 (input_bfd, addend, - (bfd_byte *) ext_rel->r_vaddr); - } - else - { - switch (r_type) - { - case ALPHA_R_OP_PUSH: - if (tos >= RELOC_STACKSIZE) - abort (); - stack[tos++] = addend; - break; - - case ALPHA_R_OP_PSUB: - if (tos == 0) - abort (); - stack[tos - 1] -= addend; - break; - - case ALPHA_R_OP_PRSHIFT: - if (tos == 0) - abort (); - stack[tos - 1] >>= addend; - break; - } - } - - adjust_addrp = false; - break; - - case ALPHA_R_OP_STORE: - /* Store a value from the reloc stack into a bitfield. If - we are generating relocateable output, all we do is - adjust the address of the reloc. */ - if (! info->relocateable) - { - bfd_vma mask; - bfd_vma val; - - if (tos == 0) - abort (); - - /* Get the relocation mask. The separate steps and the - casts to bfd_vma are attempts to avoid a bug in the - Alpha OSF 1.3 C compiler. See reloc.c for more - details. */ - mask = 1; - mask <<= (bfd_vma) r_size; - mask -= 1; - - /* FIXME: I don't know what kind of overflow checking, - if any, should be done here. */ - val = bfd_get_64 (input_bfd, - contents + r_vaddr - input_section->vma); - val &=~ mask << (bfd_vma) r_offset; - val |= (stack[--tos] & mask) << (bfd_vma) r_offset; - bfd_put_64 (input_bfd, val, - contents + r_vaddr - input_section->vma); - } - break; - - case ALPHA_R_GPVALUE: - /* I really don't know if this does the right thing. */ - gp = ecoff_data (input_bfd)->gp + r_symndx; - gp_undefined = false; - break; - } - - if (relocatep) - { - reloc_howto_type *howto; - struct ecoff_link_hash_entry *h = NULL; - asection *s = NULL; - bfd_vma relocation; - bfd_reloc_status_type r; - - /* Perform a relocation. */ - - howto = &alpha_howto_table[r_type]; - - if (r_extern) - { - h = sym_hashes[r_symndx]; - /* If h is NULL, that means that there is a reloc - against an external symbol which we thought was just - a debugging symbol. This should not happen. */ - if (h == (struct ecoff_link_hash_entry *) NULL) - abort (); - } - else - { - if (r_symndx >= NUM_RELOC_SECTIONS) - s = NULL; - else - s = symndx_to_section[r_symndx]; - - if (s == (asection *) NULL) - abort (); - } - - if (info->relocateable) - { - /* We are generating relocateable output, and must - convert the existing reloc. */ - if (r_extern) - { - if (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak - && h->indx == -1) - { - /* This symbol is not being written out. */ - if (! ((*info->callbacks->unattached_reloc) - (info, h->root.root.string, input_bfd, - input_section, r_vaddr - input_section->vma))) - return false; - } - - relocation = alpha_convert_external_reloc (output_bfd, - info, - input_bfd, - ext_rel, - h); - } - else - { - /* This is a relocation against a section. Adjust - the value by the amount the section moved. */ - relocation = (s->output_section->vma - + s->output_offset - - s->vma); - } - - /* If this is PC relative, the existing object file - appears to already have the reloc worked out. We - must subtract out the old value and add in the new - one. */ - if (howto->pc_relative) - relocation -= (input_section->output_section->vma - + input_section->output_offset - - input_section->vma); - - /* Put in any addend. */ - relocation += addend; - - /* Adjust the contents. */ - r = _bfd_relocate_contents (howto, input_bfd, relocation, - (contents - + r_vaddr - - input_section->vma)); - } - else - { - /* We are producing a final executable. */ - if (r_extern) - { - /* This is a reloc against a symbol. */ - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - asection *hsec; - - hsec = h->root.u.def.section; - relocation = (h->root.u.def.value - + hsec->output_section->vma - + hsec->output_offset); - } - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, - r_vaddr - input_section->vma))) - return false; - relocation = 0; - } - } - else - { - /* This is a reloc against a section. */ - relocation = (s->output_section->vma - + s->output_offset - - s->vma); - - /* Adjust a PC relative relocation by removing the - reference to the original source section. */ - if (howto->pc_relative) - relocation += input_section->vma; - } - - r = _bfd_final_link_relocate (howto, - input_bfd, - input_section, - contents, - r_vaddr - input_section->vma, - relocation, - addend); - } - - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (r_extern) - name = sym_hashes[r_symndx]->root.root.string; - else - name = bfd_section_name (input_bfd, - symndx_to_section[r_symndx]); - if (! ((*info->callbacks->reloc_overflow) - (info, name, alpha_howto_table[r_type].name, - (bfd_vma) 0, input_bfd, input_section, - r_vaddr - input_section->vma))) - return false; - } - break; - } - } - } - - if (info->relocateable && adjust_addrp) - { - /* Change the address of the relocation. */ - bfd_h_put_64 (input_bfd, - (input_section->output_section->vma - + input_section->output_offset - - input_section->vma - + r_vaddr), - (bfd_byte *) ext_rel->r_vaddr); - } - - if (gp_usedp && gp_undefined) - { - if (! ((*info->callbacks->reloc_dangerous) - (info, "GP relative relocation when GP not defined", - input_bfd, input_section, r_vaddr - input_section->vma))) - return false; - /* Only give the error once per link. */ - gp = 4; - _bfd_set_gp_value (output_bfd, gp); - gp_undefined = false; - } - } - - if (tos != 0) - abort (); - - return true; -} - -/* Do final adjustments to the filehdr and the aouthdr. This routine - sets the dynamic bits in the file header. */ - -/*ARGSUSED*/ -static boolean -alpha_adjust_headers (abfd, fhdr, ahdr) - bfd *abfd; - struct internal_filehdr *fhdr; - struct internal_aouthdr *ahdr; -{ - if ((abfd->flags & (DYNAMIC | EXEC_P)) == (DYNAMIC | EXEC_P)) - fhdr->f_flags |= F_ALPHA_CALL_SHARED; - else if ((abfd->flags & DYNAMIC) != 0) - fhdr->f_flags |= F_ALPHA_SHARABLE; - return true; -} - -/* Archive handling. In OSF/1 (or Digital Unix) v3.2, Digital - introduced archive packing, in which the elements in an archive are - optionally compressed using a simple dictionary scheme. We know - how to read such archives, but we don't write them. */ - -#define alpha_ecoff_slurp_armap _bfd_ecoff_slurp_armap -#define alpha_ecoff_slurp_extended_name_table \ - _bfd_ecoff_slurp_extended_name_table -#define alpha_ecoff_construct_extended_name_table \ - _bfd_ecoff_construct_extended_name_table -#define alpha_ecoff_truncate_arname _bfd_ecoff_truncate_arname -#define alpha_ecoff_write_armap _bfd_ecoff_write_armap -#define alpha_ecoff_generic_stat_arch_elt _bfd_ecoff_generic_stat_arch_elt -#define alpha_ecoff_update_armap_timestamp _bfd_ecoff_update_armap_timestamp - -/* A compressed file uses this instead of ARFMAG. */ - -#define ARFZMAG "Z\012" - -/* Read an archive header. This is like the standard routine, but it - also accepts ARFZMAG. */ - -static PTR -alpha_ecoff_read_ar_hdr (abfd) - bfd *abfd; -{ - struct areltdata *ret; - struct ar_hdr *h; - - ret = (struct areltdata *) _bfd_generic_read_ar_hdr_mag (abfd, ARFZMAG); - if (ret == NULL) - return NULL; - - h = (struct ar_hdr *) ret->arch_header; - if (strncmp (h->ar_fmag, ARFZMAG, 2) == 0) - { - bfd_byte ab[8]; - - /* This is a compressed file. We must set the size correctly. - The size is the eight bytes after the dummy file header. */ - if (bfd_seek (abfd, FILHSZ, SEEK_CUR) != 0 - || bfd_read (ab, 1, 8, abfd) != 8 - || bfd_seek (abfd, - (FILHSZ + 8), SEEK_CUR) != 0) - return NULL; - - ret->parsed_size = bfd_h_get_64 (abfd, ab); - } - - return (PTR) ret; -} - -/* Get an archive element at a specified file position. This is where - we uncompress the archive element if necessary. */ - -static bfd * -alpha_ecoff_get_elt_at_filepos (archive, filepos) - bfd *archive; - file_ptr filepos; -{ - bfd *nbfd = NULL; - struct areltdata *tdata; - struct ar_hdr *hdr; - bfd_byte ab[8]; - bfd_size_type size; - bfd_byte *buf, *p; - struct bfd_in_memory *bim; - - nbfd = _bfd_get_elt_at_filepos (archive, filepos); - if (nbfd == NULL) - goto error_return; - - if ((nbfd->flags & BFD_IN_MEMORY) != 0) - { - /* We have already expanded this BFD. */ - return nbfd; - } - - tdata = (struct areltdata *) nbfd->arelt_data; - hdr = (struct ar_hdr *) tdata->arch_header; - if (strncmp (hdr->ar_fmag, ARFZMAG, 2) != 0) - return nbfd; - - /* We must uncompress this element. We do this by copying it into a - memory buffer, and making bfd_read and bfd_seek use that buffer. - This can use a lot of memory, but it's simpler than getting a - temporary file, making that work with the file descriptor caching - code, and making sure that it is deleted at all appropriate - times. It can be changed if it ever becomes important. */ - - /* The compressed file starts with a dummy ECOFF file header. */ - if (bfd_seek (nbfd, FILHSZ, SEEK_SET) != 0) - goto error_return; - - /* The next eight bytes are the real file size. */ - if (bfd_read (ab, 1, 8, nbfd) != 8) - goto error_return; - size = bfd_h_get_64 (nbfd, ab); - - if (size == 0) - buf = NULL; - else - { - bfd_size_type left; - bfd_byte dict[4096]; - unsigned int h; - bfd_byte b; - - buf = (bfd_byte *) bfd_alloc (nbfd, size); - if (buf == NULL) - goto error_return; - p = buf; - - left = size; - - /* I don't know what the next eight bytes are for. */ - if (bfd_read (ab, 1, 8, nbfd) != 8) - goto error_return; - - /* This is the uncompression algorithm. It's a simple - dictionary based scheme in which each character is predicted - by a hash of the previous three characters. A control byte - indicates whether the character is predicted or whether it - appears in the input stream; each control byte manages the - next eight bytes in the output stream. */ - memset (dict, 0, sizeof dict); - h = 0; - while (bfd_read (&b, 1, 1, nbfd) == 1) - { - unsigned int i; - - for (i = 0; i < 8; i++, b >>= 1) - { - bfd_byte n; - - if ((b & 1) == 0) - n = dict[h]; - else - { - if (! bfd_read (&n, 1, 1, nbfd)) - goto error_return; - dict[h] = n; - } - - *p++ = n; - - --left; - if (left == 0) - break; - - h <<= 4; - h ^= n; - h &= sizeof dict - 1; - } - - if (left == 0) - break; - } - } - - /* Now the uncompressed file contents are in buf. */ - bim = ((struct bfd_in_memory *) - bfd_alloc (nbfd, sizeof (struct bfd_in_memory))); - if (bim == NULL) - goto error_return; - bim->size = size; - bim->buffer = buf; - - nbfd->mtime_set = true; - nbfd->mtime = strtol (hdr->ar_date, (char **) NULL, 10); - - nbfd->flags |= BFD_IN_MEMORY; - nbfd->iostream = (PTR) bim; - BFD_ASSERT (! nbfd->cacheable); - - return nbfd; - - error_return: - if (nbfd != NULL) - bfd_close (nbfd); - return NULL; -} - -/* Open the next archived file. */ - -static bfd * -alpha_ecoff_openr_next_archived_file (archive, last_file) - bfd *archive; - bfd *last_file; -{ - file_ptr filestart; - - if (last_file == NULL) - filestart = bfd_ardata (archive)->first_file_filepos; - else - { - struct areltdata *t; - struct ar_hdr *h; - bfd_size_type size; - - /* We can't use arelt_size here, because that uses parsed_size, - which is the uncompressed size. We need the compressed size. */ - t = (struct areltdata *) last_file->arelt_data; - h = (struct ar_hdr *) t->arch_header; - size = strtol (h->ar_size, (char **) NULL, 10); - - /* Pad to an even boundary... - Note that last_file->origin can be odd in the case of - BSD-4.4-style element with a long odd size. */ - filestart = last_file->origin + size; - filestart += filestart % 2; - } - - return alpha_ecoff_get_elt_at_filepos (archive, filestart); -} - -/* Open the archive file given an index into the armap. */ - -static bfd * -alpha_ecoff_get_elt_at_index (abfd, index) - bfd *abfd; - symindex index; -{ - carsym *entry; - - entry = bfd_ardata (abfd)->symdefs + index; - return alpha_ecoff_get_elt_at_filepos (abfd, entry->file_offset); -} - -/* This is the ECOFF backend structure. The backend field of the - target vector points to this. */ - -static const struct ecoff_backend_data alpha_ecoff_backend_data = -{ - /* COFF backend structure. */ - { - (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */ - (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */ - (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */ - (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/ - (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */ - (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */ - (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */ - alpha_ecoff_swap_filehdr_out, alpha_ecoff_swap_aouthdr_out, - alpha_ecoff_swap_scnhdr_out, - FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, true, - alpha_ecoff_swap_filehdr_in, alpha_ecoff_swap_aouthdr_in, - alpha_ecoff_swap_scnhdr_in, NULL, - alpha_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook, - alpha_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags, - _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL - }, - /* Supported architecture. */ - bfd_arch_alpha, - /* Initial portion of armap string. */ - "________64", - /* The page boundary used to align sections in a demand-paged - executable file. E.g., 0x1000. */ - 0x2000, - /* True if the .rdata section is part of the text segment, as on the - Alpha. False if .rdata is part of the data segment, as on the - MIPS. */ - true, - /* Bitsize of constructor entries. */ - 64, - /* Reloc to use for constructor entries. */ - &alpha_howto_table[ALPHA_R_REFQUAD], - { - /* Symbol table magic number. */ - magicSym2, - /* Alignment of debugging information. E.g., 4. */ - 8, - /* Sizes of external symbolic information. */ - sizeof (struct hdr_ext), - sizeof (struct dnr_ext), - sizeof (struct pdr_ext), - sizeof (struct sym_ext), - sizeof (struct opt_ext), - sizeof (struct fdr_ext), - sizeof (struct rfd_ext), - sizeof (struct ext_ext), - /* Functions to swap in external symbolic data. */ - ecoff_swap_hdr_in, - ecoff_swap_dnr_in, - ecoff_swap_pdr_in, - ecoff_swap_sym_in, - ecoff_swap_opt_in, - ecoff_swap_fdr_in, - ecoff_swap_rfd_in, - ecoff_swap_ext_in, - _bfd_ecoff_swap_tir_in, - _bfd_ecoff_swap_rndx_in, - /* Functions to swap out external symbolic data. */ - ecoff_swap_hdr_out, - ecoff_swap_dnr_out, - ecoff_swap_pdr_out, - ecoff_swap_sym_out, - ecoff_swap_opt_out, - ecoff_swap_fdr_out, - ecoff_swap_rfd_out, - ecoff_swap_ext_out, - _bfd_ecoff_swap_tir_out, - _bfd_ecoff_swap_rndx_out, - /* Function to read in symbolic data. */ - _bfd_ecoff_slurp_symbolic_info - }, - /* External reloc size. */ - RELSZ, - /* Reloc swapping functions. */ - alpha_ecoff_swap_reloc_in, - alpha_ecoff_swap_reloc_out, - /* Backend reloc tweaking. */ - alpha_adjust_reloc_in, - alpha_adjust_reloc_out, - /* Relocate section contents while linking. */ - alpha_relocate_section, - /* Do final adjustments to filehdr and aouthdr. */ - alpha_adjust_headers, - /* Read an element from an archive at a given file position. */ - alpha_ecoff_get_elt_at_filepos -}; - -/* Looking up a reloc type is Alpha specific. */ -#define _bfd_ecoff_bfd_reloc_type_lookup alpha_bfd_reloc_type_lookup - -/* So is getting relocated section contents. */ -#define _bfd_ecoff_bfd_get_relocated_section_contents \ - alpha_ecoff_get_relocated_section_contents - -/* Handling file windows is generic. */ -#define _bfd_ecoff_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -/* Relaxing sections is generic. */ -#define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section - -const bfd_target ecoffalpha_little_vec = -{ - "ecoff-littlealpha", /* name */ - bfd_target_ecoff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA), - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - - {_bfd_dummy_target, alpha_ecoff_object_p, /* bfd_check_format */ - _bfd_ecoff_archive_p, _bfd_dummy_target}, - {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (_bfd_ecoff), - BFD_JUMP_TABLE_COPY (_bfd_ecoff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (alpha_ecoff), - BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff), - BFD_JUMP_TABLE_RELOCS (_bfd_ecoff), - BFD_JUMP_TABLE_WRITE (_bfd_ecoff), - BFD_JUMP_TABLE_LINK (_bfd_ecoff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) &alpha_ecoff_backend_data -}; diff --git a/contrib/gdb/bfd/coff-apollo.c b/contrib/gdb/bfd/coff-apollo.c deleted file mode 100644 index 561b1c7..0000000 --- a/contrib/gdb/bfd/coff-apollo.c +++ /dev/null @@ -1,162 +0,0 @@ -/* BFD back-end for Apollo 68000 COFF binaries. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - By Troy Rollo (troy@cbme.unsw.edu.au) - Based on m68k standard COFF version Written by Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/apollo.h" -#include "coff/internal.h" -#include "libcoff.h" - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3) - -#ifdef ONLY_DECLARE_RELOCS -extern reloc_howto_type apollocoff_howto_table[]; -#else -reloc_howto_type apollocoff_howto_table[] = -{ - HOWTO(R_RELBYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "8", true, 0x000000ff,0x000000ff, false), - HOWTO(R_RELWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "16", true, 0x0000ffff,0x0000ffff, false), - HOWTO(R_RELLONG, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "32", true, 0xffffffff,0xffffffff, false), - HOWTO(R_PCRBYTE, 0, 0, 8, true, 0, complain_overflow_signed, 0, "DISP8", true, 0x000000ff,0x000000ff, false), - HOWTO(R_PCRWORD, 0, 1, 16, true, 0, complain_overflow_signed, 0, "DISP16", true, 0x0000ffff,0x0000ffff, false), - HOWTO(R_PCRLONG, 0, 2, 32, true, 0, complain_overflow_signed, 0, "DISP32", true, 0xffffffff,0xffffffff, false), - HOWTO(R_RELLONG_NEG, 0, -2, 32, false, 0, complain_overflow_bitfield, 0, "-32", true, 0xffffffff,0xffffffff, false), -}; -#endif /* not ONLY_DECLARE_RELOCS */ - -#ifndef BADMAG -#define BADMAG(x) M68KBADMAG(x) -#endif -#define APOLLO_M68 1 /* Customize coffcode.h */ - -/* Turn a howto into a reloc number */ - -#ifdef ONLY_DECLARE_RELOCS -extern void apollo_rtype2howto PARAMS ((arelent *internal, int relocentry)); -extern int apollo_howto2rtype PARAMS ((reloc_howto_type *)); -#else -void -apollo_rtype2howto(internal, relocentry) - arelent *internal; - int relocentry; -{ - switch (relocentry) - { - case R_RELBYTE: internal->howto = apollocoff_howto_table + 0; break; - case R_RELWORD: internal->howto = apollocoff_howto_table + 1; break; - case R_RELLONG: internal->howto = apollocoff_howto_table + 2; break; - case R_PCRBYTE: internal->howto = apollocoff_howto_table + 3; break; - case R_PCRWORD: internal->howto = apollocoff_howto_table + 4; break; - case R_PCRLONG: internal->howto = apollocoff_howto_table + 5; break; - case R_RELLONG_NEG: internal->howto = apollocoff_howto_table + 6; break; - } -} - -int -apollo_howto2rtype (internal) - reloc_howto_type *internal; -{ - if (internal->pc_relative) - { - switch (internal->bitsize) - { - case 32: return R_PCRLONG; - case 16: return R_PCRWORD; - case 8: return R_PCRBYTE; - } - } - else - { - switch (internal->bitsize) - { - case 32: return R_RELLONG; - case 16: return R_RELWORD; - case 8: return R_RELBYTE; - } - } - return R_RELLONG; -} -#endif /* not ONLY_DECLARE_RELOCS */ - -#define RTYPE2HOWTO(internal, relocentry) \ - apollo_rtype2howto(internal, (relocentry)->r_type) - -#define SELECT_RELOC(external, internal) \ - external.r_type = apollo_howto2rtype(internal); - -#include "coffcode.h" - -const bfd_target -#ifdef TARGET_SYM - TARGET_SYM = -#else - apollocoff_vec = -#endif -{ -#ifdef TARGET_NAME - TARGET_NAME, -#else - "apollo-m68k", /* name */ -#endif - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ -#ifdef NAMES_HAVE_UNDERSCORE - '_', -#else - 0, /* leading underscore */ -#endif - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE - }; diff --git a/contrib/gdb/bfd/coff-arm.c b/contrib/gdb/bfd/coff-arm.c deleted file mode 100644 index bb16b04..0000000 --- a/contrib/gdb/bfd/coff-arm.c +++ /dev/null @@ -1,537 +0,0 @@ -/* BFD back-end for ARM COFF files. - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" - -#include "coff/arm.h" - -#include "coff/internal.h" - -#ifdef COFF_WITH_PE -#include "coff/pe.h" -#endif - -#include "libcoff.h" - -static bfd_reloc_status_type -aoutarm_fix_pcrel_26_done PARAMS ((bfd *, arelent *, asymbol *, PTR, - asection *, bfd *, char **)); - -static bfd_reloc_status_type -aoutarm_fix_pcrel_26 PARAMS ((bfd *, arelent *, asymbol *, PTR, - asection *, bfd *, char **)); - - -static bfd_reloc_status_type coff_arm_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); - - -/* Used by the assembler. */ -static bfd_reloc_status_type -coff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - symvalue diff; - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - diff = reloc_entry->addend; - -#define DOIT(x) \ - x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) - - if (diff != 0) - { - reloc_howto_type *howto = reloc_entry->howto; - unsigned char *addr = (unsigned char *) data + reloc_entry->address; - - switch (howto->size) - { - case 0: - { - char x = bfd_get_8 (abfd, addr); - DOIT (x); - bfd_put_8 (abfd, x, addr); - } - break; - - case 1: - { - short x = bfd_get_16 (abfd, addr); - DOIT (x); - bfd_put_16 (abfd, x, addr); - } - break; - - case 2: - { - long x = bfd_get_32 (abfd, addr); - DOIT (x); - bfd_put_32 (abfd, x, addr); - } - break; - - default: - abort (); - } - } - - /* Now let bfd_perform_relocation finish everything up. */ - return bfd_reloc_continue; -} - -#ifndef PCRELOFFSET -#define PCRELOFFSET true -#endif - -static reloc_howto_type aoutarm_std_reloc_howto[] = -{ - /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */ - HOWTO(0, /* type */ - 0, /* rs */ - 0, /* size */ - 8, /* bsz */ - false, /* pcrel */ - 0, /* bitpos */ - complain_overflow_bitfield, /* ovf */ - coff_arm_reloc, /* sf */ - "8", /*name */ - true, /* partial */ - 0x000000ff, /*read mask */ - 0x000000ff, /* setmask */ - PCRELOFFSET /* pcdone */), - HOWTO(1, - 0, - 1, - 16, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "16", - true, - 0x0000ffff, - 0x0000ffff, - PCRELOFFSET), - HOWTO( 2, - 0, - 2, - 32, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "32", - true, - 0xffffffff, - 0xffffffff, - PCRELOFFSET), - HOWTO( 3, - 2, - 2, - 26, - true, - 0, - complain_overflow_signed, - aoutarm_fix_pcrel_26 , - "ARM26", - false, - 0x00ffffff, - 0x00ffffff, - PCRELOFFSET), - HOWTO( 4, - 0, - 0, - 8, - true, - 0, - complain_overflow_signed, - coff_arm_reloc, - "DISP8", - true, - 0x000000ff, - 0x000000ff, - true), - HOWTO( 5, - 0, - 1, - 16, - true, - 0, - complain_overflow_signed, - coff_arm_reloc, - "DISP16", - true, - 0x0000ffff, - 0x0000ffff, - true), - HOWTO( 6, - 0, - 2, - 32, - true, - 0, - complain_overflow_signed, - coff_arm_reloc, - "DISP32", - true, - 0xffffffff, - 0xffffffff, - true), - HOWTO( 7, - 2, - 2, - 26, - false, - 0, - complain_overflow_signed, - aoutarm_fix_pcrel_26_done, - "ARM26D", - true, - 0x00ffffff, - 0x00ffffff, - false), - {-1}, - HOWTO( 9, - 0, - -1, - 16, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "NEG16", - true, - 0x0000ffff, - 0x0000ffff, - false), - HOWTO( 10, - 0, - -2, - 32, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "NEG32", - true, - 0xffffffff, - 0xffffffff, - false), - HOWTO( 11, - 0, - 2, - 32, - false, - 0, - complain_overflow_bitfield, - coff_arm_reloc, - "rva32", - true, - 0xffffffff, - 0xffffffff, - PCRELOFFSET), -}; -#ifdef COFF_WITH_PE -/* Return true if this relocation should - appear in the output .reloc section. */ - -static boolean in_reloc_p (abfd, howto) - bfd * abfd; - reloc_howto_type *howto; -{ - return !howto->pc_relative && howto->type != 11; -} -#endif - - -#define RTYPE2HOWTO(cache_ptr, dst) \ - (cache_ptr)->howto = aoutarm_std_reloc_howto + (dst)->r_type; - -#define coff_rtype_to_howto coff_arm_rtype_to_howto - -static reloc_howto_type * -coff_arm_rtype_to_howto (abfd, sec, rel, h, sym, addendp) - bfd *abfd; - asection *sec; - struct internal_reloc *rel; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma *addendp; -{ - reloc_howto_type *howto; - - howto = aoutarm_std_reloc_howto + rel->r_type; - - if (rel->r_type == 11) - { - *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase; - } - return howto; - -} -/* Used by the assembler. */ - -static bfd_reloc_status_type -aoutarm_fix_pcrel_26_done (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - /* This is dead simple at present. */ - return bfd_reloc_ok; -} - -/* Used by the assembler. */ - -static bfd_reloc_status_type -aoutarm_fix_pcrel_26 (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_vma relocation; - bfd_size_type addr = reloc_entry->address; - long target = bfd_get_32 (abfd, (bfd_byte *) data + addr); - bfd_reloc_status_type flag = bfd_reloc_ok; - - /* If this is an undefined symbol, return error */ - if (symbol->section == &bfd_und_section - && (symbol->flags & BSF_WEAK) == 0) - return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined; - - /* If the sections are different, and we are doing a partial relocation, - just ignore it for now. */ - if (symbol->section->name != input_section->name - && output_bfd != (bfd *)NULL) - return bfd_reloc_continue; - - relocation = (target & 0x00ffffff) << 2; - relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend */ - relocation += symbol->value; - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - relocation -= input_section->output_section->vma; - relocation -= input_section->output_offset; - relocation -= addr; - if (relocation & 3) - return bfd_reloc_overflow; - - /* Check for overflow */ - if (relocation & 0x02000000) - { - if ((relocation & ~0x03ffffff) != ~0x03ffffff) - flag = bfd_reloc_overflow; - } - else if (relocation & ~0x03ffffff) - flag = bfd_reloc_overflow; - - target &= ~0x00ffffff; - target |= (relocation >> 2) & 0x00ffffff; - bfd_put_32 (abfd, target, (bfd_byte *) data + addr); - - /* Now the ARM magic... Change the reloc type so that it is marked as done. - Strictly this is only necessary if we are doing a partial relocation. */ - reloc_entry->howto = &aoutarm_std_reloc_howto[7]; - - return flag; -} - - -static CONST struct reloc_howto_struct * -arm_reloc_type_lookup(abfd,code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ -#define ASTD(i,j) case i: return &aoutarm_std_reloc_howto[j] - if (code == BFD_RELOC_CTOR) - switch (bfd_get_arch_info (abfd)->bits_per_address) - { - case 32: - code = BFD_RELOC_32; - break; - default: return (CONST struct reloc_howto_struct *) 0; - } - - switch (code) - { - ASTD (BFD_RELOC_16, 1); - ASTD (BFD_RELOC_32, 2); - ASTD (BFD_RELOC_ARM_PCREL_BRANCH, 3); - ASTD (BFD_RELOC_8_PCREL, 4); - ASTD (BFD_RELOC_16_PCREL, 5); - ASTD (BFD_RELOC_32_PCREL, 6); - ASTD (BFD_RELOC_RVA, 11); - default: return (CONST struct reloc_howto_struct *) 0; - } -} - - -#define coff_bfd_reloc_type_lookup arm_reloc_type_lookup - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) -#define COFF_PAGE_SIZE 0x1000 -/* Turn a howto into a reloc nunmber */ - -#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } -#define BADMAG(x) ARMBADMAG(x) -#define ARM 1 /* Customize coffcode.h */ - - -/* We use the special COFF backend linker. */ -#define coff_relocate_section _bfd_coff_generic_relocate_section - - -#include "coffcode.h" - -const bfd_target -#ifdef TARGET_LITTLE_SYM -TARGET_LITTLE_SYM = -#else -armcoff_little_vec = -#endif -{ -#ifdef TARGET_LITTLE_NAME - TARGET_LITTLE_NAME, -#else - "coff-arm-little", -#endif - bfd_target_coff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ -#ifdef TARGET_UNDERSCORE - TARGET_UNDERSCORE, /* leading underscore */ -#else - 0, /* leading underscore */ -#endif - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - -/* Note that we allow an object file to be treated as a core file as well. */ - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, coff_object_p}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; - -const bfd_target -#ifdef TARGET_BIG_SYM -TARGET_BIG_SYM = -#else -armcoff_big_vec = -#endif -{ -#ifdef TARGET_BIG_NAME - TARGET_BIG_NAME, -#else - "coff-arm-big", -#endif - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ -#ifdef TARGET_UNDERSCORE - TARGET_UNDERSCORE, /* leading underscore */ -#else - 0, /* leading underscore */ -#endif - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - -/* Note that we allow an object file to be treated as a core file as well. */ - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, coff_object_p}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-aux.c b/contrib/gdb/bfd/coff-aux.c deleted file mode 100644 index 1dba9d5..0000000 --- a/contrib/gdb/bfd/coff-aux.c +++ /dev/null @@ -1,332 +0,0 @@ -/* BFD back-end for Apple M68K COFF A/UX 3.x files. - Copyright 1996 Free Software Foundation, Inc. - Portions written by Richard Henderson <rth@tamu.edu>, - COMMON symbol munging cribbed from cf-m68klynx.c which was - written by Cygnus Support. - -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. */ - -#define TARGET_SYM m68kaux_coff_vec -#define TARGET_NAME "coff-m68k-aux" - -#ifndef TARG_AUX -#define TARG_AUX -#endif - -#define COFF_LONG_FILENAMES - -/* 4k pages */ -#define COFF_PAGE_SIZE 0x1000 - -/* On AUX, a STYP_NOLOAD|STYP_BSS section is part of a shared library. */ -#define BSS_NOLOAD_IS_SHARED_LIBRARY - -#define _bfd_m68kcoff_howto_table _bfd_m68kaux_howto_table -#define _bfd_m68kcoff_rtype2howto _bfd_m68kaux_rtype2howto -#define _bfd_m68kcoff_howto2rtype _bfd_m68kaux_howto2rtype -#define _bfd_m68kcoff_reloc_type_lookup _bfd_m68kaux_reloc_type_lookup - -/* Rather than change names lots of places, reuse the same hack */ -#define LYNX_SPECIAL_FN _bfd_m68kaux_special_fn - -#include "bfd.h" -#include "sysdep.h" - -#ifdef ANSI_PROTOTYPES -struct internal_reloc; -struct coff_link_hash_entry; -struct internal_syment; -#endif - - -static bfd_reloc_status_type _bfd_m68kaux_special_fn - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static reloc_howto_type *coff_m68k_aux_rtype_to_howto - PARAMS ((bfd *, asection *, struct internal_reloc *, - struct coff_link_hash_entry *, struct internal_syment *, - bfd_vma *)); -static boolean coff_m68k_aux_link_add_one_symbol - PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, - asection *, bfd_vma, const char *, boolean, boolean, - struct bfd_link_hash_entry **)); - - -#define coff_rtype_to_howto coff_m68k_aux_rtype_to_howto -#define coff_link_add_one_symbol coff_m68k_aux_link_add_one_symbol - - -/* Compute the addend of a reloc. If the reloc is to a common symbol, - the object file contains the value of the common symbol. By the - time this is called, the linker may be using a different symbol - from a different object file with a different value. Therefore, we - hack wildly to locate the original symbol from this file so that we - can make the correct adjustment. This macro sets coffsym to the - symbol from the original file, and uses it to set the addend value - correctly. If this is not a common symbol, the usual addend - calculation is done, except that an additional tweak is needed for - PC relative relocs. - FIXME: This macro refers to symbols and asect; these are from the - calling function, not the macro arguments. */ - -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ - { \ - coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ - if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ - coffsym = (obj_symbols (abfd) \ - + (cache_ptr->sym_ptr_ptr - symbols)); \ - else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ - if (coffsym != (coff_symbol_type *) NULL \ - && coffsym->native->u.syment.n_scnum == 0) \ - cache_ptr->addend = - coffsym->native->u.syment.n_value; \ - else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ - && ptr->section != (asection *) NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ - else \ - cache_ptr->addend = 0; \ - if (ptr && (reloc.r_type == R_PCRBYTE \ - || reloc.r_type == R_PCRWORD \ - || reloc.r_type == R_PCRLONG)) \ - cache_ptr->addend += asect->vma; \ - } - - - -#include "coff/aux-coff.h" /* override coff/internal.h and coff/m68k.h */ -#include "coff-m68k.c" - - - -/* For some reason when using m68k COFF the value stored in the .text - section for a reference to a common symbol is the value itself plus - any desired offset. (taken from work done by Ian Taylor, Cygnus Support, - for I386 COFF). */ - -/* If we are producing relocateable output, we need to do some - adjustments to the object file that are not done by the - bfd_perform_relocation function. This function is called by every - reloc type to make any required adjustments. */ - -static bfd_reloc_status_type -_bfd_m68kaux_special_fn (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - symvalue diff; - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - if (bfd_is_com_section (symbol->section)) - { - /* We are relocating a common symbol. The current value in the - object file is ORIG + OFFSET, where ORIG is the value of the - common symbol as seen by the object file when it was compiled - (this may be zero if the symbol was undefined) and OFFSET is - the offset into the common symbol (normally zero, but may be - non-zero when referring to a field in a common structure). - ORIG is the negative of reloc_entry->addend, which is set by - the CALC_ADDEND macro below. We want to replace the value in - the object file with NEW + OFFSET, where NEW is the value of - the common symbol which we are going to put in the final - object file. NEW is symbol->value. */ - diff = symbol->value + reloc_entry->addend; - } - else - { - /* For some reason bfd_perform_relocation always effectively - ignores the addend for a COFF target when producing - relocateable output. This seems to be always wrong for 386 - COFF, so we handle the addend here instead. */ - diff = reloc_entry->addend; - } - -#define DOIT(x) \ - x = ((x & ~howto->dst_mask) | \ - (((x & howto->src_mask) + diff) & howto->dst_mask)) - - if (diff != 0) - { - reloc_howto_type *howto = reloc_entry->howto; - unsigned char *addr = (unsigned char *) data + reloc_entry->address; - - switch (howto->size) - { - case 0: - { - char x = bfd_get_8 (abfd, addr); - DOIT (x); - bfd_put_8 (abfd, x, addr); - } - break; - - case 1: - { - short x = bfd_get_16 (abfd, addr); - DOIT (x); - bfd_put_16 (abfd, x, addr); - } - break; - - case 2: - { - long x = bfd_get_32 (abfd, addr); - DOIT (x); - bfd_put_32 (abfd, x, addr); - } - break; - - default: - abort (); - } - } - - /* Now let bfd_perform_relocation finish everything up. */ - return bfd_reloc_continue; -} - - -/* coff-m68k.c uses the special COFF backend linker. We need to - adjust common symbols. */ - -/*ARGSUSED*/ -static reloc_howto_type * -coff_m68k_aux_rtype_to_howto (abfd, sec, rel, h, sym, addendp) - bfd *abfd; - asection *sec; - struct internal_reloc *rel; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma *addendp; -{ - arelent relent; - reloc_howto_type *howto; - - RTYPE2HOWTO (&relent, rel); - - howto = relent.howto; - - if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) - { - /* This is a common symbol. The section contents include the - size (sym->n_value) as an addend. The relocate_section - function will be adding in the final value of the symbol. We - need to subtract out the current size in order to get the - correct result. */ - BFD_ASSERT (h != NULL); - *addendp -= sym->n_value; - } - - /* If the output symbol is common (in which case this must be a - relocateable link), we need to add in the final size of the - common symbol. */ - if (h != NULL && h->root.type == bfd_link_hash_common) - *addendp += h->root.u.c.size; - - return howto; -} - - -/* We need non-absolute symbols to override absolute symbols. This - mirrors Apple's "solution" to let a static library symbol override - a shared library symbol. On the whole not a good thing, given how - shared libraries work here, but can work if you are careful with - what you include in the shared object. */ - -boolean -coff_m68k_aux_link_add_one_symbol (info, abfd, name, flags, section, value, - string, copy, collect, hashp) - struct bfd_link_info *info; - bfd *abfd; - const char *name; - flagword flags; - asection *section; - bfd_vma value; - const char *string; - boolean copy; - boolean collect; - struct bfd_link_hash_entry **hashp; -{ - struct bfd_link_hash_entry *h; - - if ((flags & (BSF_WARNING | BSF_CONSTRUCTOR | BSF_WEAK)) == 0 && - !bfd_is_und_section (section) && - !bfd_is_com_section (section)) - { - /* The new symbol is a definition or an indirect definition */ - - /* This bit copied from linker.c */ - if (hashp != NULL && *hashp != NULL) - { - h = *hashp; - BFD_ASSERT (strcmp (h->root.string, name) == 0); - } - else - { - h = bfd_link_hash_lookup (info->hash, name, true, copy, false); - if (h == NULL) - { - if (hashp != NULL) - *hashp = NULL; - return false; - } - } - - if (info->notice_hash != (struct bfd_hash_table *) NULL - && (bfd_hash_lookup (info->notice_hash, name, false, false) - != (struct bfd_hash_entry *) NULL)) - { - if (! (*info->callbacks->notice) (info, name, abfd, section, value)) - return false; - } - - if (hashp != (struct bfd_link_hash_entry **) NULL) - *hashp = h; - /* end duplication from linker.c */ - - if (h->type == bfd_link_hash_defined - || h->type == bfd_link_hash_indirect) - { - asection *msec; - - if (h->type == bfd_link_hash_defined) - msec = h->u.def.section; - else - msec = bfd_ind_section_ptr; - - if (bfd_is_abs_section (msec) && !bfd_is_abs_section (section)) - { - h->u.def.section = section; - h->u.def.value = value; - return true; - } - else if (bfd_is_abs_section (section) && !bfd_is_abs_section (msec)) - return true; - } - } - - /* If we didn't exit early, finish processing in the generic routine */ - return _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, - value, string, copy, collect, - hashp); -} diff --git a/contrib/gdb/bfd/coff-go32.c b/contrib/gdb/bfd/coff-go32.c deleted file mode 100644 index be4adb2..0000000 --- a/contrib/gdb/bfd/coff-go32.c +++ /dev/null @@ -1,25 +0,0 @@ -/* BFD back-end for Intel 386 COFF files (go32 variant). - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by DJ Delorie. - -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. */ - -#define TARGET_SYM go32coff_vec -#define TARGET_NAME "coff-go32" -#define TARGET_UNDERSCORE '_' - -#include "coff-i386.c" diff --git a/contrib/gdb/bfd/coff-h8300.c b/contrib/gdb/bfd/coff-h8300.c deleted file mode 100644 index 48d0d5a..0000000 --- a/contrib/gdb/bfd/coff-h8300.c +++ /dev/null @@ -1,650 +0,0 @@ -/* BFD back-end for Hitachi H8/300 COFF binaries. - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. - Written by Steve Chamberlain, <sac@cygnus.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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "obstack.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "genlink.h" -#include "coff/h8300.h" -#include "coff/internal.h" -#include "libcoff.h" - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1) - - -/* special handling for H8/300 relocs. - We only come here for pcrel stuff and return normally if not an -r link. - When doing -r, we can't do any arithmetic for the pcrel stuff, because - the code in reloc.c assumes that we can manipulate the targets of - the pcrel branches. This isn't so, since the H8/300 can do relaxing, - which means that the gap after the instruction may not be enough to - contain the offset required for the branch, so we have to use the only - the addend until the final link */ - -static bfd_reloc_status_type -special (abfd, reloc_entry, symbol, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - return bfd_reloc_ok; -} - -static reloc_howto_type howto_table[] = -{ - HOWTO (R_RELBYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "8", false, 0x000000ff, 0x000000ff, false), - HOWTO (R_RELWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "16", false, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_RELLONG, 0, 2, 32, false, 0, complain_overflow_bitfield, special, "32", false, 0xffffffff, 0xffffffff, false), - HOWTO (R_PCRBYTE, 0, 0, 8, true, 0, complain_overflow_signed, special, "DISP8", false, 0x000000ff, 0x000000ff, true), - HOWTO (R_PCRWORD, 0, 1, 16, true, 0, complain_overflow_signed, special, "DISP16", false, 0x0000ffff, 0x0000ffff, true), - HOWTO (R_PCRLONG, 0, 2, 32, true, 0, complain_overflow_signed, special, "DISP32", false, 0xffffffff, 0xffffffff, true), - HOWTO (R_MOVB1, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "16/8", false, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_MOVB2, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "8/16", false, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_JMP1, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "16/pcrel", false, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_JMP2, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "pcrecl/16", false, 0x000000ff, 0x000000ff, false), - - - HOWTO (R_JMPL1, 0, 2, 32, false, 0, complain_overflow_bitfield, special, "24/pcrell", false, 0x00ffffff, 0x00ffffff, false), - HOWTO (R_JMPL_B8, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "pc8/24", false, 0x000000ff, 0x000000ff, false), - - HOWTO (R_MOVLB1, 0, 1, 16, false, 0, complain_overflow_bitfield,special, "24/8", false, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_MOVLB2, 0, 1, 16, false, 0, complain_overflow_bitfield, special, "8/24", false, 0x0000ffff, 0x0000ffff, false), - - /* An indirect reference to a function. This causes the function's address - to be added to the function vector in lo-mem and puts the address of - the function vector's entry in the jsr instruction. */ - HOWTO (R_MEM_INDIRECT, 0, 0, 8, false, 0, complain_overflow_bitfield, special, "8/indirect", false, 0x000000ff, 0x000000ff, false), - -}; - - -/* Turn a howto into a reloc number */ - -#define SELECT_RELOC(x,howto) \ - { x.r_type = select_reloc(howto); } - -#define BADMAG(x) (H8300BADMAG(x)&& H8300HBADMAG(x)) -#define H8300 1 /* Customize coffcode.h */ -#define __A_MAGIC_SET__ - - - -/* Code to swap in the reloc */ -#define SWAP_IN_RELOC_OFFSET bfd_h_get_32 -#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32 -#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \ - dst->r_stuff[0] = 'S'; \ - dst->r_stuff[1] = 'C'; - - -static int -select_reloc (howto) - reloc_howto_type *howto; -{ - return howto->type; -} - -/* Code to turn a r_type into a howto ptr, uses the above howto table - */ - -static void -rtype2howto (internal, dst) - arelent *internal; - struct internal_reloc *dst; -{ - switch (dst->r_type) - { - case R_RELBYTE: - internal->howto = howto_table + 0; - break; - case R_RELWORD: - internal->howto = howto_table + 1; - break; - case R_RELLONG: - internal->howto = howto_table + 2; - break; - case R_PCRBYTE: - internal->howto = howto_table + 3; - break; - case R_PCRWORD: - internal->howto = howto_table + 4; - break; - case R_PCRLONG: - internal->howto = howto_table + 5; - break; - case R_MOVB1: - internal->howto = howto_table + 6; - break; - case R_MOVB2: - internal->howto = howto_table + 7; - break; - case R_JMP1: - internal->howto = howto_table + 8; - break; - case R_JMP2: - internal->howto = howto_table + 9; - break; - case R_JMPL1: - internal->howto = howto_table + 10; - break; - case R_JMPL_B8: - internal->howto = howto_table + 11; - break; - case R_MOVLB1: - internal->howto = howto_table + 12; - break; - case R_MOVLB2: - internal->howto = howto_table + 13; - break; - case R_MEM_INDIRECT: - internal->howto = howto_table + 14; - break; - default: - abort (); - break; - } -} - -#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry) - - -/* Perform any necessaru magic to the addend in a reloc entry */ - - -#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \ - cache_ptr->addend = ext_reloc.r_offset; - - -#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \ - reloc_processing(relent, reloc, symbols, abfd, section) - -static void -reloc_processing (relent, reloc, symbols, abfd, section) - arelent * relent; - struct internal_reloc *reloc; - asymbol ** symbols; - bfd * abfd; - asection * section; -{ - relent->address = reloc->r_vaddr; - rtype2howto (relent, reloc); - - if (((int) reloc->r_symndx) > 0) - { - relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; - } - else - { - relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - } - - - - relent->addend = reloc->r_offset; - - relent->address -= section->vma; - /* relent->section = 0;*/ -} - - -static int -h8300_reloc16_estimate(abfd, input_section, reloc, shrink, link_info) - bfd *abfd; - asection *input_section; - arelent *reloc; - unsigned int shrink; - struct bfd_link_info *link_info; -{ - bfd_vma value; - bfd_vma dot; - bfd_vma gap; - - /* The address of the thing to be relocated will have moved back by - the size of the shrink - but we don't change reloc->address here, - since we need it to know where the relocation lives in the source - uncooked section */ - - /* reloc->address -= shrink; conceptual */ - - bfd_vma address = reloc->address - shrink; - - - switch (reloc->howto->type) - { - case R_MOVB2: - case R_JMP2: - shrink+=2; - break; - - /* Thing is a move one byte */ - case R_MOVB1: - value = bfd_coff_reloc16_get_value(reloc, link_info, input_section); - - if (value >= 0xff00) - { - - /* Change the reloc type from 16bit, possible 8 to 8bit - possible 16 */ - reloc->howto = reloc->howto + 1; - /* The place to relc moves back by one */ - /* This will be two bytes smaller in the long run */ - shrink +=2 ; - bfd_perform_slip(abfd, 2, input_section, address); - } - - break; - /* This is the 24 bit branch which could become an 8 bitter, - the relocation points to the first byte of the insn, not the - actual data */ - - case R_JMPL1: - value = bfd_coff_reloc16_get_value(reloc, link_info, input_section); - - dot = input_section->output_section->vma + - input_section->output_offset + address; - - /* See if the address we're looking at within 127 bytes of where - we are, if so then we can use a small branch rather than the - jump we were going to */ - - gap = value - dot ; - - if (-120 < (long)gap && (long)gap < 120 ) - { - - /* Change the reloc type from 24bit, possible 8 to 8bit - possible 32 */ - reloc->howto = reloc->howto + 1; - /* This will be two bytes smaller in the long run */ - shrink +=2 ; - bfd_perform_slip(abfd, 2, input_section, address); - } - break; - - case R_JMP1: - - value = bfd_coff_reloc16_get_value(reloc, link_info, input_section); - - dot = input_section->output_section->vma + - input_section->output_offset + address; - - /* See if the address we're looking at within 127 bytes of where - we are, if so then we can use a small branch rather than the - jump we were going to */ - - gap = value - (dot - shrink); - - - if (-120 < (long)gap && (long)gap < 120 ) - { - - /* Change the reloc type from 16bit, possible 8 to 8bit - possible 16 */ - reloc->howto = reloc->howto + 1; - /* The place to relc moves back by one */ - - /* This will be two bytes smaller in the long run */ - shrink +=2 ; - bfd_perform_slip(abfd, 2, input_section, address); - } - break; - } - - - return shrink; -} - - -/* First phase of a relaxing link */ - -/* Reloc types - large small - R_MOVB1 R_MOVB2 mov.b with 16bit or 8 bit address - R_JMP1 R_JMP2 jmp or pcrel branch - R_JMPL1 R_JMPL_B8 24jmp or pcrel branch - R_MOVLB1 R_MOVLB2 24 or 8 bit reloc for mov.b - -*/ - -static void -h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr, - dst_ptr) - bfd *abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - arelent *reloc; - bfd_byte *data; - unsigned int *src_ptr; - unsigned int *dst_ptr; -{ - unsigned int src_address = *src_ptr; - unsigned int dst_address = *dst_ptr; - asection *input_section = link_order->u.indirect.section; - - switch (reloc->howto->type) - { - /* A 24 bit branch which could be a 8 bit pcrel, really pointing to - the byte before the 24bit hole, so we can treat it as a 32bit pointer */ - case R_PCRBYTE: - { - bfd_vma dot = link_order->offset - + dst_address - + link_order->u.indirect.section->output_section->vma; - int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section) - - dot); - if (gap > 127 || gap < -128) - { - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), - reloc->howto->name, reloc->addend, input_section->owner, - input_section, reloc->address))) - abort (); - } - gap &= ~1; - bfd_put_8 (abfd, gap, data + dst_address); - dst_address++; - src_address++; - - break; - } - case R_PCRWORD: - { - bfd_vma dot = link_order->offset - + dst_address - + link_order->u.indirect.section->output_section->vma; - int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section) - - dot) - 1; - if (gap > 32767 || gap < -32768) - { - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), - reloc->howto->name, reloc->addend, input_section->owner, - input_section, reloc->address))) - abort (); - } - - bfd_put_16 (abfd, gap, data + dst_address); - dst_address+=2; - src_address+=2; - - break; - } - - case R_MEM_INDIRECT: /* Temporary */ - case R_RELBYTE: - { - unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - if (gap < 0xff - || (gap >= 0x0000ff00 - && gap <= 0x0000ffff) - || ( gap >= 0x00ffff00 - && gap <= 0x00ffffff) - || ( gap >= 0xffffff00 - && gap <= 0xffffffff)) - { - bfd_put_8 (abfd, gap, data + dst_address); - dst_address += 1; - src_address += 1; - } - else - { - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), - reloc->howto->name, reloc->addend, input_section->owner, - input_section, reloc->address))) - abort (); - } - } - break; - case R_JMP1: - /* A relword which would have like to have been a pcrel */ - case R_MOVB1: - /* A relword which would like to have been modified but - didn't make it */ - case R_RELWORD: - bfd_put_16 (abfd, - bfd_coff_reloc16_get_value (reloc, link_info, input_section), - data + dst_address); - dst_address += 2; - src_address += 2; - break; - case R_RELLONG: - bfd_put_32 (abfd, - bfd_coff_reloc16_get_value (reloc, link_info, input_section), - data + dst_address); - dst_address += 4; - src_address += 4; - break; - - case R_MOVB2: - /* Special relaxed type, there will be a gap between where we - get stuff from and where we put stuff to now - - for a mov.b @aa:16 -> mov.b @aa:8 - opcode 0x6a 0x0y offset - -> 0x2y off - */ - if (data[dst_address - 1] != 0x6a) - abort (); - switch (data[src_address] & 0xf0) - { - case 0x00: - /* Src is memory */ - data[dst_address - 1] = (data[src_address] & 0xf) | 0x20; - break; - case 0x80: - /* Src is reg */ - data[dst_address - 1] = (data[src_address] & 0xf) | 0x30; - break; - default: - abort (); - } - - /* the offset must fit ! after all, what was all the relaxing - about ? */ - - bfd_put_8 (abfd, - bfd_coff_reloc16_get_value (reloc, link_info, input_section), - data + dst_address); - - /* Note the magic - src goes up by two bytes, but dst by only - one */ - dst_address += 1; - src_address += 3; - - break; - - case R_JMP2: - - /* Speciial relaxed type */ - { - bfd_vma dot = link_order->offset - + dst_address - + link_order->u.indirect.section->output_section->vma; - - int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section) - - dot - 1); - - if ((gap & ~0xff) != 0 && ((gap & 0xff00) != 0xff00)) - abort (); - - bfd_put_8 (abfd, gap, data + dst_address); - - switch (data[dst_address - 1]) - { - case 0x5e: - /* jsr -> bsr */ - bfd_put_8 (abfd, 0x55, data + dst_address - 1); - break; - case 0x5a: - /* jmp ->bra */ - bfd_put_8 (abfd, 0x40, data + dst_address - 1); - break; - - default: - abort (); - } - dst_address++; - src_address += 3; - - break; - } - break; - - case R_JMPL_B8: /* 24 bit branch which is now 8 bits */ - - /* Speciial relaxed type */ - { - bfd_vma dot = link_order->offset - + dst_address - + link_order->u.indirect.section->output_section->vma; - - int gap = (bfd_coff_reloc16_get_value (reloc, link_info, input_section) - - dot - 2); - - if ((gap & ~0xff) != 0 && ((gap & 0xff00) != 0xff00)) - abort (); - - switch (data[src_address]) - { - case 0x5e: - /* jsr -> bsr */ - bfd_put_8 (abfd, 0x55, data + dst_address); - break; - case 0x5a: - /* jmp ->bra */ - bfd_put_8 (abfd, 0x40, data + dst_address); - break; - - default: - bfd_put_8 (abfd, 0xde, data + dst_address); - break; - } - - bfd_put_8 (abfd, gap, data + dst_address + 1); - dst_address += 2; - src_address += 4; - - break; - } - - case R_JMPL1: - { - int v = bfd_coff_reloc16_get_value (reloc, link_info, input_section); - int o = bfd_get_32 (abfd, data + src_address); - v = (v & 0x00ffffff) | (o & 0xff000000); - bfd_put_32 (abfd, v, data + dst_address); - dst_address += 4; - src_address += 4; - } - - break; - - - /* A 24 bit mov which could be an 8 bit move, really pointing to - the byte before the 24bit hole, so we can treat it as a 32bit pointer */ - case R_MOVLB1: - { - int v = bfd_coff_reloc16_get_value (reloc, link_info, input_section); - int o = bfd_get_32 (abfd, data + dst_address); - v = (v & 0x00ffffff) | (o & 0xff000000); - bfd_put_32 (abfd, v, data + dst_address); - dst_address += 4; - src_address += 4; - } - - break; - default: - - abort (); - break; - - } - *src_ptr = src_address; - *dst_ptr = dst_address; - -} - -#define coff_reloc16_extra_cases h8300_reloc16_extra_cases -#define coff_reloc16_estimate h8300_reloc16_estimate - -#define COFF_LONG_FILENAMES -#include "coffcode.h" - - -#undef coff_bfd_get_relocated_section_contents -#undef coff_bfd_relax_section -#define coff_bfd_get_relocated_section_contents \ - bfd_coff_reloc16_get_relocated_section_contents -#define coff_bfd_relax_section bfd_coff_reloc16_relax_section - - - -const bfd_target h8300coff_vec = -{ - "coff-h8300", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* leading char */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-h8500.c b/contrib/gdb/bfd/coff-h8500.c deleted file mode 100644 index f416f8f..0000000 --- a/contrib/gdb/bfd/coff-h8500.c +++ /dev/null @@ -1,355 +0,0 @@ -/* BFD back-end for Hitachi H8/500 COFF binaries. - Copyright 1993, 1994 Free Software Foundation, Inc. - Contributed by Cygnus Support. - Written by Steve Chamberlain, <sac@cygnus.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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "obstack.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "coff/h8500.h" -#include "coff/internal.h" -#include "libcoff.h" - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1) - -static reloc_howto_type r_imm8 = -HOWTO (R_H8500_IMM8, 0, 1, 8, false, 0, - complain_overflow_bitfield, 0, "r_imm8", true, 0x000000ff, 0x000000ff, false); - -static reloc_howto_type r_imm16 = -HOWTO (R_H8500_IMM16, 0, 1, 16, false, 0, - complain_overflow_bitfield, 0, "r_imm16", true, 0x0000ffff, 0x0000ffff, false); - -static reloc_howto_type r_imm24 = -HOWTO (R_H8500_IMM24, 0, 1, 24, false, 0, - complain_overflow_bitfield, 0, "r_imm24", true, 0x00ffffff, 0x00ffffff, false); - -static reloc_howto_type r_imm32 = -HOWTO (R_H8500_IMM32, 0, 1, 32, false, 0, - complain_overflow_bitfield, 0, "r_imm32", true, 0xffffffff, 0xffffffff, false); - - -static reloc_howto_type r_high8 = -HOWTO (R_H8500_HIGH8, 0, 1, 8, false, 0, - complain_overflow_dont, 0, "r_high8", true, 0x000000ff, 0x000000ff, false); - -static reloc_howto_type r_low16 = -HOWTO (R_H8500_LOW16, 0, 1, 16, false, 0, - complain_overflow_dont, 0, "r_low16", true, 0x0000ffff, 0x0000ffff, false); - -static reloc_howto_type r_pcrel8 = -HOWTO (R_H8500_PCREL8, 0, 1, 8, true, 0, complain_overflow_signed, 0, "r_pcrel8", true, 0, 0, true); - - -static reloc_howto_type r_pcrel16 = -HOWTO (R_H8500_PCREL16, 0, 1, 16, true, 0, complain_overflow_signed, 0, "r_pcrel16", true, 0, 0, true); - -static reloc_howto_type r_high16 = -HOWTO (R_H8500_HIGH16, 0, 1, 8, false, 0, - complain_overflow_dont, 0, "r_high16", true, 0x000ffff, 0x0000ffff, false); - - -/* Turn a howto into a reloc number */ - -static int -coff_h8500_select_reloc (howto) - reloc_howto_type *howto; -{ - return howto->type; -} - -#define SELECT_RELOC(x,howto) x.r_type = coff_h8500_select_reloc(howto) - - -#define BADMAG(x) H8500BADMAG(x) -#define H8500 1 /* Customize coffcode.h */ - -#define __A_MAGIC_SET__ - -/* Code to swap in the reloc */ -#define SWAP_IN_RELOC_OFFSET bfd_h_get_32 -#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32 -#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \ - dst->r_stuff[0] = 'S'; \ - dst->r_stuff[1] = 'C'; - -/* Code to turn a r_type into a howto ptr, uses the above howto table - */ - -static void -rtype2howto(internal, dst) - arelent * internal; - struct internal_reloc *dst; -{ - switch (dst->r_type) - { - default: - abort (); - break; - case R_H8500_IMM8: - internal->howto = &r_imm8; - break; - case R_H8500_IMM16: - internal->howto = &r_imm16; - break; - case R_H8500_IMM24: - internal->howto = &r_imm24; - break; - case R_H8500_IMM32: - internal->howto = &r_imm32; - break; - case R_H8500_PCREL8: - internal->howto = &r_pcrel8; - break; - case R_H8500_PCREL16: - internal->howto = &r_pcrel16; - break; - case R_H8500_HIGH8: - internal->howto = &r_high8; - break; - case R_H8500_HIGH16: - internal->howto = &r_high16; - break; - case R_H8500_LOW16: - internal->howto = &r_low16; - break; - } -} - -#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry) - - -/* Perform any necessaru magic to the addend in a reloc entry */ - - -#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \ - cache_ptr->addend = ext_reloc.r_offset; - - -#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \ - reloc_processing(relent, reloc, symbols, abfd, section) - -static void reloc_processing (relent, reloc, symbols, abfd, section) - arelent * relent; - struct internal_reloc *reloc; - asymbol ** symbols; - bfd * abfd; - asection * section; -{ - relent->address = reloc->r_vaddr; - rtype2howto (relent, reloc); - - if (reloc->r_symndx > 0) - { - relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; - } - else - { - relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - } - - - relent->addend = reloc->r_offset; - relent->address -= section->vma; -} - -static void -extra_case (in_abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr) - bfd *in_abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - arelent *reloc; - bfd_byte *data; - unsigned int *src_ptr; - unsigned int *dst_ptr; -{ - bfd_byte *d = data+*dst_ptr; - asection *input_section = link_order->u.indirect.section; - switch (reloc->howto->type) - { - case R_H8500_IMM8: - bfd_put_8 (in_abfd, - bfd_coff_reloc16_get_value (reloc, link_info, input_section), - d); - (*dst_ptr) += 1; - (*src_ptr) += 1; - break; - - case R_H8500_HIGH8: - bfd_put_8 (in_abfd, - (bfd_coff_reloc16_get_value (reloc, link_info, input_section) - >> 16), - d ); - (*dst_ptr) += 1; - (*src_ptr) += 1; - break; - - case R_H8500_IMM16: - bfd_put_16 (in_abfd, - bfd_coff_reloc16_get_value (reloc, link_info, input_section), - d ); - (*dst_ptr) += 2; - (*src_ptr) += 2; - break; - - case R_H8500_LOW16: - bfd_put_16 (in_abfd, - bfd_coff_reloc16_get_value (reloc, link_info, input_section), - d); - - (*dst_ptr) += 2; - (*src_ptr) += 2; - break; - - case R_H8500_HIGH16: - bfd_put_16 (in_abfd, - (bfd_coff_reloc16_get_value (reloc, link_info, input_section) - >>16), - d); - - (*dst_ptr) += 2; - (*src_ptr) += 2; - break; - - case R_H8500_IMM24: - { - int v = bfd_coff_reloc16_get_value(reloc, link_info, input_section); - int o = bfd_get_32(in_abfd, data+ *dst_ptr -1); - v = (v & 0x00ffffff) | (o & 0xff00000); - bfd_put_32 (in_abfd, v, data + *dst_ptr -1); - (*dst_ptr) +=3; - (*src_ptr)+=3;; - } - break; - case R_H8500_IMM32: - { - int v = bfd_coff_reloc16_get_value(reloc, link_info, input_section); - bfd_put_32 (in_abfd, v, data + *dst_ptr); - (*dst_ptr) +=4; - (*src_ptr)+=4;; - } - break; - - - case R_H8500_PCREL8: - { - bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - bfd_vma dot = link_order->offset - + *dst_ptr - + link_order->u.indirect.section->output_section->vma; - int gap = dst - dot - 1; /* -1 since were in the odd byte of the - word and the pc's been incremented */ - - if (gap > 128 || gap < -128) - { - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), - reloc->howto->name, reloc->addend, input_section->owner, - input_section, reloc->address))) - abort (); - } - bfd_put_8 (in_abfd, gap, data + *dst_ptr); - (*dst_ptr)++; - (*src_ptr)++; - break; - } - case R_H8500_PCREL16: - { - bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - bfd_vma dot = link_order->offset - + *dst_ptr - + link_order->u.indirect.section->output_section->vma; - int gap = dst - dot - 1; /* -1 since were in the odd byte of the - word and the pc's been incremented */ - - if (gap > 32767 || gap < -32768) - { - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), - reloc->howto->name, reloc->addend, input_section->owner, - input_section, reloc->address))) - abort (); - } - bfd_put_16 (in_abfd, gap, data + *dst_ptr); - (*dst_ptr)+=2; - (*src_ptr)+=2; - break; - } - - default: - abort (); - } -} - -#define coff_reloc16_extra_cases extra_case - -#include "coffcode.h" - - -#undef coff_bfd_get_relocated_section_contents -#undef coff_bfd_relax_section -#define coff_bfd_get_relocated_section_contents \ - bfd_coff_reloc16_get_relocated_section_contents -#define coff_bfd_relax_section bfd_coff_reloc16_relax_section - -const bfd_target h8500coff_vec = -{ - "coff-h8500", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* leading symbol underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-i860.c b/contrib/gdb/bfd/coff-i860.c deleted file mode 100644 index 9605cdf..0000000 --- a/contrib/gdb/bfd/coff-i860.c +++ /dev/null @@ -1,423 +0,0 @@ -/* BFD back-end for Intel 860 COFF files. - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. - Created mostly by substituting "860" for "386" in coff-i386.c - Harry Dolan <dolan@ssd.intel.com>, October 1995 - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" - -#include "coff/i860.h" - -#include "coff/internal.h" - -#include "libcoff.h" - -static bfd_reloc_status_type coff_i860_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static reloc_howto_type *coff_i860_rtype_to_howto - PARAMS ((bfd *, asection *, struct internal_reloc *, - struct coff_link_hash_entry *, struct internal_syment *, - bfd_vma *)); - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) -/* The page size is a guess based on ELF. */ - -#define COFF_PAGE_SIZE 0x1000 - -/* For some reason when using i860 COFF the value stored in the .text - section for a reference to a common symbol is the value itself plus - any desired offset. Ian Taylor, Cygnus Support. */ - -/* If we are producing relocateable output, we need to do some - adjustments to the object file that are not done by the - bfd_perform_relocation function. This function is called by every - reloc type to make any required adjustments. */ - -static bfd_reloc_status_type -coff_i860_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - symvalue diff; - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - - if (bfd_is_com_section (symbol->section)) - { - /* We are relocating a common symbol. The current value in the - object file is ORIG + OFFSET, where ORIG is the value of the - common symbol as seen by the object file when it was compiled - (this may be zero if the symbol was undefined) and OFFSET is - the offset into the common symbol (normally zero, but may be - non-zero when referring to a field in a common structure). - ORIG is the negative of reloc_entry->addend, which is set by - the CALC_ADDEND macro below. We want to replace the value in - the object file with NEW + OFFSET, where NEW is the value of - the common symbol which we are going to put in the final - object file. NEW is symbol->value. */ - diff = symbol->value + reloc_entry->addend; - } - else - { - /* For some reason bfd_perform_relocation always effectively - ignores the addend for a COFF target when producing - relocateable output. This seems to be always wrong for 860 - COFF, so we handle the addend here instead. */ - diff = reloc_entry->addend; - } - - -#define DOIT(x) \ - x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) - - if (diff != 0) - { - reloc_howto_type *howto = reloc_entry->howto; - unsigned char *addr = (unsigned char *) data + reloc_entry->address; - - switch (howto->size) - { - case 0: - { - char x = bfd_get_8 (abfd, addr); - DOIT (x); - bfd_put_8 (abfd, x, addr); - } - break; - - case 1: - { - short x = bfd_get_16 (abfd, addr); - DOIT (x); - bfd_put_16 (abfd, x, addr); - } - break; - - case 2: - { - long x = bfd_get_32 (abfd, addr); - DOIT (x); - bfd_put_32 (abfd, x, addr); - } - break; - - default: - abort (); - } - } - - /* Now let bfd_perform_relocation finish everything up. */ - return bfd_reloc_continue; -} - -#ifndef PCRELOFFSET -#define PCRELOFFSET false -#endif - -static reloc_howto_type howto_table[] = -{ - {0}, - {1}, - {2}, - {3}, - {4}, - {5}, - HOWTO (R_DIR32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i860_reloc, /* special_function */ - "dir32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - true), /* pcrel_offset */ - /* {7}, */ - HOWTO (R_IMAGEBASE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i860_reloc, /* special_function */ - "rva32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - {010}, - {011}, - {012}, - {013}, - {014}, - {015}, - {016}, - HOWTO (R_RELBYTE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i860_reloc, /* special_function */ - "8", /* name */ - true, /* partial_inplace */ - 0x000000ff, /* src_mask */ - 0x000000ff, /* dst_mask */ - PCRELOFFSET), /* pcrel_offset */ - HOWTO (R_RELWORD, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i860_reloc, /* special_function */ - "16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - PCRELOFFSET), /* pcrel_offset */ - HOWTO (R_RELLONG, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i860_reloc, /* special_function */ - "32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - PCRELOFFSET), /* pcrel_offset */ - HOWTO (R_PCRBYTE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - coff_i860_reloc, /* special_function */ - "DISP8", /* name */ - true, /* partial_inplace */ - 0x000000ff, /* src_mask */ - 0x000000ff, /* dst_mask */ - PCRELOFFSET), /* pcrel_offset */ - HOWTO (R_PCRWORD, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - coff_i860_reloc, /* special_function */ - "DISP16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - PCRELOFFSET), /* pcrel_offset */ - HOWTO (R_PCRLONG, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - coff_i860_reloc, /* special_function */ - "DISP32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - PCRELOFFSET) /* pcrel_offset */ -}; - -/* Turn a howto into a reloc nunmber */ - -#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } -#define BADMAG(x) I860BADMAG(x) -#define I860 1 /* Customize coffcode.h */ - -#define RTYPE2HOWTO(cache_ptr, dst) \ - (cache_ptr)->howto = howto_table + (dst)->r_type; - -/* For 860 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared - library. On some other COFF targets STYP_BSS is normally - STYP_NOLOAD. */ -#define BSS_NOLOAD_IS_SHARED_LIBRARY - -/* Compute the addend of a reloc. If the reloc is to a common symbol, - the object file contains the value of the common symbol. By the - time this is called, the linker may be using a different symbol - from a different object file with a different value. Therefore, we - hack wildly to locate the original symbol from this file so that we - can make the correct adjustment. This macro sets coffsym to the - symbol from the original file, and uses it to set the addend value - correctly. If this is not a common symbol, the usual addend - calculation is done, except that an additional tweak is needed for - PC relative relocs. - FIXME: This macro refers to symbols and asect; these are from the - calling function, not the macro arguments. */ - -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ - { \ - coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ - if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ - coffsym = (obj_symbols (abfd) \ - + (cache_ptr->sym_ptr_ptr - symbols)); \ - else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ - if (coffsym != (coff_symbol_type *) NULL \ - && coffsym->native->u.syment.n_scnum == 0) \ - cache_ptr->addend = - coffsym->native->u.syment.n_value; \ - else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ - && ptr->section != (asection *) NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ - else \ - cache_ptr->addend = 0; \ - if (ptr && howto_table[reloc.r_type].pc_relative) \ - cache_ptr->addend += asect->vma; \ - } - -/* We use the special COFF backend linker. */ -#define coff_relocate_section _bfd_coff_generic_relocate_section - -static reloc_howto_type * -coff_i860_rtype_to_howto (abfd, sec, rel, h, sym, addendp) - bfd *abfd; - asection *sec; - struct internal_reloc *rel; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma *addendp; -{ - - reloc_howto_type *howto; - - howto = howto_table + rel->r_type; - - if (howto->pc_relative) - *addendp += sec->vma; - - if (sym != NULL && sym->n_scnum == 0 && sym->n_value != 0) - { - /* This is a common symbol. The section contents include the - size (sym->n_value) as an addend. The relocate_section - function will be adding in the final value of the symbol. We - need to subtract out the current size in order to get the - correct result. */ - - BFD_ASSERT (h != NULL); - - - /* I think we *do* want to bypass this. If we don't, I have seen some data - parameters get the wrong relcation address. If I link two versions - with and without this section bypassed and then do a binary comparison, - the addresses which are different can be looked up in the map. The - case in which this section has been bypassed has addresses which correspond - to values I can find in the map */ - *addendp -= sym->n_value; - } - - /* If the output symbol is common (in which case this must be a - relocateable link), we need to add in the final size of the - common symbol. */ - if (h != NULL && h->root.type == bfd_link_hash_common) - *addendp += h->root.u.c.size; - - return howto; -} - -#define coff_rtype_to_howto coff_i860_rtype_to_howto - -#include "coffcode.h" - -static const bfd_target * -i3coff_object_p(a) - bfd *a; -{ - return coff_object_p(a); -} - -const bfd_target -#ifdef TARGET_SYM - TARGET_SYM = -#else - i860coff_vec = -#endif -{ -#ifdef TARGET_NAME - TARGET_NAME, -#else - "coff-i860", /* name */ -#endif - bfd_target_coff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* leading underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - -/* Note that we allow an object file to be treated as a core file as well. */ - {_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, i3coff_object_p}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-i960.c b/contrib/gdb/bfd/coff-i960.c deleted file mode 100644 index ed30125..0000000 --- a/contrib/gdb/bfd/coff-i960.c +++ /dev/null @@ -1,683 +0,0 @@ -/* BFD back-end for Intel 960 COFF files. - Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - -#define I960 1 -#define BADMAG(x) I960BADMAG(x) - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/i960.h" -#include "coff/internal.h" -#include "libcoff.h" /* to allow easier abstraction-breaking */ - -static bfd_reloc_status_type optcall_callback - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_reloc_status_type coff_i960_relocate - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static reloc_howto_type *coff_i960_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static boolean coff_i960_start_final_link - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean coff_i960_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - struct internal_reloc *, struct internal_syment *, asection **)); -static boolean coff_i960_adjust_symndx - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, - struct internal_reloc *, boolean *)); - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3) - -/* The i960 does not support an MMU, so COFF_PAGE_SIZE can be - arbitrarily small. */ -#define COFF_PAGE_SIZE 1 - -#define COFF_LONG_FILENAMES - -/* This is just like the usual CALC_ADDEND, but it includes the - section VMA for PC relative relocs. */ -#ifndef CALC_ADDEND -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ - { \ - coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ - if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ - coffsym = (obj_symbols (abfd) \ - + (cache_ptr->sym_ptr_ptr - symbols)); \ - else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ - if (coffsym != (coff_symbol_type *) NULL \ - && coffsym->native->u.syment.n_scnum == 0) \ - cache_ptr->addend = 0; \ - else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ - && ptr->section != (asection *) NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ - else \ - cache_ptr->addend = 0; \ - if (ptr && (reloc.r_type == 25 || reloc.r_type == 27)) \ - cache_ptr->addend += asect->vma; \ - } -#endif - -#define CALLS 0x66003800 /* Template for 'calls' instruction */ -#define BAL 0x0b000000 /* Template for 'bal' instruction */ -#define BAL_MASK 0x00ffffff - -static bfd_reloc_status_type -optcall_callback (abfd, reloc_entry, symbol_in, data, - input_section, ignore_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol_in; - PTR data; - asection *input_section; - bfd *ignore_bfd; - char **error_message; -{ - /* This item has already been relocated correctly, but we may be - * able to patch in yet better code - done by digging out the - * correct info on this symbol */ - bfd_reloc_status_type result; - coff_symbol_type *cs = coffsymbol(symbol_in); - - /* Don't do anything with symbols which aren't tied up yet, - except move the reloc. */ - if (bfd_is_und_section (cs->symbol.section)) { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* So the target symbol has to be of coff type, and the symbol - has to have the correct native information within it */ - if ((bfd_asymbol_flavour(&cs->symbol) != bfd_target_coff_flavour) - || (cs->native == (combined_entry_type *)NULL)) - { - /* This is interesting, consider the case where we're outputting coff - from a mix n match input, linking from coff to a symbol defined in a - bout file will cause this match to be true. Should I complain? This - will only work if the bout symbol is non leaf. */ - *error_message = - (char *) "uncertain calling convention for non-COFF symbol"; - result = bfd_reloc_dangerous; - } - else - { - switch (cs->native->u.syment.n_sclass) - { - case C_LEAFSTAT: - case C_LEAFEXT: - /* This is a call to a leaf procedure, replace instruction with a bal - to the correct location. */ - { - union internal_auxent *aux = &((cs->native+2)->u.auxent); - int word = bfd_get_32(abfd, (bfd_byte *)data + reloc_entry->address); - int olf = (aux->x_bal.x_balntry - cs->native->u.syment.n_value); - BFD_ASSERT(cs->native->u.syment.n_numaux==2); - - /* We replace the original call instruction with a bal to - the bal entry point - the offset of which is described in - the 2nd auxent of the original symbol. We keep the native - sym and auxents untouched, so the delta between the two - is the offset of the bal entry point. */ - word = ((word + olf) & BAL_MASK) | BAL; - bfd_put_32(abfd, word, (bfd_byte *) data + reloc_entry->address); - } - result = bfd_reloc_ok; - break; - case C_SCALL: - /* This is a call to a system call, replace with a calls to # */ - BFD_ASSERT(0); - result = bfd_reloc_ok; - break; - default: - result = bfd_reloc_ok; - break; - } - } - return result; -} - -/* i960 COFF is used by VxWorks 5.1. However, VxWorks 5.1 does not - appear to correctly handle a reloc against a symbol defined in the - same object file. It appears to simply discard such relocs, rather - than adding their values into the object file. We handle this here - by converting all relocs against defined symbols into relocs - against the section symbol, when generating a relocateable output - file. - - Note that this function is only called if we are not using the COFF - specific backend linker. It only does something when doing a - relocateable link, which will almost certainly fail when not - generating COFF i960 output, so this function is actually no longer - useful. It was used before this target was converted to use the - COFF specific backend linker. */ - -static bfd_reloc_status_type -coff_i960_relocate (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - asection *osec; - - if (output_bfd == NULL) - { - /* Not generating relocateable output file. */ - return bfd_reloc_continue; - } - - if (bfd_is_und_section (bfd_get_section (symbol))) - { - /* Symbol is not defined, so no need to worry about it. */ - return bfd_reloc_continue; - } - - if (bfd_is_com_section (bfd_get_section (symbol))) - { - /* I don't really know what the right action is for a common - symbol. */ - return bfd_reloc_continue; - } - - /* Convert the reloc to use the section symbol. FIXME: This method - is ridiculous. */ - osec = bfd_get_section (symbol)->output_section; - if (coff_section_data (output_bfd, osec) != NULL - && coff_section_data (output_bfd, osec)->tdata != NULL) - reloc_entry->sym_ptr_ptr = - (asymbol **) coff_section_data (output_bfd, osec)->tdata; - else - { - const char *sec_name; - asymbol **syms, **sym_end; - - sec_name = bfd_get_section_name (output_bfd, osec); - syms = bfd_get_outsymbols (output_bfd); - sym_end = syms + bfd_get_symcount (output_bfd); - for (; syms < sym_end; syms++) - { - if (bfd_asymbol_name (*syms) != NULL - && (*syms)->value == 0 - && strcmp ((*syms)->section->output_section->name, - sec_name) == 0) - break; - } - - if (syms >= sym_end) - abort (); - - reloc_entry->sym_ptr_ptr = syms; - - if (coff_section_data (output_bfd, osec) == NULL) - { - osec->used_by_bfd = - ((PTR) bfd_zalloc (abfd, - sizeof (struct coff_section_tdata))); - if (osec->used_by_bfd == NULL) - return bfd_reloc_overflow; - } - coff_section_data (output_bfd, osec)->tdata = (PTR) syms; - } - - /* Let bfd_perform_relocation do its thing, which will include - stuffing the symbol addend into the object file. */ - return bfd_reloc_continue; -} - -static reloc_howto_type howto_rellong = - HOWTO ((unsigned int) R_RELLONG, 0, 2, 32,false, 0, - complain_overflow_bitfield, coff_i960_relocate,"rellong", true, - 0xffffffff, 0xffffffff, 0); -static reloc_howto_type howto_iprmed = - HOWTO (R_IPRMED, 0, 2, 24,true,0, complain_overflow_signed, - coff_i960_relocate, "iprmed ", true, 0x00ffffff, 0x00ffffff, 0); -static reloc_howto_type howto_optcall = - HOWTO (R_OPTCALL, 0,2,24,true,0, complain_overflow_signed, - optcall_callback, "optcall", true, 0x00ffffff, 0x00ffffff, 0); - -static reloc_howto_type * -coff_i960_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - switch (code) - { - default: - return 0; - case BFD_RELOC_I960_CALLJ: - return &howto_optcall; - case BFD_RELOC_32: - case BFD_RELOC_CTOR: - return &howto_rellong; - case BFD_RELOC_24_PCREL: - return &howto_iprmed; - } -} - -/* The real code is in coffcode.h */ - -#define RTYPE2HOWTO(cache_ptr, dst) \ -{ \ - reloc_howto_type *howto_ptr; \ - switch ((dst)->r_type) { \ - case 17: howto_ptr = &howto_rellong; break; \ - case 25: howto_ptr = &howto_iprmed; break; \ - case 27: howto_ptr = &howto_optcall; break; \ - default: howto_ptr = 0; break; \ - } \ - (cache_ptr)->howto = howto_ptr; \ - } - -/* i960 COFF is used by VxWorks 5.1. However, VxWorks 5.1 does not - appear to correctly handle a reloc against a symbol defined in the - same object file. It appears to simply discard such relocs, rather - than adding their values into the object file. We handle this by - converting all relocs against global symbols into relocs against - internal symbols at the start of the section. This routine is - called at the start of the linking process, and it creates the - necessary symbols. */ - -static boolean -coff_i960_start_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - bfd_size_type symesz = bfd_coff_symesz (abfd); - asection *o; - bfd_byte *esym; - - if (! info->relocateable) - return true; - - esym = (bfd_byte *) bfd_malloc (symesz); - if (esym == NULL) - return false; - - if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0) - return false; - - for (o = abfd->sections; o != NULL; o = o->next) - { - struct internal_syment isym; - - strncpy (isym._n._n_name, o->name, SYMNMLEN); - isym.n_value = 0; - isym.n_scnum = o->target_index; - isym.n_type = T_NULL; - isym.n_sclass = C_STAT; - isym.n_numaux = 0; - - bfd_coff_swap_sym_out (abfd, (PTR) &isym, (PTR) esym); - - if (bfd_write (esym, symesz, 1, abfd) != symesz) - { - free (esym); - return false; - } - - obj_raw_syment_count (abfd) += 1; - } - - free (esym); - - return true; -} - -/* The reloc processing routine for the optimized COFF linker. */ - -static boolean -coff_i960_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, syms, sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - struct internal_reloc *relocs; - struct internal_syment *syms; - asection **sections; -{ - struct internal_reloc *rel; - struct internal_reloc *relend; - - rel = relocs; - relend = rel + input_section->reloc_count; - for (; rel < relend; rel++) - { - long symndx; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma addend; - bfd_vma val; - reloc_howto_type *howto; - bfd_reloc_status_type rstat = bfd_reloc_ok; - boolean done; - - symndx = rel->r_symndx; - - if (symndx == -1) - { - h = NULL; - sym = NULL; - } - else - { - h = obj_coff_sym_hashes (input_bfd)[symndx]; - sym = syms + symndx; - } - - if (sym != NULL && sym->n_scnum != 0) - addend = - sym->n_value; - else - addend = 0; - - switch (rel->r_type) - { - case 17: howto = &howto_rellong; break; - case 25: howto = &howto_iprmed; break; - case 27: howto = &howto_optcall; break; - default: - bfd_set_error (bfd_error_bad_value); - return false; - } - - val = 0; - - if (h == NULL) - { - asection *sec; - - if (symndx == -1) - { - sec = bfd_abs_section_ptr; - val = 0; - } - else - { - sec = sections[symndx]; - val = (sec->output_section->vma - + sec->output_offset - + sym->n_value - - sec->vma); - } - } - else - { - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - asection *sec; - - sec = h->root.u.def.section; - val = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (! info->relocateable) - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return false; - } - } - - done = false; - - if (howto->type == R_OPTCALL && ! info->relocateable && symndx != -1) - { - int class; - - if (h != NULL) - class = h->class; - else - class = sym->n_sclass; - - switch (class) - { - case C_NULL: - /* This symbol is apparently not from a COFF input file. - We warn, and then assume that it is not a leaf - function. */ - if (! ((*info->callbacks->reloc_dangerous) - (info, - "uncertain calling convention for non-COFF symbol", - input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return false; - break; - case C_LEAFSTAT: - case C_LEAFEXT: - /* This is a call to a leaf procedure; use the bal - instruction. */ - { - long olf; - unsigned long word; - - if (h != NULL) - { - BFD_ASSERT (h->numaux == 2); - olf = h->aux[1].x_bal.x_balntry; - } - else - { - bfd_byte *esyms; - union internal_auxent aux; - - BFD_ASSERT (sym->n_numaux == 2); - esyms = (bfd_byte *) obj_coff_external_syms (input_bfd); - esyms += (symndx + 2) * bfd_coff_symesz (input_bfd); - bfd_coff_swap_aux_in (input_bfd, (PTR) esyms, sym->n_type, - sym->n_sclass, 1, sym->n_numaux, - (PTR) &aux); - olf = aux.x_bal.x_balntry; - } - - word = bfd_get_32 (input_bfd, - (contents - + (rel->r_vaddr - input_section->vma))); - word = ((word + olf - val) & BAL_MASK) | BAL; - bfd_put_32 (input_bfd, - word, - (contents - + (rel->r_vaddr - input_section->vma))); - done = true; - } - break; - case C_SCALL: - BFD_ASSERT (0); - break; - } - } - - if (! done) - { - if (howto->pc_relative) - addend += input_section->vma; - rstat = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, - rel->r_vaddr - input_section->vma, - val, addend); - } - - switch (rstat) - { - default: - abort (); - case bfd_reloc_ok: - break; - case bfd_reloc_overflow: - { - const char *name; - char buf[SYMNMLEN + 1]; - - if (symndx == -1) - name = "*ABS*"; - else if (h != NULL) - name = h->root.root.string; - else - { - name = _bfd_coff_internal_syment_name (input_bfd, sym, buf); - if (name == NULL) - return false; - } - - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, input_bfd, - input_section, rel->r_vaddr - input_section->vma))) - return false; - } - } - } - - return true; -} - -/* Adjust the symbol index of any reloc against a global symbol to - instead be a reloc against the internal symbol we created specially - for the section. */ - -/*ARGSUSED*/ -static boolean -coff_i960_adjust_symndx (obfd, info, ibfd, sec, irel, adjustedp) - bfd *obfd; - struct bfd_link_info *info; - bfd *ibfd; - asection *sec; - struct internal_reloc *irel; - boolean *adjustedp; -{ - struct coff_link_hash_entry *h; - - *adjustedp = false; - - h = obj_coff_sym_hashes (ibfd)[irel->r_symndx]; - if (h == NULL - || (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak)) - return true; - - irel->r_symndx = h->root.u.def.section->output_section->target_index - 1; - *adjustedp = true; - - return true; -} - -#define coff_start_final_link coff_i960_start_final_link - -#define coff_relocate_section coff_i960_relocate_section - -#define coff_adjust_symndx coff_i960_adjust_symndx - -#define coff_bfd_reloc_type_lookup coff_i960_reloc_type_lookup - -#include "coffcode.h" - -const bfd_target icoff_little_vec = -{ - "coff-Intel-little", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* leading underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; - - -const bfd_target icoff_big_vec = -{ - "coff-Intel-big", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* leading underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - -bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ -bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-m68k.c b/contrib/gdb/bfd/coff-m68k.c deleted file mode 100644 index 77fb45b..0000000 --- a/contrib/gdb/bfd/coff-m68k.c +++ /dev/null @@ -1,203 +0,0 @@ -/* BFD back-end for Motorola 68000 COFF binaries. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/m68k.h" -#include "coff/internal.h" -#include "libcoff.h" - -#ifndef LYNX_SPECIAL_FN -#define LYNX_SPECIAL_FN 0 -#endif - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) - -#ifndef COFF_PAGE_SIZE -/* The page size is a guess based on ELF. */ -#define COFF_PAGE_SIZE 0x2000 -#endif - -/* Clean up namespace. */ -#define m68kcoff_howto_table _bfd_m68kcoff_howto_table -#define m68k_rtype2howto _bfd_m68kcoff_rtype2howto -#define m68k_howto2rtype _bfd_m68kcoff_howto2rtype -#define m68k_reloc_type_lookup _bfd_m68kcoff_reloc_type_lookup - -#ifdef ONLY_DECLARE_RELOCS -extern reloc_howto_type m68kcoff_howto_table[]; -#else -reloc_howto_type m68kcoff_howto_table[] = -{ - HOWTO(R_RELBYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, LYNX_SPECIAL_FN, "8", true, 0x000000ff,0x000000ff, false), - HOWTO(R_RELWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, LYNX_SPECIAL_FN, "16", true, 0x0000ffff,0x0000ffff, false), - HOWTO(R_RELLONG, 0, 2, 32, false, 0, complain_overflow_bitfield, LYNX_SPECIAL_FN, "32", true, 0xffffffff,0xffffffff, false), - HOWTO(R_PCRBYTE, 0, 0, 8, true, 0, complain_overflow_signed, LYNX_SPECIAL_FN, "DISP8", true, 0x000000ff,0x000000ff, false), - HOWTO(R_PCRWORD, 0, 1, 16, true, 0, complain_overflow_signed, LYNX_SPECIAL_FN, "DISP16", true, 0x0000ffff,0x0000ffff, false), - HOWTO(R_PCRLONG, 0, 2, 32, true, 0, complain_overflow_signed, LYNX_SPECIAL_FN, "DISP32", true, 0xffffffff,0xffffffff, false), - HOWTO(R_RELLONG_NEG, 0, -2, 32, false, 0, complain_overflow_bitfield, LYNX_SPECIAL_FN, "-32", true, 0xffffffff,0xffffffff, false), -}; -#endif /* not ONLY_DECLARE_RELOCS */ - -#ifndef BADMAG -#define BADMAG(x) M68KBADMAG(x) -#endif -#define M68 1 /* Customize coffcode.h */ - -/* Turn a howto into a reloc number */ - -#ifdef ONLY_DECLARE_RELOCS -extern void m68k_rtype2howto PARAMS ((arelent *internal, int relocentry)); -extern int m68k_howto2rtype PARAMS ((reloc_howto_type *)); -extern reloc_howto_type *m68k_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -#else -void -m68k_rtype2howto(internal, relocentry) - arelent *internal; - int relocentry; -{ - switch (relocentry) - { - case R_RELBYTE: internal->howto = m68kcoff_howto_table + 0; break; - case R_RELWORD: internal->howto = m68kcoff_howto_table + 1; break; - case R_RELLONG: internal->howto = m68kcoff_howto_table + 2; break; - case R_PCRBYTE: internal->howto = m68kcoff_howto_table + 3; break; - case R_PCRWORD: internal->howto = m68kcoff_howto_table + 4; break; - case R_PCRLONG: internal->howto = m68kcoff_howto_table + 5; break; - case R_RELLONG_NEG: internal->howto = m68kcoff_howto_table + 6; break; - } -} - -int -m68k_howto2rtype (internal) - reloc_howto_type *internal; -{ - if (internal->pc_relative) - { - switch (internal->bitsize) - { - case 32: return R_PCRLONG; - case 16: return R_PCRWORD; - case 8: return R_PCRBYTE; - } - } - else - { - switch (internal->bitsize) - { - case 32: return R_RELLONG; - case 16: return R_RELWORD; - case 8: return R_RELBYTE; - } - } - return R_RELLONG; -} - -reloc_howto_type * -m68k_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - switch (code) - { - default: return NULL; - case BFD_RELOC_8: return m68kcoff_howto_table + 0; - case BFD_RELOC_16: return m68kcoff_howto_table + 1; - case BFD_RELOC_CTOR: - case BFD_RELOC_32: return m68kcoff_howto_table + 2; - case BFD_RELOC_8_PCREL: return m68kcoff_howto_table + 3; - case BFD_RELOC_16_PCREL: return m68kcoff_howto_table + 4; - case BFD_RELOC_32_PCREL: return m68kcoff_howto_table + 5; - /* FIXME: There doesn't seem to be a code for R_RELLONG_NEG. */ - } - /*NOTREACHED*/ -} - -#endif /* not ONLY_DECLARE_RELOCS */ - -#define RTYPE2HOWTO(internal, relocentry) \ - m68k_rtype2howto(internal, (relocentry)->r_type) - -#define SELECT_RELOC(external, internal) \ - external.r_type = m68k_howto2rtype(internal); - -#define coff_bfd_reloc_type_lookup m68k_reloc_type_lookup - -#define coff_relocate_section _bfd_coff_generic_relocate_section - -#include "coffcode.h" - -const bfd_target -#ifdef TARGET_SYM - TARGET_SYM = -#else - m68kcoff_vec = -#endif -{ -#ifdef TARGET_NAME - TARGET_NAME, -#else - "coff-m68k", /* name */ -#endif - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ -#ifdef NAMES_HAVE_UNDERSCORE - '_', -#else - 0, /* leading underscore */ -#endif - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE - }; diff --git a/contrib/gdb/bfd/coff-m88k.c b/contrib/gdb/bfd/coff-m88k.c deleted file mode 100644 index 414106d..0000000 --- a/contrib/gdb/bfd/coff-m88k.c +++ /dev/null @@ -1,311 +0,0 @@ -/* BFD back-end for Motorola 88000 COFF "Binary Compatability Standard" files. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - -#define M88 1 /* Customize various include files */ -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/m88k.h" -#include "coff/internal.h" -#include "libcoff.h" - -static bfd_reloc_status_type m88k_special_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static void rtype2howto PARAMS ((arelent *, struct internal_reloc *)); -static void reloc_processing - PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection *)); - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3) - -static bfd_reloc_status_type -m88k_special_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - reloc_howto_type *howto = reloc_entry->howto; - - switch (howto->type) - { - case R_HVRT16: - case R_LVRT16: - if (output_bfd != (bfd *) NULL) - { - /* This is a partial relocation, and we want to apply the - relocation to the reloc entry rather than the raw data. - Modify the reloc inplace to reflect what we now know. */ - - reloc_entry->address += input_section->output_offset; - } - else - { - bfd_vma output_base = 0; - bfd_vma addr = reloc_entry->address; - bfd_vma x = bfd_get_16 (abfd, (bfd_byte *) data + addr); - asection *reloc_target_output_section; - long relocation = 0; - - /* Work out which section the relocation is targetted at and the - initial relocation command value. */ - - /* Get symbol value. (Common symbols are special.) */ - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - reloc_target_output_section = symbol->section->output_section; - - /* Convert input-section-relative symbol value to absolute. */ - if (output_bfd) - output_base = 0; - else - output_base = reloc_target_output_section->vma; - - relocation += output_base + symbol->section->output_offset; - - /* Add in supplied addend. */ - relocation += ((reloc_entry->addend << howto->bitsize) + x); - - reloc_entry->addend = 0; - - relocation >>= (bfd_vma) howto->rightshift; - - /* Shift everything up to where it's going to be used */ - - relocation <<= (bfd_vma) howto->bitpos; - - if (relocation) - bfd_put_16 (abfd, relocation, (unsigned char *) data + addr); - } - - return bfd_reloc_ok; - break; - - default: - if (output_bfd != (bfd *) NULL) - { - /* This is a partial relocation, and we want to apply the - relocation to the reloc entry rather than the raw data. - Modify the reloc inplace to reflect what we now know. */ - - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - break; - } - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - return bfd_reloc_ok; -} - -static reloc_howto_type howto_table[] = -{ - HOWTO (R_PCR16L, /* type */ - 02, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - m88k_special_reloc, /* special_function */ - "PCR16L", /* name */ - false, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - true), /* pcrel_offset */ - - HOWTO (R_PCR26L, /* type */ - 02, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - m88k_special_reloc, /* special_function */ - "PCR26L", /* name */ - false, /* partial_inplace */ - 0x03ffffff, /* src_mask */ - 0x03ffffff, /* dst_mask */ - true), /* pcrel_offset */ - - HOWTO (R_VRT16, /* type */ - 00, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - m88k_special_reloc, /* special_function */ - "VRT16", /* name */ - false, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - true), /* pcrel_offset */ - - HOWTO (R_HVRT16, /* type */ - 16, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - m88k_special_reloc, /* special_function */ - "HVRT16", /* name */ - false, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - true), /* pcrel_offset */ - - HOWTO (R_LVRT16, /* type */ - 00, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - m88k_special_reloc, /* special_function */ - "LVRT16", /* name */ - false, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - true), /* pcrel_offset */ - - HOWTO (R_VRT32, /* type */ - 00, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - m88k_special_reloc, /* special_function */ - "VRT32", /* name */ - false, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - true), /* pcrel_offset */ -}; - -/* Code to turn an external r_type into a pointer to an entry in the - above howto table. */ -static void -rtype2howto (cache_ptr, dst) - arelent *cache_ptr; - struct internal_reloc *dst; -{ - if (dst->r_type >= R_PCR16L && dst->r_type <= R_VRT32) - { - cache_ptr->howto = howto_table + dst->r_type - R_PCR16L; - } - else - { - BFD_ASSERT (0); - } -} - -#define RTYPE2HOWTO(cache_ptr, dst) rtype2howto (cache_ptr, dst) - - -/* Code to swap in the reloc offset */ -#define SWAP_IN_RELOC_OFFSET bfd_h_get_16 -#define SWAP_OUT_RELOC_OFFSET bfd_h_put_16 - - -#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \ - reloc_processing(relent, reloc, symbols, abfd, section) - -static void -reloc_processing (relent, reloc, symbols, abfd, section) - arelent *relent; - struct internal_reloc *reloc; - asymbol **symbols; - bfd *abfd; - asection *section; -{ - relent->address = reloc->r_vaddr; - rtype2howto (relent, reloc); - - if (((int) reloc->r_symndx) > 0) - { - relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; - } - else - { - relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - } - - relent->addend = reloc->r_offset; - relent->address -= section->vma; -} - -#define BADMAG(x) MC88BADMAG(x) -#include "coffcode.h" - -#undef coff_write_armap - -const bfd_target m88kbcs_vec = -{ - "coff-m88kbcs", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* leading underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-mips.c b/contrib/gdb/bfd/coff-mips.c deleted file mode 100644 index c860f9a..0000000 --- a/contrib/gdb/bfd/coff-mips.c +++ /dev/null @@ -1,2596 +0,0 @@ -/* BFD back-end for MIPS Extended-Coff files. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Original version by Per Bothner. - Full support added by Ian Lance Taylor, ian@cygnus.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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "coff/internal.h" -#include "coff/sym.h" -#include "coff/symconst.h" -#include "coff/ecoff.h" -#include "coff/mips.h" -#include "libcoff.h" -#include "libecoff.h" - -/* Prototypes for static functions. */ - -static boolean mips_ecoff_bad_format_hook PARAMS ((bfd *abfd, PTR filehdr)); -static void mips_ecoff_swap_reloc_in PARAMS ((bfd *, PTR, - struct internal_reloc *)); -static void mips_ecoff_swap_reloc_out PARAMS ((bfd *, - const struct internal_reloc *, - PTR)); -static void mips_adjust_reloc_in PARAMS ((bfd *, - const struct internal_reloc *, - arelent *)); -static void mips_adjust_reloc_out PARAMS ((bfd *, const arelent *, - struct internal_reloc *)); -static bfd_reloc_status_type mips_generic_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_refhi_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_reflo_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_gprel_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_relhi_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_rello_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_switch_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static void mips_relocate_hi PARAMS ((struct internal_reloc *refhi, - struct internal_reloc *reflo, - bfd *input_bfd, - asection *input_section, - bfd_byte *contents, - size_t adjust, - bfd_vma relocation, - boolean pcrel)); -static boolean mips_relocate_section PARAMS ((bfd *, struct bfd_link_info *, - bfd *, asection *, - bfd_byte *, PTR)); -static boolean mips_read_relocs PARAMS ((bfd *, asection *)); -static boolean mips_relax_section PARAMS ((bfd *, asection *, - struct bfd_link_info *, - boolean *)); -static boolean mips_relax_pcrel16 PARAMS ((struct bfd_link_info *, bfd *, - asection *, - struct ecoff_link_hash_entry *, - bfd_byte *, bfd_vma)); - -/* ECOFF has COFF sections, but the debugging information is stored in - a completely different format. ECOFF targets use some of the - swapping routines from coffswap.h, and some of the generic COFF - routines in coffgen.c, but, unlike the real COFF targets, do not - use coffcode.h itself. - - Get the generic COFF swapping routines, except for the reloc, - symbol, and lineno ones. Give them ECOFF names. */ -#define MIPSECOFF -#define NO_COFF_RELOCS -#define NO_COFF_SYMBOLS -#define NO_COFF_LINENOS -#define coff_swap_filehdr_in mips_ecoff_swap_filehdr_in -#define coff_swap_filehdr_out mips_ecoff_swap_filehdr_out -#define coff_swap_aouthdr_in mips_ecoff_swap_aouthdr_in -#define coff_swap_aouthdr_out mips_ecoff_swap_aouthdr_out -#define coff_swap_scnhdr_in mips_ecoff_swap_scnhdr_in -#define coff_swap_scnhdr_out mips_ecoff_swap_scnhdr_out -#include "coffswap.h" - -/* Get the ECOFF swapping routines. */ -#define ECOFF_32 -#include "ecoffswap.h" - -/* How to process the various relocs types. */ - -static reloc_howto_type mips_howto_table[] = -{ - /* Reloc type 0 is ignored. The reloc reading code ensures that - this is a reference to the .abs section, which will cause - bfd_perform_relocation to do nothing. */ - HOWTO (MIPS_R_IGNORE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "IGNORE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 16 bit reference to a symbol, normally from a data section. */ - HOWTO (MIPS_R_REFHALF, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - mips_generic_reloc, /* special_function */ - "REFHALF", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 32 bit reference to a symbol, normally from a data section. */ - HOWTO (MIPS_R_REFWORD, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - mips_generic_reloc, /* special_function */ - "REFWORD", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 26 bit absolute jump address. */ - HOWTO (MIPS_R_JMPADDR, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - /* This needs complex overflow - detection, because the upper four - bits must match the PC. */ - mips_generic_reloc, /* special_function */ - "JMPADDR", /* name */ - true, /* partial_inplace */ - 0x3ffffff, /* src_mask */ - 0x3ffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* The high 16 bits of a symbol value. Handled by the function - mips_refhi_reloc. */ - HOWTO (MIPS_R_REFHI, /* type */ - 16, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - mips_refhi_reloc, /* special_function */ - "REFHI", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* The low 16 bits of a symbol value. */ - HOWTO (MIPS_R_REFLO, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - mips_reflo_reloc, /* special_function */ - "REFLO", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A reference to an offset from the gp register. Handled by the - function mips_gprel_reloc. */ - HOWTO (MIPS_R_GPREL, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - mips_gprel_reloc, /* special_function */ - "GPREL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A reference to a literal using an offset from the gp register. - Handled by the function mips_gprel_reloc. */ - HOWTO (MIPS_R_LITERAL, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - mips_gprel_reloc, /* special_function */ - "LITERAL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - { 8 }, - { 9 }, - { 10 }, - { 11 }, - - /* This reloc is a Cygnus extension used when generating position - independent code for embedded systems. It represents a 16 bit PC - relative reloc rightshifted twice as used in the MIPS branch - instructions. */ - HOWTO (MIPS_R_PCREL16, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - mips_generic_reloc, /* special_function */ - "PCREL16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - true), /* pcrel_offset */ - - /* This reloc is a Cygnus extension used when generating position - independent code for embedded systems. It represents the high 16 - bits of a PC relative reloc. The next reloc must be - MIPS_R_RELLO, and the addend is formed from the addends of the - two instructions, just as in MIPS_R_REFHI and MIPS_R_REFLO. The - final value is actually PC relative to the location of the - MIPS_R_RELLO reloc, not the MIPS_R_RELHI reloc. */ - HOWTO (MIPS_R_RELHI, /* type */ - 16, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - mips_relhi_reloc, /* special_function */ - "RELHI", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - true), /* pcrel_offset */ - - /* This reloc is a Cygnus extension used when generating position - independent code for embedded systems. It represents the low 16 - bits of a PC relative reloc. */ - HOWTO (MIPS_R_RELLO, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - mips_rello_reloc, /* special_function */ - "RELLO", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - true), /* pcrel_offset */ - - { 15 }, - { 16 }, - { 17 }, - { 18 }, - { 19 }, - { 20 }, - { 21 }, - - /* This reloc is a Cygnus extension used when generating position - independent code for embedded systems. It represents an entry in - a switch table, which is the difference between two symbols in - the .text section. The symndx is actually the offset from the - reloc address to the subtrahend. See include/coff/mips.h for - more details. */ - HOWTO (MIPS_R_SWITCH, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - mips_switch_reloc, /* special_function */ - "SWITCH", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - true) /* pcrel_offset */ -}; - -#define MIPS_HOWTO_COUNT \ - (sizeof mips_howto_table / sizeof mips_howto_table[0]) - -/* When the linker is doing relaxing, it may change a external PCREL16 - reloc. This typically represents an instruction like - bal foo - We change it to - .set noreorder - bal $L1 - lui $at,%hi(foo - $L1) - $L1: - addiu $at,%lo(foo - $L1) - addu $at,$at,$31 - jalr $at - PCREL16_EXPANSION_ADJUSTMENT is the number of bytes this changes the - instruction by. */ - -#define PCREL16_EXPANSION_ADJUSTMENT (4 * 4) - -/* See whether the magic number matches. */ - -static boolean -mips_ecoff_bad_format_hook (abfd, filehdr) - bfd *abfd; - PTR filehdr; -{ - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; - - switch (internal_f->f_magic) - { - case MIPS_MAGIC_1: - /* I don't know what endianness this implies. */ - return true; - - case MIPS_MAGIC_BIG: - case MIPS_MAGIC_BIG2: - case MIPS_MAGIC_BIG3: - return bfd_big_endian (abfd); - - case MIPS_MAGIC_LITTLE: - case MIPS_MAGIC_LITTLE2: - case MIPS_MAGIC_LITTLE3: - return bfd_little_endian (abfd); - - default: - return false; - } -} - -/* Reloc handling. MIPS ECOFF relocs are packed into 8 bytes in - external form. They use a bit which indicates whether the symbol - is external. */ - -/* Swap a reloc in. */ - -static void -mips_ecoff_swap_reloc_in (abfd, ext_ptr, intern) - bfd *abfd; - PTR ext_ptr; - struct internal_reloc *intern; -{ - const RELOC *ext = (RELOC *) ext_ptr; - - intern->r_vaddr = bfd_h_get_32 (abfd, (bfd_byte *) ext->r_vaddr); - if (bfd_header_big_endian (abfd)) - { - intern->r_symndx = (((int) ext->r_bits[0] - << RELOC_BITS0_SYMNDX_SH_LEFT_BIG) - | ((int) ext->r_bits[1] - << RELOC_BITS1_SYMNDX_SH_LEFT_BIG) - | ((int) ext->r_bits[2] - << RELOC_BITS2_SYMNDX_SH_LEFT_BIG)); - intern->r_type = ((ext->r_bits[3] & RELOC_BITS3_TYPE_BIG) - >> RELOC_BITS3_TYPE_SH_BIG); - intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_BIG) != 0; - } - else - { - intern->r_symndx = (((int) ext->r_bits[0] - << RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE) - | ((int) ext->r_bits[1] - << RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE) - | ((int) ext->r_bits[2] - << RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE)); - intern->r_type = (((ext->r_bits[3] & RELOC_BITS3_TYPE_LITTLE) - >> RELOC_BITS3_TYPE_SH_LITTLE) - | ((ext->r_bits[3] & RELOC_BITS3_TYPEHI_LITTLE) - << RELOC_BITS3_TYPEHI_SH_LITTLE)); - intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0; - } - - /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or - MIPS_R_RELLO reloc, r_symndx is actually the offset from the - reloc address to the base of the difference (see - include/coff/mips.h for more details). We copy symndx into the - r_offset field so as not to confuse ecoff_slurp_reloc_table in - ecoff.c. In adjust_reloc_in we then copy r_offset into the reloc - addend. */ - if (intern->r_type == MIPS_R_SWITCH - || (! intern->r_extern - && (intern->r_type == MIPS_R_RELLO - || intern->r_type == MIPS_R_RELHI))) - { - BFD_ASSERT (! intern->r_extern); - intern->r_offset = intern->r_symndx; - if (intern->r_offset & 0x800000) - intern->r_offset -= 0x1000000; - intern->r_symndx = RELOC_SECTION_TEXT; - } -} - -/* Swap a reloc out. */ - -static void -mips_ecoff_swap_reloc_out (abfd, intern, dst) - bfd *abfd; - const struct internal_reloc *intern; - PTR dst; -{ - RELOC *ext = (RELOC *) dst; - long r_symndx; - - BFD_ASSERT (intern->r_extern - || (intern->r_symndx >= 0 && intern->r_symndx <= 12)); - - /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELLO or - MIPS_R_RELHI reloc, we actually want to write the contents of - r_offset out as the symbol index. This undoes the change made by - mips_ecoff_swap_reloc_in. */ - if (intern->r_type != MIPS_R_SWITCH - && (intern->r_extern - || (intern->r_type != MIPS_R_RELHI - && intern->r_type != MIPS_R_RELLO))) - r_symndx = intern->r_symndx; - else - { - BFD_ASSERT (intern->r_symndx == RELOC_SECTION_TEXT); - r_symndx = intern->r_offset & 0xffffff; - } - - bfd_h_put_32 (abfd, intern->r_vaddr, (bfd_byte *) ext->r_vaddr); - if (bfd_header_big_endian (abfd)) - { - ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_BIG; - ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_BIG; - ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_BIG; - ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_BIG) - & RELOC_BITS3_TYPE_BIG) - | (intern->r_extern ? RELOC_BITS3_EXTERN_BIG : 0)); - } - else - { - ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_LITTLE; - ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_LITTLE; - ext->r_bits[2] = r_symndx >> RELOC_BITS2_SYMNDX_SH_LEFT_LITTLE; - ext->r_bits[3] = (((intern->r_type << RELOC_BITS3_TYPE_SH_LITTLE) - & RELOC_BITS3_TYPE_LITTLE) - | ((intern->r_type >> RELOC_BITS3_TYPEHI_SH_LITTLE - & RELOC_BITS3_TYPEHI_LITTLE)) - | (intern->r_extern ? RELOC_BITS3_EXTERN_LITTLE : 0)); - } -} - -/* Finish canonicalizing a reloc. Part of this is generic to all - ECOFF targets, and that part is in ecoff.c. The rest is done in - this backend routine. It must fill in the howto field. */ - -static void -mips_adjust_reloc_in (abfd, intern, rptr) - bfd *abfd; - const struct internal_reloc *intern; - arelent *rptr; -{ - if (intern->r_type > MIPS_R_SWITCH) - abort (); - - if (! intern->r_extern - && (intern->r_type == MIPS_R_GPREL - || intern->r_type == MIPS_R_LITERAL)) - rptr->addend += ecoff_data (abfd)->gp; - - /* If the type is MIPS_R_IGNORE, make sure this is a reference to - the absolute section so that the reloc is ignored. */ - if (intern->r_type == MIPS_R_IGNORE) - rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - - /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or - MIPS_R_RELLO reloc, we want the addend field of the BFD relocto - hold the value which was originally in the symndx field of the - internal MIPS ECOFF reloc. This value was copied into - intern->r_offset by mips_swap_reloc_in, and here we copy it into - the addend field. */ - if (intern->r_type == MIPS_R_SWITCH - || (! intern->r_extern - && (intern->r_type == MIPS_R_RELHI - || intern->r_type == MIPS_R_RELLO))) - rptr->addend = intern->r_offset; - - rptr->howto = &mips_howto_table[intern->r_type]; -} - -/* Make any adjustments needed to a reloc before writing it out. None - are needed for MIPS. */ - -static void -mips_adjust_reloc_out (abfd, rel, intern) - bfd *abfd; - const arelent *rel; - struct internal_reloc *intern; -{ - /* For a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or - MIPS_R_RELLO reloc, we must copy rel->addend into - intern->r_offset. This will then be written out as the symbol - index by mips_ecoff_swap_reloc_out. This operation parallels the - action of mips_adjust_reloc_in. */ - if (intern->r_type == MIPS_R_SWITCH - || (! intern->r_extern - && (intern->r_type == MIPS_R_RELHI - || intern->r_type == MIPS_R_RELLO))) - intern->r_offset = rel->addend; -} - -/* ECOFF relocs are either against external symbols, or against - sections. If we are producing relocateable output, and the reloc - is against an external symbol, and nothing has given us any - additional addend, the resulting reloc will also be against the - same symbol. In such a case, we don't want to change anything - about the way the reloc is handled, since it will all be done at - final link time. Rather than put special case code into - bfd_perform_relocation, all the reloc types use this howto - function. It just short circuits the reloc if producing - relocateable output against an external symbol. */ - -static bfd_reloc_status_type -mips_generic_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - return bfd_reloc_continue; -} - -/* Do a REFHI relocation. This has to be done in combination with a - REFLO reloc, because there is a carry from the REFLO to the REFHI. - Here we just save the information we need; we do the actual - relocation when we see the REFLO. MIPS ECOFF requires that the - REFLO immediately follow the REFHI, so this ought to work. */ - -static bfd_byte *mips_refhi_addr; -static bfd_vma mips_refhi_addend; - -static bfd_reloc_status_type -mips_refhi_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_reloc_status_type ret; - bfd_vma relocation; - - /* If we're relocating, and this an external symbol, we don't want - to change anything. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - ret = bfd_reloc_ok; - if (bfd_is_und_section (symbol->section) - && output_bfd == (bfd *) NULL) - ret = bfd_reloc_undefined; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - /* Save the information, and let REFLO do the actual relocation. */ - mips_refhi_addr = (bfd_byte *) data + reloc_entry->address; - mips_refhi_addend = relocation; - - if (output_bfd != (bfd *) NULL) - reloc_entry->address += input_section->output_offset; - - return ret; -} - -/* Do a REFLO relocation. This is a straightforward 16 bit inplace - relocation; this function exists in order to do the REFHI - relocation described above. */ - -static bfd_reloc_status_type -mips_reflo_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - if (mips_refhi_addr != (bfd_byte *) NULL) - { - unsigned long insn; - unsigned long val; - unsigned long vallo; - - /* Do the REFHI relocation. Note that we actually don't need to - know anything about the REFLO itself, except where to find - the low 16 bits of the addend needed by the REFHI. */ - insn = bfd_get_32 (abfd, mips_refhi_addr); - vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address) - & 0xffff); - val = ((insn & 0xffff) << 16) + vallo; - val += mips_refhi_addend; - - /* The low order 16 bits are always treated as a signed value. - Therefore, a negative value in the low order bits requires an - adjustment in the high order bits. We need to make this - adjustment in two ways: once for the bits we took from the - data, and once for the bits we are putting back in to the - data. */ - if ((vallo & 0x8000) != 0) - val -= 0x10000; - if ((val & 0x8000) != 0) - val += 0x10000; - - insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff); - bfd_put_32 (abfd, insn, mips_refhi_addr); - - mips_refhi_addr = (bfd_byte *) NULL; - } - - /* Now do the REFLO reloc in the usual way. */ - return mips_generic_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message); -} - -/* Do a GPREL relocation. This is a 16 bit value which must become - the offset from the gp register. */ - -static bfd_reloc_status_type -mips_gprel_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - boolean relocateable; - bfd_vma gp; - bfd_vma relocation; - unsigned long val; - unsigned long insn; - - /* If we're relocating, and this is an external symbol with no - addend, we don't want to change anything. We will only have an - addend if this is a newly created reloc, not read from an ECOFF - file. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - if (output_bfd != (bfd *) NULL) - relocateable = true; - else - { - relocateable = false; - output_bfd = symbol->section->output_section->owner; - } - - if (bfd_is_und_section (symbol->section) - && relocateable == false) - return bfd_reloc_undefined; - - /* We have to figure out the gp value, so that we can adjust the - symbol value correctly. We look up the symbol _gp in the output - BFD. If we can't find it, we're stuck. We cache it in the ECOFF - target data. We don't need to adjust the symbol value for an - external symbol if we are producing relocateable output. */ - gp = _bfd_get_gp_value (output_bfd); - if (gp == 0 - && (relocateable == false - || (symbol->flags & BSF_SECTION_SYM) != 0)) - { - if (relocateable != false) - { - /* Make up a value. */ - gp = symbol->section->output_section->vma + 0x4000; - _bfd_set_gp_value (output_bfd, gp); - } - else - { - unsigned int count; - asymbol **sym; - unsigned int i; - - count = bfd_get_symcount (output_bfd); - sym = bfd_get_outsymbols (output_bfd); - - if (sym == (asymbol **) NULL) - i = count; - else - { - for (i = 0; i < count; i++, sym++) - { - register CONST char *name; - - name = bfd_asymbol_name (*sym); - if (*name == '_' && strcmp (name, "_gp") == 0) - { - gp = bfd_asymbol_value (*sym); - _bfd_set_gp_value (output_bfd, gp); - break; - } - } - } - - if (i >= count) - { - /* Only get the error once. */ - gp = 4; - _bfd_set_gp_value (output_bfd, gp); - *error_message = - (char *) "GP relative relocation when _gp not defined"; - return bfd_reloc_dangerous; - } - } - } - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); - - /* Set val to the offset into the section or symbol. */ - val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff; - if (val & 0x8000) - val -= 0x10000; - - /* Adjust val for the final section location and GP value. If we - are producing relocateable output, we don't want to do this for - an external symbol. */ - if (relocateable == false - || (symbol->flags & BSF_SECTION_SYM) != 0) - val += relocation - gp; - - insn = (insn &~ 0xffff) | (val & 0xffff); - bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address); - - if (relocateable != false) - reloc_entry->address += input_section->output_offset; - - /* Make sure it fit in 16 bits. */ - if (val >= 0x8000 && val < 0xffff8000) - return bfd_reloc_overflow; - - return bfd_reloc_ok; -} - -/* Do a RELHI relocation. We do this in conjunction with a RELLO - reloc, just as REFHI and REFLO are done together. RELHI and RELLO - are Cygnus extensions used when generating position independent - code for embedded systems. */ - -static bfd_byte *mips_relhi_addr; -static bfd_vma mips_relhi_addend; - -static bfd_reloc_status_type -mips_relhi_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_reloc_status_type ret; - bfd_vma relocation; - - /* If this is a reloc against a section symbol, then it is correct - in the object file. The only time we want to change this case is - when we are relaxing, and that is handled entirely by - mips_relocate_section and never calls this function. */ - if ((symbol->flags & BSF_SECTION_SYM) != 0) - { - if (output_bfd != (bfd *) NULL) - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* This is an external symbol. If we're relocating, we don't want - to change anything. */ - if (output_bfd != (bfd *) NULL) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - ret = bfd_reloc_ok; - if (bfd_is_und_section (symbol->section) - && output_bfd == (bfd *) NULL) - ret = bfd_reloc_undefined; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - /* Save the information, and let RELLO do the actual relocation. */ - mips_relhi_addr = (bfd_byte *) data + reloc_entry->address; - mips_relhi_addend = relocation; - - if (output_bfd != (bfd *) NULL) - reloc_entry->address += input_section->output_offset; - - return ret; -} - -/* Do a RELLO relocation. This is a straightforward 16 bit PC - relative relocation; this function exists in order to do the RELHI - relocation described above. */ - -static bfd_reloc_status_type -mips_rello_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - if (mips_relhi_addr != (bfd_byte *) NULL) - { - unsigned long insn; - unsigned long val; - unsigned long vallo; - - /* Do the RELHI relocation. Note that we actually don't need to - know anything about the RELLO itself, except where to find - the low 16 bits of the addend needed by the RELHI. */ - insn = bfd_get_32 (abfd, mips_relhi_addr); - vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address) - & 0xffff); - val = ((insn & 0xffff) << 16) + vallo; - val += mips_relhi_addend; - - /* If the symbol is defined, make val PC relative. If the - symbol is not defined we don't want to do this, because we - don't want the value in the object file to incorporate the - address of the reloc. */ - if (! bfd_is_und_section (bfd_get_section (symbol)) - && ! bfd_is_com_section (bfd_get_section (symbol))) - val -= (input_section->output_section->vma - + input_section->output_offset - + reloc_entry->address); - - /* The low order 16 bits are always treated as a signed value. - Therefore, a negative value in the low order bits requires an - adjustment in the high order bits. We need to make this - adjustment in two ways: once for the bits we took from the - data, and once for the bits we are putting back in to the - data. */ - if ((vallo & 0x8000) != 0) - val -= 0x10000; - if ((val & 0x8000) != 0) - val += 0x10000; - - insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff); - bfd_put_32 (abfd, insn, mips_relhi_addr); - - mips_relhi_addr = (bfd_byte *) NULL; - } - - /* If this is a reloc against a section symbol, then it is correct - in the object file. The only time we want to change this case is - when we are relaxing, and that is handled entirely by - mips_relocate_section and never calls this function. */ - if ((symbol->flags & BSF_SECTION_SYM) != 0) - { - if (output_bfd != (bfd *) NULL) - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* bfd_perform_relocation does not handle pcrel_offset relocations - correctly when generating a relocateable file, so handle them - directly here. */ - if (output_bfd != (bfd *) NULL) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* Now do the RELLO reloc in the usual way. */ - return mips_generic_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message); -} - -/* This is the special function for the MIPS_R_SWITCH reloc. This - special reloc is normally correct in the object file, and only - requires special handling when relaxing. We don't want - bfd_perform_relocation to tamper with it at all. */ - -/*ARGSUSED*/ -static bfd_reloc_status_type -mips_switch_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - return bfd_reloc_ok; -} - -/* Get the howto structure for a generic reloc type. */ - -static reloc_howto_type * -mips_bfd_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - int mips_type; - - switch (code) - { - case BFD_RELOC_16: - mips_type = MIPS_R_REFHALF; - break; - case BFD_RELOC_32: - case BFD_RELOC_CTOR: - mips_type = MIPS_R_REFWORD; - break; - case BFD_RELOC_MIPS_JMP: - mips_type = MIPS_R_JMPADDR; - break; - case BFD_RELOC_HI16_S: - mips_type = MIPS_R_REFHI; - break; - case BFD_RELOC_LO16: - mips_type = MIPS_R_REFLO; - break; - case BFD_RELOC_MIPS_GPREL: - mips_type = MIPS_R_GPREL; - break; - case BFD_RELOC_MIPS_LITERAL: - mips_type = MIPS_R_LITERAL; - break; - case BFD_RELOC_16_PCREL_S2: - mips_type = MIPS_R_PCREL16; - break; - case BFD_RELOC_PCREL_HI16_S: - mips_type = MIPS_R_RELHI; - break; - case BFD_RELOC_PCREL_LO16: - mips_type = MIPS_R_RELLO; - break; - case BFD_RELOC_GPREL32: - mips_type = MIPS_R_SWITCH; - break; - default: - return (reloc_howto_type *) NULL; - } - - return &mips_howto_table[mips_type]; -} - -/* A helper routine for mips_relocate_section which handles the REFHI - and RELHI relocations. The REFHI relocation must be followed by a - REFLO relocation (and RELHI by a RELLO), and the addend used is - formed from the addends of both instructions. */ - -static void -mips_relocate_hi (refhi, reflo, input_bfd, input_section, contents, adjust, - relocation, pcrel) - struct internal_reloc *refhi; - struct internal_reloc *reflo; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - size_t adjust; - bfd_vma relocation; - boolean pcrel; -{ - unsigned long insn; - unsigned long val; - unsigned long vallo; - - insn = bfd_get_32 (input_bfd, - contents + adjust + refhi->r_vaddr - input_section->vma); - vallo = (bfd_get_32 (input_bfd, - contents + adjust + reflo->r_vaddr - input_section->vma) - & 0xffff); - val = ((insn & 0xffff) << 16) + vallo; - val += relocation; - - /* The low order 16 bits are always treated as a signed value. - Therefore, a negative value in the low order bits requires an - adjustment in the high order bits. We need to make this - adjustment in two ways: once for the bits we took from the data, - and once for the bits we are putting back in to the data. */ - if ((vallo & 0x8000) != 0) - val -= 0x10000; - - if (pcrel) - val -= (input_section->output_section->vma - + input_section->output_offset - + (reflo->r_vaddr - input_section->vma + adjust)); - - if ((val & 0x8000) != 0) - val += 0x10000; - - insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff); - bfd_put_32 (input_bfd, (bfd_vma) insn, - contents + adjust + refhi->r_vaddr - input_section->vma); -} - -/* Relocate a section while linking a MIPS ECOFF file. */ - -static boolean -mips_relocate_section (output_bfd, info, input_bfd, input_section, - contents, external_relocs) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - PTR external_relocs; -{ - asection **symndx_to_section; - struct ecoff_link_hash_entry **sym_hashes; - bfd_vma gp; - boolean gp_undefined; - size_t adjust; - long *offsets; - struct external_reloc *ext_rel; - struct external_reloc *ext_rel_end; - unsigned int i; - boolean got_lo; - struct internal_reloc lo_int_rel; - - BFD_ASSERT (input_bfd->xvec->header_byteorder - == output_bfd->xvec->header_byteorder); - - /* We keep a table mapping the symndx found in an internal reloc to - the appropriate section. This is faster than looking up the - section by name each time. */ - symndx_to_section = ecoff_data (input_bfd)->symndx_to_section; - if (symndx_to_section == (asection **) NULL) - { - symndx_to_section = ((asection **) - bfd_alloc (input_bfd, - (NUM_RELOC_SECTIONS - * sizeof (asection *)))); - if (!symndx_to_section) - return false; - - symndx_to_section[RELOC_SECTION_NONE] = NULL; - symndx_to_section[RELOC_SECTION_TEXT] = - bfd_get_section_by_name (input_bfd, ".text"); - symndx_to_section[RELOC_SECTION_RDATA] = - bfd_get_section_by_name (input_bfd, ".rdata"); - symndx_to_section[RELOC_SECTION_DATA] = - bfd_get_section_by_name (input_bfd, ".data"); - symndx_to_section[RELOC_SECTION_SDATA] = - bfd_get_section_by_name (input_bfd, ".sdata"); - symndx_to_section[RELOC_SECTION_SBSS] = - bfd_get_section_by_name (input_bfd, ".sbss"); - symndx_to_section[RELOC_SECTION_BSS] = - bfd_get_section_by_name (input_bfd, ".bss"); - symndx_to_section[RELOC_SECTION_INIT] = - bfd_get_section_by_name (input_bfd, ".init"); - symndx_to_section[RELOC_SECTION_LIT8] = - bfd_get_section_by_name (input_bfd, ".lit8"); - symndx_to_section[RELOC_SECTION_LIT4] = - bfd_get_section_by_name (input_bfd, ".lit4"); - symndx_to_section[RELOC_SECTION_XDATA] = NULL; - symndx_to_section[RELOC_SECTION_PDATA] = NULL; - symndx_to_section[RELOC_SECTION_FINI] = - bfd_get_section_by_name (input_bfd, ".fini"); - symndx_to_section[RELOC_SECTION_LITA] = NULL; - symndx_to_section[RELOC_SECTION_ABS] = NULL; - - ecoff_data (input_bfd)->symndx_to_section = symndx_to_section; - } - - sym_hashes = ecoff_data (input_bfd)->sym_hashes; - - gp = _bfd_get_gp_value (output_bfd); - if (gp == 0) - gp_undefined = true; - else - gp_undefined = false; - - got_lo = false; - - adjust = 0; - - if (ecoff_section_data (input_bfd, input_section) == NULL) - offsets = NULL; - else - offsets = ecoff_section_data (input_bfd, input_section)->offsets; - - ext_rel = (struct external_reloc *) external_relocs; - ext_rel_end = ext_rel + input_section->reloc_count; - for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++) - { - struct internal_reloc int_rel; - bfd_vma addend; - reloc_howto_type *howto; - struct ecoff_link_hash_entry *h = NULL; - asection *s = NULL; - bfd_vma relocation; - bfd_reloc_status_type r; - - if (! got_lo) - mips_ecoff_swap_reloc_in (input_bfd, (PTR) ext_rel, &int_rel); - else - { - int_rel = lo_int_rel; - got_lo = false; - } - - BFD_ASSERT (int_rel.r_type - < sizeof mips_howto_table / sizeof mips_howto_table[0]); - - /* The REFHI and RELHI relocs requires special handling. they - must be followed by a REFLO or RELLO reloc, respectively, and - the addend is formed from both relocs. */ - if (int_rel.r_type == MIPS_R_REFHI - || int_rel.r_type == MIPS_R_RELHI) - { - BFD_ASSERT ((ext_rel + 1) < ext_rel_end); - mips_ecoff_swap_reloc_in (input_bfd, (PTR) (ext_rel + 1), - &lo_int_rel); - BFD_ASSERT ((lo_int_rel.r_type - == (int_rel.r_type == MIPS_R_REFHI - ? MIPS_R_REFLO - : MIPS_R_RELLO)) - && int_rel.r_extern == lo_int_rel.r_extern - && int_rel.r_symndx == lo_int_rel.r_symndx); - got_lo = true; - } - - howto = &mips_howto_table[int_rel.r_type]; - - /* The SWITCH reloc must be handled specially. This reloc is - marks the location of a difference between two portions of an - object file. The symbol index does not reference a symbol, - but is actually the offset from the reloc to the subtrahend - of the difference. This reloc is correct in the object file, - and needs no further adjustment, unless we are relaxing. If - we are relaxing, we may have to add in an offset. Since no - symbols are involved in this reloc, we handle it completely - here. */ - if (int_rel.r_type == MIPS_R_SWITCH) - { - if (offsets != NULL - && offsets[i] != 0) - { - r = _bfd_relocate_contents (howto, input_bfd, - (bfd_vma) offsets[i], - (contents - + adjust - + int_rel.r_vaddr - - input_section->vma)); - BFD_ASSERT (r == bfd_reloc_ok); - } - - continue; - } - - if (int_rel.r_extern) - { - h = sym_hashes[int_rel.r_symndx]; - /* If h is NULL, that means that there is a reloc against an - external symbol which we thought was just a debugging - symbol. This should not happen. */ - if (h == (struct ecoff_link_hash_entry *) NULL) - abort (); - } - else - { - if (int_rel.r_symndx < 0 || int_rel.r_symndx >= NUM_RELOC_SECTIONS) - s = NULL; - else - s = symndx_to_section[int_rel.r_symndx]; - - if (s == (asection *) NULL) - abort (); - } - - /* The GPREL reloc uses an addend: the difference in the GP - values. */ - if (int_rel.r_type != MIPS_R_GPREL - && int_rel.r_type != MIPS_R_LITERAL) - addend = 0; - else - { - if (gp_undefined) - { - if (! ((*info->callbacks->reloc_dangerous) - (info, "GP relative relocation when GP not defined", - input_bfd, input_section, - int_rel.r_vaddr - input_section->vma))) - return false; - /* Only give the error once per link. */ - gp = 4; - _bfd_set_gp_value (output_bfd, gp); - gp_undefined = false; - } - if (! int_rel.r_extern) - { - /* This is a relocation against a section. The current - addend in the instruction is the difference between - INPUT_SECTION->vma and the GP value of INPUT_BFD. We - must change this to be the difference between the - final definition (which will end up in RELOCATION) - and the GP value of OUTPUT_BFD (which is in GP). */ - addend = ecoff_data (input_bfd)->gp - gp; - } - else if (! info->relocateable - || h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - /* This is a relocation against a defined symbol. The - current addend in the instruction is simply the - desired offset into the symbol (normally zero). We - are going to change this into a relocation against a - defined symbol, so we want the instruction to hold - the difference between the final definition of the - symbol (which will end up in RELOCATION) and the GP - value of OUTPUT_BFD (which is in GP). */ - addend = - gp; - } - else - { - /* This is a relocation against an undefined or common - symbol. The current addend in the instruction is - simply the desired offset into the symbol (normally - zero). We are generating relocateable output, and we - aren't going to define this symbol, so we just leave - the instruction alone. */ - addend = 0; - } - } - - /* If we are relaxing, mips_relax_section may have set - offsets[i] to some value. A value of 1 means we must expand - a PC relative branch into a multi-instruction of sequence, - and any other value is an addend. */ - if (offsets != NULL - && offsets[i] != 0) - { - BFD_ASSERT (! info->relocateable); - BFD_ASSERT (int_rel.r_type == MIPS_R_PCREL16 - || int_rel.r_type == MIPS_R_RELHI - || int_rel.r_type == MIPS_R_RELLO); - if (offsets[i] != 1) - addend += offsets[i]; - else - { - bfd_byte *here; - - BFD_ASSERT (int_rel.r_extern - && int_rel.r_type == MIPS_R_PCREL16); - - /* Move the rest of the instructions up. */ - here = (contents - + adjust - + int_rel.r_vaddr - - input_section->vma); - memmove (here + PCREL16_EXPANSION_ADJUSTMENT, here, - (size_t) (input_section->_raw_size - - (int_rel.r_vaddr - input_section->vma))); - - /* Generate the new instructions. */ - if (! mips_relax_pcrel16 (info, input_bfd, input_section, - h, here, - (input_section->output_section->vma - + input_section->output_offset - + (int_rel.r_vaddr - - input_section->vma) - + adjust))) - return false; - - /* We must adjust everything else up a notch. */ - adjust += PCREL16_EXPANSION_ADJUSTMENT; - - /* mips_relax_pcrel16 handles all the details of this - relocation. */ - continue; - } - } - - /* If we are relaxing, and this is a reloc against the .text - segment, we may need to adjust it if some branches have been - expanded. The reloc types which are likely to occur in the - .text section are handled efficiently by mips_relax_section, - and thus do not need to be handled here. */ - if (ecoff_data (input_bfd)->debug_info.adjust != NULL - && ! int_rel.r_extern - && int_rel.r_symndx == RELOC_SECTION_TEXT - && (strcmp (bfd_get_section_name (input_bfd, input_section), - ".text") != 0 - || (int_rel.r_type != MIPS_R_PCREL16 - && int_rel.r_type != MIPS_R_SWITCH - && int_rel.r_type != MIPS_R_RELHI - && int_rel.r_type != MIPS_R_RELLO))) - { - bfd_vma adr; - struct ecoff_value_adjust *a; - - /* We need to get the addend so that we know whether we need - to adjust the address. */ - BFD_ASSERT (int_rel.r_type == MIPS_R_REFWORD); - - adr = bfd_get_32 (input_bfd, - (contents - + adjust - + int_rel.r_vaddr - - input_section->vma)); - - for (a = ecoff_data (input_bfd)->debug_info.adjust; - a != (struct ecoff_value_adjust *) NULL; - a = a->next) - { - if (adr >= a->start && adr < a->end) - addend += a->adjust; - } - } - - if (info->relocateable) - { - /* We are generating relocateable output, and must convert - the existing reloc. */ - if (int_rel.r_extern) - { - if ((h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && ! bfd_is_abs_section (h->root.u.def.section)) - { - const char *name; - - /* This symbol is defined in the output. Convert - the reloc from being against the symbol to being - against the section. */ - - /* Clear the r_extern bit. */ - int_rel.r_extern = 0; - - /* Compute a new r_symndx value. */ - s = h->root.u.def.section; - name = bfd_get_section_name (output_bfd, - s->output_section); - - int_rel.r_symndx = -1; - switch (name[1]) - { - case 'b': - if (strcmp (name, ".bss") == 0) - int_rel.r_symndx = RELOC_SECTION_BSS; - break; - case 'd': - if (strcmp (name, ".data") == 0) - int_rel.r_symndx = RELOC_SECTION_DATA; - break; - case 'f': - if (strcmp (name, ".fini") == 0) - int_rel.r_symndx = RELOC_SECTION_FINI; - break; - case 'i': - if (strcmp (name, ".init") == 0) - int_rel.r_symndx = RELOC_SECTION_INIT; - break; - case 'l': - if (strcmp (name, ".lit8") == 0) - int_rel.r_symndx = RELOC_SECTION_LIT8; - else if (strcmp (name, ".lit4") == 0) - int_rel.r_symndx = RELOC_SECTION_LIT4; - break; - case 'r': - if (strcmp (name, ".rdata") == 0) - int_rel.r_symndx = RELOC_SECTION_RDATA; - break; - case 's': - if (strcmp (name, ".sdata") == 0) - int_rel.r_symndx = RELOC_SECTION_SDATA; - else if (strcmp (name, ".sbss") == 0) - int_rel.r_symndx = RELOC_SECTION_SBSS; - break; - case 't': - if (strcmp (name, ".text") == 0) - int_rel.r_symndx = RELOC_SECTION_TEXT; - break; - } - - if (int_rel.r_symndx == -1) - abort (); - - /* Add the section VMA and the symbol value. */ - relocation = (h->root.u.def.value - + s->output_section->vma - + s->output_offset); - - /* For a PC relative relocation, the object file - currently holds just the addend. We must adjust - by the address to get the right value. */ - if (howto->pc_relative) - { - relocation -= int_rel.r_vaddr - input_section->vma; - - /* If we are converting a RELHI or RELLO reloc - from being against an external symbol to - being against a section, we must put a - special value into the r_offset field. This - value is the old addend. The r_offset for - both the RELOHI and RELLO relocs are the - same, and we set both when we see RELHI. */ - if (int_rel.r_type == MIPS_R_RELHI) - { - long addhi, addlo; - - addhi = bfd_get_32 (input_bfd, - (contents - + adjust - + int_rel.r_vaddr - - input_section->vma)); - addhi &= 0xffff; - if (addhi & 0x8000) - addhi -= 0x10000; - addhi <<= 16; - - addlo = bfd_get_32 (input_bfd, - (contents - + adjust - + lo_int_rel.r_vaddr - - input_section->vma)); - addlo &= 0xffff; - if (addlo & 0x8000) - addlo -= 0x10000; - - int_rel.r_offset = addhi + addlo; - lo_int_rel.r_offset = int_rel.r_offset; - } - } - - h = NULL; - } - else - { - /* Change the symndx value to the right one for the - output BFD. */ - int_rel.r_symndx = h->indx; - if (int_rel.r_symndx == -1) - { - /* This symbol is not being written out. */ - if (! ((*info->callbacks->unattached_reloc) - (info, h->root.root.string, input_bfd, - input_section, - int_rel.r_vaddr - input_section->vma))) - return false; - int_rel.r_symndx = 0; - } - relocation = 0; - } - } - else - { - /* This is a relocation against a section. Adjust the - value by the amount the section moved. */ - relocation = (s->output_section->vma - + s->output_offset - - s->vma); - } - - relocation += addend; - addend = 0; - - /* Adjust a PC relative relocation by removing the reference - to the original address in the section and including the - reference to the new address. However, external RELHI - and RELLO relocs are PC relative, but don't include any - reference to the address. The addend is merely an - addend. */ - if (howto->pc_relative - && (! int_rel.r_extern - || (int_rel.r_type != MIPS_R_RELHI - && int_rel.r_type != MIPS_R_RELLO))) - relocation -= (input_section->output_section->vma - + input_section->output_offset - - input_section->vma); - - /* Adjust the contents. */ - if (relocation == 0) - r = bfd_reloc_ok; - else - { - if (int_rel.r_type != MIPS_R_REFHI - && int_rel.r_type != MIPS_R_RELHI) - r = _bfd_relocate_contents (howto, input_bfd, relocation, - (contents - + adjust - + int_rel.r_vaddr - - input_section->vma)); - else - { - mips_relocate_hi (&int_rel, &lo_int_rel, - input_bfd, input_section, contents, - adjust, relocation, - int_rel.r_type == MIPS_R_RELHI); - r = bfd_reloc_ok; - } - } - - /* Adjust the reloc address. */ - int_rel.r_vaddr += (input_section->output_section->vma - + input_section->output_offset - - input_section->vma); - - /* Save the changed reloc information. */ - mips_ecoff_swap_reloc_out (input_bfd, &int_rel, (PTR) ext_rel); - } - else - { - /* We are producing a final executable. */ - if (int_rel.r_extern) - { - /* This is a reloc against a symbol. */ - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - asection *hsec; - - hsec = h->root.u.def.section; - relocation = (h->root.u.def.value - + hsec->output_section->vma - + hsec->output_offset); - } - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, - int_rel.r_vaddr - input_section->vma))) - return false; - relocation = 0; - } - } - else - { - /* This is a reloc against a section. */ - relocation = (s->output_section->vma - + s->output_offset - - s->vma); - - /* A PC relative reloc is already correct in the object - file. Make it look like a pcrel_offset relocation by - adding in the start address. */ - if (howto->pc_relative) - { - if (int_rel.r_type != MIPS_R_RELHI) - relocation += int_rel.r_vaddr + adjust; - else - relocation += lo_int_rel.r_vaddr + adjust; - } - } - - if (int_rel.r_type != MIPS_R_REFHI - && int_rel.r_type != MIPS_R_RELHI) - r = _bfd_final_link_relocate (howto, - input_bfd, - input_section, - contents, - (int_rel.r_vaddr - - input_section->vma - + adjust), - relocation, - addend); - else - { - mips_relocate_hi (&int_rel, &lo_int_rel, input_bfd, - input_section, contents, adjust, - relocation, - int_rel.r_type == MIPS_R_RELHI); - r = bfd_reloc_ok; - } - } - - /* MIPS_R_JMPADDR requires peculiar overflow detection. The - instruction provides a 28 bit address (the two lower bits are - implicit zeroes) which is combined with the upper four bits - of the instruction address. */ - if (r == bfd_reloc_ok - && int_rel.r_type == MIPS_R_JMPADDR - && (((relocation - + addend - + (int_rel.r_extern ? 0 : s->vma)) - & 0xf0000000) - != ((input_section->output_section->vma - + input_section->output_offset - + (int_rel.r_vaddr - input_section->vma) - + adjust) - & 0xf0000000))) - r = bfd_reloc_overflow; - - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (int_rel.r_extern) - name = h->root.root.string; - else - name = bfd_section_name (input_bfd, s); - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, - input_bfd, input_section, - int_rel.r_vaddr - input_section->vma))) - return false; - } - break; - } - } - } - - return true; -} - -/* Read in the relocs for a section. */ - -static boolean -mips_read_relocs (abfd, sec) - bfd *abfd; - asection *sec; -{ - struct ecoff_section_tdata *section_tdata; - - section_tdata = ecoff_section_data (abfd, sec); - if (section_tdata == (struct ecoff_section_tdata *) NULL) - { - sec->used_by_bfd = - (PTR) bfd_alloc_by_size_t (abfd, sizeof (struct ecoff_section_tdata)); - if (sec->used_by_bfd == NULL) - return false; - - section_tdata = ecoff_section_data (abfd, sec); - section_tdata->external_relocs = NULL; - section_tdata->contents = NULL; - section_tdata->offsets = NULL; - } - - if (section_tdata->external_relocs == NULL) - { - bfd_size_type external_relocs_size; - - external_relocs_size = (ecoff_backend (abfd)->external_reloc_size - * sec->reloc_count); - - section_tdata->external_relocs = - (PTR) bfd_alloc (abfd, external_relocs_size); - if (section_tdata->external_relocs == NULL && external_relocs_size != 0) - return false; - - if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0 - || (bfd_read (section_tdata->external_relocs, 1, - external_relocs_size, abfd) - != external_relocs_size)) - return false; - } - - return true; -} - -/* Relax a section when linking a MIPS ECOFF file. This is used for - embedded PIC code, which always uses PC relative branches which - only have an 18 bit range on MIPS. If a branch is not in range, we - generate a long instruction sequence to compensate. Each time we - find a branch to expand, we have to check all the others again to - make sure they are still in range. This is slow, but it only has - to be done when -relax is passed to the linker. - - This routine figures out which branches need to expand; the actual - expansion is done in mips_relocate_section when the section - contents are relocated. The information is stored in the offsets - field of the ecoff_section_tdata structure. An offset of 1 means - that the branch must be expanded into a multi-instruction PC - relative branch (such an offset will only occur for a PC relative - branch to an external symbol). Any other offset must be a multiple - of four, and is the amount to change the branch by (such an offset - will only occur for a PC relative branch within the same section). - - We do not modify the section relocs or contents themselves so that - if memory usage becomes an issue we can discard them and read them - again. The only information we must save in memory between this - routine and the mips_relocate_section routine is the table of - offsets. */ - -static boolean -mips_relax_section (abfd, sec, info, again) - bfd *abfd; - asection *sec; - struct bfd_link_info *info; - boolean *again; -{ - struct ecoff_section_tdata *section_tdata; - bfd_byte *contents = NULL; - long *offsets; - struct external_reloc *ext_rel; - struct external_reloc *ext_rel_end; - unsigned int i; - - /* Assume we are not going to need another pass. */ - *again = false; - - /* If we are not generating an ECOFF file, this is much too - confusing to deal with. */ - if (info->hash->creator->flavour != bfd_get_flavour (abfd)) - return true; - - /* If there are no relocs, there is nothing to do. */ - if (sec->reloc_count == 0) - return true; - - /* We are only interested in PC relative relocs, and why would there - ever be one from anything but the .text section? */ - if (strcmp (bfd_get_section_name (abfd, sec), ".text") != 0) - return true; - - /* Read in the relocs, if we haven't already got them. */ - section_tdata = ecoff_section_data (abfd, sec); - if (section_tdata == (struct ecoff_section_tdata *) NULL - || section_tdata->external_relocs == NULL) - { - if (! mips_read_relocs (abfd, sec)) - goto error_return; - section_tdata = ecoff_section_data (abfd, sec); - } - - if (sec->_cooked_size == 0) - { - /* We must initialize _cooked_size only the first time we are - called. */ - sec->_cooked_size = sec->_raw_size; - } - - contents = section_tdata->contents; - offsets = section_tdata->offsets; - - /* Look for any external PC relative relocs. Internal PC relative - relocs are already correct in the object file, so they certainly - can not overflow. */ - ext_rel = (struct external_reloc *) section_tdata->external_relocs; - ext_rel_end = ext_rel + sec->reloc_count; - for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++) - { - struct internal_reloc int_rel; - struct ecoff_link_hash_entry *h; - asection *hsec; - bfd_signed_vma relocation; - struct external_reloc *adj_ext_rel; - unsigned int adj_i; - unsigned long ext_count; - struct ecoff_link_hash_entry **adj_h_ptr; - struct ecoff_link_hash_entry **adj_h_ptr_end; - struct ecoff_value_adjust *adjust; - - /* If we have already expanded this reloc, we certainly don't - need to do it again. */ - if (offsets != (long *) NULL && offsets[i] == 1) - continue; - - /* Quickly check that this reloc is external PCREL16. */ - if (bfd_header_big_endian (abfd)) - { - if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_BIG) == 0 - || (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_BIG) - >> RELOC_BITS3_TYPE_SH_BIG) - != MIPS_R_PCREL16)) - continue; - } - else - { - if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) == 0 - || (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_LITTLE) - >> RELOC_BITS3_TYPE_SH_LITTLE) - != MIPS_R_PCREL16)) - continue; - } - - mips_ecoff_swap_reloc_in (abfd, (PTR) ext_rel, &int_rel); - - h = ecoff_data (abfd)->sym_hashes[int_rel.r_symndx]; - if (h == (struct ecoff_link_hash_entry *) NULL) - abort (); - - if (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak) - { - /* Just ignore undefined symbols. These will presumably - generate an error later in the link. */ - continue; - } - - /* Get the value of the symbol. */ - hsec = h->root.u.def.section; - relocation = (h->root.u.def.value - + hsec->output_section->vma - + hsec->output_offset); - - /* Subtract out the current address. */ - relocation -= (sec->output_section->vma - + sec->output_offset - + (int_rel.r_vaddr - sec->vma)); - - /* The addend is stored in the object file. In the normal case - of ``bal symbol'', the addend will be -4. It will only be - different in the case of ``bal symbol+constant''. To avoid - always reading in the section contents, we don't check the - addend in the object file (we could easily check the contents - if we happen to have already read them in, but I fear that - this could be confusing). This means we will screw up if - there is a branch to a symbol that is in range, but added to - a constant which puts it out of range; in such a case the - link will fail with a reloc overflow error. Since the - compiler will never generate such code, it should be easy - enough to work around it by changing the assembly code in the - source file. */ - relocation -= 4; - - /* Now RELOCATION is the number we want to put in the object - file. See whether it fits. */ - if (relocation >= -0x20000 && relocation < 0x20000) - continue; - - /* Now that we know this reloc needs work, which will rarely - happen, go ahead and grab the section contents. */ - if (contents == (bfd_byte *) NULL) - { - if (info->keep_memory) - contents = (bfd_byte *) bfd_alloc (abfd, sec->_raw_size); - else - contents = (bfd_byte *) bfd_malloc ((size_t) sec->_raw_size); - if (contents == (bfd_byte *) NULL) - goto error_return; - if (! bfd_get_section_contents (abfd, sec, (PTR) contents, - (file_ptr) 0, sec->_raw_size)) - goto error_return; - if (info->keep_memory) - section_tdata->contents = contents; - } - - /* We only support changing the bal instruction. It would be - possible to handle other PC relative branches, but some of - them (the conditional branches) would require a different - length instruction sequence which would complicate both this - routine and mips_relax_pcrel16. It could be written if - somebody felt it were important. Ignoring this reloc will - presumably cause a reloc overflow error later on. */ - if (bfd_get_32 (abfd, contents + int_rel.r_vaddr - sec->vma) - != 0x0411ffff) /* bgezal $0,. == bal . */ - continue; - - /* Bother. We need to expand this reloc, and we will need to - make another relaxation pass since this change may put other - relocs out of range. We need to examine the local branches - and we need to allocate memory to hold the offsets we must - add to them. We also need to adjust the values of all - symbols in the object file following this location. */ - - sec->_cooked_size += PCREL16_EXPANSION_ADJUSTMENT; - *again = true; - - if (offsets == (long *) NULL) - { - size_t size; - - size = sec->reloc_count * sizeof (long); - offsets = (long *) bfd_alloc_by_size_t (abfd, size); - if (offsets == (long *) NULL) - goto error_return; - memset (offsets, 0, size); - section_tdata->offsets = offsets; - } - - offsets[i] = 1; - - /* Now look for all PC relative references that cross this reloc - and adjust their offsets. */ - adj_ext_rel = (struct external_reloc *) section_tdata->external_relocs; - for (adj_i = 0; adj_ext_rel < ext_rel_end; adj_ext_rel++, adj_i++) - { - struct internal_reloc adj_int_rel; - bfd_vma start, stop; - int change; - - mips_ecoff_swap_reloc_in (abfd, (PTR) adj_ext_rel, &adj_int_rel); - - if (adj_int_rel.r_type == MIPS_R_PCREL16) - { - unsigned long insn; - - /* We only care about local references. External ones - will be relocated correctly anyhow. */ - if (adj_int_rel.r_extern) - continue; - - /* We are only interested in a PC relative reloc within - this section. FIXME: Cross section PC relative - relocs may not be handled correctly; does anybody - care? */ - if (adj_int_rel.r_symndx != RELOC_SECTION_TEXT) - continue; - - start = adj_int_rel.r_vaddr; - - insn = bfd_get_32 (abfd, - contents + adj_int_rel.r_vaddr - sec->vma); - - stop = (insn & 0xffff) << 2; - if ((stop & 0x20000) != 0) - stop -= 0x40000; - stop += adj_int_rel.r_vaddr + 4; - } - else if (adj_int_rel.r_type == MIPS_R_RELHI) - { - struct internal_reloc rello; - long addhi, addlo; - - /* The next reloc must be MIPS_R_RELLO, and we handle - them together. */ - BFD_ASSERT (adj_ext_rel + 1 < ext_rel_end); - - mips_ecoff_swap_reloc_in (abfd, (PTR) (adj_ext_rel + 1), &rello); - - BFD_ASSERT (rello.r_type == MIPS_R_RELLO); - - addhi = bfd_get_32 (abfd, - contents + adj_int_rel.r_vaddr - sec->vma); - addhi &= 0xffff; - if (addhi & 0x8000) - addhi -= 0x10000; - addhi <<= 16; - - addlo = bfd_get_32 (abfd, contents + rello.r_vaddr - sec->vma); - addlo &= 0xffff; - if (addlo & 0x8000) - addlo -= 0x10000; - - if (adj_int_rel.r_extern) - { - /* The value we want here is - sym - RELLOaddr + addend - which we can express as - sym - (RELLOaddr - addend) - Therefore if we are expanding the area between - RELLOaddr and RELLOaddr - addend we must adjust - the addend. This is admittedly ambiguous, since - we might mean (sym + addend) - RELLOaddr, but in - practice we don't, and there is no way to handle - that case correctly since at this point we have - no idea whether any reloc is being expanded - between sym and sym + addend. */ - start = rello.r_vaddr - (addhi + addlo); - stop = rello.r_vaddr; - } - else - { - /* An internal RELHI/RELLO pair represents the - difference between two addresses, $LC0 - foo. - The symndx value is actually the difference - between the reloc address and $LC0. This lets us - compute $LC0, and, by considering the addend, - foo. If the reloc we are expanding falls between - those two relocs, we must adjust the addend. At - this point, the symndx value is actually in the - r_offset field, where it was put by - mips_ecoff_swap_reloc_in. */ - start = rello.r_vaddr - adj_int_rel.r_offset; - stop = start + addhi + addlo; - } - } - else if (adj_int_rel.r_type == MIPS_R_SWITCH) - { - /* A MIPS_R_SWITCH reloc represents a word of the form - .word $L3-$LS12 - The value in the object file is correct, assuming the - original value of $L3. The symndx value is actually - the difference between the reloc address and $LS12. - This lets us compute the original value of $LS12 as - vaddr - symndx - and the original value of $L3 as - vaddr - symndx + addend - where addend is the value from the object file. At - this point, the symndx value is actually found in the - r_offset field, since it was moved by - mips_ecoff_swap_reloc_in. */ - start = adj_int_rel.r_vaddr - adj_int_rel.r_offset; - stop = start + bfd_get_32 (abfd, - (contents - + adj_int_rel.r_vaddr - - sec->vma)); - } - else - continue; - - /* If the range expressed by this reloc, which is the - distance between START and STOP crosses the reloc we are - expanding, we must adjust the offset. The sign of the - adjustment depends upon the direction in which the range - crosses the reloc being expanded. */ - if (start <= int_rel.r_vaddr && stop > int_rel.r_vaddr) - change = PCREL16_EXPANSION_ADJUSTMENT; - else if (start > int_rel.r_vaddr && stop <= int_rel.r_vaddr) - change = - PCREL16_EXPANSION_ADJUSTMENT; - else - change = 0; - - offsets[adj_i] += change; - - if (adj_int_rel.r_type == MIPS_R_RELHI) - { - adj_ext_rel++; - adj_i++; - offsets[adj_i] += change; - } - } - - /* Find all symbols in this section defined by this object file - and adjust their values. Note that we decide whether to - adjust the value based on the value stored in the ECOFF EXTR - structure, because the value stored in the hash table may - have been changed by an earlier expanded reloc and thus may - no longer correctly indicate whether the symbol is before or - after the expanded reloc. */ - ext_count = ecoff_data (abfd)->debug_info.symbolic_header.iextMax; - adj_h_ptr = ecoff_data (abfd)->sym_hashes; - adj_h_ptr_end = adj_h_ptr + ext_count; - for (; adj_h_ptr < adj_h_ptr_end; adj_h_ptr++) - { - struct ecoff_link_hash_entry *adj_h; - - adj_h = *adj_h_ptr; - if (adj_h != (struct ecoff_link_hash_entry *) NULL - && (adj_h->root.type == bfd_link_hash_defined - || adj_h->root.type == bfd_link_hash_defweak) - && adj_h->root.u.def.section == sec - && adj_h->esym.asym.value > int_rel.r_vaddr) - adj_h->root.u.def.value += PCREL16_EXPANSION_ADJUSTMENT; - } - - /* Add an entry to the symbol value adjust list. This is used - by bfd_ecoff_debug_accumulate to adjust the values of - internal symbols and FDR's. */ - adjust = ((struct ecoff_value_adjust *) - bfd_alloc (abfd, sizeof (struct ecoff_value_adjust))); - if (adjust == (struct ecoff_value_adjust *) NULL) - goto error_return; - - adjust->start = int_rel.r_vaddr; - adjust->end = sec->vma + sec->_raw_size; - adjust->adjust = PCREL16_EXPANSION_ADJUSTMENT; - - adjust->next = ecoff_data (abfd)->debug_info.adjust; - ecoff_data (abfd)->debug_info.adjust = adjust; - } - - if (contents != (bfd_byte *) NULL && ! info->keep_memory) - free (contents); - - return true; - - error_return: - if (contents != (bfd_byte *) NULL && ! info->keep_memory) - free (contents); - return false; -} - -/* This routine is called from mips_relocate_section when a PC - relative reloc must be expanded into the five instruction sequence. - It handles all the details of the expansion, including resolving - the reloc. */ - -static boolean -mips_relax_pcrel16 (info, input_bfd, input_section, h, location, address) - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - struct ecoff_link_hash_entry *h; - bfd_byte *location; - bfd_vma address; -{ - bfd_vma relocation; - - /* 0x0411ffff is bgezal $0,. == bal . */ - BFD_ASSERT (bfd_get_32 (input_bfd, location) == 0x0411ffff); - - /* We need to compute the distance between the symbol and the - current address plus eight. */ - relocation = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - relocation -= address + 8; - - /* If the lower half is negative, increment the upper 16 half. */ - if ((relocation & 0x8000) != 0) - relocation += 0x10000; - - bfd_put_32 (input_bfd, 0x04110001, location); /* bal .+8 */ - bfd_put_32 (input_bfd, - 0x3c010000 | ((relocation >> 16) & 0xffff), /* lui $at,XX */ - location + 4); - bfd_put_32 (input_bfd, - 0x24210000 | (relocation & 0xffff), /* addiu $at,$at,XX */ - location + 8); - bfd_put_32 (input_bfd, 0x003f0821, location + 12); /* addu $at,$at,$ra */ - bfd_put_32 (input_bfd, 0x0020f809, location + 16); /* jalr $at */ - - return true; -} - -/* Given a .sdata section and a .rel.sdata in-memory section, store - relocation information into the .rel.sdata section which can be - used at runtime to relocate the section. This is called by the - linker when the --embedded-relocs switch is used. This is called - after the add_symbols entry point has been called for all the - objects, and before the final_link entry point is called. This - function presumes that the object was compiled using - -membedded-pic. */ - -boolean -bfd_mips_ecoff_create_embedded_relocs (abfd, info, datasec, relsec, errmsg) - bfd *abfd; - struct bfd_link_info *info; - asection *datasec; - asection *relsec; - char **errmsg; -{ - struct ecoff_link_hash_entry **sym_hashes; - struct ecoff_section_tdata *section_tdata; - struct external_reloc *ext_rel; - struct external_reloc *ext_rel_end; - bfd_byte *p; - - BFD_ASSERT (! info->relocateable); - - *errmsg = NULL; - - if (datasec->reloc_count == 0) - return true; - - sym_hashes = ecoff_data (abfd)->sym_hashes; - - if (! mips_read_relocs (abfd, datasec)) - return false; - - relsec->contents = (bfd_byte *) bfd_alloc (abfd, datasec->reloc_count * 4); - if (relsec->contents == NULL) - return false; - - p = relsec->contents; - - section_tdata = ecoff_section_data (abfd, datasec); - ext_rel = (struct external_reloc *) section_tdata->external_relocs; - ext_rel_end = ext_rel + datasec->reloc_count; - for (; ext_rel < ext_rel_end; ext_rel++, p += 4) - { - struct internal_reloc int_rel; - boolean text_relative; - - mips_ecoff_swap_reloc_in (abfd, (PTR) ext_rel, &int_rel); - - /* We are going to write a four byte word into the runtime reloc - section. The word will be the address in the data section - which must be relocated. This must be on a word boundary, - which means the lower two bits must be zero. We use the - least significant bit to indicate how the value in the data - section must be relocated. A 0 means that the value is - relative to the text section, while a 1 indicates that the - value is relative to the data section. Given that we are - assuming the code was compiled using -membedded-pic, there - should not be any other possibilities. */ - - /* We can only relocate REFWORD relocs at run time. */ - if (int_rel.r_type != MIPS_R_REFWORD) - { - *errmsg = "unsupported reloc type"; - bfd_set_error (bfd_error_bad_value); - return false; - } - - if (int_rel.r_extern) - { - struct ecoff_link_hash_entry *h; - - h = sym_hashes[int_rel.r_symndx]; - /* If h is NULL, that means that there is a reloc against an - external symbol which we thought was just a debugging - symbol. This should not happen. */ - if (h == (struct ecoff_link_hash_entry *) NULL) - abort (); - if ((h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && (h->root.u.def.section->flags & SEC_CODE) != 0) - text_relative = true; - else - text_relative = false; - } - else - { - switch (int_rel.r_symndx) - { - case RELOC_SECTION_TEXT: - text_relative = true; - break; - case RELOC_SECTION_SDATA: - case RELOC_SECTION_SBSS: - case RELOC_SECTION_LIT8: - text_relative = false; - break; - default: - /* No other sections should appear in -membedded-pic - code. */ - *errmsg = "reloc against unsupported section"; - bfd_set_error (bfd_error_bad_value); - return false; - } - } - - if ((int_rel.r_offset & 3) != 0) - { - *errmsg = "reloc not properly aligned"; - bfd_set_error (bfd_error_bad_value); - return false; - } - - bfd_put_32 (abfd, - (int_rel.r_vaddr - datasec->vma + datasec->output_offset - + (text_relative ? 0 : 1)), - p); - } - - return true; -} - -/* This is the ECOFF backend structure. The backend field of the - target vector points to this. */ - -static const struct ecoff_backend_data mips_ecoff_backend_data = -{ - /* COFF backend structure. */ - { - (void (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR))) bfd_void, /* aux_in */ - (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_in */ - (void (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_in */ - (unsigned (*) PARAMS ((bfd *,PTR,int,int,int,int,PTR)))bfd_void,/*aux_out*/ - (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* sym_out */ - (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* lineno_out */ - (unsigned (*) PARAMS ((bfd *,PTR,PTR))) bfd_void, /* reloc_out */ - mips_ecoff_swap_filehdr_out, mips_ecoff_swap_aouthdr_out, - mips_ecoff_swap_scnhdr_out, - FILHSZ, AOUTSZ, SCNHSZ, 0, 0, 0, 0, true, - mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in, - mips_ecoff_swap_scnhdr_in, NULL, - mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook, - _bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags, - _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL - }, - /* Supported architecture. */ - bfd_arch_mips, - /* Initial portion of armap string. */ - "__________", - /* The page boundary used to align sections in a demand-paged - executable file. E.g., 0x1000. */ - 0x1000, - /* True if the .rdata section is part of the text segment, as on the - Alpha. False if .rdata is part of the data segment, as on the - MIPS. */ - false, - /* Bitsize of constructor entries. */ - 32, - /* Reloc to use for constructor entries. */ - &mips_howto_table[MIPS_R_REFWORD], - { - /* Symbol table magic number. */ - magicSym, - /* Alignment of debugging information. E.g., 4. */ - 4, - /* Sizes of external symbolic information. */ - sizeof (struct hdr_ext), - sizeof (struct dnr_ext), - sizeof (struct pdr_ext), - sizeof (struct sym_ext), - sizeof (struct opt_ext), - sizeof (struct fdr_ext), - sizeof (struct rfd_ext), - sizeof (struct ext_ext), - /* Functions to swap in external symbolic data. */ - ecoff_swap_hdr_in, - ecoff_swap_dnr_in, - ecoff_swap_pdr_in, - ecoff_swap_sym_in, - ecoff_swap_opt_in, - ecoff_swap_fdr_in, - ecoff_swap_rfd_in, - ecoff_swap_ext_in, - _bfd_ecoff_swap_tir_in, - _bfd_ecoff_swap_rndx_in, - /* Functions to swap out external symbolic data. */ - ecoff_swap_hdr_out, - ecoff_swap_dnr_out, - ecoff_swap_pdr_out, - ecoff_swap_sym_out, - ecoff_swap_opt_out, - ecoff_swap_fdr_out, - ecoff_swap_rfd_out, - ecoff_swap_ext_out, - _bfd_ecoff_swap_tir_out, - _bfd_ecoff_swap_rndx_out, - /* Function to read in symbolic data. */ - _bfd_ecoff_slurp_symbolic_info - }, - /* External reloc size. */ - RELSZ, - /* Reloc swapping functions. */ - mips_ecoff_swap_reloc_in, - mips_ecoff_swap_reloc_out, - /* Backend reloc tweaking. */ - mips_adjust_reloc_in, - mips_adjust_reloc_out, - /* Relocate section contents while linking. */ - mips_relocate_section, - /* Do final adjustments to filehdr and aouthdr. */ - NULL, - /* Read an element from an archive at a given file position. */ - _bfd_get_elt_at_filepos -}; - -/* Looking up a reloc type is MIPS specific. */ -#define _bfd_ecoff_bfd_reloc_type_lookup mips_bfd_reloc_type_lookup - -/* Getting relocated section contents is generic. */ -#define _bfd_ecoff_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents - -/* Handling file windows is generic. */ -#define _bfd_ecoff_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -/* Relaxing sections is MIPS specific. */ -#define _bfd_ecoff_bfd_relax_section mips_relax_section - -const bfd_target ecoff_little_vec = -{ - "ecoff-littlemips", /* name */ - bfd_target_ecoff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA), - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - _bfd_ecoff_archive_p, _bfd_dummy_target}, - {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (_bfd_ecoff), - BFD_JUMP_TABLE_COPY (_bfd_ecoff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff), - BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff), - BFD_JUMP_TABLE_RELOCS (_bfd_ecoff), - BFD_JUMP_TABLE_WRITE (_bfd_ecoff), - BFD_JUMP_TABLE_LINK (_bfd_ecoff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) &mips_ecoff_backend_data -}; - -const bfd_target ecoff_big_vec = -{ - "ecoff-bigmips", /* name */ - bfd_target_ecoff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA), - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - _bfd_ecoff_archive_p, _bfd_dummy_target}, - {bfd_false, _bfd_ecoff_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, _bfd_ecoff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (_bfd_ecoff), - BFD_JUMP_TABLE_COPY (_bfd_ecoff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff), - BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff), - BFD_JUMP_TABLE_RELOCS (_bfd_ecoff), - BFD_JUMP_TABLE_WRITE (_bfd_ecoff), - BFD_JUMP_TABLE_LINK (_bfd_ecoff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) &mips_ecoff_backend_data -}; diff --git a/contrib/gdb/bfd/coff-pmac.c b/contrib/gdb/bfd/coff-pmac.c deleted file mode 100644 index f3332d9..0000000 --- a/contrib/gdb/bfd/coff-pmac.c +++ /dev/null @@ -1,27 +0,0 @@ -/* BFD back-end for Apple et al PowerPC Mac "XCOFF" files. - Copyright 1995 Free Software Foundation, Inc. - -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. */ - -#define TARGET_SYM pmac_xcoff_vec -#define TARGET_NAME "xcoff-powermac" - -/* Tweak coffcode.h based on this being a PowerMac instead of RS/6000. */ - -#define POWERMAC - -#include "coff-rs6000.c" diff --git a/contrib/gdb/bfd/coff-ppc.c b/contrib/gdb/bfd/coff-ppc.c deleted file mode 100644 index 4caf3d8..0000000 --- a/contrib/gdb/bfd/coff-ppc.c +++ /dev/null @@ -1,3255 +0,0 @@ -/* BFD back-end for PowerPC Microsoft Portable Executable files. - Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - - Original version pieced together by Kim Knuttila (krk@cygnus.com) - - There is nothing new under the sun. This file draws a lot on other - coff files, in particular, those for the rs/6000, alpha, mips, and - intel backends, and the PE work for the arm. - -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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Current State: - - objdump works - - relocs generated by gas - - ld will link files, but they do not run. - - dlltool will not produce correct output in some .reloc cases, and will - not produce the right glue code for dll function calls. -*/ - - -#include "bfd.h" -#include "sysdep.h" - -#include "libbfd.h" -#include "obstack.h" - -#include "coff/powerpc.h" -#include "coff/internal.h" - -#include "coff/pe.h" - -#ifdef BADMAG -#undef BADMAG -#endif - -#define BADMAG(x) PPCBADMAG(x) - -#include "libcoff.h" - -/* The toc is a set of bfd_vma fields. We use the fact that valid */ -/* addresses are even (i.e. the bit representing "1" is off) to allow */ -/* us to encode a little extra information in the field */ -/* - Unallocated addresses are intialized to 1. */ -/* - Allocated addresses are even numbers. */ -/* The first time we actually write a reference to the toc in the bfd, */ -/* we want to record that fact in a fixup file (if it is asked for), so */ -/* we keep track of whether or not an address has been written by marking */ -/* the low order bit with a "1" upon writing */ - -#define SET_UNALLOCATED(x) ((x) = 1) -#define IS_UNALLOCATED(x) ((x) == 1) - -#define IS_WRITTEN(x) ((x) & 1) -#define MARK_AS_WRITTEN(x) ((x) |= 1) -#define MAKE_ADDR_AGAIN(x) ((x) &= ~1) - -/* In order not to add an int to every hash table item for every coff - linker, we define our own hash table, derived from the coff one */ - -/* PE linker hash table entries. */ - -struct ppc_coff_link_hash_entry -{ - struct coff_link_hash_entry root; /* First entry, as required */ - - /* As we wonder around the relocs, we'll keep the assigned toc_offset - here */ - bfd_vma toc_offset; /* Our addition, as required */ - int symbol_is_glue; - unsigned long int glue_insn; - char eye_catcher[8]; -}; - -/* Need a 7 char string for an eye catcher */ -#define EYE "krkjunk" - -#define CHECK_EYE(addr) \ - if (strcmp(addr, EYE) != 0) \ - { \ - fprintf(stderr,\ - "File %s, line %d, Hash check failure, bad eye %8s\n", \ - __FILE__, __LINE__, addr); \ - abort(); \ - } - -/* PE linker hash table. */ - -struct ppc_coff_link_hash_table -{ - struct coff_link_hash_table root; /* First entry, as required */ -}; - -static struct bfd_hash_entry *ppc_coff_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, - const char *)); - -/* Routine to create an entry in the link hash table. */ - -static struct bfd_hash_entry * -ppc_coff_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct ppc_coff_link_hash_entry *ret = - (struct ppc_coff_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct ppc_coff_link_hash_entry *) NULL) - ret = (struct ppc_coff_link_hash_entry *) - bfd_hash_allocate (table, - sizeof (struct ppc_coff_link_hash_entry)); - - if (ret == (struct ppc_coff_link_hash_entry *) NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = ((struct ppc_coff_link_hash_entry *) - _bfd_coff_link_hash_newfunc ((struct bfd_hash_entry *) ret, - table, string)); - - if (ret) - { - /* Initialize the local fields. */ - SET_UNALLOCATED(ret->toc_offset); - ret->symbol_is_glue = 0; - ret->glue_insn = 0; - strcpy(ret->eye_catcher, EYE); - } - - return (struct bfd_hash_entry *) ret; -} - -/* Initialize a PE linker hash table. */ - -static boolean -ppc_coff_link_hash_table_init (table, abfd, newfunc) - struct ppc_coff_link_hash_table *table; - bfd *abfd; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); -{ - return _bfd_coff_link_hash_table_init (&table->root, abfd, newfunc); -} - -/* Create a PE linker hash table. */ - -static struct bfd_link_hash_table * -ppc_coff_link_hash_table_create (abfd) - bfd *abfd; -{ - struct ppc_coff_link_hash_table *ret; - - ret = ((struct ppc_coff_link_hash_table *) - bfd_alloc (abfd, sizeof (struct ppc_coff_link_hash_table))); - if (ret == NULL) - return NULL; - if (! ppc_coff_link_hash_table_init (ret, abfd, - ppc_coff_link_hash_newfunc)) - { - bfd_release (abfd, ret); - return (struct bfd_link_hash_table *) NULL; - } - return &ret->root.root; -} - -/* Now, tailor coffcode.h to use our hash stuff */ - -#define coff_bfd_link_hash_table_create ppc_coff_link_hash_table_create - - -/* The nt loader points the toc register to &toc + 32768, in order to */ -/* use the complete range of a 16-bit displacement (I guess). We have */ -/* to adjust for this when we fix up loads displaced off the toc reg. */ -#define TOC_LOAD_ADJUSTMENT (-32768) -#define TOC_SECTION_NAME ".private.toc" - -/* The main body of code is in coffcode.h. */ - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3) - -/* In case we're on a 32-bit machine, construct a 64-bit "-1" value - from smaller values. Start with zero, widen, *then* decrement. */ -#define MINUS_ONE (((bfd_vma)0) - 1) - -/* these should definitely go in a header file somewhere... */ - -/* NOP */ -#define IMAGE_REL_PPC_ABSOLUTE 0x0000 - -/* 64-bit address */ -#define IMAGE_REL_PPC_ADDR64 0x0001 - -/* 32-bit address */ -#define IMAGE_REL_PPC_ADDR32 0x0002 - -/* 26-bit address, shifted left 2 (branch absolute) */ -#define IMAGE_REL_PPC_ADDR24 0x0003 - -/* 16-bit address */ -#define IMAGE_REL_PPC_ADDR16 0x0004 - -/* 16-bit address, shifted left 2 (load doubleword) */ -#define IMAGE_REL_PPC_ADDR14 0x0005 - -/* 26-bit PC-relative offset, shifted left 2 (branch relative) */ -#define IMAGE_REL_PPC_REL24 0x0006 - -/* 16-bit PC-relative offset, shifted left 2 (br cond relative) */ -#define IMAGE_REL_PPC_REL14 0x0007 - -/* 16-bit offset from TOC base */ -#define IMAGE_REL_PPC_TOCREL16 0x0008 - -/* 16-bit offset from TOC base, shifted left 2 (load doubleword) */ -#define IMAGE_REL_PPC_TOCREL14 0x0009 - -/* 32-bit addr w/o image base */ -#define IMAGE_REL_PPC_ADDR32NB 0x000A - -/* va of containing section (as in an image sectionhdr) */ -#define IMAGE_REL_PPC_SECREL 0x000B - -/* sectionheader number */ -#define IMAGE_REL_PPC_SECTION 0x000C - -/* substitute TOC restore instruction iff symbol is glue code */ -#define IMAGE_REL_PPC_IFGLUE 0x000D - -/* symbol is glue code; virtual address is TOC restore instruction */ -#define IMAGE_REL_PPC_IMGLUE 0x000E - -/* va of containing section (limited to 16 bits) */ -#define IMAGE_REL_PPC_SECREL16 0x000F - -/* stuff to handle immediate data when the number of bits in the */ -/* data is greater than the number of bits in the immediate field */ -/* We need to do (usually) 32 bit arithmetic on 16 bit chunks */ -#define IMAGE_REL_PPC_REFHI 0x0010 -#define IMAGE_REL_PPC_REFLO 0x0011 -#define IMAGE_REL_PPC_PAIR 0x0012 - -/* This is essentially the same as tocrel16, with TOCDEFN assumed */ -#define IMAGE_REL_PPC_TOCREL16_DEFN 0x0013 - -/* Flag bits in IMAGE_RELOCATION.TYPE */ - -/* subtract reloc value rather than adding it */ -#define IMAGE_REL_PPC_NEG 0x0100 - -/* fix branch prediction bit to predict branch taken */ -#define IMAGE_REL_PPC_BRTAKEN 0x0200 - -/* fix branch prediction bit to predict branch not taken */ -#define IMAGE_REL_PPC_BRNTAKEN 0x0400 - -/* toc slot defined in file (or, data in toc) */ -#define IMAGE_REL_PPC_TOCDEFN 0x0800 - -/* masks to isolate above values in IMAGE_RELOCATION.Type */ -#define IMAGE_REL_PPC_TYPEMASK 0x00FF -#define IMAGE_REL_PPC_FLAGMASK 0x0F00 - -#define EXTRACT_TYPE(x) ((x) & IMAGE_REL_PPC_TYPEMASK) -#define EXTRACT_FLAGS(x) ((x) & IMAGE_REL_PPC_FLAGMASK) -#define EXTRACT_JUNK(x) \ - ((x) & ~(IMAGE_REL_PPC_TYPEMASK | IMAGE_REL_PPC_FLAGMASK)) - - -/* static helper functions to make relocation work */ -/* (Work In Progress) */ - -static bfd_reloc_status_type ppc_refhi_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type ppc_reflo_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type ppc_pair_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); - - -static bfd_reloc_status_type ppc_toc16_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); - -static bfd_reloc_status_type ppc_addr32nb_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); - -static bfd_reloc_status_type ppc_section_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); - -static bfd_reloc_status_type ppc_secrel_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); - -static bfd_reloc_status_type ppc_imglue_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); - - - -static boolean in_reloc_p PARAMS((bfd *abfd, reloc_howto_type *howto)); - - -/* FIXME: It'll take a while to get through all of these. I only need a few to - get us started, so those I'll make sure work. Those marked FIXME are either - completely unverified or have a specific unknown marked in the comment */ - -/*---------------------------------------------------------------------------*/ -/* */ -/* Relocation entries for Windows/NT on PowerPC. */ -/* */ -/* From the document "" we find the following listed as used relocs: */ -/* */ -/* ABSOLUTE : The noop */ -/* ADDR[64|32|16] : fields that hold addresses in data fields or the */ -/* 16 bit displacement field on a load/store. */ -/* ADDR[24|14] : fields that hold addresses in branch and cond */ -/* branches. These represent [26|16] bit addresses. */ -/* The low order 2 bits are preserved. */ -/* REL[24|14] : branches relative to the Instruction Address */ -/* register. These represent [26|16] bit addresses, */ -/* as before. The instruction field will be zero, and */ -/* the address of the SYM will be inserted at link time. */ -/* TOCREL16 : 16 bit displacement field referring to a slot in */ -/* toc. */ -/* TOCREL14 : 16 bit displacement field, similar to REL14 or ADDR14. */ -/* ADDR32NB : 32 bit address relative to the virtual origin. */ -/* (On the alpha, this is always a linker generated thunk)*/ -/* (i.e. 32bit addr relative to the image base) */ -/* SECREL : The value is relative to the start of the section */ -/* containing the symbol. */ -/* SECTION : access to the header containing the item. Supports the */ -/* codeview debugger. */ -/* */ -/* In particular, note that the document does not indicate that the */ -/* relocations listed in the header file are used. */ -/* */ -/* */ -/* */ -/*---------------------------------------------------------------------------*/ - -static reloc_howto_type ppc_coff_howto_table[] = -{ - /* IMAGE_REL_PPC_ABSOLUTE 0x0000 NOP */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_ABSOLUTE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* dont complain_on_overflow */ - 0, /* special_function */ - "ABSOLUTE", /* name */ - false, /* partial_inplace */ - 0x00, /* src_mask */ - 0x00, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_ADDR64 0x0001 64-bit address */ - /* Unused: */ - HOWTO(IMAGE_REL_PPC_ADDR64, /* type */ - 0, /* rightshift */ - 3, /* size (0 = byte, 1 = short, 2 = long) */ - 64, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "ADDR64", /* name */ - true, /* partial_inplace */ - MINUS_ONE, /* src_mask */ - MINUS_ONE, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_ADDR32 0x0002 32-bit address */ - /* Used: */ - HOWTO (IMAGE_REL_PPC_ADDR32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "ADDR32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_ADDR24 0x0003 26-bit address, shifted left 2 (branch absolute) */ - /* the LI field is in bit 6 through bit 29 is 24 bits, + 2 for the shift */ - /* Of course, That's the IBM approved bit numbering, which is not what */ - /* anyone else uses.... The li field is in bit 2 thru 25 */ - /* Used: */ - HOWTO (IMAGE_REL_PPC_ADDR24, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "ADDR24", /* name */ - true, /* partial_inplace */ - 0x07fffffc, /* src_mask */ - 0x07fffffc, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_ADDR16 0x0004 16-bit address */ - /* Used: */ - HOWTO (IMAGE_REL_PPC_ADDR16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "ADDR16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_ADDR14 0x0005 */ - /* 16-bit address, shifted left 2 (load doubleword) */ - /* FIXME: the mask is likely wrong, and the bit position may be as well */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_ADDR14, /* type */ - 1, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "ADDR16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_REL24 0x0006 */ - /* 26-bit PC-relative offset, shifted left 2 (branch relative) */ - /* Used: */ - HOWTO (IMAGE_REL_PPC_REL24, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "REL24", /* name */ - true, /* partial_inplace */ - 0x3fffffc, /* src_mask */ - 0x3fffffc, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_REL14 0x0007 */ - /* 16-bit PC-relative offset, shifted left 2 (br cond relative) */ - /* FIXME: the mask is likely wrong, and the bit position may be as well */ - /* FIXME: how does it know how far to shift? */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_ADDR14, /* type */ - 1, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "ADDR16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - true), /* pcrel_offset */ - - /* IMAGE_REL_PPC_TOCREL16 0x0008 */ - /* 16-bit offset from TOC base */ - /* Used: */ - HOWTO (IMAGE_REL_PPC_TOCREL16,/* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - ppc_toc16_reloc, /* special_function */ - "TOCREL16", /* name */ - false, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_TOCREL14 0x0009 */ - /* 16-bit offset from TOC base, shifted left 2 (load doubleword) */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_TOCREL14,/* type */ - 1, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "TOCREL14", /* name */ - false, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_ADDR32NB 0x000A */ - /* 32-bit addr w/ image base */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_ADDR32NB,/* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "ADDR32NB", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_SECREL 0x000B */ - /* va of containing section (as in an image sectionhdr) */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_SECREL,/* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - ppc_secrel_reloc, /* special_function */ - "SECREL", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - true), /* pcrel_offset */ - - /* IMAGE_REL_PPC_SECTION 0x000C */ - /* sectionheader number */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_SECTION,/* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - ppc_section_reloc, /* special_function */ - "SECTION", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - true), /* pcrel_offset */ - - /* IMAGE_REL_PPC_IFGLUE 0x000D */ - /* substitute TOC restore instruction iff symbol is glue code */ - /* Used: */ - HOWTO (IMAGE_REL_PPC_IFGLUE,/* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "IFGLUE", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_IMGLUE 0x000E */ - /* symbol is glue code; virtual address is TOC restore instruction */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_IMGLUE,/* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - ppc_imglue_reloc, /* special_function */ - "IMGLUE", /* name */ - false, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_SECREL16 0x000F */ - /* va of containing section (limited to 16 bits) */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_SECREL16,/* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "SECREL16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - true), /* pcrel_offset */ - - /* IMAGE_REL_PPC_REFHI 0x0010 */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_REFHI, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - ppc_refhi_reloc, /* special_function */ - "REFHI", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_REFLO 0x0011 */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_REFLO, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - ppc_refhi_reloc, /* special_function */ - "REFLO", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_PAIR 0x0012 */ - /* Unused: */ - HOWTO (IMAGE_REL_PPC_PAIR, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - ppc_pair_reloc, /* special_function */ - "PAIR", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* IMAGE_REL_PPC_TOCREL16_DEFN 0x0013 */ - /* 16-bit offset from TOC base, without causing a definition */ - /* Used: */ - HOWTO ( (IMAGE_REL_PPC_TOCREL16 | IMAGE_REL_PPC_TOCDEFN), /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "TOCREL16, TOCDEFN", /* name */ - false, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - -}; - - - - -/* Some really cheezy macros that can be turned on to test stderr :-) */ - -#ifdef DEBUG_RELOC -#define UN_IMPL(x) \ -{ \ - static int i; \ - if (i == 0) \ - { \ - i = 1; \ - fprintf(stderr,"Unimplemented Relocation -- %s\n",x); \ - } \ -} - -#define DUMP_RELOC(n,r) \ -{ \ - fprintf(stderr,"%s sym %d, addr %d, addend %d\n", \ - n, (*(r->sym_ptr_ptr))->name, \ - r->address, r->addend); \ -} - -/* Given a reloc name, n, and a pointer to an internal_reloc, - dump out interesting information on the contents - -#define n_name _n._n_name -#define n_zeroes _n._n_n._n_zeroes -#define n_offset _n._n_n._n_offset - -*/ - -#define DUMP_RELOC2(n,r) \ -{ \ - fprintf(stderr,"%s sym %d, r_vaddr %d %s\n", \ - n, r->r_symndx, r->r_vaddr,\ - (((r->r_type) & IMAGE_REL_PPC_TOCDEFN) == 0) \ - ?" ":" TOCDEFN" ); \ -} - -#else -#define UN_IMPL(x) -#define DUMP_RELOC(n,r) -#define DUMP_RELOC2(n,r) -#endif - - - -/* toc construction and management routines */ -extern bfd* bfd_of_toc_owner; -extern long int global_toc_size; - -extern long int import_table_size; -extern long int first_thunk_address; -extern long int thunk_size; - -enum toc_type -{ - default_toc, - toc_32, - toc_64 -}; - -enum ref_category -{ - priv, - pub, - data -}; - -struct list_ele -{ - struct list_ele *next; - bfd_vma addr; - enum ref_category cat; - int offset; - const char *name; -}; - -extern struct list_ele *head; -extern struct list_ele *tail; - -static void -record_toc(toc_section, our_toc_offset, cat, name) - asection *toc_section; - int our_toc_offset; - enum ref_category cat; - const char *name; -{ - /* add this entry to our toc addr-offset-name list */ - struct list_ele *t; - t = bfd_malloc (sizeof (struct list_ele)); - if (t == NULL) - abort (); - t->next = 0; - t->offset = our_toc_offset; - t->name = name; - t->cat = cat; - t->addr = toc_section->output_offset + our_toc_offset; - - if (head == 0) - { - head = t; - tail = t; - } - else - { - tail->next = t; - tail = t; - } -} - -/* record a toc offset against a symbol */ -static int -ppc_record_toc_entry(abfd, info, sec, sym, toc_kind) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - int sym; - enum toc_type toc_kind; -{ - bfd_byte *t; - bfd_byte *old_contents; - asection *s; - int element_size; - int data; - int offset; - struct ppc_coff_link_hash_entry *h; - struct coff_symbol_struct *target; - int ret_val; - const char *name; - - int *local_syms; - - h = 0; - - h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]); - if (h != 0) - { - CHECK_EYE(h->eye_catcher); - } - - if (h == 0) - { - local_syms = obj_coff_local_toc_table(abfd); - if (local_syms == 0) - { - int i; - /* allocate a table */ - local_syms = - (int *) bfd_zalloc (abfd, - obj_raw_syment_count(abfd) * sizeof(int)); - if (local_syms == 0) - return false; - obj_coff_local_toc_table(abfd) = local_syms; - for (i = 0; i < obj_raw_syment_count(abfd); ++i) - { - SET_UNALLOCATED(local_syms[i]); - } - } - - if (IS_UNALLOCATED(local_syms[sym])) - { - local_syms[sym] = global_toc_size; - ret_val = global_toc_size; - global_toc_size += 4; - - /* The size must fit in a 16bit displacment */ - if (global_toc_size >= 65535) - { - fprintf(stderr, - "Exceeded toc size of 65535\n"); - abort(); - } - -#ifdef TOC_DEBUG - fprintf(stderr, - "Setting toc_offset for local sym %d to %d\n", - sym, ret_val); -#endif - } - else - { - ret_val = local_syms[sym]; -#ifdef TOC_DEBUG - fprintf(stderr, - "toc_offset already set for local sym %d to %d\n", - sym, ret_val); -#endif - } - } - else - { - name = h->root.root.root.string; - - /* check to see if there's a toc slot allocated. If not, do it - here. It will be used in relocate_section */ - if (IS_UNALLOCATED(h->toc_offset)) - { - h->toc_offset = global_toc_size; - ret_val = global_toc_size; - global_toc_size += 4; - - /* The size must fit in a 16bit displacment */ - if (global_toc_size >= 65535) - { - fprintf(stderr, - "Exceeded toc size of 65535\n"); - abort(); - } - -#ifdef TOC_DEBUG - fprintf(stderr, - "Setting toc_offset for sym %d (%s) [h=%p] to %d\n", - sym, name, h, ret_val); -#endif - } - else - { - ret_val = h->toc_offset; -#ifdef TOC_DEBUG - fprintf(stderr, - "toc_offset already set for sym %d (%s) [h=%p] to %d\n", - sym, name, h, ret_val); -#endif - } - } - - return ret_val; -} -/* FIXME: record a toc offset against a data-in-toc symbol */ -/* Now, there is currenly some confusion on what this means. In some - compilers one sees the moral equivalent of: - .tocd - define some data - .text - refer to the data with a [tocv] qualifier - In general, one sees something to indicate that a tocd has been - seen, and that would trigger the allocation of data in toc. The IBM - docs seem to suggest that anything with the TOCDEFN qualifier should - never trigger storage allocation. However, in the kernel32.lib that - we've been using for our test bed, there are a couple of variables - referenced that fail that test. - - So it can't work that way. -*/ -static int -ppc_record_data_in_toc_entry(abfd, info, sec, sym, toc_kind) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - int sym; - enum toc_type toc_kind; -{ - bfd_byte *t; - bfd_byte *old_contents; - asection *s; - int element_size; - int data; - int offset; - struct ppc_coff_link_hash_entry *h = 0; - struct coff_symbol_struct *target; - int ret_val; - const char *name; - - int *local_syms; - - h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]); - - if (h == 0) - { - local_syms = obj_coff_local_toc_table(abfd); - if (local_syms == 0) - { - int i; - /* allocate a table */ - local_syms = - (int *) bfd_zalloc (abfd, - obj_raw_syment_count(abfd) * sizeof(int)); - if (local_syms == 0) - return false; - obj_coff_local_toc_table(abfd) = local_syms; - for (i = 0; i < obj_raw_syment_count(abfd); ++i) - { - SET_UNALLOCATED(local_syms[i]); - } - } - - if (IS_UNALLOCATED(local_syms[sym])) - { - local_syms[sym] = global_toc_size; - ret_val = global_toc_size; - global_toc_size += 4; -#ifdef TOC_DEBUG - fprintf(stderr, - "Setting data_in_toc_offset for local sym %d to %d\n", - sym, ret_val); -#endif - } - else - { - ret_val = local_syms[sym]; -#ifdef TOC_DEBUG - fprintf(stderr, - "data_in_toc_offset already set for local sym %d to %d\n", - sym, ret_val); -#endif - } - } - else - { - CHECK_EYE(h->eye_catcher); - - name = h->root.root.root.string; - - /* check to see if there's a toc slot allocated. If not, do it - here. It will be used in relocate_section */ - if (IS_UNALLOCATED(h->toc_offset)) - { -#if 0 - h->toc_offset = global_toc_size; -#endif - ret_val = global_toc_size; - /* We're allocating a chunk of the toc, as opposed to a slot */ - /* FIXME: alignment? */ - - global_toc_size += 4; -#ifdef TOC_DEBUG - fprintf(stderr, - "Setting data_in_toc_offset for sym %d (%s) [h=%p] to %d\n", - sym, name, h, ret_val); -#endif - } - else - { - ret_val = h->toc_offset; -#ifdef TOC_DEBUG - fprintf(stderr, - "data_in_toc_offset already set for sym %d (%s) [h=%p] to %d\n", - sym, name, h, ret_val); -#endif - } - } - - return ret_val; -} - -/* record a toc offset against a symbol */ -static void -ppc_mark_symbol_as_glue(abfd, sym, rel) - bfd *abfd; - int sym; - struct internal_reloc *rel; -{ - struct ppc_coff_link_hash_entry *h; - - h = (struct ppc_coff_link_hash_entry *) (obj_coff_sym_hashes (abfd)[sym]); - - CHECK_EYE(h->eye_catcher); - - h->symbol_is_glue = 1; - h->glue_insn = bfd_get_32 (abfd, (bfd_byte *) &rel->r_vaddr); - - return; -} - - -/* Provided the symbol, returns the value reffed */ -static long get_symbol_value PARAMS ((asymbol *)); - -static long -get_symbol_value (symbol) - asymbol *symbol; -{ - long relocation = 0; - - if (bfd_is_com_section (symbol->section)) - { - relocation = 0; - } - else - { - relocation = symbol->value + - symbol->section->output_section->vma + - symbol->section->output_offset; - } - - return(relocation); -} - -/* Return true if this relocation should - appear in the output .reloc section. */ - -static boolean in_reloc_p(abfd, howto) - bfd * abfd; - reloc_howto_type *howto; -{ - return - (! howto->pc_relative) - && (howto->type != IMAGE_REL_PPC_ADDR32NB) - && (howto->type != IMAGE_REL_PPC_TOCREL16) - && (howto->type != IMAGE_REL_PPC_IMGLUE) - && (howto->type != IMAGE_REL_PPC_IFGLUE) - && (howto->type != IMAGE_REL_PPC_SECREL) - && (howto->type != IMAGE_REL_PPC_SECTION) - && (howto->type != IMAGE_REL_PPC_SECREL16) - && (howto->type != IMAGE_REL_PPC_REFHI) - && (howto->type != IMAGE_REL_PPC_REFLO) - && (howto->type != IMAGE_REL_PPC_PAIR) - && (howto->type != IMAGE_REL_PPC_TOCREL16_DEFN) ; -} - -/* this function is in charge of performing all the ppc PE relocations */ -/* Don't yet know if we want to do this this particular way ... (krk) */ -/* FIXME: (it is not yet enabled) */ - -static bfd_reloc_status_type -pe_ppc_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol_in; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - /* the consth relocation comes in two parts, we have to remember - the state between calls, in these variables */ - static boolean part1_consth_active = false; - static unsigned long part1_consth_value; - - unsigned long insn; - unsigned long sym_value; - unsigned long unsigned_value; - unsigned short r_type; - long signed_value; - - unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/ - bfd_byte *hit_data =addr + (bfd_byte *)(data); - - fprintf(stderr, "pe_ppc_reloc (%s)\n", TARGET_LITTLE_NAME); - - r_type = reloc_entry->howto->type; - - if (output_bfd) - { - /* Partial linking - do nothing */ - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - if (symbol_in != NULL - && bfd_is_und_section (symbol_in->section)) - { - /* Keep the state machine happy in case we're called again */ - if (r_type == IMAGE_REL_PPC_REFHI) - { - part1_consth_active = true; - part1_consth_value = 0; - } - return(bfd_reloc_undefined); - } - - if ((part1_consth_active) && (r_type != IMAGE_REL_PPC_PAIR)) - { - part1_consth_active = false; - *error_message = (char *) "Missing PAIR"; - return(bfd_reloc_dangerous); - } - - - sym_value = get_symbol_value(symbol_in); - - return(bfd_reloc_ok); -} - -/* The reloc processing routine for the optimized COFF linker. */ - -static boolean -coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, syms, sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - struct internal_reloc *relocs; - struct internal_syment *syms; - asection **sections; -{ - struct internal_reloc *rel; - struct internal_reloc *relend; - boolean hihalf; - bfd_vma hihalf_val; - asection *toc_section = 0; - bfd_vma relocation; - reloc_howto_type *howto = 0; - -#ifdef DEBUG_RELOC - fprintf(stderr, - "pe_ppc_relocate_section (%s) for %s in bfd %s\n", - TARGET_LITTLE_NAME, - input_section->name, - input_bfd->filename); - -#endif - - /* If we are performing a relocateable link, we don't need to do a - thing. The caller will take care of adjusting the reloc - addresses and symbol indices. */ - if (info->relocateable) - return true; - - hihalf = false; - hihalf_val = 0; - - rel = relocs; - relend = rel + input_section->reloc_count; - for (; rel < relend; rel++) - { - long symndx; - struct ppc_coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma val; - - asection *sec; - bfd_reloc_status_type rstat; - bfd_byte *loc; - - unsigned short r_type = EXTRACT_TYPE (rel->r_type); - unsigned short r_flags = EXTRACT_FLAGS(rel->r_type); - unsigned short junk = EXTRACT_JUNK (rel->r_type); - -#ifdef DEBUG_RELOC - /* now examine flags */ - if (r_flags != 0) - { - fprintf (stderr, "Reloc with flags found!"); - if ( r_flags & IMAGE_REL_PPC_NEG ) - fprintf (stderr, " NEG"); - if ( r_flags & IMAGE_REL_PPC_BRTAKEN ) - fprintf (stderr, " BRTAKEN"); - if ( r_flags & IMAGE_REL_PPC_BRNTAKEN ) - fprintf (stderr, " BRNTAKEN"); - if ( r_flags & IMAGE_REL_PPC_TOCDEFN ) - fprintf (stderr, " TOCDEFN"); - fprintf(stderr, "\n"); - } -#endif - - symndx = rel->r_symndx; - loc = contents + rel->r_vaddr - input_section->vma; - - /* FIXME: check bounds on r_type */ - howto = ppc_coff_howto_table + r_type; - - if (symndx == -1) - { - h = NULL; - sym = NULL; - } - else - { - h = (struct ppc_coff_link_hash_entry *) - (obj_coff_sym_hashes (input_bfd)[symndx]); - if (h != 0) - { - CHECK_EYE(h->eye_catcher); - } - - sym = syms + symndx; - } - - sec = NULL; - val = 0; - - /* FIXME: PAIR unsupported in the following code */ - if (h == NULL) - { - if (symndx == -1) - sec = bfd_abs_section_ptr; - else - { - sec = sections[symndx]; - val = (sec->output_section->vma - + sec->output_offset - + sym->n_value - - sec->vma); - } - } - else - { - CHECK_EYE(h->eye_catcher); - - if (h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak) - { - sec = h->root.root.u.def.section; - val = (h->root.root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else - { -fprintf(stderr, - "missing %s\n",h->root.root.root.string); - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.root.string, input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return false; - } - } - - rstat = bfd_reloc_ok; - - /* Each case must do its own relocation, setting rstat appropriately */ - switch (r_type) - { - default: - fprintf( stderr, - "ERROR: during reloc processing -- unsupported reloc %s\n", - howto->name); - bfd_set_error (bfd_error_bad_value); - abort(); - return false; - case IMAGE_REL_PPC_TOCREL16: - { - bfd_vma our_toc_offset; - int fixit; - - DUMP_RELOC2(howto->name, rel); - - if (toc_section == 0) - { - toc_section = bfd_get_section_by_name (bfd_of_toc_owner, - TOC_SECTION_NAME); -#ifdef TOC_DEBUG - - fprintf(stderr, - "BFD of toc owner %p (%s), section addr of %s %p\n", - bfd_of_toc_owner, bfd_of_toc_owner->filename, - TOC_SECTION_NAME, toc_section); -#endif - - if ( toc_section == NULL ) - { - fprintf(stderr, "No Toc section!\n"); - abort(); - } - } - - /* - * Amazing bit tricks present. As we may have seen earlier, we - * use the 1 bit to tell us whether or not a toc offset has been - * allocated. Now that they've all been allocated, we will use - * the 1 bit to tell us if we've written this particular toc - * entry out. - */ - fixit = false; - if (h == 0) - { /* it is a file local symbol */ - int *local_toc_table; - const char *name; - - sym = syms + symndx; - name = sym->_n._n_name; - - local_toc_table = obj_coff_local_toc_table(input_bfd); - our_toc_offset = local_toc_table[symndx]; - - if (IS_WRITTEN(our_toc_offset)) - { - /* if it has been written out, it is marked with the - 1 bit. Fix up our offset, but do not write it out - again. - */ - MAKE_ADDR_AGAIN(our_toc_offset); -#ifdef TOC_DEBUG - - fprintf(stderr, - "Not writing out toc_offset of %d for %s\n", - our_toc_offset, name); -#endif - } - else - { - /* write out the toc entry */ - record_toc(toc_section, our_toc_offset, priv, strdup(name)); -#ifdef TOC_DEBUG - fprintf(stderr, - "Writing out toc_offset " - "toc_section (%p,%p)+%d val %d for %s\n", - toc_section, - toc_section->contents, - our_toc_offset, - val, - name); -#endif - - bfd_put_32(output_bfd, - val, - toc_section->contents + our_toc_offset); - - MARK_AS_WRITTEN(local_toc_table[symndx]); - fixit = true; - } - } - else - { - const char *name = h->root.root.root.string; - our_toc_offset = h->toc_offset; - - if ((r_flags & IMAGE_REL_PPC_TOCDEFN) - == IMAGE_REL_PPC_TOCDEFN ) -#if 0 - /* This is wrong. If tocdefn is on, we must unconditionally - assume the following path */ - && IS_UNALLOCATED(our_toc_offset)) -#endif - { - /* This is unbelievable cheese. Some knowledgable asm - hacker has decided to use r2 as a base for loading - a value. He/She does this by setting the tocdefn bit, - and not supplying a toc definition. The behaviour is - then to use the difference between the value of the - symbol and the actual location of the toc as the toc - index. - - In fact, what is usually happening is, because the - Import Address Table is mapped immediately following - the toc, some trippy library code trying for speed on - dll linkage, takes advantage of that and considers - the IAT to be part of the toc, thus saving a load. - */ -#ifdef DEBUG_RELOC - fprintf(stderr, - "TOCDEFN is on, (%s) (%p) our_toc_offset = %x\n", - name, h, our_toc_offset); -#endif - - our_toc_offset = val - - (toc_section->output_section->vma + - toc_section->output_offset); - -#ifdef DEBUG_RELOC - fprintf(stderr, - " our_toc_offset set to %x\n", our_toc_offset); -#endif - - /* The size must still fit in a 16bit displacment */ - if (our_toc_offset >= 65535) - { - fprintf(stderr, - "TOCDEFN Relocation exceeded " - "displacment of 65535\n"); - abort(); - } - - record_toc(toc_section, our_toc_offset, pub, strdup(name)); - } - else if (IS_WRITTEN(our_toc_offset)) - { - /* if it has been written out, it is marked with the - 1 bit. Fix up our offset, but do not write it out - again. - */ - MAKE_ADDR_AGAIN(our_toc_offset); -#ifdef TOC_DEBUG - fprintf(stderr, - "Not writing out toc_offset of %d for %s\n", - our_toc_offset, name); -#endif - } - else - { - record_toc(toc_section, our_toc_offset, pub, strdup(name)); - -#ifdef TOC_DEBUG - /* write out the toc entry */ - fprintf(stderr, - "Writing out toc_offset " - "toc_section (%p,%p)+%d val %d for %s\n", - toc_section, - toc_section->contents, - our_toc_offset, - val, - name); -#endif - - /* write out the toc entry */ - bfd_put_32(output_bfd, - val, - toc_section->contents + our_toc_offset); - - MARK_AS_WRITTEN(h->toc_offset); - /* The tricky part is that this is the address that */ - /* needs a .reloc entry for it */ - fixit = true; - } - } - - if (fixit && info->base_file) - { - /* So if this is non pcrelative, and is referenced - to a section or a common symbol, then it needs a reloc */ - - /* relocation to a symbol in a section which - isn't absolute - we output the address here - to a file */ - - bfd_vma addr = toc_section->output_section->vma - + toc_section->output_offset + our_toc_offset; - - if (coff_data(output_bfd)->pe) - addr -= pe_data(output_bfd)->pe_opthdr.ImageBase; - -#ifdef DEBUG_RELOC - fprintf(stderr, - " Toc Section .reloc candidate addr = %x\n", addr); -#endif - fwrite (&addr, 1,4, (FILE *) info->base_file); - } - - - /* FIXME: this test is conservative */ - if ( (r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN && - our_toc_offset > toc_section->_raw_size) - { - fprintf(stderr, - "reloc offset is bigger than the toc size!\n"); - abort(); - } - - /* Now we know the relocation for this toc reference */ - relocation = our_toc_offset + TOC_LOAD_ADJUSTMENT; - rstat = _bfd_relocate_contents (howto, - input_bfd, - relocation, - loc); - } - break; - case IMAGE_REL_PPC_IFGLUE: - { - /* To solve this, we need to know whether or not the symbol */ - /* appearing on the call instruction is a glue function or not. */ - /* A glue function must announce itself via a IMGLUE reloc, and */ - /* the reloc contains the required toc restore instruction */ - - bfd_vma x; - const char *my_name; - DUMP_RELOC2(howto->name, rel); - - if (h != 0) - { - my_name = h->root.root.root.string; - if (h->symbol_is_glue == 1) - { - x = bfd_get_32(input_bfd, loc); - bfd_put_32(input_bfd, h->glue_insn, loc); - } - } - } - break; - case IMAGE_REL_PPC_SECREL: - /* Unimplemented: codeview debugging information */ - /* For fast access to the header of the section - containing the item. */ - break; - case IMAGE_REL_PPC_SECTION: - /* Unimplemented: codeview debugging information */ - /* Is used to indicate that the value should be relative - to the beginning of the section that contains the - symbol */ - break; - case IMAGE_REL_PPC_ABSOLUTE: - { - const char *my_name; - if (h == 0) - my_name = (syms+symndx)->_n._n_name; - else - { - my_name = h->root.root.root.string; - } - - fprintf(stderr, - "Warning: unsupported reloc %s <file %s, section %s>\n", - howto->name, - bfd_get_filename(input_bfd), - input_section->name); - - fprintf(stderr,"sym %d (%s), r_vaddr %d (%x)\n", - rel->r_symndx, my_name, rel->r_vaddr, rel->r_vaddr); - } - break; - case IMAGE_REL_PPC_IMGLUE: - { - /* There is nothing to do now. This reloc was noted in the first - pass over the relocs, and the glue instruction extracted */ - const char *my_name; - if (h->symbol_is_glue == 1) - break; - my_name = h->root.root.root.string; - fprintf(stderr, - "Warning: previously missed IMGLUE reloc %s <file %s, section %s>\n", - howto->name, - bfd_get_filename(input_bfd), - input_section->name); - break; - - } - break; - - case IMAGE_REL_PPC_ADDR32NB: - { - struct coff_link_hash_entry *myh = 0; - const char *name = 0; - DUMP_RELOC2(howto->name, rel); - - if (strncmp(".idata$2",input_section->name,8) == 0 && first_thunk_address == 0) - { - /* set magic values */ - int idata5offset; - struct coff_link_hash_entry *myh = 0; - myh = coff_link_hash_lookup (coff_hash_table (info), - "__idata5_magic__", - false, false, true); - first_thunk_address = myh->root.u.def.value + - sec->output_section->vma + - sec->output_offset - - pe_data(output_bfd)->pe_opthdr.ImageBase; - - idata5offset = myh->root.u.def.value; - myh = coff_link_hash_lookup (coff_hash_table (info), - "__idata6_magic__", - false, false, true); - - thunk_size = myh->root.u.def.value - idata5offset; - myh = coff_link_hash_lookup (coff_hash_table (info), - "__idata4_magic__", - false, false, true); - import_table_size = myh->root.u.def.value; -#ifdef DEBUG_RELOC - fprintf(stderr, - "first computation triggered fta %x, ts %d(%x), its %d(%x)\n", - first_thunk_address, thunk_size, thunk_size, import_table_size, - import_table_size); -#endif - } - - if (h == 0) - { /* it is a file local symbol */ - sym = syms + symndx; - name = sym->_n._n_name; - } - else - { - char *target = 0; - - name = h->root.root.root.string; - if (strcmp(".idata$2", name) == 0) - target = "__idata2_magic__"; - else if (strcmp(".idata$4", name) == 0) - target = "__idata4_magic__"; - else if (strcmp(".idata$5", name) == 0) - target = "__idata5_magic__"; - - if (target != 0) - { - myh = 0; - - myh = coff_link_hash_lookup (coff_hash_table (info), - target, - false, false, true); - if (myh == 0) - { - fprintf(stderr, "Missing idata magic cookies, " - "this cannot work anyway...\n"); - abort(); - } - - val = myh->root.u.def.value + - sec->output_section->vma + sec->output_offset; - if (first_thunk_address == 0) - { - int idata5offset; - myh = coff_link_hash_lookup (coff_hash_table (info), - "__idata5_magic__", - false, false, true); - first_thunk_address = myh->root.u.def.value + - sec->output_section->vma + - sec->output_offset - - pe_data(output_bfd)->pe_opthdr.ImageBase; - - idata5offset = myh->root.u.def.value; - myh = coff_link_hash_lookup (coff_hash_table (info), - "__idata6_magic__", - false, false, true); - - thunk_size = myh->root.u.def.value - idata5offset; - myh = coff_link_hash_lookup (coff_hash_table (info), - "__idata4_magic__", - false, false, true); - import_table_size = myh->root.u.def.value; -#ifdef DEBUG_RELOC - - fprintf(stderr, - "second computation triggered fta %x, ts %d(%x), its %d(%x)\n", - first_thunk_address, thunk_size, thunk_size, import_table_size, - import_table_size); -#endif - } - } - } - - rstat = _bfd_relocate_contents (howto, - input_bfd, - val - - pe_data(output_bfd)->pe_opthdr.ImageBase, - loc); - } - break; - - case IMAGE_REL_PPC_REL24: - DUMP_RELOC2(howto->name, rel); - val -= (input_section->output_section->vma - + input_section->output_offset); - - rstat = _bfd_relocate_contents (howto, - input_bfd, - val, - loc); - break; - case IMAGE_REL_PPC_ADDR16: - case IMAGE_REL_PPC_ADDR24: - case IMAGE_REL_PPC_ADDR32: - DUMP_RELOC2(howto->name, rel); - rstat = _bfd_relocate_contents (howto, - input_bfd, - val, - loc); - break; - } - - if ( info->base_file ) - { - /* So if this is non pcrelative, and is referenced - to a section or a common symbol, then it needs a reloc */ - if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto)) - { - /* relocation to a symbol in a section which - isn't absolute - we output the address here - to a file */ - bfd_vma addr = rel->r_vaddr - - input_section->vma - + input_section->output_offset - + input_section->output_section->vma; - - if (coff_data(output_bfd)->pe) - { - bfd_vma before_addr = addr; - addr -= pe_data(output_bfd)->pe_opthdr.ImageBase; -#ifdef DEBUG_RELOC - fprintf(stderr, - " adjusted down from %x to %x", before_addr, addr); -#endif - } -#ifdef DEBUG_RELOC - fprintf(stderr, "\n"); -#endif - - fwrite (&addr, 1,4, (FILE *) info->base_file); - } - } - - switch (rstat) - { - default: - abort (); - case bfd_reloc_ok: - break; - case bfd_reloc_overflow: - { - const char *name; - char buf[SYMNMLEN + 1]; - - if (symndx == -1) - name = "*ABS*"; - else if (h != NULL) - name = h->root.root.root.string; - else if (sym == NULL) - name = "*unknown*"; - else if (sym->_n._n_n._n_zeroes == 0 - && sym->_n._n_n._n_offset != 0) - name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset; - else - { - strncpy (buf, sym->_n._n_name, SYMNMLEN); - buf[SYMNMLEN] = '\0'; - name = buf; - } -#if 0 - else - { - name = _bfd_coff_internal_syment_name (input_bfd, sym, buf); - if (name == NULL) - return false; - } -#endif - - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, - (bfd_vma) 0, input_bfd, - input_section, rel->r_vaddr - input_section->vma))) - { -#ifdef DEBUG_RELOC - fprintf(stderr, - "pe_ppc_relocate_section (%s) for %s in bfd %s RETURNING TRUE\n", - TARGET_LITTLE_NAME, - input_section->name, - input_bfd->filename); - -#endif - return false; - } - } - } - - } - -#ifdef DEBUG_RELOC - fprintf(stderr, - "pe_ppc_relocate_section (%s) for %s in bfd %s RETURNING TRUE\n", - TARGET_LITTLE_NAME, - input_section->name, - input_bfd->filename); - -#endif - - return true; -} - - -#ifdef COFF_IMAGE_WITH_PE - -long int global_toc_size = 4; - -bfd* bfd_of_toc_owner = 0; - -long int import_table_size; -long int first_thunk_address; -long int thunk_size; - -struct list_ele *head; -struct list_ele *tail; - -static char * -h1 = "\n\t\t\tTOC MAPPING\n\n"; -static char * -h2 = " TOC disassembly Comments Name\n"; -static char * -h3 = " Offset spelling (if present)\n"; - -void -dump_toc(vfile) - void *vfile; -{ - FILE *file = vfile; - struct list_ele *t; - - fprintf(file, h1); - fprintf(file, h2); - fprintf(file, h3); - - for(t = head; t != 0; t=t->next) - { - char *cat; - - if (t->cat == priv) - cat = "private "; - else if (t->cat == pub) - cat = "public "; - else if (t->cat == data) - cat = "data-in-toc "; - - if (t->offset > global_toc_size) - { - if (t->offset <= global_toc_size + thunk_size) - cat = "IAT reference "; - else - { - fprintf(file, - "**** global_toc_size %d(%x), thunk_size %d(%x)\n", - global_toc_size, global_toc_size, thunk_size, thunk_size); - cat = "Out of bounds!"; - } - } - - fprintf(file, - " %04lx (%d)", t->offset, t->offset - 32768); - fprintf(file, - " %s %s\n", - cat, t->name); - - } - - fprintf(file, "\n"); -} - -boolean -ppc_allocate_toc_section (info) - struct bfd_link_info *info; -{ - asection *s; - bfd_byte *foo; - static char test_char = '1'; - - if ( global_toc_size == 0 ) /* FIXME: does this get me in trouble? */ - return true; - - if (bfd_of_toc_owner == 0) - { - fprintf(stderr, - "There is no bfd that owns the toc section!\n"); - abort(); - } - - s = bfd_get_section_by_name ( bfd_of_toc_owner , TOC_SECTION_NAME); - if (s == NULL) - { - fprintf(stderr, "No Toc section!\n"); - abort(); - } - - foo = bfd_alloc(bfd_of_toc_owner, global_toc_size); - memset(foo, test_char, global_toc_size); - - s->_raw_size = s->_cooked_size = global_toc_size; - s->contents = foo; - - return true; -} - -boolean -ppc_process_before_allocation (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - asection *sec; - struct internal_reloc *i, *rel; - -#ifdef DEBUG_RELOC - fprintf(stderr, - "ppc_process_before_allocation: BFD %s\n", - bfd_get_filename(abfd)); -#endif - - /* here we have a bfd that is to be included on the link. We have a hook - to do reloc rummaging, before section sizes are nailed down. */ - - _bfd_coff_get_external_symbols(abfd); - - /* rummage around all the relocs and map the toc */ - sec = abfd->sections; - - if (sec == 0) - { - return true; - } - - for (; sec != 0; sec = sec->next) - { - int toc_offset; - -#ifdef DEBUG_RELOC - fprintf(stderr, - " section %s reloc count %d\n", - sec->name, - sec->reloc_count); -#endif - - if (sec->reloc_count == 0) - continue; - - /* load the relocs */ - /* FIXME: there may be a storage leak here */ - i=_bfd_coff_read_internal_relocs(abfd,sec,1,0,0,0); - - if (i == 0) - abort(); - - for (rel=i;rel<i+sec->reloc_count;++rel) - { - unsigned short r_type = EXTRACT_TYPE (rel->r_type); - unsigned short r_flags = EXTRACT_FLAGS(rel->r_type); - unsigned short junk = EXTRACT_JUNK (rel->r_type); - -#ifdef DEBUG_RELOC - /* now examine flags */ - if (r_flags != 0) - { - fprintf (stderr, "Reloc with flags found!"); - if ( r_flags & IMAGE_REL_PPC_NEG ) - fprintf (stderr, " NEG"); - if ( r_flags & IMAGE_REL_PPC_BRTAKEN ) - fprintf (stderr, " BRTAKEN"); - if ( r_flags & IMAGE_REL_PPC_BRNTAKEN ) - fprintf (stderr, " BRNTAKEN"); - if ( r_flags & IMAGE_REL_PPC_TOCDEFN ) - fprintf (stderr, " TOCDEFN"); - fprintf(stderr, "\n"); - } -#endif - - DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel); - - switch(r_type) - { - case IMAGE_REL_PPC_TOCREL16: -#if 0 - /* FIXME: - This remains unimplemented for now, as it currently adds - un-necessary elements to the toc. All we need to do today - is not do anything if TOCDEFN is on. - */ - if ( r_flags & IMAGE_REL_PPC_TOCDEFN ) - toc_offset = ppc_record_data_in_toc_entry(abfd, info, sec, - rel->r_symndx, - default_toc); - else - toc_offset = ppc_record_toc_entry(abfd, info, sec, - rel->r_symndx, default_toc); -#endif - if ( (r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN ) - toc_offset = ppc_record_toc_entry(abfd, info, sec, - rel->r_symndx, default_toc); - break; - case IMAGE_REL_PPC_IMGLUE: - ppc_mark_symbol_as_glue(abfd, rel->r_symndx, rel); - break; - default: - break; - } - } - } -} - -#endif - - -static bfd_reloc_status_type -ppc_refhi_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - UN_IMPL("REFHI"); - DUMP_RELOC("REFHI",reloc_entry); - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - return bfd_reloc_undefined; -} - -static bfd_reloc_status_type -ppc_reflo_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - UN_IMPL("REFLO"); - DUMP_RELOC("REFLO",reloc_entry); - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - return bfd_reloc_undefined; -} - -static bfd_reloc_status_type -ppc_pair_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - UN_IMPL("PAIR"); - DUMP_RELOC("PAIR",reloc_entry); - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - return bfd_reloc_undefined; -} - - -static bfd_reloc_status_type -ppc_toc16_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - UN_IMPL("TOCREL16"); - DUMP_RELOC("TOCREL16",reloc_entry); - - if (output_bfd == (bfd *) NULL) - { - return bfd_reloc_continue; - } - - return bfd_reloc_ok; -} - -/* ADDR32NB : 32 bit address relative to the virtual origin. */ -/* (On the alpha, this is always a linker generated thunk)*/ -/* (i.e. 32bit addr relative to the image base) */ -/* */ -/* */ - -static bfd_reloc_status_type -ppc_addr32nb_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - UN_IMPL("ADDR32NB"); - DUMP_RELOC("ADDR32NB",reloc_entry); - - return bfd_reloc_ok; -} - -static bfd_reloc_status_type -ppc_secrel_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - UN_IMPL("SECREL"); - DUMP_RELOC("SECREL",reloc_entry); - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - return bfd_reloc_ok; -} - -static bfd_reloc_status_type -ppc_section_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - UN_IMPL("SECTION"); - DUMP_RELOC("SECTION",reloc_entry); - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - return bfd_reloc_ok; -} - -static bfd_reloc_status_type -ppc_imglue_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - UN_IMPL("IMGLUE"); - DUMP_RELOC("IMGLUE",reloc_entry); - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - return bfd_reloc_ok; -} - - - -#define MAX_RELOC_INDEX \ - (sizeof(ppc_coff_howto_table) / sizeof(ppc_coff_howto_table[0]) - 1) - - -/* FIXME: There is a possiblity that when we read in a reloc from a file, - that there are some bits encoded in the upper portion of the - type field. Not yet implemented. -*/ -static void ppc_coff_rtype2howto PARAMS ((arelent *relent, - struct internal_reloc *internal)); - -static void -ppc_coff_rtype2howto (relent, internal) - arelent *relent; - struct internal_reloc *internal; -{ - - /* We can encode one of three things in the type field, aside from the - type: - 1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction - value, rather than an addition value - 2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that - the branch is expected to be taken or not. - 3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file - For now, we just strip this stuff to find the type, and ignore it other - than that. - */ - reloc_howto_type *howto; - unsigned short r_type = EXTRACT_TYPE (internal->r_type); - unsigned short r_flags = EXTRACT_FLAGS(internal->r_type); - unsigned short junk = EXTRACT_JUNK (internal->r_type); - - /* the masking process only slices off the bottom byte for r_type. */ - if ( r_type > MAX_RELOC_INDEX ) - { - fprintf(stderr, - "ppc_coff_rtype2howto: reloc index %d out of range [%d, %d]\n", - internal->r_type, 0, MAX_RELOC_INDEX); - abort(); - } - - /* check for absolute crap */ - if ( junk != 0 ) - { - fprintf(stderr, - "ppc_coff_rtype2howto: reloc index %d contains junk %d\n", - internal->r_type, junk); - abort(); - } - -#ifdef DEBUG_RELOC - /* now examine flags */ - if (r_flags != 0) - { - fprintf (stderr, "Reloc with flags found!"); - if ( r_flags & IMAGE_REL_PPC_NEG ) - fprintf (stderr, " NEG"); - if ( r_flags & IMAGE_REL_PPC_BRTAKEN ) - fprintf (stderr, " BRTAKEN"); - if ( r_flags & IMAGE_REL_PPC_BRNTAKEN ) - fprintf (stderr, " BRNTAKEN"); - if ( r_flags & IMAGE_REL_PPC_TOCDEFN ) - fprintf (stderr, " TOCDEFN"); - fprintf(stderr, "\n"); - } -#endif - - switch(r_type) - { - case IMAGE_REL_PPC_ADDR16: - case IMAGE_REL_PPC_REL24: - case IMAGE_REL_PPC_ADDR24: - case IMAGE_REL_PPC_ADDR32: - case IMAGE_REL_PPC_IFGLUE: - case IMAGE_REL_PPC_ADDR32NB: - case IMAGE_REL_PPC_SECTION: - case IMAGE_REL_PPC_SECREL: - DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal); - howto = ppc_coff_howto_table + r_type; - break; - case IMAGE_REL_PPC_IMGLUE: - DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal); - howto = ppc_coff_howto_table + r_type; - break; - case IMAGE_REL_PPC_TOCREL16: - DUMP_RELOC2(ppc_coff_howto_table[r_type].name, internal); - if (r_flags & IMAGE_REL_PPC_TOCDEFN) - howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16_DEFN; - else - howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16; - break; - default: - fprintf(stderr, - "Warning: Unsupported reloc %s [%d] used -- it may not work.\n", - ppc_coff_howto_table[r_type].name, - r_type); - howto = ppc_coff_howto_table + r_type; - break; - } - - relent->howto = howto; - -} - -static reloc_howto_type * -coff_ppc_rtype_to_howto (abfd, sec, rel, h, sym, addendp) - bfd *abfd; - asection *sec; - struct internal_reloc *rel; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma *addendp; -{ - reloc_howto_type *howto; - - /* We can encode one of three things in the type field, aside from the - type: - 1. IMAGE_REL_PPC_NEG - indicates the value field is a subtraction - value, rather than an addition value - 2. IMAGE_REL_PPC_BRTAKEN, IMAGE_REL_PPC_BRNTAKEN - indicates that - the branch is expected to be taken or not. - 3. IMAGE_REL_PPC_TOCDEFN - toc slot definition in the file - For now, we just strip this stuff to find the type, and ignore it other - than that. - */ - - unsigned short r_type = EXTRACT_TYPE (rel->r_type); - unsigned short r_flags = EXTRACT_FLAGS(rel->r_type); - unsigned short junk = EXTRACT_JUNK (rel->r_type); - - /* the masking process only slices off the bottom byte for r_type. */ - if ( r_type > MAX_RELOC_INDEX ) - { - fprintf(stderr, - "coff_ppc_rtype_to_howto: index %d out of range [%d, %d]\n", - r_type, 0, MAX_RELOC_INDEX); - abort(); - } - - /* check for absolute crap */ - if ( junk != 0 ) - { - fprintf(stderr, - "coff_ppc_rtype_to_howto: reloc index %d contains junk %d\n", - rel->r_type, junk); - abort(); - } - -#ifdef DEBUG_RELOC - /* now examine flags */ - if (r_flags != 0) - { - fprintf (stderr, "Reloc with flags found!"); - if ( r_flags & IMAGE_REL_PPC_NEG ) - fprintf (stderr, " NEG"); - if ( r_flags & IMAGE_REL_PPC_BRTAKEN ) - fprintf (stderr, " BRTAKEN"); - if ( r_flags & IMAGE_REL_PPC_BRNTAKEN ) - fprintf (stderr, " BRNTAKEN"); - if ( r_flags & IMAGE_REL_PPC_TOCDEFN ) - fprintf (stderr, " TOCDEFN"); - fprintf(stderr, "\n"); - } -#endif - - switch(r_type) - { - case IMAGE_REL_PPC_ADDR32NB: - DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel); - *addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase; - howto = ppc_coff_howto_table + r_type; - break; - case IMAGE_REL_PPC_TOCREL16: - DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel); - if (r_flags & IMAGE_REL_PPC_TOCDEFN) - howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16_DEFN; - else - howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16; - break; - case IMAGE_REL_PPC_ADDR16: - case IMAGE_REL_PPC_REL24: - case IMAGE_REL_PPC_ADDR24: - case IMAGE_REL_PPC_ADDR32: - case IMAGE_REL_PPC_IFGLUE: - case IMAGE_REL_PPC_SECTION: - case IMAGE_REL_PPC_SECREL: - DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel); - howto = ppc_coff_howto_table + r_type; - break; - case IMAGE_REL_PPC_IMGLUE: - DUMP_RELOC2(ppc_coff_howto_table[r_type].name, rel); - howto = ppc_coff_howto_table + r_type; - break; - default: - fprintf(stderr, - "Warning: Unsupported reloc %s [%d] used -- it may not work.\n", - ppc_coff_howto_table[r_type].name, - r_type); - howto = ppc_coff_howto_table + r_type; - break; - } - - return howto; -} - - -/* a cheesy little macro to make the code a little more readable */ -#define HOW2MAP(bfd_rtype,ppc_rtype) \ - case bfd_rtype: return &ppc_coff_howto_table[ppc_rtype] - -static reloc_howto_type *ppc_coff_reloc_type_lookup -PARAMS ((bfd *, bfd_reloc_code_real_type)); - -static reloc_howto_type * -ppc_coff_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - -#ifdef DEBUG_RELOC - fprintf(stderr, "ppc_coff_reloc_type_lookup for %s\n", - bfd_get_reloc_code_name(code)); -#endif - - switch (code) - { - HOW2MAP(BFD_RELOC_32_GOTOFF, IMAGE_REL_PPC_IMGLUE); - HOW2MAP(BFD_RELOC_16_GOT_PCREL, IMAGE_REL_PPC_IFGLUE); - HOW2MAP(BFD_RELOC_16, IMAGE_REL_PPC_ADDR16); - HOW2MAP(BFD_RELOC_PPC_B26, IMAGE_REL_PPC_REL24); - HOW2MAP(BFD_RELOC_PPC_BA26, IMAGE_REL_PPC_ADDR24); - HOW2MAP(BFD_RELOC_PPC_TOC16, IMAGE_REL_PPC_TOCREL16); - HOW2MAP(BFD_RELOC_16_GOTOFF, IMAGE_REL_PPC_TOCREL16_DEFN); - HOW2MAP(BFD_RELOC_32, IMAGE_REL_PPC_ADDR32); - HOW2MAP(BFD_RELOC_RVA, IMAGE_REL_PPC_ADDR32NB); - default: - return NULL; - } - - return NULL; -} - -#undef HOW2MAP - - -/* Tailor coffcode.h -- macro heaven. */ - -#define RTYPE2HOWTO(cache_ptr, dst) ppc_coff_rtype2howto (cache_ptr, dst) - -#ifndef COFF_IMAGE_WITH_PE -static void -ppc_coff_swap_sym_in_hook (); -#endif - -/* We use the special COFF backend linker, with our own special touch. */ - -#define coff_bfd_reloc_type_lookup ppc_coff_reloc_type_lookup -#define coff_rtype_to_howto coff_ppc_rtype_to_howto -#define coff_relocate_section coff_ppc_relocate_section -#define coff_bfd_final_link ppc_bfd_coff_final_link - -#ifndef COFF_IMAGE_WITH_PE -#define coff_swap_sym_in_hook ppc_coff_swap_sym_in_hook -#endif - -#define SELECT_RELOC(internal, howto) {internal.r_type=howto->type;} - -#define COFF_PAGE_SIZE 0x1000 - -#define POWERPC_LE_PE - -#include "coffcode.h" - - - -#ifndef COFF_IMAGE_WITH_PE -/* FIXME: - What we're trying to do here is allocate a toc section (early), and attach - it to the last bfd to be processed. This avoids the problem of having a toc - written out before all files have been processed. This code allocates - a toc section for every file, and records the last one seen. There are - at least two problems with this approach: - 1. We allocate whole bunches of toc sections that are ignored, but at - at least we will not allocate a toc if no .toc is present. - 2. It's not clear to me that being the last bfd read necessarily means - that you are the last bfd closed. - 3. Doing it on a "swap in" hook depends on when the "swap in" is called, - and how often, etc. It's not clear to me that there isn't a hole here. -*/ - -static void -ppc_coff_swap_sym_in_hook (abfd, ext1, in1) - bfd *abfd; - PTR ext1; - PTR in1; -{ - SYMENT *ext = (SYMENT *)ext1; - struct internal_syment *in = (struct internal_syment *)in1; - - if (bfd_of_toc_owner != 0) /* we already have a toc, so go home */ - return; - - if (strcmp(in->_n._n_name, ".toc") == 0) - { - flagword flags; - register asection *s; - char *foo; - - s = bfd_get_section_by_name ( abfd , TOC_SECTION_NAME); - if (s != NULL) - { - return; - } - - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ; - -#ifdef TOC_DEBUG - fprintf(stderr, - "ppc_coff_swap_sym_in_hook: about to create the %s section\n", - TOC_SECTION_NAME); -#endif - - s = bfd_make_section (abfd, TOC_SECTION_NAME); - - if (s == NULL - || !bfd_set_section_flags (abfd, s, flags) - || !bfd_set_section_alignment (abfd, s, 2)) - { - fprintf(stderr, - "toc section allocation failed!\n"); - abort(); - } - - /* save the bfd for later allocation */ - bfd_of_toc_owner = abfd; - } - - return; -} -#endif - -boolean -ppc_bfd_coff_final_link (); - -#ifndef COFF_IMAGE_WITH_PE - -static boolean -ppc_do_last(abfd) - bfd *abfd; -{ - if (abfd == bfd_of_toc_owner) - return true; - else - return false; -} - -static bfd * -ppc_get_last() -{ - return bfd_of_toc_owner; -} - -/* this piece of machinery exists only to guarantee that the bfd that holds - the toc section is written last. - - This does depend on bfd_make_section attaching a new section to the - end of the section list for the bfd. - - This is otherwise intended to be functionally the same as - cofflink.c:_bfd_coff_final_link(). It is specifically different only - where the POWERPC_LE_PE macro modifies the code. It is left in as a - precise form of comment. krk@cygnus.com -*/ -#define POWERPC_LE_PE - - -/* Do the final link step. */ - -boolean -ppc_bfd_coff_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - bfd_size_type symesz; - struct coff_final_link_info finfo; - boolean debug_merge_allocated; - asection *o; - struct bfd_link_order *p; - size_t max_sym_count; - size_t max_lineno_count; - size_t max_reloc_count; - size_t max_output_reloc_count; - size_t max_contents_size; - file_ptr rel_filepos; - unsigned int relsz; - file_ptr line_filepos; - unsigned int linesz; - bfd *sub; - bfd_byte *external_relocs = NULL; - char strbuf[STRING_SIZE_SIZE]; - - symesz = bfd_coff_symesz (abfd); - - finfo.info = info; - finfo.output_bfd = abfd; - finfo.strtab = NULL; - finfo.section_info = NULL; - finfo.last_file_index = -1; - finfo.internal_syms = NULL; - finfo.sec_ptrs = NULL; - finfo.sym_indices = NULL; - finfo.outsyms = NULL; - finfo.linenos = NULL; - finfo.contents = NULL; - finfo.external_relocs = NULL; - finfo.internal_relocs = NULL; - debug_merge_allocated = false; - - coff_data (abfd)->link_info = info; - - finfo.strtab = _bfd_stringtab_init (); - if (finfo.strtab == NULL) - goto error_return; - - if (! coff_debug_merge_hash_table_init (&finfo.debug_merge)) - goto error_return; - debug_merge_allocated = true; - - /* Compute the file positions for all the sections. */ - if (! abfd->output_has_begun) - bfd_coff_compute_section_file_positions (abfd); - - /* Count the line numbers and relocation entries required for the - output file. Set the file positions for the relocs. */ - rel_filepos = obj_relocbase (abfd); - relsz = bfd_coff_relsz (abfd); - max_contents_size = 0; - max_lineno_count = 0; - max_reloc_count = 0; - - for (o = abfd->sections; o != NULL; o = o->next) - { - o->reloc_count = 0; - o->lineno_count = 0; - for (p = o->link_order_head; p != NULL; p = p->next) - { - - if (p->type == bfd_indirect_link_order) - { - asection *sec; - - sec = p->u.indirect.section; - - if (info->strip == strip_none - || info->strip == strip_some) - o->lineno_count += sec->lineno_count; - - if (info->relocateable) - o->reloc_count += sec->reloc_count; - - if (sec->_raw_size > max_contents_size) - max_contents_size = sec->_raw_size; - if (sec->lineno_count > max_lineno_count) - max_lineno_count = sec->lineno_count; - if (sec->reloc_count > max_reloc_count) - max_reloc_count = sec->reloc_count; - } - else if (info->relocateable - && (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order)) - ++o->reloc_count; - } - if (o->reloc_count == 0) - o->rel_filepos = 0; - else - { - o->flags |= SEC_RELOC; - o->rel_filepos = rel_filepos; - rel_filepos += o->reloc_count * relsz; - } - } - - /* If doing a relocateable link, allocate space for the pointers we - need to keep. */ - if (info->relocateable) - { - unsigned int i; - - /* We use section_count + 1, rather than section_count, because - the target_index fields are 1 based. */ - finfo.section_info = - ((struct coff_link_section_info *) - bfd_malloc ((abfd->section_count + 1) - * sizeof (struct coff_link_section_info))); - if (finfo.section_info == NULL) - goto error_return; - for (i = 0; i <= abfd->section_count; i++) - { - finfo.section_info[i].relocs = NULL; - finfo.section_info[i].rel_hashes = NULL; - } - } - - /* We now know the size of the relocs, so we can determine the file - positions of the line numbers. */ - line_filepos = rel_filepos; - linesz = bfd_coff_linesz (abfd); - max_output_reloc_count = 0; - for (o = abfd->sections; o != NULL; o = o->next) - { - if (o->lineno_count == 0) - o->line_filepos = 0; - else - { - o->line_filepos = line_filepos; - line_filepos += o->lineno_count * linesz; - } - - if (o->reloc_count != 0) - { - /* We don't know the indices of global symbols until we have - written out all the local symbols. For each section in - the output file, we keep an array of pointers to hash - table entries. Each entry in the array corresponds to a - reloc. When we find a reloc against a global symbol, we - set the corresponding entry in this array so that we can - fix up the symbol index after we have written out all the - local symbols. - - Because of this problem, we also keep the relocs in - memory until the end of the link. This wastes memory, - but only when doing a relocateable link, which is not the - common case. */ - BFD_ASSERT (info->relocateable); - finfo.section_info[o->target_index].relocs = - ((struct internal_reloc *) - bfd_malloc (o->reloc_count * sizeof (struct internal_reloc))); - finfo.section_info[o->target_index].rel_hashes = - ((struct coff_link_hash_entry **) - bfd_malloc (o->reloc_count - * sizeof (struct coff_link_hash_entry *))); - if (finfo.section_info[o->target_index].relocs == NULL - || finfo.section_info[o->target_index].rel_hashes == NULL) - goto error_return; - - if (o->reloc_count > max_output_reloc_count) - max_output_reloc_count = o->reloc_count; - } - - /* Reset the reloc and lineno counts, so that we can use them to - count the number of entries we have output so far. */ - o->reloc_count = 0; - o->lineno_count = 0; - } - - obj_sym_filepos (abfd) = line_filepos; - - /* Figure out the largest number of symbols in an input BFD. Take - the opportunity to clear the output_has_begun fields of all the - input BFD's. */ - max_sym_count = 0; - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - size_t sz; - - sub->output_has_begun = false; - sz = obj_raw_syment_count (sub); - if (sz > max_sym_count) - max_sym_count = sz; - } - - /* Allocate some buffers used while linking. */ - finfo.internal_syms = ((struct internal_syment *) - bfd_malloc (max_sym_count - * sizeof (struct internal_syment))); - finfo.sec_ptrs = (asection **) bfd_malloc (max_sym_count - * sizeof (asection *)); - finfo.sym_indices = (long *) bfd_malloc (max_sym_count * sizeof (long)); - finfo.outsyms = ((bfd_byte *) - bfd_malloc ((size_t) ((max_sym_count + 1) * symesz))); - finfo.linenos = (bfd_byte *) bfd_malloc (max_lineno_count - * bfd_coff_linesz (abfd)); - finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size); - finfo.external_relocs = (bfd_byte *) bfd_malloc (max_reloc_count * relsz); - if (! info->relocateable) - finfo.internal_relocs = ((struct internal_reloc *) - bfd_malloc (max_reloc_count - * sizeof (struct internal_reloc))); - if ((finfo.internal_syms == NULL && max_sym_count > 0) - || (finfo.sec_ptrs == NULL && max_sym_count > 0) - || (finfo.sym_indices == NULL && max_sym_count > 0) - || finfo.outsyms == NULL - || (finfo.linenos == NULL && max_lineno_count > 0) - || (finfo.contents == NULL && max_contents_size > 0) - || (finfo.external_relocs == NULL && max_reloc_count > 0) - || (! info->relocateable - && finfo.internal_relocs == NULL - && max_reloc_count > 0)) - goto error_return; - - /* We now know the position of everything in the file, except that - we don't know the size of the symbol table and therefore we don't - know where the string table starts. We just build the string - table in memory as we go along. We process all the relocations - for a single input file at once. */ - obj_raw_syment_count (abfd) = 0; - - if (coff_backend_info (abfd)->_bfd_coff_start_final_link) - { - if (! bfd_coff_start_final_link (abfd, info)) - goto error_return; - } - - for (o = abfd->sections; o != NULL; o = o->next) - { - for (p = o->link_order_head; p != NULL; p = p->next) - { - if (p->type == bfd_indirect_link_order - && (bfd_get_flavour (p->u.indirect.section->owner) - == bfd_target_coff_flavour)) - { - sub = p->u.indirect.section->owner; -#ifdef POWERPC_LE_PE - if (! sub->output_has_begun && !ppc_do_last(sub)) -#else - if (! sub->output_has_begun) -#endif - { - if (! _bfd_coff_link_input_bfd (&finfo, sub)) - goto error_return; - sub->output_has_begun = true; - } - } - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - { - if (! _bfd_coff_reloc_link_order (abfd, &finfo, o, p)) - goto error_return; - } - else - { - if (! _bfd_default_link_order (abfd, info, o, p)) - goto error_return; - } - } - } - -#ifdef POWERPC_LE_PE - { - extern bfd* ppc_get_last(); - bfd* last_one = ppc_get_last(); - if (last_one) - { - if (! _bfd_coff_link_input_bfd (&finfo, last_one)) - goto error_return; - } - last_one->output_has_begun = true; - } -#endif - - /* Free up the buffers used by _bfd_coff_link_input_bfd. */ - - coff_debug_merge_hash_table_free (&finfo.debug_merge); - debug_merge_allocated = false; - - if (finfo.internal_syms != NULL) - { - free (finfo.internal_syms); - finfo.internal_syms = NULL; - } - if (finfo.sec_ptrs != NULL) - { - free (finfo.sec_ptrs); - finfo.sec_ptrs = NULL; - } - if (finfo.sym_indices != NULL) - { - free (finfo.sym_indices); - finfo.sym_indices = NULL; - } - if (finfo.linenos != NULL) - { - free (finfo.linenos); - finfo.linenos = NULL; - } - if (finfo.contents != NULL) - { - free (finfo.contents); - finfo.contents = NULL; - } - if (finfo.external_relocs != NULL) - { - free (finfo.external_relocs); - finfo.external_relocs = NULL; - } - if (finfo.internal_relocs != NULL) - { - free (finfo.internal_relocs); - finfo.internal_relocs = NULL; - } - - /* The value of the last C_FILE symbol is supposed to be the symbol - index of the first external symbol. Write it out again if - necessary. */ - if (finfo.last_file_index != -1 - && (unsigned int) finfo.last_file.n_value != obj_raw_syment_count (abfd)) - { - finfo.last_file.n_value = obj_raw_syment_count (abfd); - bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file, - (PTR) finfo.outsyms); - if (bfd_seek (abfd, - (obj_sym_filepos (abfd) - + finfo.last_file_index * symesz), - SEEK_SET) != 0 - || bfd_write (finfo.outsyms, symesz, 1, abfd) != symesz) - return false; - } - - /* Write out the global symbols. */ - finfo.failed = false; - coff_link_hash_traverse (coff_hash_table (info), _bfd_coff_write_global_sym, - (PTR) &finfo); - if (finfo.failed) - goto error_return; - - /* The outsyms buffer is used by _bfd_coff_write_global_sym. */ - if (finfo.outsyms != NULL) - { - free (finfo.outsyms); - finfo.outsyms = NULL; - } - - if (info->relocateable) - { - /* Now that we have written out all the global symbols, we know - the symbol indices to use for relocs against them, and we can - finally write out the relocs. */ - external_relocs = ((bfd_byte *) - bfd_malloc (max_output_reloc_count * relsz)); - if (external_relocs == NULL) - goto error_return; - - for (o = abfd->sections; o != NULL; o = o->next) - { - struct internal_reloc *irel; - struct internal_reloc *irelend; - struct coff_link_hash_entry **rel_hash; - bfd_byte *erel; - - if (o->reloc_count == 0) - continue; - - irel = finfo.section_info[o->target_index].relocs; - irelend = irel + o->reloc_count; - rel_hash = finfo.section_info[o->target_index].rel_hashes; - erel = external_relocs; - for (; irel < irelend; irel++, rel_hash++, erel += relsz) - { - if (*rel_hash != NULL) - { - BFD_ASSERT ((*rel_hash)->indx >= 0); - irel->r_symndx = (*rel_hash)->indx; - } - bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel); - } - - if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0 - || bfd_write ((PTR) external_relocs, relsz, o->reloc_count, - abfd) != relsz * o->reloc_count) - goto error_return; - } - - free (external_relocs); - external_relocs = NULL; - } - - /* Free up the section information. */ - if (finfo.section_info != NULL) - { - unsigned int i; - - for (i = 0; i < abfd->section_count; i++) - { - if (finfo.section_info[i].relocs != NULL) - free (finfo.section_info[i].relocs); - if (finfo.section_info[i].rel_hashes != NULL) - free (finfo.section_info[i].rel_hashes); - } - free (finfo.section_info); - finfo.section_info = NULL; - } - - /* Write out the string table. */ - if (obj_raw_syment_count (abfd) != 0) - { - if (bfd_seek (abfd, - (obj_sym_filepos (abfd) - + obj_raw_syment_count (abfd) * symesz), - SEEK_SET) != 0) - return false; - -#if STRING_SIZE_SIZE == 4 - bfd_h_put_32 (abfd, - _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE, - (bfd_byte *) strbuf); -#else - #error Change bfd_h_put_32 -#endif - - if (bfd_write (strbuf, 1, STRING_SIZE_SIZE, abfd) != STRING_SIZE_SIZE) - return false; - - if (! _bfd_stringtab_emit (abfd, finfo.strtab)) - return false; - } - - _bfd_stringtab_free (finfo.strtab); - - /* Setting bfd_get_symcount to 0 will cause write_object_contents to - not try to write out the symbols. */ - bfd_get_symcount (abfd) = 0; - - return true; - - error_return: - if (debug_merge_allocated) - coff_debug_merge_hash_table_free (&finfo.debug_merge); - if (finfo.strtab != NULL) - _bfd_stringtab_free (finfo.strtab); - if (finfo.section_info != NULL) - { - unsigned int i; - - for (i = 0; i < abfd->section_count; i++) - { - if (finfo.section_info[i].relocs != NULL) - free (finfo.section_info[i].relocs); - if (finfo.section_info[i].rel_hashes != NULL) - free (finfo.section_info[i].rel_hashes); - } - free (finfo.section_info); - } - if (finfo.internal_syms != NULL) - free (finfo.internal_syms); - if (finfo.sec_ptrs != NULL) - free (finfo.sec_ptrs); - if (finfo.sym_indices != NULL) - free (finfo.sym_indices); - if (finfo.outsyms != NULL) - free (finfo.outsyms); - if (finfo.linenos != NULL) - free (finfo.linenos); - if (finfo.contents != NULL) - free (finfo.contents); - if (finfo.external_relocs != NULL) - free (finfo.external_relocs); - if (finfo.internal_relocs != NULL) - free (finfo.internal_relocs); - if (external_relocs != NULL) - free (external_relocs); - return false; -} -#endif - - -/* The transfer vectors that lead the outside world to all of the above. */ - -#ifdef TARGET_LITTLE_SYM -const bfd_target -TARGET_LITTLE_SYM = -{ - TARGET_LITTLE_NAME, /* name or coff-arm-little */ - bfd_target_coff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little */ - - (HAS_RELOC | EXEC_P | /* FIXME: object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading char */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen??? FIXMEmgo */ - - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p }, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; -#endif - -#ifdef TARGET_BIG_SYM -const bfd_target -TARGET_BIG_SYM = -{ - TARGET_BIG_NAME, - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* FIXME: object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading char */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen??? FIXMEmgo */ - - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, /* _bfd_dummy_target */ coff_object_p }, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; - -#endif diff --git a/contrib/gdb/bfd/coff-rs6000.c b/contrib/gdb/bfd/coff-rs6000.c deleted file mode 100644 index c065bd4..0000000 --- a/contrib/gdb/bfd/coff-rs6000.c +++ /dev/null @@ -1,1403 +0,0 @@ -/* BFD back-end for IBM RS/6000 "XCOFF" files. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - FIXME: Can someone provide a transliteration of this name into ASCII? - Using the following chars caused a compiler warning on HIUX (so I replaced - them with octal escapes), and isn't useful without an understanding of what - character set it is. - Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365, - and John Gilmore. - Archive support from Damon A. Permezel. - Contributed by IBM Corporation and Cygnus Support. - -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. */ - -/* Internalcoff.h and coffcode.h modify themselves based on this flag. */ -#define RS6000COFF_C 1 - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/internal.h" -#include "coff/rs6000.h" -#include "libcoff.h" - -/* The main body of code is in coffcode.h. */ - -static boolean xcoff_mkobject PARAMS ((bfd *)); -static boolean xcoff_copy_private_bfd_data PARAMS ((bfd *, bfd *)); -static void xcoff_rtype2howto - PARAMS ((arelent *, struct internal_reloc *)); -static reloc_howto_type *xcoff_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static boolean xcoff_slurp_armap PARAMS ((bfd *)); -static const bfd_target *xcoff_archive_p PARAMS ((bfd *)); -static PTR xcoff_read_ar_hdr PARAMS ((bfd *)); -static bfd *xcoff_openr_next_archived_file PARAMS ((bfd *, bfd *)); -static int xcoff_generic_stat_arch_elt PARAMS ((bfd *, struct stat *)); -static const char *normalize_filename PARAMS ((bfd *)); -static boolean xcoff_write_armap - PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int)); -static boolean xcoff_write_archive_contents PARAMS ((bfd *)); - -/* We use our own tdata type. Its first field is the COFF tdata type, - so the COFF routines are compatible. */ - -static boolean -xcoff_mkobject (abfd) - bfd *abfd; -{ - coff_data_type *coff; - - abfd->tdata.xcoff_obj_data = - ((struct xcoff_tdata *) - bfd_zalloc (abfd, sizeof (struct xcoff_tdata))); - if (abfd->tdata.xcoff_obj_data == NULL) - return false; - coff = coff_data (abfd); - coff->symbols = (coff_symbol_type *) NULL; - coff->conversion_table = (unsigned int *) NULL; - coff->raw_syments = (struct coff_ptr_struct *) NULL; - coff->relocbase = 0; - - xcoff_data (abfd)->modtype = ('1' << 8) | 'L'; - - /* We set cputype to -1 to indicate that it has not been - initialized. */ - xcoff_data (abfd)->cputype = -1; - - xcoff_data (abfd)->csects = NULL; - xcoff_data (abfd)->debug_indices = NULL; - - return true; -} - -/* Copy XCOFF data from one BFD to another. */ - -static boolean -xcoff_copy_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; -{ - struct xcoff_tdata *ix, *ox; - asection *sec; - - if (ibfd->xvec != obfd->xvec) - return true; - ix = xcoff_data (ibfd); - ox = xcoff_data (obfd); - ox->full_aouthdr = ix->full_aouthdr; - ox->toc = ix->toc; - if (ix->sntoc == 0) - ox->sntoc = 0; - else - { - sec = coff_section_from_bfd_index (ibfd, ix->sntoc); - if (sec == NULL) - ox->sntoc = 0; - else - ox->sntoc = sec->output_section->target_index; - } - if (ix->snentry == 0) - ox->snentry = 0; - else - { - sec = coff_section_from_bfd_index (ibfd, ix->snentry); - if (sec == NULL) - ox->snentry = 0; - else - ox->snentry = sec->output_section->target_index; - } - ox->text_align_power = ix->text_align_power; - ox->data_align_power = ix->data_align_power; - ox->modtype = ix->modtype; - ox->cputype = ix->cputype; - ox->maxdata = ix->maxdata; - ox->maxstack = ix->maxstack; - return true; -} - -/* The XCOFF reloc table. Actually, XCOFF relocations specify the - bitsize and whether they are signed or not, along with a - conventional type. This table is for the types, which are used for - different algorithms for putting in the reloc. Many of these - relocs need special_function entries, which I have not written. */ - -static reloc_howto_type xcoff_howto_table[] = -{ - /* Standard 32 bit relocation. */ - HOWTO (0, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_POS", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32 bit relocation, but store negative value. */ - HOWTO (1, /* type */ - 0, /* rightshift */ - -2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_NEG", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32 bit PC relative relocation. */ - HOWTO (2, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "R_REL", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit TOC relative relocation. */ - HOWTO (3, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_TOC", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* I don't really know what this is. */ - HOWTO (4, /* type */ - 1, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RTB", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* External TOC relative symbol. */ - HOWTO (5, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_GL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Local TOC relative symbol. */ - HOWTO (6, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_TCL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - { 7 }, - - /* Non modifiable absolute branch. */ - HOWTO (8, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_BA", /* name */ - true, /* partial_inplace */ - 0x3fffffc, /* src_mask */ - 0x3fffffc, /* dst_mask */ - false), /* pcrel_offset */ - - { 9 }, - - /* Non modifiable relative branch. */ - HOWTO (0xa, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "R_BR", /* name */ - true, /* partial_inplace */ - 0x3fffffc, /* src_mask */ - 0x3fffffc, /* dst_mask */ - false), /* pcrel_offset */ - - { 0xb }, - - /* Indirect load. */ - HOWTO (0xc, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Load address. */ - HOWTO (0xd, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RLA", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - { 0xe }, - - /* Non-relocating reference. */ - HOWTO (0xf, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_REF", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - { 0x10 }, - { 0x11 }, - - /* TOC relative indirect load. */ - HOWTO (0x12, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_TRL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* TOC relative load address. */ - HOWTO (0x13, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_TRLA", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable relative branch. */ - HOWTO (0x14, /* type */ - 1, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RRTBI", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable absolute branch. */ - HOWTO (0x15, /* type */ - 1, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RRTBA", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable call absolute indirect. */ - HOWTO (0x16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_CAI", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable call relative. */ - HOWTO (0x17, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_CREL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable branch absolute. */ - HOWTO (0x18, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RBA", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable branch absolute. */ - HOWTO (0x19, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RBAC", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable branch relative. */ - HOWTO (0x1a, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "R_RBR", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable branch absolute. */ - HOWTO (0x1b, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RBRC", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false) /* pcrel_offset */ -}; - -static void -xcoff_rtype2howto (relent, internal) - arelent *relent; - struct internal_reloc *internal; -{ - relent->howto = xcoff_howto_table + internal->r_type; - - /* The r_size field of an XCOFF reloc encodes the bitsize of the - relocation, as well as indicating whether it is signed or not. - Doublecheck that the relocation information gathered from the - type matches this information. */ - if (relent->howto->bitsize != ((unsigned int) internal->r_size & 0x1f) + 1) - abort (); -#if 0 - if ((internal->r_size & 0x80) != 0 - ? (relent->howto->complain_on_overflow != complain_overflow_signed) - : (relent->howto->complain_on_overflow != complain_overflow_bitfield)) - abort (); -#endif -} - -static reloc_howto_type * -xcoff_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - switch (code) - { - case BFD_RELOC_PPC_B26: - return &xcoff_howto_table[0xa]; - case BFD_RELOC_PPC_BA26: - return &xcoff_howto_table[8]; - case BFD_RELOC_PPC_TOC16: - return &xcoff_howto_table[3]; - case BFD_RELOC_32: - case BFD_RELOC_CTOR: - return &xcoff_howto_table[0]; - default: - return NULL; - } -} - -#define SELECT_RELOC(internal, howto) \ - { \ - internal.r_type = howto->type; \ - internal.r_size = \ - ((howto->complain_on_overflow == complain_overflow_signed \ - ? 0x80 \ - : 0) \ - | (howto->bitsize - 1)); \ - } - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3) - -#define COFF_LONG_FILENAMES - -#define RTYPE2HOWTO(cache_ptr, dst) xcoff_rtype2howto (cache_ptr, dst) - -#define coff_mkobject xcoff_mkobject -#define coff_bfd_copy_private_bfd_data xcoff_copy_private_bfd_data -#define coff_bfd_reloc_type_lookup xcoff_reloc_type_lookup -#define coff_relocate_section _bfd_ppc_xcoff_relocate_section - -#include "coffcode.h" - -/* XCOFF archive support. The original version of this code was by - Damon A. Permezel. It was enhanced to permit cross support, and - writing archive files, by Ian Lance Taylor, Cygnus Support. - - XCOFF uses its own archive format. Everything is hooked together - with file offset links, so it is possible to rapidly update an - archive in place. Of course, we don't do that. An XCOFF archive - has a real file header, not just an ARMAG string. The structure of - the file header and of each archive header appear below. - - An XCOFF archive also has a member table, which is a list of - elements in the archive (you can get that by looking through the - linked list, but you have to read a lot more of the file). The - member table has a normal archive header with an empty name. It is - normally (and perhaps must be) the second to last entry in the - archive. The member table data is almost printable ASCII. It - starts with a 12 character decimal string which is the number of - entries in the table. For each entry it has a 12 character decimal - string which is the offset in the archive of that member. These - entries are followed by a series of null terminated strings which - are the member names for each entry. - - Finally, an XCOFF archive has a global symbol table, which is what - we call the armap. The global symbol table has a normal archive - header with an empty name. It is normally (and perhaps must be) - the last entry in the archive. The contents start with a four byte - binary number which is the number of entries. This is followed by - a that many four byte binary numbers; each is the file offset of an - entry in the archive. These numbers are followed by a series of - null terminated strings, which are symbol names. */ - -/* XCOFF archives use this as a magic string. */ - -#define XCOFFARMAG "<aiaff>\012" -#define SXCOFFARMAG 8 - -/* This terminates an XCOFF archive member name. */ - -#define XCOFFARFMAG "`\012" -#define SXCOFFARFMAG 2 - -/* XCOFF archives start with this (printable) structure. */ - -struct xcoff_ar_file_hdr -{ - /* Magic string. */ - char magic[SXCOFFARMAG]; - - /* Offset of the member table (decimal ASCII string). */ - char memoff[12]; - - /* Offset of the global symbol table (decimal ASCII string). */ - char symoff[12]; - - /* Offset of the first member in the archive (decimal ASCII string). */ - char firstmemoff[12]; - - /* Offset of the last member in the archive (decimal ASCII string). */ - char lastmemoff[12]; - - /* Offset of the first member on the free list (decimal ASCII - string). */ - char freeoff[12]; -}; - -#define SIZEOF_AR_FILE_HDR (5 * 12 + SXCOFFARMAG) - -/* Each XCOFF archive member starts with this (printable) structure. */ - -struct xcoff_ar_hdr -{ - /* File size not including the header (decimal ASCII string). */ - char size[12]; - - /* File offset of next archive member (decimal ASCII string). */ - char nextoff[12]; - - /* File offset of previous archive member (decimal ASCII string). */ - char prevoff[12]; - - /* File mtime (decimal ASCII string). */ - char date[12]; - - /* File UID (decimal ASCII string). */ - char uid[12]; - - /* File GID (decimal ASCII string). */ - char gid[12]; - - /* File mode (octal ASCII string). */ - char mode[12]; - - /* Length of file name (decimal ASCII string). */ - char namlen[4]; - - /* This structure is followed by the file name. The length of the - name is given in the namlen field. If the length of the name is - odd, the name is followed by a null byte. The name and optional - null byte are followed by XCOFFARFMAG, which is not included in - namlen. The contents of the archive member follow; the number of - bytes is given in the size field. */ -}; - -#define SIZEOF_AR_HDR (7 * 12 + 4) - -/* We store a copy of the xcoff_ar_file_hdr in the tdata field of the - artdata structure. */ -#define xcoff_ardata(abfd) \ - ((struct xcoff_ar_file_hdr *) bfd_ardata (abfd)->tdata) - -/* We store a copy of the xcoff_ar_hdr in the arelt_data field of an - archive element. */ -#define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data)) -#define arch_xhdr(bfd) \ - ((struct xcoff_ar_hdr *) arch_eltdata (bfd)->arch_header) - -/* XCOFF archives do not have anything which corresponds to an - extended name table. */ - -#define xcoff_slurp_extended_name_table bfd_false -#define xcoff_construct_extended_name_table \ - ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \ - bfd_false) -#define xcoff_truncate_arname bfd_dont_truncate_arname - -/* We can use the standard get_elt_at_index routine. */ - -#define xcoff_get_elt_at_index _bfd_generic_get_elt_at_index - -/* XCOFF archives do not have a timestamp. */ - -#define xcoff_update_armap_timestamp bfd_true - -/* Read in the armap of an XCOFF archive. */ - -static boolean -xcoff_slurp_armap (abfd) - bfd *abfd; -{ - file_ptr off; - struct xcoff_ar_hdr hdr; - size_t namlen; - bfd_size_type sz; - bfd_byte *contents, *cend; - unsigned int c, i; - carsym *arsym; - bfd_byte *p; - - if (xcoff_ardata (abfd) == NULL) - { - bfd_has_map (abfd) = false; - return true; - } - - off = strtol (xcoff_ardata (abfd)->symoff, (char **) NULL, 10); - if (off == 0) - { - bfd_has_map (abfd) = false; - return true; - } - - if (bfd_seek (abfd, off, SEEK_SET) != 0) - return false; - - /* The symbol table starts with a normal archive header. */ - if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR) - return false; - - /* Skip the name (normally empty). */ - namlen = strtol (hdr.namlen, (char **) NULL, 10); - if (bfd_seek (abfd, ((namlen + 1) & ~1) + SXCOFFARFMAG, SEEK_CUR) != 0) - return false; - - /* Read in the entire symbol table. */ - sz = strtol (hdr.size, (char **) NULL, 10); - contents = (bfd_byte *) bfd_alloc (abfd, sz); - if (contents == NULL) - return false; - if (bfd_read ((PTR) contents, 1, sz, abfd) != sz) - return false; - - /* The symbol table starts with a four byte count. */ - c = bfd_h_get_32 (abfd, contents); - - if (c * 4 >= sz) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - bfd_ardata (abfd)->symdefs = ((carsym *) - bfd_alloc (abfd, c * sizeof (carsym))); - if (bfd_ardata (abfd)->symdefs == NULL) - return false; - - /* After the count comes a list of four byte file offsets. */ - for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 4; - i < c; - ++i, ++arsym, p += 4) - arsym->file_offset = bfd_h_get_32 (abfd, p); - - /* After the file offsets come null terminated symbol names. */ - cend = contents + sz; - for (i = 0, arsym = bfd_ardata (abfd)->symdefs; - i < c; - ++i, ++arsym, p += strlen ((char *) p) + 1) - { - if (p >= cend) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - arsym->name = (char *) p; - } - - bfd_ardata (abfd)->symdef_count = c; - bfd_has_map (abfd) = true; - - return true; -} - -/* See if this is an XCOFF archive. */ - -static const bfd_target * -xcoff_archive_p (abfd) - bfd *abfd; -{ - struct xcoff_ar_file_hdr hdr; - - if (bfd_read ((PTR) &hdr, SIZEOF_AR_FILE_HDR, 1, abfd) - != SIZEOF_AR_FILE_HDR) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - if (strncmp (hdr.magic, XCOFFARMAG, SXCOFFARMAG) != 0) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* We are setting bfd_ardata(abfd) here, but since bfd_ardata - involves a cast, we can't do it as the left operand of - assignment. */ - abfd->tdata.aout_ar_data = - (struct artdata *) bfd_zalloc (abfd, sizeof (struct artdata)); - - if (bfd_ardata (abfd) == (struct artdata *) NULL) - return NULL; - - bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff, - (char **) NULL, 10); - bfd_ardata (abfd)->cache = NULL; - bfd_ardata (abfd)->archive_head = NULL; - bfd_ardata (abfd)->symdefs = NULL; - bfd_ardata (abfd)->extended_names = NULL; - - bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, SIZEOF_AR_FILE_HDR); - if (bfd_ardata (abfd)->tdata == NULL) - return NULL; - - memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR); - - if (! xcoff_slurp_armap (abfd)) - { - bfd_release (abfd, bfd_ardata (abfd)); - abfd->tdata.aout_ar_data = (struct artdata *) NULL; - return NULL; - } - - return abfd->xvec; -} - -/* Read the archive header in an XCOFF archive. */ - -static PTR -xcoff_read_ar_hdr (abfd) - bfd *abfd; -{ - struct xcoff_ar_hdr hdr; - size_t namlen; - struct xcoff_ar_hdr *hdrp; - struct areltdata *ret; - - if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR) - return NULL; - - namlen = strtol (hdr.namlen, (char **) NULL, 10); - hdrp = bfd_alloc (abfd, SIZEOF_AR_HDR + namlen + 1); - if (hdrp == NULL) - return NULL; - memcpy (hdrp, &hdr, SIZEOF_AR_HDR); - if (bfd_read ((char *) hdrp + SIZEOF_AR_HDR, 1, namlen, abfd) != namlen) - return NULL; - ((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0'; - - ret = (struct areltdata *) bfd_alloc (abfd, sizeof (struct areltdata)); - if (ret == NULL) - return NULL; - ret->arch_header = (char *) hdrp; - ret->parsed_size = strtol (hdr.size, (char **) NULL, 10); - ret->filename = (char *) hdrp + SIZEOF_AR_HDR; - - /* Skip over the XCOFFARFMAG at the end of the file name. */ - if (bfd_seek (abfd, (namlen & 1) + SXCOFFARFMAG, SEEK_CUR) != 0) - return NULL; - - return (PTR) ret; -} - -/* Open the next element in an XCOFF archive. */ - -static bfd * -xcoff_openr_next_archived_file (archive, last_file) - bfd *archive; - bfd *last_file; -{ - file_ptr filestart; - - if (xcoff_ardata (archive) == NULL) - { - bfd_set_error (bfd_error_invalid_operation); - return NULL; - } - - if (last_file == NULL) - filestart = bfd_ardata (archive)->first_file_filepos; - else - filestart = strtol (arch_xhdr (last_file)->nextoff, (char **) NULL, 10); - - if (filestart == 0 - || filestart == strtol (xcoff_ardata (archive)->memoff, - (char **) NULL, 10) - || filestart == strtol (xcoff_ardata (archive)->symoff, - (char **) NULL, 10)) - { - bfd_set_error (bfd_error_no_more_archived_files); - return NULL; - } - - return _bfd_get_elt_at_filepos (archive, filestart); -} - -/* Stat an element in an XCOFF archive. */ - -static int -xcoff_generic_stat_arch_elt (abfd, s) - bfd *abfd; - struct stat *s; -{ - struct xcoff_ar_hdr *hdrp; - - if (abfd->arelt_data == NULL) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - - hdrp = arch_xhdr (abfd); - - s->st_mtime = strtol (hdrp->date, (char **) NULL, 10); - s->st_uid = strtol (hdrp->uid, (char **) NULL, 10); - s->st_gid = strtol (hdrp->gid, (char **) NULL, 10); - s->st_mode = strtol (hdrp->mode, (char **) NULL, 8); - s->st_size = arch_eltdata (abfd)->parsed_size; - - return 0; -} - -/* Normalize a file name for inclusion in an archive. */ - -static const char * -normalize_filename (abfd) - bfd *abfd; -{ - const char *file; - const char *filename; - - file = bfd_get_filename (abfd); - filename = strrchr (file, '/'); - if (filename != NULL) - filename++; - else - filename = file; - return filename; -} - -/* Write out an XCOFF armap. */ - -/*ARGSUSED*/ -static boolean -xcoff_write_armap (abfd, elength, map, orl_count, stridx) - bfd *abfd; - unsigned int elength; - struct orl *map; - unsigned int orl_count; - int stridx; -{ - struct xcoff_ar_hdr hdr; - char *p; - unsigned char buf[4]; - bfd *sub; - file_ptr fileoff; - unsigned int i; - - memset (&hdr, 0, sizeof hdr); - sprintf (hdr.size, "%ld", (long) (4 + orl_count * 4 + stridx)); - sprintf (hdr.nextoff, "%d", 0); - memcpy (hdr.prevoff, xcoff_ardata (abfd)->memoff, 12); - sprintf (hdr.date, "%d", 0); - sprintf (hdr.uid, "%d", 0); - sprintf (hdr.gid, "%d", 0); - sprintf (hdr.mode, "%d", 0); - sprintf (hdr.namlen, "%d", 0); - - /* We need spaces, not null bytes, in the header. */ - for (p = (char *) &hdr; p < (char *) &hdr + SIZEOF_AR_HDR; p++) - if (*p == '\0') - *p = ' '; - - if (bfd_write ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR - || bfd_write (XCOFFARFMAG, 1, SXCOFFARFMAG, abfd) != SXCOFFARFMAG) - return false; - - bfd_h_put_32 (abfd, orl_count, buf); - if (bfd_write (buf, 1, 4, abfd) != 4) - return false; - - sub = abfd->archive_head; - fileoff = SIZEOF_AR_FILE_HDR; - i = 0; - while (sub != NULL && i < orl_count) - { - size_t namlen; - - while (((bfd *) (map[i]).pos) == sub) - { - bfd_h_put_32 (abfd, fileoff, buf); - if (bfd_write (buf, 1, 4, abfd) != 4) - return false; - ++i; - } - namlen = strlen (normalize_filename (sub)); - namlen = (namlen + 1) &~ 1; - fileoff += (SIZEOF_AR_HDR - + namlen - + SXCOFFARFMAG - + arelt_size (sub)); - fileoff = (fileoff + 1) &~ 1; - sub = sub->next; - } - - for (i = 0; i < orl_count; i++) - { - const char *name; - size_t namlen; - - name = *map[i].name; - namlen = strlen (name); - if (bfd_write (name, 1, namlen + 1, abfd) != namlen + 1) - return false; - } - - if ((stridx & 1) != 0) - { - char b; - - b = '\0'; - if (bfd_write (&b, 1, 1, abfd) != 1) - return false; - } - - return true; -} - -/* Write out an XCOFF archive. We always write an entire archive, - rather than fussing with the freelist and so forth. */ - -static boolean -xcoff_write_archive_contents (abfd) - bfd *abfd; -{ - struct xcoff_ar_file_hdr fhdr; - size_t count; - size_t total_namlen; - file_ptr *offsets; - boolean makemap; - boolean hasobjects; - file_ptr prevoff, nextoff; - bfd *sub; - unsigned int i; - struct xcoff_ar_hdr ahdr; - bfd_size_type size; - char *p; - char decbuf[13]; - - memset (&fhdr, 0, sizeof fhdr); - strncpy (fhdr.magic, XCOFFARMAG, SXCOFFARMAG); - sprintf (fhdr.firstmemoff, "%d", SIZEOF_AR_FILE_HDR); - sprintf (fhdr.freeoff, "%d", 0); - - count = 0; - total_namlen = 0; - for (sub = abfd->archive_head; sub != NULL; sub = sub->next) - { - ++count; - total_namlen += strlen (normalize_filename (sub)) + 1; - } - offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr)); - if (offsets == NULL) - return false; - - if (bfd_seek (abfd, SIZEOF_AR_FILE_HDR, SEEK_SET) != 0) - return false; - - makemap = bfd_has_map (abfd); - hasobjects = false; - prevoff = 0; - nextoff = SIZEOF_AR_FILE_HDR; - for (sub = abfd->archive_head, i = 0; sub != NULL; sub = sub->next, i++) - { - const char *name; - size_t namlen; - struct xcoff_ar_hdr *ahdrp; - bfd_size_type remaining; - - if (makemap && ! hasobjects) - { - if (bfd_check_format (sub, bfd_object)) - hasobjects = true; - } - - name = normalize_filename (sub); - namlen = strlen (name); - - if (sub->arelt_data != NULL) - ahdrp = arch_xhdr (sub); - else - ahdrp = NULL; - - if (ahdrp == NULL) - { - struct stat s; - - memset (&ahdr, 0, sizeof ahdr); - ahdrp = &ahdr; - if (stat (bfd_get_filename (sub), &s) != 0) - { - bfd_set_error (bfd_error_system_call); - return false; - } - - sprintf (ahdrp->size, "%ld", (long) s.st_size); - sprintf (ahdrp->date, "%ld", (long) s.st_mtime); - sprintf (ahdrp->uid, "%ld", (long) s.st_uid); - sprintf (ahdrp->gid, "%ld", (long) s.st_gid); - sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode); - - if (sub->arelt_data == NULL) - { - sub->arelt_data = ((struct areltdata *) - bfd_alloc (sub, sizeof (struct areltdata))); - if (sub->arelt_data == NULL) - return false; - } - - arch_eltdata (sub)->parsed_size = s.st_size; - } - - sprintf (ahdrp->prevoff, "%ld", (long) prevoff); - sprintf (ahdrp->namlen, "%ld", (long) namlen); - - /* If the length of the name is odd, we write out the null byte - after the name as well. */ - namlen = (namlen + 1) &~ 1; - - remaining = arelt_size (sub); - size = (SIZEOF_AR_HDR - + namlen - + SXCOFFARFMAG - + remaining); - - BFD_ASSERT (nextoff == bfd_tell (abfd)); - - offsets[i] = nextoff; - - prevoff = nextoff; - nextoff += size + (size & 1); - - sprintf (ahdrp->nextoff, "%ld", (long) nextoff); - - /* We need spaces, not null bytes, in the header. */ - for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++) - if (*p == '\0') - *p = ' '; - - if (bfd_write ((PTR) ahdrp, 1, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR - || bfd_write ((PTR) name, 1, namlen, abfd) != namlen - || (bfd_write ((PTR) XCOFFARFMAG, 1, SXCOFFARFMAG, abfd) - != SXCOFFARFMAG)) - return false; - - if (bfd_seek (sub, (file_ptr) 0, SEEK_SET) != 0) - return false; - while (remaining != 0) - { - bfd_size_type amt; - bfd_byte buffer[DEFAULT_BUFFERSIZE]; - - amt = sizeof buffer; - if (amt > remaining) - amt = remaining; - if (bfd_read (buffer, 1, amt, sub) != amt - || bfd_write (buffer, 1, amt, abfd) != amt) - return false; - remaining -= amt; - } - - if ((size & 1) != 0) - { - bfd_byte b; - - b = '\0'; - if (bfd_write (&b, 1, 1, abfd) != 1) - return false; - } - } - - sprintf (fhdr.lastmemoff, "%ld", (long) prevoff); - - /* Write out the member table. */ - - BFD_ASSERT (nextoff == bfd_tell (abfd)); - sprintf (fhdr.memoff, "%ld", (long) nextoff); - - memset (&ahdr, 0, sizeof ahdr); - sprintf (ahdr.size, "%ld", (long) (12 + count * 12 + total_namlen)); - sprintf (ahdr.prevoff, "%ld", (long) prevoff); - sprintf (ahdr.date, "%d", 0); - sprintf (ahdr.uid, "%d", 0); - sprintf (ahdr.gid, "%d", 0); - sprintf (ahdr.mode, "%d", 0); - sprintf (ahdr.namlen, "%d", 0); - - size = (SIZEOF_AR_HDR - + 12 - + count * 12 - + total_namlen - + SXCOFFARFMAG); - - prevoff = nextoff; - nextoff += size + (size & 1); - - if (makemap && hasobjects) - sprintf (ahdr.nextoff, "%ld", (long) nextoff); - else - sprintf (ahdr.nextoff, "%d", 0); - - /* We need spaces, not null bytes, in the header. */ - for (p = (char *) &ahdr; p < (char *) &ahdr + SIZEOF_AR_HDR; p++) - if (*p == '\0') - *p = ' '; - - if (bfd_write ((PTR) &ahdr, 1, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR - || (bfd_write ((PTR) XCOFFARFMAG, 1, SXCOFFARFMAG, abfd) - != SXCOFFARFMAG)) - return false; - - sprintf (decbuf, "%-12ld", (long) count); - if (bfd_write ((PTR) decbuf, 1, 12, abfd) != 12) - return false; - for (i = 0; i < count; i++) - { - sprintf (decbuf, "%-12ld", (long) offsets[i]); - if (bfd_write ((PTR) decbuf, 1, 12, abfd) != 12) - return false; - } - for (sub = abfd->archive_head; sub != NULL; sub = sub->next) - { - const char *name; - size_t namlen; - - name = normalize_filename (sub); - namlen = strlen (name); - if (bfd_write ((PTR) name, 1, namlen + 1, abfd) != namlen + 1) - return false; - } - if ((size & 1) != 0) - { - bfd_byte b; - - b = '\0'; - if (bfd_write ((PTR) &b, 1, 1, abfd) != 1) - return false; - } - - /* Write out the armap, if appropriate. */ - - if (! makemap || ! hasobjects) - sprintf (fhdr.symoff, "%d", 0); - else - { - BFD_ASSERT (nextoff == bfd_tell (abfd)); - sprintf (fhdr.symoff, "%ld", (long) nextoff); - bfd_ardata (abfd)->tdata = (PTR) &fhdr; - if (! _bfd_compute_and_write_armap (abfd, 0)) - return false; - } - - /* Write out the archive file header. */ - - /* We need spaces, not null bytes, in the header. */ - for (p = (char *) &fhdr; p < (char *) &fhdr + SIZEOF_AR_FILE_HDR; p++) - if (*p == '\0') - *p = ' '; - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || (bfd_write ((PTR) &fhdr, SIZEOF_AR_FILE_HDR, 1, abfd) != - SIZEOF_AR_FILE_HDR)) - return false; - - return true; -} - -/* We can't use the usual coff_sizeof_headers routine, because AIX - always uses an a.out header. */ - -/*ARGSUSED*/ -static int -_bfd_xcoff_sizeof_headers (abfd, reloc) - bfd *abfd; - boolean reloc; -{ - int size; - - size = FILHSZ; - if (xcoff_data (abfd)->full_aouthdr) - size += AOUTSZ; - else - size += SMALL_AOUTSZ; - size += abfd->section_count * SCNHSZ; - return size; -} - -#define CORE_FILE_P _bfd_dummy_target - -#define coff_core_file_failing_command _bfd_nocore_core_file_failing_command -#define coff_core_file_failing_signal _bfd_nocore_core_file_failing_signal -#define coff_core_file_matches_executable_p \ - _bfd_nocore_core_file_matches_executable_p - -#ifdef AIX_CORE -#undef CORE_FILE_P -#define CORE_FILE_P rs6000coff_core_p -extern const bfd_target * rs6000coff_core_p (); -extern boolean rs6000coff_get_section_contents (); -extern boolean rs6000coff_core_file_matches_executable_p (); - -#undef coff_core_file_matches_executable_p -#define coff_core_file_matches_executable_p \ - rs6000coff_core_file_matches_executable_p - -extern char *rs6000coff_core_file_failing_command PARAMS ((bfd *abfd)); -#undef coff_core_file_failing_command -#define coff_core_file_failing_command rs6000coff_core_file_failing_command - -extern int rs6000coff_core_file_failing_signal PARAMS ((bfd *abfd)); -#undef coff_core_file_failing_signal -#define coff_core_file_failing_signal rs6000coff_core_file_failing_signal - -#undef coff_get_section_contents -#define coff_get_section_contents rs6000coff_get_section_contents -#endif /* AIX_CORE */ - -#ifdef LYNX_CORE - -#undef CORE_FILE_P -#define CORE_FILE_P lynx_core_file_p -extern const bfd_target *lynx_core_file_p PARAMS ((bfd *abfd)); - -extern boolean lynx_core_file_matches_executable_p PARAMS ((bfd *core_bfd, - bfd *exec_bfd)); -#undef coff_core_file_matches_executable_p -#define coff_core_file_matches_executable_p lynx_core_file_matches_executable_p - -extern char *lynx_core_file_failing_command PARAMS ((bfd *abfd)); -#undef coff_core_file_failing_command -#define coff_core_file_failing_command lynx_core_file_failing_command - -extern int lynx_core_file_failing_signal PARAMS ((bfd *abfd)); -#undef coff_core_file_failing_signal -#define coff_core_file_failing_signal lynx_core_file_failing_signal - -#endif /* LYNX_CORE */ - -#define _bfd_xcoff_bfd_get_relocated_section_contents \ - coff_bfd_get_relocated_section_contents -#define _bfd_xcoff_bfd_relax_section coff_bfd_relax_section -#define _bfd_xcoff_bfd_link_split_section coff_bfd_link_split_section - -/* The transfer vector that leads the outside world to all of the above. */ - -const bfd_target -#ifdef TARGET_SYM - TARGET_SYM = -#else - rs6000coff_vec = -#endif -{ -#ifdef TARGET_NAME - TARGET_NAME, -#else - "aixcoff-rs6000", /* name */ -#endif - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | DYNAMIC | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading char */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen??? FIXMEmgo */ - - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - xcoff_archive_p, CORE_FILE_P}, - {bfd_false, coff_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - xcoff_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (coff), - BFD_JUMP_TABLE_ARCHIVE (xcoff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (_bfd_xcoff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-sh.c b/contrib/gdb/bfd/coff-sh.c deleted file mode 100644 index 17bb4b1..0000000 --- a/contrib/gdb/bfd/coff-sh.c +++ /dev/null @@ -1,1525 +0,0 @@ -/* BFD back-end for Hitachi Super-H COFF binaries. - Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - Contributed by Cygnus Support. - Written by Steve Chamberlain, <sac@cygnus.com>. - Relaxing code written by Ian Lance Taylor, <ian@cygnus.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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "obstack.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "coff/sh.h" -#include "coff/internal.h" -#include "libcoff.h" - -/* Internal functions. */ -static bfd_reloc_status_type sh_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static long get_symbol_value PARAMS ((asymbol *)); -static boolean sh_relax_section - PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *)); -static boolean sh_relax_delete_bytes - PARAMS ((bfd *, asection *, bfd_vma, int)); -static boolean sh_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - struct internal_reloc *, struct internal_syment *, asection **)); -static bfd_byte *sh_coff_get_relocated_section_contents - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *, boolean, asymbol **)); - -/* Default section alignment to 2**2. */ -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2) - -/* Generate long file names. */ -#define COFF_LONG_FILENAMES - -/* The supported relocations. There are a lot of relocations defined - in coff/internal.h which we do not expect to ever see. */ -static reloc_howto_type sh_coff_howtos[] = -{ - { 0 }, - { 1 }, - { 2 }, - { 3 }, /* R_SH_PCREL8 */ - { 4 }, /* R_SH_PCREL16 */ - { 5 }, /* R_SH_HIGH8 */ - { 6 }, /* R_SH_IMM24 */ - { 7 }, /* R_SH_LOW16 */ - { 8 }, - { 9 }, /* R_SH_PCDISP8BY4 */ - - HOWTO (R_SH_PCDISP8BY2, /* type */ - 1, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_pcdisp8by2", /* name */ - true, /* partial_inplace */ - 0xff, /* src_mask */ - 0xff, /* dst_mask */ - true), /* pcrel_offset */ - - { 11 }, /* R_SH_PCDISP8 */ - - HOWTO (R_SH_PCDISP, /* type */ - 1, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 12, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_pcdisp12by2", /* name */ - true, /* partial_inplace */ - 0xfff, /* src_mask */ - 0xfff, /* dst_mask */ - true), /* pcrel_offset */ - - { 13 }, - - HOWTO (R_SH_IMM32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_imm32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - { 15 }, - { 16 }, /* R_SH_IMM8 */ - { 17 }, /* R_SH_IMM8BY2 */ - { 18 }, /* R_SH_IMM8BY4 */ - { 19 }, /* R_SH_IMM4 */ - { 20 }, /* R_SH_IMM4BY2 */ - { 21 }, /* R_SH_IMM4BY4 */ - - HOWTO (R_SH_PCRELIMM8BY2, /* type */ - 1, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_unsigned, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_pcrelimm8by2", /* name */ - true, /* partial_inplace */ - 0xff, /* src_mask */ - 0xff, /* dst_mask */ - true), /* pcrel_offset */ - - HOWTO (R_SH_PCRELIMM8BY4, /* type */ - 2, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_unsigned, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_pcrelimm8by4", /* name */ - true, /* partial_inplace */ - 0xff, /* src_mask */ - 0xff, /* dst_mask */ - true), /* pcrel_offset */ - - HOWTO (R_SH_IMM16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_imm16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - HOWTO (R_SH_SWITCH16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_switch16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - HOWTO (R_SH_SWITCH32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_switch32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - HOWTO (R_SH_USES, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_uses", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - HOWTO (R_SH_COUNT, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_count", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - HOWTO (R_SH_ALIGN, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - sh_reloc, /* special_function */ - "r_align", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false) /* pcrel_offset */ -}; - -#define SH_COFF_HOWTO_COUNT (sizeof sh_coff_howtos / sizeof sh_coff_howtos[0]) - -/* Check for a bad magic number. */ -#define BADMAG(x) SHBADMAG(x) - -/* Customize coffcode.h (this is not currently used). */ -#define SH 1 - -/* FIXME: This should not be set here. */ -#define __A_MAGIC_SET__ - -/* Swap the r_offset field in and out. */ -#define SWAP_IN_RELOC_OFFSET bfd_h_get_32 -#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32 - -/* Swap out extra information in the reloc structure. */ -#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \ - do \ - { \ - dst->r_stuff[0] = 'S'; \ - dst->r_stuff[1] = 'C'; \ - } \ - while (0) - -/* Get the value of a symbol, when performing a relocation. */ - -static long -get_symbol_value (symbol) - asymbol *symbol; -{ - bfd_vma relocation; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = (symbol->value + - symbol->section->output_section->vma + - symbol->section->output_offset); - - return relocation; -} - -/* This macro is used in coffcode.h to get the howto corresponding to - an internal reloc. */ - -#define RTYPE2HOWTO(relent, internal) \ - ((relent)->howto = \ - ((internal)->r_type < SH_COFF_HOWTO_COUNT \ - ? &sh_coff_howtos[(internal)->r_type] \ - : (reloc_howto_type *) NULL)) - -/* This is the same as the macro in coffcode.h, except that it copies - r_offset into reloc_entry->addend for some relocs. */ -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ - { \ - coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ - if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ - coffsym = (obj_symbols (abfd) \ - + (cache_ptr->sym_ptr_ptr - symbols)); \ - else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ - if (coffsym != (coff_symbol_type *) NULL \ - && coffsym->native->u.syment.n_scnum == 0) \ - cache_ptr->addend = 0; \ - else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ - && ptr->section != (asection *) NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ - else \ - cache_ptr->addend = 0; \ - if ((reloc).r_type == R_SH_SWITCH16 \ - || (reloc).r_type == R_SH_SWITCH32 \ - || (reloc).r_type == R_SH_USES \ - || (reloc).r_type == R_SH_COUNT \ - || (reloc).r_type == R_SH_ALIGN) \ - cache_ptr->addend = (reloc).r_offset; \ - } - -/* This is the howto function for the SH relocations. */ - -static bfd_reloc_status_type -sh_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol_in; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - unsigned long insn; - bfd_vma sym_value; - unsigned short r_type; - bfd_vma addr = reloc_entry->address; - bfd_byte *hit_data = addr + (bfd_byte *) data; - - r_type = reloc_entry->howto->type; - - if (output_bfd != NULL) - { - /* Partial linking--do nothing. */ - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* Almost all relocs have to do with relaxing. If any work must be - done for them, it has been done in sh_relax_section. */ - if (r_type != R_SH_IMM32 - && (r_type != R_SH_PCDISP - || (symbol_in->flags & BSF_LOCAL) != 0)) - return bfd_reloc_ok; - - if (symbol_in != NULL - && bfd_is_und_section (symbol_in->section)) - return bfd_reloc_undefined; - - sym_value = get_symbol_value (symbol_in); - - switch (r_type) - { - case R_SH_IMM32: - insn = bfd_get_32 (abfd, hit_data); - insn += sym_value + reloc_entry->addend; - bfd_put_32 (abfd, insn, hit_data); - break; - case R_SH_PCDISP: - insn = bfd_get_16 (abfd, hit_data); - sym_value += reloc_entry->addend; - sym_value -= (input_section->output_section->vma - + input_section->output_offset - + addr - + 4); - sym_value += (insn & 0xfff) << 1; - if (insn & 0x800) - sym_value -= 0x1000; - insn = (insn & 0xf000) | (sym_value & 0xfff); - bfd_put_16 (abfd, insn, hit_data); - if (sym_value < (bfd_vma) -0x1000 || sym_value >= 0x1000) - return bfd_reloc_overflow; - break; - default: - abort (); - break; - } - - return bfd_reloc_ok; -} - -/* We can do relaxing. */ -#define coff_bfd_relax_section sh_relax_section - -/* We use the special COFF backend linker. */ -#define coff_relocate_section sh_relocate_section - -/* When relaxing, we need to use special code to get the relocated - section contents. */ -#define coff_bfd_get_relocated_section_contents \ - sh_coff_get_relocated_section_contents - -#include "coffcode.h" - -/* This function handles relaxing on the SH. - - Function calls on the SH look like this: - - movl L1,r0 - ... - jsr @r0 - ... - L1: - .long function - - The compiler and assembler will cooperate to create R_SH_USES - relocs on the jsr instructions. The r_offset field of the - R_SH_USES reloc is the PC relative offset to the instruction which - loads the register (the r_offset field is computed as though it - were a jump instruction, so the offset value is actually from four - bytes past the instruction). The linker can use this reloc to - determine just which function is being called, and thus decide - whether it is possible to replace the jsr with a bsr. - - If multiple function calls are all based on a single register load - (i.e., the same function is called multiple times), the compiler - guarantees that each function call will have an R_SH_USES reloc. - Therefore, if the linker is able to convert each R_SH_USES reloc - which refers to that address, it can safely eliminate the register - load. - - When the assembler creates an R_SH_USES reloc, it examines it to - determine which address is being loaded (L1 in the above example). - It then counts the number of references to that address, and - creates an R_SH_COUNT reloc at that address. The r_offset field of - the R_SH_COUNT reloc will be the number of references. If the - linker is able to eliminate a register load, it can use the - R_SH_COUNT reloc to see whether it can also eliminate the function - address. */ - -static boolean -sh_relax_section (abfd, sec, link_info, again) - bfd *abfd; - asection *sec; - struct bfd_link_info *link_info; - boolean *again; -{ - struct internal_reloc *internal_relocs; - struct internal_reloc *free_relocs = NULL; - struct internal_reloc *irel, *irelend; - bfd_byte *contents = NULL; - bfd_byte *free_contents = NULL; - - *again = false; - - if (link_info->relocateable - || (sec->flags & SEC_RELOC) == 0 - || sec->reloc_count == 0) - return true; - - /* If this is the first time we have been called for this section, - initialize the cooked size. */ - if (sec->_cooked_size == 0) - sec->_cooked_size = sec->_raw_size; - - internal_relocs = (_bfd_coff_read_internal_relocs - (abfd, sec, link_info->keep_memory, - (bfd_byte *) NULL, false, - (struct internal_reloc *) NULL)); - if (internal_relocs == NULL) - goto error_return; - if (! link_info->keep_memory) - free_relocs = internal_relocs; - - irelend = internal_relocs + sec->reloc_count; - for (irel = internal_relocs; irel < irelend; irel++) - { - bfd_vma laddr, paddr, symval; - unsigned short insn; - struct internal_reloc *irelfn, *irelscan, *irelcount; - struct internal_syment sym; - bfd_signed_vma foff; - - if (irel->r_type != R_SH_USES) - continue; - - /* Get the section contents. */ - if (contents == NULL) - { - if (coff_section_data (abfd, sec) != NULL - && coff_section_data (abfd, sec)->contents != NULL) - contents = coff_section_data (abfd, sec)->contents; - else - { - contents = (bfd_byte *) bfd_malloc (sec->_raw_size); - if (contents == NULL) - goto error_return; - free_contents = contents; - - if (! bfd_get_section_contents (abfd, sec, contents, - (file_ptr) 0, sec->_raw_size)) - goto error_return; - } - } - - /* The r_offset field of the R_SH_USES reloc will point us to - the register load. The 4 is because the r_offset field is - computed as though it were a jump offset, which are based - from 4 bytes after the jump instruction. */ - laddr = irel->r_vaddr - sec->vma + 4 + irel->r_offset; - if (laddr >= sec->_raw_size) - { - (*_bfd_error_handler) ("%s: 0x%lx: warning: bad R_SH_USES offset", - bfd_get_filename (abfd), - (unsigned long) irel->r_vaddr); - continue; - } - insn = bfd_get_16 (abfd, contents + laddr); - - /* If the instruction is not mov.l NN,rN, we don't know what to - do. */ - if ((insn & 0xf000) != 0xd000) - { - ((*_bfd_error_handler) - ("%s: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x", - bfd_get_filename (abfd), (unsigned long) irel->r_vaddr, insn)); - continue; - } - - /* Get the address from which the register is being loaded. The - displacement in the mov.l instruction is quadrupled. It is a - displacement from four bytes after the movl instruction, but, - before adding in the PC address, two least significant bits - of the PC are cleared. We assume that the section is aligned - on a four byte boundary. */ - paddr = insn & 0xff; - paddr *= 4; - paddr += (laddr + 4) &~ 3; - if (paddr >= sec->_raw_size) - { - ((*_bfd_error_handler) - ("%s: 0x%lx: warning: bad R_SH_USES load offset", - bfd_get_filename (abfd), (unsigned long) irel->r_vaddr)); - continue; - } - - /* Get the reloc for the address from which the register is - being loaded. This reloc will tell us which function is - actually being called. */ - paddr += sec->vma; - for (irelfn = internal_relocs; irelfn < irelend; irelfn++) - if (irelfn->r_vaddr == paddr - && irelfn->r_type == R_SH_IMM32) - break; - if (irelfn >= irelend) - { - ((*_bfd_error_handler) - ("%s: 0x%lx: warning: could not find expected reloc", - bfd_get_filename (abfd), (unsigned long) paddr)); - continue; - } - - /* Get the value of the symbol referred to by the reloc. */ - if (! _bfd_coff_get_external_symbols (abfd)) - goto error_return; - bfd_coff_swap_sym_in (abfd, - ((bfd_byte *) obj_coff_external_syms (abfd) - + (irelfn->r_symndx - * bfd_coff_symesz (abfd))), - &sym); - if (sym.n_scnum != 0 && sym.n_scnum != sec->target_index) - { - ((*_bfd_error_handler) - ("%s: 0x%lx: warning: symbol in unexpected section", - bfd_get_filename (abfd), (unsigned long) paddr)); - continue; - } - - if (sym.n_sclass != C_EXT) - { - symval = (sym.n_value - - sec->vma - + sec->output_section->vma - + sec->output_offset); - } - else - { - struct coff_link_hash_entry *h; - - h = obj_coff_sym_hashes (abfd)[irelfn->r_symndx]; - BFD_ASSERT (h != NULL); - if (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak) - { - /* This appears to be a reference to an undefined - symbol. Just ignore it--it will be caught by the - regular reloc processing. */ - continue; - } - - symval = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - } - - symval += bfd_get_32 (abfd, contents + paddr - sec->vma); - - /* See if this function call can be shortened. */ - foff = (symval - - (irel->r_vaddr - - sec->vma - + sec->output_section->vma - + sec->output_offset - + 4)); - if (foff < -0x1000 || foff >= 0x1000) - { - /* After all that work, we can't shorten this function call. */ - continue; - } - - /* Shorten the function call. */ - - /* For simplicity of coding, we are going to modify the section - contents, the section relocs, and the BFD symbol table. We - must tell the rest of the code not to free up this - information. It would be possible to instead create a table - of changes which have to be made, as is done in coff-mips.c; - that would be more work, but would require less memory when - the linker is run. */ - - if (coff_section_data (abfd, sec) == NULL) - { - sec->used_by_bfd = - ((PTR) bfd_zalloc (abfd, sizeof (struct coff_section_tdata))); - if (sec->used_by_bfd == NULL) - goto error_return; - } - - coff_section_data (abfd, sec)->relocs = internal_relocs; - coff_section_data (abfd, sec)->keep_relocs = true; - free_relocs = NULL; - - coff_section_data (abfd, sec)->contents = contents; - coff_section_data (abfd, sec)->keep_contents = true; - free_contents = NULL; - - obj_coff_keep_syms (abfd) = true; - - /* Replace the jsr with a bsr. */ - - /* Change the R_SH_USES reloc into an R_SH_PCDISP reloc, and - replace the jsr with a bsr. */ - irel->r_type = R_SH_PCDISP; - irel->r_symndx = irelfn->r_symndx; - if (sym.n_sclass != C_EXT) - { - /* If this needs to be changed because of future relaxing, - it will be handled here like other internal PCDISP - relocs. */ - bfd_put_16 (abfd, - 0xb000 | ((foff >> 1) & 0xfff), - contents + irel->r_vaddr - sec->vma); - } - else - { - /* We can't fully resolve this yet, because the external - symbol value may be changed by future relaxing. We let - the final link phase handle it. */ - bfd_put_16 (abfd, 0xb000, contents + irel->r_vaddr - sec->vma); - } - - /* See if there is another R_SH_USES reloc referring to the same - register load. */ - for (irelscan = internal_relocs; irelscan < irelend; irelscan++) - if (irelscan->r_type == R_SH_USES - && laddr == irelscan->r_vaddr - sec->vma + 4 + irelscan->r_offset) - break; - if (irelscan < irelend) - { - /* Some other function call depends upon this register load, - and we have not yet converted that function call. - Indeed, we may never be able to convert it. There is - nothing else we can do at this point. */ - continue; - } - - /* Look for a R_SH_COUNT reloc on the location where the - function address is stored. Do this before deleting any - bytes, to avoid confusion about the address. */ - for (irelcount = internal_relocs; irelcount < irelend; irelcount++) - if (irelcount->r_vaddr == paddr - && irelcount->r_type == R_SH_COUNT) - break; - - /* Delete the register load. */ - if (! sh_relax_delete_bytes (abfd, sec, laddr, 2)) - goto error_return; - - /* That will change things, so, just in case it permits some - other function call to come within range, we should relax - again. Note that this is not required, and it may be slow. */ - *again = true; - - /* Now check whether we got a COUNT reloc. */ - if (irelcount >= irelend) - { - ((*_bfd_error_handler) - ("%s: 0x%lx: warning: could not find expected COUNT reloc", - bfd_get_filename (abfd), (unsigned long) paddr)); - continue; - } - - /* The number of uses is stored in the r_offset field. We've - just deleted one. */ - if (irelcount->r_offset == 0) - { - ((*_bfd_error_handler) ("%s: 0x%lx: warning: bad count", - bfd_get_filename (abfd), - (unsigned long) paddr)); - continue; - } - - --irelcount->r_offset; - - /* If there are no more uses, we can delete the address. Reload - the address from irelfn, in case it was changed by the - previous call to sh_relax_delete_bytes. */ - if (irelcount->r_offset == 0) - { - if (! sh_relax_delete_bytes (abfd, sec, - irelfn->r_vaddr - sec->vma, 4)) - goto error_return; - } - - /* We've done all we can with that function call. */ - } - - if (free_relocs != NULL) - { - free (free_relocs); - free_relocs = NULL; - } - - if (free_contents != NULL) - { - if (! link_info->keep_memory) - free (free_contents); - else - { - /* Cache the section contents for coff_link_input_bfd. */ - if (coff_section_data (abfd, sec) == NULL) - { - sec->used_by_bfd = - ((PTR) bfd_zalloc (abfd, sizeof (struct coff_section_tdata))); - if (sec->used_by_bfd == NULL) - goto error_return; - coff_section_data (abfd, sec)->relocs = NULL; - } - coff_section_data (abfd, sec)->contents = contents; - } - } - - return true; - - error_return: - if (free_relocs != NULL) - free (free_relocs); - if (free_contents != NULL) - free (free_contents); - return false; -} - -/* Delete some bytes from a section while relaxing. */ - -static boolean -sh_relax_delete_bytes (abfd, sec, addr, count) - bfd *abfd; - asection *sec; - bfd_vma addr; - int count; -{ - bfd_byte *contents; - struct internal_reloc *irel, *irelend; - struct internal_reloc *irelalign; - bfd_vma toaddr; - bfd_byte *esym, *esymend; - bfd_size_type symesz; - struct coff_link_hash_entry **sym_hash; - asection *o; - - contents = coff_section_data (abfd, sec)->contents; - - /* The deletion must stop at the next ALIGN reloc for an aligment - power larger than the number of bytes we are deleting. */ - - irelalign = NULL; - toaddr = sec->_cooked_size; - - irel = coff_section_data (abfd, sec)->relocs; - irelend = irel + sec->reloc_count; - for (; irel < irelend; irel++) - { - if (irel->r_type == R_SH_ALIGN - && irel->r_vaddr - sec->vma > addr - && count < (1 << irel->r_offset)) - { - irelalign = irel; - toaddr = irel->r_vaddr - sec->vma; - break; - } - } - - /* Actually delete the bytes. */ - memmove (contents + addr, contents + addr + count, toaddr - addr - count); - if (irelalign == NULL) - sec->_cooked_size -= count; - else - memset (contents + toaddr - count, 0, count); - - /* Adjust all the relocs. */ - for (irel = coff_section_data (abfd, sec)->relocs; irel < irelend; irel++) - { - bfd_vma nraddr, start, stop; - int insn = 0; - struct internal_syment sym; - int off, adjust, oinsn; - bfd_signed_vma voff; - boolean overflow; - - /* Get the new reloc address. */ - nraddr = irel->r_vaddr - sec->vma; - if ((irel->r_vaddr - sec->vma > addr - && irel->r_vaddr - sec->vma < toaddr) - || (irel->r_type == R_SH_ALIGN - && irel->r_vaddr - sec->vma == toaddr)) - nraddr -= count; - - /* See if this reloc was for the bytes we have deleted, in which - case we no longer care about it. */ - if (irel->r_vaddr - sec->vma >= addr - && irel->r_vaddr - sec->vma < addr + count - && irel->r_type != R_SH_ALIGN) - irel->r_type = R_SH_UNUSED; - - /* If this is a PC relative reloc, see if the range it covers - includes the bytes we have deleted. */ - switch (irel->r_type) - { - default: - break; - - case R_SH_PCDISP8BY2: - case R_SH_PCDISP: - case R_SH_PCRELIMM8BY2: - case R_SH_PCRELIMM8BY4: - start = irel->r_vaddr - sec->vma; - insn = bfd_get_16 (abfd, contents + nraddr); - break; - } - - switch (irel->r_type) - { - default: - start = stop = addr; - break; - - case R_SH_IMM32: - /* If this reloc is against a symbol defined in this - section, and the symbol will not be adjusted below, we - must check the addend to see it will put the value in - range to be adjusted, and hence must be changed. */ - bfd_coff_swap_sym_in (abfd, - ((bfd_byte *) obj_coff_external_syms (abfd) - + (irel->r_symndx - * bfd_coff_symesz (abfd))), - &sym); - if (sym.n_sclass != C_EXT - && sym.n_scnum == sec->target_index - && ((bfd_vma) sym.n_value <= addr - || (bfd_vma) sym.n_value >= toaddr)) - { - bfd_vma val; - - val = bfd_get_32 (abfd, contents + nraddr); - val += sym.n_value; - if (val >= addr && val < toaddr) - bfd_put_32 (abfd, val - count, contents + nraddr); - } - start = stop = addr; - break; - - case R_SH_PCDISP8BY2: - off = insn & 0xff; - if (off & 0x80) - off -= 0x100; - stop = (bfd_vma) ((bfd_signed_vma) start + 4 + off * 2); - break; - - case R_SH_PCDISP: - bfd_coff_swap_sym_in (abfd, - ((bfd_byte *) obj_coff_external_syms (abfd) - + (irel->r_symndx - * bfd_coff_symesz (abfd))), - &sym); - if (sym.n_sclass == C_EXT) - start = stop = addr; - else - { - off = insn & 0xfff; - if (off & 0x800) - off -= 0x1000; - stop = (bfd_vma) ((bfd_signed_vma) start + 4 + off * 2); - } - break; - - case R_SH_PCRELIMM8BY2: - off = insn & 0xff; - stop = start + 4 + off * 2; - break; - - case R_SH_PCRELIMM8BY4: - off = insn & 0xff; - stop = (start &~ (bfd_vma) 3) + 4 + off * 4; - break; - - case R_SH_SWITCH16: - case R_SH_SWITCH32: - /* These relocs types represent - .word L2-L1 - The r_offset field holds the difference between the reloc - address and L1. That is the start of the reloc, and - adding in the contents gives us the top. We must adjust - both the r_offset field and the section contents. */ - - start = irel->r_vaddr - sec->vma; - stop = (bfd_vma) ((bfd_signed_vma) start - (long) irel->r_offset); - - if (start > addr - && start < toaddr - && (stop <= addr || stop >= toaddr)) - irel->r_offset += count; - else if (stop > addr - && stop < toaddr - && (start <= addr || start >= toaddr)) - irel->r_offset -= count; - - start = stop; - - if (irel->r_type == R_SH_SWITCH16) - voff = bfd_get_signed_16 (abfd, contents + nraddr); - else - voff = bfd_get_signed_32 (abfd, contents + nraddr); - stop = (bfd_vma) ((bfd_signed_vma) start + voff); - - break; - - case R_SH_USES: - start = irel->r_vaddr - sec->vma; - stop = (bfd_vma) ((bfd_signed_vma) start - + (long) irel->r_offset - + 4); - break; - } - - if (start > addr - && start < toaddr - && (stop <= addr || stop >= toaddr)) - adjust = count; - else if (stop > addr - && stop < toaddr - && (start <= addr || start >= toaddr)) - adjust = - count; - else - adjust = 0; - - if (adjust != 0) - { - oinsn = insn; - overflow = false; - switch (irel->r_type) - { - default: - abort (); - break; - - case R_SH_PCDISP8BY2: - case R_SH_PCRELIMM8BY2: - insn += adjust / 2; - if ((oinsn & 0xff00) != (insn & 0xff00)) - overflow = true; - bfd_put_16 (abfd, insn, contents + nraddr); - break; - - case R_SH_PCDISP: - insn += adjust / 2; - if ((oinsn & 0xf000) != (insn & 0xf000)) - overflow = true; - bfd_put_16 (abfd, insn, contents + nraddr); - break; - - case R_SH_PCRELIMM8BY4: - BFD_ASSERT (adjust == count || count >= 4); - if (count >= 4) - insn += adjust / 4; - else - { - if ((irel->r_vaddr & 3) == 0) - ++insn; - } - if ((oinsn & 0xff00) != (insn & 0xff00)) - overflow = true; - bfd_put_16 (abfd, insn, contents + nraddr); - break; - - case R_SH_SWITCH16: - voff += adjust; - if (voff < - 0x8000 || voff >= 0x8000) - overflow = true; - bfd_put_signed_16 (abfd, voff, contents + nraddr); - break; - - case R_SH_SWITCH32: - voff += adjust; - bfd_put_signed_32 (abfd, voff, contents + nraddr); - break; - - case R_SH_USES: - irel->r_offset += adjust; - break; - } - - if (overflow) - { - ((*_bfd_error_handler) - ("%s: 0x%lx: fatal: reloc overflow while relaxing", - bfd_get_filename (abfd), (unsigned long) irel->r_vaddr)); - bfd_set_error (bfd_error_bad_value); - return false; - } - } - - irel->r_vaddr = nraddr + sec->vma; - } - - /* Look through all the other sections. If there contain any IMM32 - relocs against internal symbols which we are not going to adjust - below, we may need to adjust the addends. */ - for (o = abfd->sections; o != NULL; o = o->next) - { - struct internal_reloc *internal_relocs; - struct internal_reloc *irelscan, *irelscanend; - bfd_byte *ocontents; - - if (o == sec - || (o->flags & SEC_RELOC) == 0 - || o->reloc_count == 0) - continue; - - /* We always cache the relocs. Perhaps, if info->keep_memory is - false, we should free them, if we are permitted to, when we - leave sh_coff_relax_section. */ - internal_relocs = (_bfd_coff_read_internal_relocs - (abfd, o, true, (bfd_byte *) NULL, false, - (struct internal_reloc *) NULL)); - if (internal_relocs == NULL) - return false; - - ocontents = NULL; - irelscanend = internal_relocs + o->reloc_count; - for (irelscan = internal_relocs; irelscan < irelscanend; irelscan++) - { - struct internal_syment sym; - - if (irelscan->r_type != R_SH_IMM32) - continue; - - bfd_coff_swap_sym_in (abfd, - ((bfd_byte *) obj_coff_external_syms (abfd) - + (irelscan->r_symndx - * bfd_coff_symesz (abfd))), - &sym); - if (sym.n_sclass != C_EXT - && sym.n_scnum == sec->target_index - && ((bfd_vma) sym.n_value <= addr - || (bfd_vma) sym.n_value >= toaddr)) - { - bfd_vma val; - - if (ocontents == NULL) - { - if (coff_section_data (abfd, o)->contents != NULL) - ocontents = coff_section_data (abfd, o)->contents; - else - { - /* We always cache the section contents. - Perhaps, if info->keep_memory is false, we - should free them, if we are permitted to, - when we leave sh_coff_relax_section. */ - ocontents = (bfd_byte *) bfd_malloc (o->_raw_size); - if (ocontents == NULL) - return false; - if (! bfd_get_section_contents (abfd, o, ocontents, - (file_ptr) 0, - o->_raw_size)) - return false; - coff_section_data (abfd, o)->contents = ocontents; - } - } - - val = bfd_get_32 (abfd, ocontents + irelscan->r_vaddr - o->vma); - val += sym.n_value; - if (val >= addr && val < toaddr) - bfd_put_32 (abfd, val - count, - ocontents + irelscan->r_vaddr - o->vma); - - coff_section_data (abfd, o)->keep_contents = true; - } - } - } - - /* Adjusting the internal symbols will not work if something has - already retrieved the generic symbols. It would be possible to - make this work by adjusting the generic symbols at the same time. - However, this case should not arise in normal usage. */ - if (obj_symbols (abfd) != NULL - || obj_raw_syments (abfd) != NULL) - { - ((*_bfd_error_handler) - ("%s: fatal: generic symbols retrieved before relaxing", - bfd_get_filename (abfd))); - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - /* Adjust all the symbols. */ - sym_hash = obj_coff_sym_hashes (abfd); - symesz = bfd_coff_symesz (abfd); - esym = (bfd_byte *) obj_coff_external_syms (abfd); - esymend = esym + obj_raw_syment_count (abfd) * symesz; - while (esym < esymend) - { - struct internal_syment isym; - - bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &isym); - - if (isym.n_scnum == sec->target_index - && (bfd_vma) isym.n_value > addr - && (bfd_vma) isym.n_value < toaddr) - { - isym.n_value -= count; - - bfd_coff_swap_sym_out (abfd, (PTR) &isym, (PTR) esym); - - if (*sym_hash != NULL) - { - BFD_ASSERT ((*sym_hash)->root.type == bfd_link_hash_defined - || (*sym_hash)->root.type == bfd_link_hash_defweak); - BFD_ASSERT ((*sym_hash)->root.u.def.value >= addr - && (*sym_hash)->root.u.def.value < toaddr); - (*sym_hash)->root.u.def.value -= count; - } - } - - esym += (isym.n_numaux + 1) * symesz; - sym_hash += isym.n_numaux + 1; - } - - /* See if we can move the ALIGN reloc forward. We have adjusted - r_vaddr for it already. */ - if (irelalign != NULL) - { - bfd_vma alignaddr; - - alignaddr = BFD_ALIGN (irelalign->r_vaddr - sec->vma, - 1 << irelalign->r_offset); - if (alignaddr != toaddr) - { - /* Tail recursion. */ - return sh_relax_delete_bytes (abfd, sec, - irelalign->r_vaddr - sec->vma, - 1 << irelalign->r_offset); - } - } - - return true; -} - -/* This is a modification of _bfd_coff_generic_relocate_section, which - will handle SH relaxing. */ - -static boolean -sh_relocate_section (output_bfd, info, input_bfd, input_section, contents, - relocs, syms, sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - struct internal_reloc *relocs; - struct internal_syment *syms; - asection **sections; -{ - struct internal_reloc *rel; - struct internal_reloc *relend; - - rel = relocs; - relend = rel + input_section->reloc_count; - for (; rel < relend; rel++) - { - long symndx; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma addend; - bfd_vma val; - reloc_howto_type *howto; - bfd_reloc_status_type rstat; - - /* Almost all relocs have to do with relaxing. If any work must - be done for them, it has been done in sh_relax_section. */ - if (rel->r_type != R_SH_IMM32 - && rel->r_type != R_SH_PCDISP) - continue; - - symndx = rel->r_symndx; - - if (symndx == -1) - { - h = NULL; - sym = NULL; - } - else - { - h = obj_coff_sym_hashes (input_bfd)[symndx]; - sym = syms + symndx; - } - - if (sym != NULL && sym->n_scnum != 0) - addend = - sym->n_value; - else - addend = 0; - - if (rel->r_type == R_SH_PCDISP) - addend -= 4; - - if (rel->r_type >= SH_COFF_HOWTO_COUNT) - howto = NULL; - else - howto = &sh_coff_howtos[rel->r_type]; - - if (howto == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - val = 0; - - if (h == NULL) - { - asection *sec; - - /* There is nothing to do for an internal PCDISP reloc. */ - if (rel->r_type == R_SH_PCDISP) - continue; - - if (symndx == -1) - { - sec = bfd_abs_section_ptr; - val = 0; - } - else - { - sec = sections[symndx]; - val = (sec->output_section->vma - + sec->output_offset - + sym->n_value - - sec->vma); - } - } - else - { - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - asection *sec; - - sec = h->root.u.def.section; - val = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (! info->relocateable) - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return false; - } - } - - rstat = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, - rel->r_vaddr - input_section->vma, - val, addend); - - switch (rstat) - { - default: - abort (); - case bfd_reloc_ok: - break; - case bfd_reloc_overflow: - { - const char *name; - char buf[SYMNMLEN + 1]; - - if (symndx == -1) - name = "*ABS*"; - else if (h != NULL) - name = h->root.root.string; - else if (sym->_n._n_n._n_zeroes == 0 - && sym->_n._n_n._n_offset != 0) - name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset; - else - { - strncpy (buf, sym->_n._n_name, SYMNMLEN); - buf[SYMNMLEN] = '\0'; - name = buf; - } - - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, input_bfd, - input_section, rel->r_vaddr - input_section->vma))) - return false; - } - } - } - - return true; -} - -/* This is a version of bfd_generic_get_relocated_section_contents - which uses sh_relocate_section. */ - -static bfd_byte * -sh_coff_get_relocated_section_contents (output_bfd, link_info, link_order, - data, relocateable, symbols) - bfd *output_bfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - bfd_byte *data; - boolean relocateable; - asymbol **symbols; -{ - asection *input_section = link_order->u.indirect.section; - bfd *input_bfd = input_section->owner; - asection **sections = NULL; - struct internal_reloc *internal_relocs = NULL; - struct internal_syment *internal_syms = NULL; - - /* We only need to handle the case of relaxing, or of having a - particular set of section contents, specially. */ - if (relocateable - || coff_section_data (input_bfd, input_section) == NULL - || coff_section_data (input_bfd, input_section)->contents == NULL) - return bfd_generic_get_relocated_section_contents (output_bfd, link_info, - link_order, data, - relocateable, - symbols); - - memcpy (data, coff_section_data (input_bfd, input_section)->contents, - input_section->_raw_size); - - if ((input_section->flags & SEC_RELOC) != 0 - && input_section->reloc_count > 0) - { - bfd_size_type symesz = bfd_coff_symesz (input_bfd); - bfd_byte *esym, *esymend; - struct internal_syment *isymp; - asection **secpp; - - if (! _bfd_coff_get_external_symbols (input_bfd)) - goto error_return; - - internal_relocs = (_bfd_coff_read_internal_relocs - (input_bfd, input_section, false, (bfd_byte *) NULL, - false, (struct internal_reloc *) NULL)); - if (internal_relocs == NULL) - goto error_return; - - internal_syms = ((struct internal_syment *) - bfd_malloc (obj_raw_syment_count (input_bfd) - * sizeof (struct internal_syment))); - if (internal_syms == NULL) - goto error_return; - - sections = (asection **) bfd_malloc (obj_raw_syment_count (input_bfd) - * sizeof (asection *)); - if (sections == NULL) - goto error_return; - - isymp = internal_syms; - secpp = sections; - esym = (bfd_byte *) obj_coff_external_syms (input_bfd); - esymend = esym + obj_raw_syment_count (input_bfd) * symesz; - while (esym < esymend) - { - bfd_coff_swap_sym_in (input_bfd, (PTR) esym, (PTR) isymp); - - if (isymp->n_scnum != 0) - *secpp = coff_section_from_bfd_index (input_bfd, isymp->n_scnum); - else - { - if (isymp->n_value == 0) - *secpp = bfd_und_section_ptr; - else - *secpp = bfd_com_section_ptr; - } - - esym += (isymp->n_numaux + 1) * symesz; - secpp += isymp->n_numaux + 1; - isymp += isymp->n_numaux + 1; - } - - if (! sh_relocate_section (output_bfd, link_info, input_bfd, - input_section, data, internal_relocs, - internal_syms, sections)) - goto error_return; - - free (sections); - sections = NULL; - free (internal_syms); - internal_syms = NULL; - free (internal_relocs); - internal_relocs = NULL; - } - - return data; - - error_return: - if (internal_relocs != NULL) - free (internal_relocs); - if (internal_syms != NULL) - free (internal_syms); - if (sections != NULL) - free (sections); - return NULL; -} - -/* The target vectors. */ - -const bfd_target shcoff_vec = -{ - "coff-sh", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), - '_', /* leading symbol underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; - -const bfd_target shlcoff_vec = -{ - "coff-shl", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little endian too*/ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), - '_', /* leading symbol underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-sparc.c b/contrib/gdb/bfd/coff-sparc.c deleted file mode 100644 index b9bc595..0000000 --- a/contrib/gdb/bfd/coff-sparc.c +++ /dev/null @@ -1,278 +0,0 @@ -/* BFD back-end for Sparc COFF files. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/sparc.h" -#include "coff/internal.h" -#include "libcoff.h" - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3) - -#define BADMAG(x) ((x).f_magic != SPARCMAGIC && (x).f_magic != LYNXCOFFMAGIC) - -/* The page size is a guess based on ELF. */ -#define COFF_PAGE_SIZE 0x10000 - -enum reloc_type - { - R_SPARC_NONE = 0, - R_SPARC_8, R_SPARC_16, R_SPARC_32, - R_SPARC_DISP8, R_SPARC_DISP16, R_SPARC_DISP32, - R_SPARC_WDISP30, R_SPARC_WDISP22, - R_SPARC_HI22, R_SPARC_22, - R_SPARC_13, R_SPARC_LO10, - R_SPARC_GOT10, R_SPARC_GOT13, R_SPARC_GOT22, - R_SPARC_PC10, R_SPARC_PC22, - R_SPARC_WPLT30, - R_SPARC_COPY, - R_SPARC_GLOB_DAT, R_SPARC_JMP_SLOT, - R_SPARC_RELATIVE, - R_SPARC_UA32, - R_SPARC_max - }; - -#if 0 -static CONST char *CONST reloc_type_names[] = -{ - "R_SPARC_NONE", - "R_SPARC_8", "R_SPARC_16", "R_SPARC_32", - "R_SPARC_DISP8", "R_SPARC_DISP16", "R_SPARC_DISP32", - "R_SPARC_WDISP30", "R_SPARC_WDISP22", - "R_SPARC_HI22", "R_SPARC_22", - "R_SPARC_13", "R_SPARC_LO10", - "R_SPARC_GOT10", "R_SPARC_GOT13", "R_SPARC_GOT22", - "R_SPARC_PC10", "R_SPARC_PC22", - "R_SPARC_WPLT30", - "R_SPARC_COPY", - "R_SPARC_GLOB_DAT", "R_SPARC_JMP_SLOT", - "R_SPARC_RELATIVE", - "R_SPARC_UA32", -}; -#endif - -/* This is stolen pretty directly from elf.c. */ -static bfd_reloc_status_type -bfd_coff_generic_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, - asection *, bfd *, char **)); - -static bfd_reloc_status_type -bfd_coff_generic_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - return bfd_reloc_continue; -} - -static reloc_howto_type coff_sparc_howto_table[] = -{ - HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_NONE", false,0,0x00000000,true), - HOWTO(R_SPARC_8, 0,0, 8,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_8", false,0,0x000000ff,true), - HOWTO(R_SPARC_16, 0,1,16,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_16", false,0,0x0000ffff,true), - HOWTO(R_SPARC_32, 0,2,32,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_32", false,0,0xffffffff,true), - HOWTO(R_SPARC_DISP8, 0,0, 8,true, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_DISP8", false,0,0x000000ff,true), - HOWTO(R_SPARC_DISP16, 0,1,16,true, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_DISP16", false,0,0x0000ffff,true), - HOWTO(R_SPARC_DISP32, 0,2,32,true, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_DISP32", false,0,0x00ffffff,true), - HOWTO(R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_WDISP30", false,0,0x3fffffff,true), - HOWTO(R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed, bfd_coff_generic_reloc,"R_SPARC_WDISP22", false,0,0x003fffff,true), - HOWTO(R_SPARC_HI22, 10,2,22,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_HI22", false,0,0x003fffff,true), - HOWTO(R_SPARC_22, 0,2,22,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_22", false,0,0x003fffff,true), - HOWTO(R_SPARC_13, 0,2,13,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_13", false,0,0x00001fff,true), - HOWTO(R_SPARC_LO10, 0,2,10,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_LO10", false,0,0x000003ff,true), - HOWTO(R_SPARC_GOT10, 0,2,10,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_GOT10", false,0,0x000003ff,true), - HOWTO(R_SPARC_GOT13, 0,2,13,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_GOT13", false,0,0x00001fff,true), - HOWTO(R_SPARC_GOT22, 10,2,22,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_GOT22", false,0,0x003fffff,true), - HOWTO(R_SPARC_PC10, 0,2,10,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_PC10", false,0,0x000003ff,true), - HOWTO(R_SPARC_PC22, 0,2,22,false,0,complain_overflow_bitfield,bfd_coff_generic_reloc,"R_SPARC_PC22", false,0,0x003fffff,true), - HOWTO(R_SPARC_WPLT30, 0,0,00,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_WPLT30", false,0,0x00000000,true), - HOWTO(R_SPARC_COPY, 0,0,00,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_COPY", false,0,0x00000000,true), - HOWTO(R_SPARC_GLOB_DAT,0,0,00,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_GLOB_DAT",false,0,0x00000000,true), - HOWTO(R_SPARC_JMP_SLOT,0,0,00,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_JMP_SLOT",false,0,0x00000000,true), - HOWTO(R_SPARC_RELATIVE,0,0,00,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_RELATIVE",false,0,0x00000000,true), - HOWTO(R_SPARC_UA32, 0,0,00,false,0,complain_overflow_dont, bfd_coff_generic_reloc,"R_SPARC_UA32", false,0,0x00000000,true), -}; - -struct coff_reloc_map { - unsigned char bfd_reloc_val; - unsigned char coff_reloc_val; -}; - -static CONST struct coff_reloc_map sparc_reloc_map[] = -{ - { BFD_RELOC_NONE, R_SPARC_NONE, }, - { BFD_RELOC_16, R_SPARC_16, }, - { BFD_RELOC_8, R_SPARC_8 }, - { BFD_RELOC_8_PCREL, R_SPARC_DISP8 }, - { BFD_RELOC_CTOR, R_SPARC_32 }, /* @@ Assumes 32 bits. */ - { BFD_RELOC_32, R_SPARC_32 }, - { BFD_RELOC_32_PCREL, R_SPARC_DISP32 }, - { BFD_RELOC_HI22, R_SPARC_HI22 }, - { BFD_RELOC_LO10, R_SPARC_LO10, }, - { BFD_RELOC_32_PCREL_S2, R_SPARC_WDISP30 }, - { BFD_RELOC_SPARC22, R_SPARC_22 }, - { BFD_RELOC_SPARC13, R_SPARC_13 }, - { BFD_RELOC_SPARC_GOT10, R_SPARC_GOT10 }, - { BFD_RELOC_SPARC_GOT13, R_SPARC_GOT13 }, - { BFD_RELOC_SPARC_GOT22, R_SPARC_GOT22 }, - { BFD_RELOC_SPARC_PC10, R_SPARC_PC10 }, - { BFD_RELOC_SPARC_PC22, R_SPARC_PC22 }, - { BFD_RELOC_SPARC_WPLT30, R_SPARC_WPLT30 }, - { BFD_RELOC_SPARC_COPY, R_SPARC_COPY }, - { BFD_RELOC_SPARC_GLOB_DAT, R_SPARC_GLOB_DAT }, - { BFD_RELOC_SPARC_JMP_SLOT, R_SPARC_JMP_SLOT }, - { BFD_RELOC_SPARC_RELATIVE, R_SPARC_RELATIVE }, - { BFD_RELOC_SPARC_WDISP22, R_SPARC_WDISP22 }, - /* { BFD_RELOC_SPARC_UA32, R_SPARC_UA32 }, not used?? */ -}; - -static reloc_howto_type * -coff_sparc_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - unsigned int i; - for (i = 0; i < sizeof (sparc_reloc_map) / sizeof (struct coff_reloc_map); i++) - { - if (sparc_reloc_map[i].bfd_reloc_val == code) - return &coff_sparc_howto_table[(int) sparc_reloc_map[i].coff_reloc_val]; - } - return 0; -} -#define coff_bfd_reloc_type_lookup coff_sparc_reloc_type_lookup - -static void -rtype2howto (cache_ptr, dst) - arelent *cache_ptr; - struct internal_reloc *dst; -{ - BFD_ASSERT (dst->r_type < (unsigned int) R_SPARC_max); - cache_ptr->howto = &coff_sparc_howto_table[dst->r_type]; -} - -#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry) - -#define SWAP_IN_RELOC_OFFSET bfd_h_get_32 -#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32 -/* This is just like the standard one, except that we don't set up an - addend for relocs against global symbols (otherwise linking objects - created by -r fails), and we add in the reloc offset at the end. */ -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ - { \ - coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ - if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ - coffsym = (obj_symbols (abfd) \ - + (cache_ptr->sym_ptr_ptr - symbols)); \ - else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ - if (coffsym != (coff_symbol_type *) NULL \ - && coffsym->native->u.syment.n_scnum == 0) \ - cache_ptr->addend = 0; \ - else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ - && ptr->section != (asection *) NULL \ - && (ptr->flags & BSF_GLOBAL) == 0) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ - else \ - cache_ptr->addend = 0; \ - cache_ptr->addend += reloc.r_offset; \ - } - -/* Clear the r_spare field in relocs. */ -#define SWAP_OUT_RELOC_EXTRA(abfd,src,dst) \ - do { \ - dst->r_spare[0] = 0; \ - dst->r_spare[1] = 0; \ - } while (0) - -#define __A_MAGIC_SET__ - -/* Enable Sparc-specific hacks in coffcode.h. */ - -#define COFF_SPARC - -#include "coffcode.h" - -const bfd_target -#ifdef TARGET_SYM - TARGET_SYM = -#else - sparccoff_vec = -#endif -{ -#ifdef TARGET_NAME - TARGET_NAME, -#else - "coff-sparc", /* name */ -#endif - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* leading underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - -/* Note that we allow an object file to be treated as a core file as well. */ - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, coff_object_p}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-u68k.c b/contrib/gdb/bfd/coff-u68k.c deleted file mode 100644 index 97ea73f..0000000 --- a/contrib/gdb/bfd/coff-u68k.c +++ /dev/null @@ -1,35 +0,0 @@ -/* BFD back-end for Motorola 68000 COFF binaries having underscore with name. - Copyright 1990, 1991, 1992 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - -#define TARGET_SYM m68kcoffun_vec -#define TARGET_NAME "coff-m68k-un" - -#define NAMES_HAVE_UNDERSCORE - -/* define this to not have multiple copy of m68k_rtype2howto - in the executable file */ -#define ONLY_DECLARE_RELOCS - -/* This magic number indicates that the names have underscores. - Other 68k magic numbers indicate that the names do not have - underscores. */ -#define BADMAG(x) ((x).f_magic != MC68KBCSMAGIC) - -#include "coff-m68k.c" diff --git a/contrib/gdb/bfd/coff-w65.c b/contrib/gdb/bfd/coff-w65.c deleted file mode 100644 index a02243f..0000000 --- a/contrib/gdb/bfd/coff-w65.c +++ /dev/null @@ -1,446 +0,0 @@ -/* BFD back-end for WDC 65816 COFF binaries. - Copyright 1995 Free Software Foundation, Inc. - Written by Steve Chamberlain, <sac@cygnus.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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "obstack.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "coff/w65.h" -#include "coff/internal.h" -#include "libcoff.h" - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1) -static reloc_howto_type howto_table[] = -{ - HOWTO (R_W65_ABS8, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "abs8", true, 0x000000ff, 0x000000ff, false), - HOWTO (R_W65_ABS16, 1, 0, 16, false, 0, complain_overflow_bitfield, 0, "abs16", true, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_W65_ABS24, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "abs24", true, 0x00ffffff, 0x00ffffff, false), - HOWTO (R_W65_ABS8S8, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, ">abs8", true, 0x000000ff, 0x000000ff, false), - HOWTO (R_W65_ABS8S16, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "^abs8", true, 0x000000ff, 0x000000ff, false), - HOWTO (R_W65_ABS16S8, 1, 0, 16, false, 0, complain_overflow_bitfield, 0, ">abs16", true, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_W65_ABS16S16,1, 0, 16, false, 0, complain_overflow_bitfield, 0, "^abs16", true, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_W65_PCR8, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "pcrel8", true, 0x000000ff, 0x000000ff, true), - HOWTO (R_W65_PCR16, 1, 0, 16, false, 0, complain_overflow_bitfield, 0, "pcrel16", true, 0x0000ffff, 0x0000ffff, true), - HOWTO (R_W65_DP, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "dp", true, 0x000000ff, 0x000000ff, false), - -}; - - -/* Turn a howto into a reloc number */ - -#define SELECT_RELOC(x,howto) \ - { x.r_type = select_reloc(howto); } - -#define BADMAG(x) (W65BADMAG(x)) -#define W65 1 /* Customize coffcode.h */ -#define __A_MAGIC_SET__ - - -/* Code to swap in the reloc */ -#define SWAP_IN_RELOC_OFFSET bfd_h_get_32 -#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32 -#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \ - dst->r_stuff[0] = 'S'; \ - dst->r_stuff[1] = 'C'; - - -static int -select_reloc (howto) - reloc_howto_type *howto; -{ - return howto->type ; -} - -/* Code to turn a r_type into a howto ptr, uses the above howto table - */ - -static void -rtype2howto (internal, dst) - arelent *internal; - struct internal_reloc *dst; -{ - internal->howto = howto_table + dst->r_type - 1; -} - -#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry) - - -/* Perform any necessaru magic to the addend in a reloc entry */ - - -#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \ - cache_ptr->addend = ext_reloc.r_offset; - - -#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \ - reloc_processing(relent, reloc, symbols, abfd, section) - -static void -reloc_processing (relent, reloc, symbols, abfd, section) - arelent * relent; - struct internal_reloc *reloc; - asymbol ** symbols; - bfd * abfd; - asection * section; -{ - relent->address = reloc->r_vaddr; - rtype2howto (relent, reloc); - - if (((int) reloc->r_symndx) > 0) - { - relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; - } - else - { - relent->sym_ptr_ptr = (asymbol **)&(bfd_abs_symbol); - } - - - - relent->addend = reloc->r_offset; - - relent->address -= section->vma; - /* relent->section = 0;*/ -} - - -static int -h8300_reloc16_estimate(abfd, input_section, reloc, shrink, link_info) - bfd *abfd; - asection *input_section; - arelent *reloc; - unsigned int shrink; - struct bfd_link_info *link_info; -{ - bfd_vma value; - bfd_vma dot; - bfd_vma gap; - - /* The address of the thing to be relocated will have moved back by - the size of the shrink - but we don't change reloc->address here, - since we need it to know where the relocation lives in the source - uncooked section */ - - /* reloc->address -= shrink; conceptual */ - - bfd_vma address = reloc->address - shrink; - - - switch (reloc->howto->type) - { - case R_MOVB2: - case R_JMP2: - shrink+=2; - break; - - /* Thing is a move one byte */ - case R_MOVB1: - value = bfd_coff_reloc16_get_value(reloc, link_info, input_section); - - if (value >= 0xff00) - { - - /* Change the reloc type from 16bit, possible 8 to 8bit - possible 16 */ - reloc->howto = reloc->howto + 1; - /* The place to relc moves back by one */ - /* This will be two bytes smaller in the long run */ - shrink +=2 ; - bfd_perform_slip(abfd, 2, input_section, address); - } - - break; - /* This is the 24 bit branch which could become an 8 bitter, - the relocation points to the first byte of the insn, not the - actual data */ - - case R_JMPL1: - value = bfd_coff_reloc16_get_value(reloc, link_info, input_section); - - dot = input_section->output_section->vma + - input_section->output_offset + address; - - /* See if the address we're looking at within 127 bytes of where - we are, if so then we can use a small branch rather than the - jump we were going to */ - - gap = value - dot ; - - if (-120 < (long)gap && (long)gap < 120 ) - { - - /* Change the reloc type from 24bit, possible 8 to 8bit - possible 32 */ - reloc->howto = reloc->howto + 1; - /* This will be two bytes smaller in the long run */ - shrink +=2 ; - bfd_perform_slip(abfd, 2, input_section, address); - } - break; - - case R_JMP1: - - value = bfd_coff_reloc16_get_value(reloc, link_info, input_section); - - dot = input_section->output_section->vma + - input_section->output_offset + address; - - /* See if the address we're looking at within 127 bytes of where - we are, if so then we can use a small branch rather than the - jump we were going to */ - - gap = value - (dot - shrink); - - - if (-120 < (long)gap && (long)gap < 120 ) - { - - /* Change the reloc type from 16bit, possible 8 to 8bit - possible 16 */ - reloc->howto = reloc->howto + 1; - /* The place to relc moves back by one */ - - /* This will be two bytes smaller in the long run */ - shrink +=2 ; - bfd_perform_slip(abfd, 2, input_section, address); - } - break; - } - - - return shrink; -} - - -/* First phase of a relaxing link */ - -/* Reloc types - large small - R_MOVB1 R_MOVB2 mov.b with 16bit or 8 bit address - R_JMP1 R_JMP2 jmp or pcrel branch - R_JMPL1 R_JMPL_B8 24jmp or pcrel branch - R_MOVLB1 R_MOVLB2 24 or 8 bit reloc for mov.b - -*/ - -static void -h8300_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr, - dst_ptr) - bfd *abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - arelent *reloc; - bfd_byte *data; - unsigned int *src_ptr; - unsigned int *dst_ptr; -{ - unsigned int src_address = *src_ptr; - unsigned int dst_address = *dst_ptr; - asection *input_section = link_order->u.indirect.section; - - switch (reloc->howto->type) - { - case R_W65_ABS8: - case R_W65_DP: - { - unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - bfd_put_8 (abfd, gap, data + dst_address); - dst_address += 1; - src_address += 1; - } - break; - - case R_W65_ABS8S8: - { - unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - gap >>= 8; - bfd_put_8 (abfd, gap, data + dst_address); - dst_address += 1; - src_address += 1; - } - break; - - case R_W65_ABS8S16: - { - unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - gap >>=16; - bfd_put_8 (abfd, gap, data + dst_address); - dst_address += 1; - src_address += 1; - } - break; - - case R_W65_ABS16: - { - unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - - bfd_put_16 (abfd, gap, data + dst_address); - dst_address += 2; - src_address += 2; - } - break; - case R_W65_ABS16S8: - { - unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - gap >>= 8; - bfd_put_16 (abfd, gap, data + dst_address); - dst_address += 2; - src_address += 2; - } - break; - case R_W65_ABS16S16: - { - unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - gap >>= 16; - bfd_put_16 (abfd, gap, data + dst_address); - dst_address += 2; - src_address += 2; - } - break; - - case R_W65_ABS24: - { - unsigned int gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - bfd_put_16 (abfd, gap, data + dst_address); - bfd_put_8 (abfd, gap>>16, data+dst_address+2); - dst_address += 3; - src_address += 3; - } - break; - - case R_W65_PCR8: - { - int gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - bfd_vma dot = link_order->offset - + dst_address - + link_order->u.indirect.section->output_section->vma; - - gap -= dot + 1; - if (gap < -128 || gap > 127) { - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), - reloc->howto->name, reloc->addend, input_section->owner, - input_section, reloc->address))) - abort(); - } - bfd_put_8 (abfd, gap, data + dst_address); - dst_address += 1; - src_address += 1; - } - break; - - case R_W65_PCR16: - { - bfd_vma gap = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - bfd_vma dot = link_order->offset - + dst_address - + link_order->u.indirect.section->output_section->vma; - - - /* This wraps within the page, so ignore the relativeness, look at the - high part */ - if ((gap & 0xf0000) != (dot & 0xf0000)) { - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), - reloc->howto->name, reloc->addend, input_section->owner, - input_section, reloc->address))) - abort(); - } - - gap -= dot + 2; - bfd_put_16 (abfd, gap, data + dst_address); - dst_address += 2; - src_address += 2; - } - break; - default: - printf("ignoring reloc %s\n", reloc->howto->name); - break; - - } - *src_ptr = src_address; - *dst_ptr = dst_address; - -} - -#define coff_reloc16_extra_cases h8300_reloc16_extra_cases -#define coff_reloc16_estimate h8300_reloc16_estimate - -#include "coffcode.h" - - -#undef coff_bfd_get_relocated_section_contents -#undef coff_bfd_relax_section -#define coff_bfd_get_relocated_section_contents \ - bfd_coff_reloc16_get_relocated_section_contents -#define coff_bfd_relax_section bfd_coff_reloc16_relax_section - - - -bfd_target w65_vec = -{ - "coff-w65", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* header byte order is little */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* leading char */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-we32k.c b/contrib/gdb/bfd/coff-we32k.c deleted file mode 100644 index 36f1fa1..0000000 --- a/contrib/gdb/bfd/coff-we32k.c +++ /dev/null @@ -1,110 +0,0 @@ -/* BFD back-end for we32k COFF files. - Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. - Contributed by Brendan Kehoe (brendan@cs.widener.edu). - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/we32k.h" -#include "coff/internal.h" -#include "libcoff.h" - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3) - -static reloc_howto_type howto_table[] = -{ - {0}, - {1}, - {2}, - {3}, - {4}, - {5}, - HOWTO(R_DIR32, 0, 2, 32, false, 0,complain_overflow_bitfield, 0, "dir32", true, 0xffffffff,0xffffffff, false), - {7}, - {010}, - {011}, - {012}, - {013}, - {014}, - {015}, - {016}, - HOWTO(R_RELBYTE, 0, 0, 8, false, 0, complain_overflow_bitfield, 0, "8", true, 0x000000ff,0x000000ff, false), - HOWTO(R_RELWORD, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "16", true, 0x0000ffff,0x0000ffff, false), - HOWTO(R_RELLONG, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "32", true, 0xffffffff,0xffffffff, false), - HOWTO(R_PCRBYTE, 0, 0, 8, true, 0, complain_overflow_signed, 0, "DISP8", true, 0x000000ff,0x000000ff, false), - HOWTO(R_PCRWORD, 0, 1, 16, true, 0, complain_overflow_signed, 0, "DISP16", true, 0x0000ffff,0x0000ffff, false), - HOWTO(R_PCRLONG, 0, 2, 32, true, 0, complain_overflow_signed, 0, "DISP32", true, 0xffffffff,0xffffffff, false), -}; - -/* Turn a howto into a reloc nunmber */ - -#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } -#define BADMAG(x) WE32KBADMAG(x) -#define WE32K 1 - -#define RTYPE2HOWTO(cache_ptr, dst) \ - (cache_ptr)->howto = howto_table + (dst)->r_type; - -#include "coffcode.h" - -#define coff_write_armap bsd_write_armap - -const bfd_target we32kcoff_vec = -{ - "coff-we32k", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/coff-z8k.c b/contrib/gdb/bfd/coff-z8k.c deleted file mode 100644 index 5609d35..0000000 --- a/contrib/gdb/bfd/coff-z8k.c +++ /dev/null @@ -1,281 +0,0 @@ -/* BFD back-end for Zilog Z800n COFF binaries. - Copyright 1992, 1993, 1994 Free Software Foundation, Inc. - Contributed by Cygnus Support. - Written by Steve Chamberlain, <sac@cygnus.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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "obstack.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "coff/z8k.h" -#include "coff/internal.h" -#include "libcoff.h" - -#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (1) - -static reloc_howto_type r_imm32 = -HOWTO (R_IMM32, 0, 1, 32, false, 0, - complain_overflow_bitfield, 0, "r_imm32", true, 0xffffffff, - 0xffffffff, false); - -static reloc_howto_type r_imm4l = -HOWTO (R_IMM4L, 0, 1, 4, false, 0, - complain_overflow_bitfield, 0, "r_imm4l", true, 0xf, 0xf, false); - -static reloc_howto_type r_da = -HOWTO (R_IMM16, 0, 1, 16, false, 0, - complain_overflow_bitfield, 0, "r_da", true, 0x0000ffff, 0x0000ffff, - false); - -static reloc_howto_type r_imm8 = -HOWTO (R_IMM8, 0, 1, 8, false, 0, - complain_overflow_bitfield, 0, "r_imm8", true, 0x000000ff, 0x000000ff, - false); - -static reloc_howto_type r_jr = -HOWTO (R_JR, 0, 1, 8, true, 0, complain_overflow_signed, 0, - "r_jr", true, 0, 0, true); - -/* Turn a howto into a reloc number */ - -static int -coff_z8k_select_reloc (howto) - reloc_howto_type *howto; -{ - return howto->type; -} - -#define SELECT_RELOC(x,howto) x.r_type = coff_z8k_select_reloc(howto) - - -#define BADMAG(x) Z8KBADMAG(x) -#define Z8K 1 /* Customize coffcode.h */ -#define __A_MAGIC_SET__ - - - -/* Code to swap in the reloc */ -#define SWAP_IN_RELOC_OFFSET bfd_h_get_32 -#define SWAP_OUT_RELOC_OFFSET bfd_h_put_32 -#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \ - dst->r_stuff[0] = 'S'; \ - dst->r_stuff[1] = 'C'; - -/* Code to turn a r_type into a howto ptr, uses the above howto table - */ - -static void -rtype2howto (internal, dst) - arelent * internal; - struct internal_reloc *dst; -{ - switch (dst->r_type) - { - default: - abort (); - break; - case R_IMM8: - internal->howto = &r_imm8; - break; - case R_IMM16: - internal->howto = &r_da; - break; - case R_JR: - internal->howto = &r_jr; - break; - case R_IMM32: - internal->howto = &r_imm32; - break; - case R_IMM4L: - internal->howto = &r_imm4l; - break; - } -} - -#define RTYPE2HOWTO(internal, relocentry) rtype2howto(internal,relocentry) - - -/* Perform any necessaru magic to the addend in a reloc entry */ - - -#define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \ - cache_ptr->addend = ext_reloc.r_offset; - - -#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \ - reloc_processing(relent, reloc, symbols, abfd, section) - -static void -reloc_processing (relent, reloc, symbols, abfd, section) - arelent * relent; - struct internal_reloc *reloc; - asymbol ** symbols; - bfd * abfd; - asection * section; -{ - relent->address = reloc->r_vaddr; - rtype2howto (relent, reloc); - - if (reloc->r_symndx > 0) - { - relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx]; - } - else - { - relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - } - - - relent->addend = reloc->r_offset; - relent->address -= section->vma; -} - -static void -extra_case (in_abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr) - bfd *in_abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - arelent *reloc; - bfd_byte *data; - unsigned int *src_ptr; - unsigned int *dst_ptr; -{ - asection *input_section = link_order->u.indirect.section; - - switch (reloc->howto->type) - { - case R_IMM8: - bfd_put_8 (in_abfd, - bfd_coff_reloc16_get_value (reloc, link_info, input_section), - data + *dst_ptr); - (*dst_ptr) += 1; - (*src_ptr) += 1; - break; - - case R_IMM32: - bfd_put_32 (in_abfd, - bfd_coff_reloc16_get_value (reloc, link_info, input_section), - data + *dst_ptr); - (*dst_ptr) += 4; - (*src_ptr) += 4; - break; - - case R_IMM4L: - bfd_put_8 (in_abfd, - ((bfd_get_8 (in_abfd, data + *dst_ptr) & 0xf0) - | (0x0f - & bfd_coff_reloc16_get_value (reloc, link_info, - input_section))), - data + *dst_ptr); - (*dst_ptr) += 1; - (*src_ptr) += 1; - break; - - case R_IMM16: - bfd_put_16 (in_abfd, - bfd_coff_reloc16_get_value (reloc, link_info, input_section), - data + *dst_ptr); - (*dst_ptr) += 2; - (*src_ptr) += 2; - break; - - case R_JR: - { - bfd_vma dst = bfd_coff_reloc16_get_value (reloc, link_info, - input_section); - bfd_vma dot = (link_order->offset - + *dst_ptr - + input_section->output_section->vma); - int gap = dst - dot - 1;/* -1 since were in the odd byte of the - word and the pc's been incremented */ - - if (gap & 1) - abort (); - gap /= 2; - if (gap > 128 || gap < -128) - { - if (! ((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*reloc->sym_ptr_ptr), - reloc->howto->name, reloc->addend, input_section->owner, - input_section, reloc->address))) - abort (); - } - bfd_put_8 (in_abfd, gap, data + *dst_ptr); - (*dst_ptr)++; - (*src_ptr)++; - break; - } - default: - abort (); - } -} - -#define coff_reloc16_extra_cases extra_case - -#include "coffcode.h" - - -#undef coff_bfd_get_relocated_section_contents -#undef coff_bfd_relax_section -#define coff_bfd_get_relocated_section_contents \ - bfd_coff_reloc16_get_relocated_section_contents -#define coff_bfd_relax_section bfd_coff_reloc16_relax_section - -const bfd_target z8kcoff_vec = -{ - "coff-z8k", /* name */ - bfd_target_coff_flavour, - BFD_ENDIAN_BIG, /* data byte order is big */ - BFD_ENDIAN_BIG, /* header byte order is big */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* leading symbol underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/contrib/gdb/bfd/cofflink.c b/contrib/gdb/bfd/cofflink.c deleted file mode 100644 index c4a42a0..0000000 --- a/contrib/gdb/bfd/cofflink.c +++ /dev/null @@ -1,2327 +0,0 @@ -/* COFF specific linker code. - Copyright 1994, 1995, 1996 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Cygnus Support. - -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 contains the COFF backend linker code. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "coff/internal.h" -#include "libcoff.h" - -static boolean coff_link_add_object_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean coff_link_check_archive_element - PARAMS ((bfd *, struct bfd_link_info *, boolean *)); -static boolean coff_link_check_ar_symbols - PARAMS ((bfd *, struct bfd_link_info *, boolean *)); -static boolean coff_link_add_symbols PARAMS ((bfd *, struct bfd_link_info *)); - -/* Create an entry in a COFF linker hash table. */ - -struct bfd_hash_entry * -_bfd_coff_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct coff_link_hash_entry *ret = (struct coff_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct coff_link_hash_entry *) NULL) - ret = ((struct coff_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct coff_link_hash_entry))); - if (ret == (struct coff_link_hash_entry *) NULL) - return (struct bfd_hash_entry *) ret; - - /* Call the allocation method of the superclass. */ - ret = ((struct coff_link_hash_entry *) - _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, - table, string)); - if (ret != (struct coff_link_hash_entry *) NULL) - { - /* Set local fields. */ - ret->indx = -1; - ret->type = T_NULL; - ret->class = C_NULL; - ret->numaux = 0; - ret->auxbfd = NULL; - ret->aux = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Initialize a COFF linker hash table. */ - -boolean -_bfd_coff_link_hash_table_init (table, abfd, newfunc) - struct coff_link_hash_table *table; - bfd *abfd; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); -{ - return _bfd_link_hash_table_init (&table->root, abfd, newfunc); -} - -/* Create a COFF linker hash table. */ - -struct bfd_link_hash_table * -_bfd_coff_link_hash_table_create (abfd) - bfd *abfd; -{ - struct coff_link_hash_table *ret; - - ret = ((struct coff_link_hash_table *) - bfd_alloc (abfd, sizeof (struct coff_link_hash_table))); - if (ret == NULL) - return NULL; - if (! _bfd_coff_link_hash_table_init (ret, abfd, - _bfd_coff_link_hash_newfunc)) - { - bfd_release (abfd, ret); - return (struct bfd_link_hash_table *) NULL; - } - return &ret->root; -} - -/* Create an entry in a COFF debug merge hash table. */ - -struct bfd_hash_entry * -_bfd_coff_debug_merge_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct coff_debug_merge_hash_entry *ret = - (struct coff_debug_merge_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct coff_debug_merge_hash_entry *) NULL) - ret = ((struct coff_debug_merge_hash_entry *) - bfd_hash_allocate (table, - sizeof (struct coff_debug_merge_hash_entry))); - if (ret == (struct coff_debug_merge_hash_entry *) NULL) - return (struct bfd_hash_entry *) ret; - - /* Call the allocation method of the superclass. */ - ret = ((struct coff_debug_merge_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - if (ret != (struct coff_debug_merge_hash_entry *) NULL) - { - /* Set local fields. */ - ret->types = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Given a COFF BFD, add symbols to the global hash table as - appropriate. */ - -boolean -_bfd_coff_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - switch (bfd_get_format (abfd)) - { - case bfd_object: - return coff_link_add_object_symbols (abfd, info); - case bfd_archive: - return (_bfd_generic_link_add_archive_symbols - (abfd, info, coff_link_check_archive_element)); - default: - bfd_set_error (bfd_error_wrong_format); - return false; - } -} - -/* Add symbols from a COFF object file. */ - -static boolean -coff_link_add_object_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - if (! _bfd_coff_get_external_symbols (abfd)) - return false; - if (! coff_link_add_symbols (abfd, info)) - return false; - - if (! info->keep_memory) - { - if (! _bfd_coff_free_symbols (abfd)) - return false; - } - return true; -} - -/* Check a single archive element to see if we need to include it in - the link. *PNEEDED is set according to whether this element is - needed in the link or not. This is called via - _bfd_generic_link_add_archive_symbols. */ - -static boolean -coff_link_check_archive_element (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; -{ - if (! _bfd_coff_get_external_symbols (abfd)) - return false; - - if (! coff_link_check_ar_symbols (abfd, info, pneeded)) - return false; - - if (*pneeded) - { - if (! coff_link_add_symbols (abfd, info)) - return false; - } - - if (! info->keep_memory || ! *pneeded) - { - if (! _bfd_coff_free_symbols (abfd)) - return false; - } - - return true; -} - -/* Look through the symbols to see if this object file should be - included in the link. */ - -static boolean -coff_link_check_ar_symbols (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; -{ - boolean (*sym_is_global) PARAMS ((bfd *, struct internal_syment *)); - bfd_size_type symesz; - bfd_byte *esym; - bfd_byte *esym_end; - - *pneeded = false; - - sym_is_global = coff_backend_info (abfd)->_bfd_coff_sym_is_global; - - symesz = bfd_coff_symesz (abfd); - esym = (bfd_byte *) obj_coff_external_syms (abfd); - esym_end = esym + obj_raw_syment_count (abfd) * symesz; - while (esym < esym_end) - { - struct internal_syment sym; - - bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym); - - if ((sym.n_sclass == C_EXT - || (sym_is_global && (*sym_is_global) (abfd, &sym))) - && (sym.n_scnum != 0 || sym.n_value != 0)) - { - const char *name; - char buf[SYMNMLEN + 1]; - struct bfd_link_hash_entry *h; - - /* This symbol is externally visible, and is defined by this - object file. */ - - name = _bfd_coff_internal_syment_name (abfd, &sym, buf); - if (name == NULL) - return false; - h = bfd_link_hash_lookup (info->hash, name, false, false, true); - - /* We are only interested in symbols that are currently - undefined. If a symbol is currently known to be common, - COFF linkers do not bring in an object file which defines - it. */ - if (h != (struct bfd_link_hash_entry *) NULL - && h->type == bfd_link_hash_undefined) - { - if (! (*info->callbacks->add_archive_element) (info, abfd, name)) - return false; - *pneeded = true; - return true; - } - } - - esym += (sym.n_numaux + 1) * symesz; - } - - /* We do not need this object file. */ - return true; -} - -/* Add all the symbols from an object file to the hash table. */ - -static boolean -coff_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - boolean (*sym_is_global) PARAMS ((bfd *, struct internal_syment *)); - boolean default_copy; - bfd_size_type symcount; - struct coff_link_hash_entry **sym_hash; - bfd_size_type symesz; - bfd_byte *esym; - bfd_byte *esym_end; - - sym_is_global = coff_backend_info (abfd)->_bfd_coff_sym_is_global; - - if (info->keep_memory) - default_copy = false; - else - default_copy = true; - - symcount = obj_raw_syment_count (abfd); - - /* We keep a list of the linker hash table entries that correspond - to particular symbols. */ - sym_hash = ((struct coff_link_hash_entry **) - bfd_alloc (abfd, - ((size_t) symcount - * sizeof (struct coff_link_hash_entry *)))); - if (sym_hash == NULL && symcount != 0) - return false; - obj_coff_sym_hashes (abfd) = sym_hash; - memset (sym_hash, 0, - (size_t) symcount * sizeof (struct coff_link_hash_entry *)); - - symesz = bfd_coff_symesz (abfd); - BFD_ASSERT (symesz == bfd_coff_auxesz (abfd)); - esym = (bfd_byte *) obj_coff_external_syms (abfd); - esym_end = esym + symcount * symesz; - while (esym < esym_end) - { - struct internal_syment sym; - boolean copy; - - bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym); - - if (sym.n_sclass == C_EXT - || (sym_is_global && (*sym_is_global) (abfd, &sym))) - { - const char *name; - char buf[SYMNMLEN + 1]; - flagword flags; - asection *section; - bfd_vma value; - - /* This symbol is externally visible. */ - - name = _bfd_coff_internal_syment_name (abfd, &sym, buf); - if (name == NULL) - return false; - - /* We must copy the name into memory if we got it from the - syment itself, rather than the string table. */ - copy = default_copy; - if (sym._n._n_n._n_zeroes != 0 - || sym._n._n_n._n_offset == 0) - copy = true; - - value = sym.n_value; - - if (sym.n_scnum == 0) - { - if (value == 0) - { - flags = 0; - section = bfd_und_section_ptr; - } - else - { - flags = BSF_GLOBAL; - section = bfd_com_section_ptr; - } - } - else - { - flags = BSF_EXPORT | BSF_GLOBAL; - section = coff_section_from_bfd_index (abfd, sym.n_scnum); - value -= section->vma; - } - - if (! (bfd_coff_link_add_one_symbol - (info, abfd, name, flags, section, value, - (const char *) NULL, copy, false, - (struct bfd_link_hash_entry **) sym_hash))) - return false; - - if (info->hash->creator->flavour == bfd_get_flavour (abfd)) - { - if (((*sym_hash)->class == C_NULL - && (*sym_hash)->type == T_NULL) - || sym.n_scnum != 0 - || (sym.n_value != 0 - && (*sym_hash)->root.type != bfd_link_hash_defined)) - { - (*sym_hash)->class = sym.n_sclass; - (*sym_hash)->type = sym.n_type; - (*sym_hash)->numaux = sym.n_numaux; - (*sym_hash)->auxbfd = abfd; - if (sym.n_numaux != 0) - { - union internal_auxent *alloc; - unsigned int i; - bfd_byte *eaux; - union internal_auxent *iaux; - - alloc = ((union internal_auxent *) - bfd_hash_allocate (&info->hash->table, - (sym.n_numaux - * sizeof (*alloc)))); - if (alloc == NULL) - return false; - for (i = 0, eaux = esym + symesz, iaux = alloc; - i < sym.n_numaux; - i++, eaux += symesz, iaux++) - bfd_coff_swap_aux_in (abfd, (PTR) eaux, sym.n_type, - sym.n_sclass, i, sym.n_numaux, - (PTR) iaux); - (*sym_hash)->aux = alloc; - } - } - } - } - - esym += (sym.n_numaux + 1) * symesz; - sym_hash += sym.n_numaux + 1; - } - - return true; -} - -/* Do the final link step. */ - -boolean -_bfd_coff_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - bfd_size_type symesz; - struct coff_final_link_info finfo; - boolean debug_merge_allocated; - asection *o; - struct bfd_link_order *p; - size_t max_sym_count; - size_t max_lineno_count; - size_t max_reloc_count; - size_t max_output_reloc_count; - size_t max_contents_size; - file_ptr rel_filepos; - unsigned int relsz; - file_ptr line_filepos; - unsigned int linesz; - bfd *sub; - bfd_byte *external_relocs = NULL; - char strbuf[STRING_SIZE_SIZE]; - - symesz = bfd_coff_symesz (abfd); - - finfo.info = info; - finfo.output_bfd = abfd; - finfo.strtab = NULL; - finfo.section_info = NULL; - finfo.last_file_index = -1; - finfo.internal_syms = NULL; - finfo.sec_ptrs = NULL; - finfo.sym_indices = NULL; - finfo.outsyms = NULL; - finfo.linenos = NULL; - finfo.contents = NULL; - finfo.external_relocs = NULL; - finfo.internal_relocs = NULL; - debug_merge_allocated = false; - - coff_data (abfd)->link_info = info; - - finfo.strtab = _bfd_stringtab_init (); - if (finfo.strtab == NULL) - goto error_return; - - if (! coff_debug_merge_hash_table_init (&finfo.debug_merge)) - goto error_return; - debug_merge_allocated = true; - - /* Compute the file positions for all the sections. */ - if (! abfd->output_has_begun) - bfd_coff_compute_section_file_positions (abfd); - - /* Count the line numbers and relocation entries required for the - output file. Set the file positions for the relocs. */ - rel_filepos = obj_relocbase (abfd); - relsz = bfd_coff_relsz (abfd); - max_contents_size = 0; - max_lineno_count = 0; - max_reloc_count = 0; - - for (o = abfd->sections; o != NULL; o = o->next) - { - o->reloc_count = 0; - o->lineno_count = 0; - for (p = o->link_order_head; p != NULL; p = p->next) - { - - if (p->type == bfd_indirect_link_order) - { - asection *sec; - - sec = p->u.indirect.section; - - if (info->strip == strip_none - || info->strip == strip_some) - o->lineno_count += sec->lineno_count; - - if (info->relocateable) - o->reloc_count += sec->reloc_count; - - if (sec->_raw_size > max_contents_size) - max_contents_size = sec->_raw_size; - if (sec->lineno_count > max_lineno_count) - max_lineno_count = sec->lineno_count; - if (sec->reloc_count > max_reloc_count) - max_reloc_count = sec->reloc_count; - } - else if (info->relocateable - && (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order)) - ++o->reloc_count; - } - if (o->reloc_count == 0) - o->rel_filepos = 0; - else - { - o->flags |= SEC_RELOC; - o->rel_filepos = rel_filepos; - rel_filepos += o->reloc_count * relsz; - } - } - - /* If doing a relocateable link, allocate space for the pointers we - need to keep. */ - if (info->relocateable) - { - unsigned int i; - - /* We use section_count + 1, rather than section_count, because - the target_index fields are 1 based. */ - finfo.section_info = - ((struct coff_link_section_info *) - bfd_malloc ((abfd->section_count + 1) - * sizeof (struct coff_link_section_info))); - if (finfo.section_info == NULL) - goto error_return; - for (i = 0; i <= abfd->section_count; i++) - { - finfo.section_info[i].relocs = NULL; - finfo.section_info[i].rel_hashes = NULL; - } - } - - /* We now know the size of the relocs, so we can determine the file - positions of the line numbers. */ - line_filepos = rel_filepos; - linesz = bfd_coff_linesz (abfd); - max_output_reloc_count = 0; - for (o = abfd->sections; o != NULL; o = o->next) - { - if (o->lineno_count == 0) - o->line_filepos = 0; - else - { - o->line_filepos = line_filepos; - line_filepos += o->lineno_count * linesz; - } - - if (o->reloc_count != 0) - { - /* We don't know the indices of global symbols until we have - written out all the local symbols. For each section in - the output file, we keep an array of pointers to hash - table entries. Each entry in the array corresponds to a - reloc. When we find a reloc against a global symbol, we - set the corresponding entry in this array so that we can - fix up the symbol index after we have written out all the - local symbols. - - Because of this problem, we also keep the relocs in - memory until the end of the link. This wastes memory, - but only when doing a relocateable link, which is not the - common case. */ - BFD_ASSERT (info->relocateable); - finfo.section_info[o->target_index].relocs = - ((struct internal_reloc *) - bfd_malloc (o->reloc_count * sizeof (struct internal_reloc))); - finfo.section_info[o->target_index].rel_hashes = - ((struct coff_link_hash_entry **) - bfd_malloc (o->reloc_count - * sizeof (struct coff_link_hash_entry *))); - if (finfo.section_info[o->target_index].relocs == NULL - || finfo.section_info[o->target_index].rel_hashes == NULL) - goto error_return; - - if (o->reloc_count > max_output_reloc_count) - max_output_reloc_count = o->reloc_count; - } - - /* Reset the reloc and lineno counts, so that we can use them to - count the number of entries we have output so far. */ - o->reloc_count = 0; - o->lineno_count = 0; - } - - obj_sym_filepos (abfd) = line_filepos; - - /* Figure out the largest number of symbols in an input BFD. Take - the opportunity to clear the output_has_begun fields of all the - input BFD's. */ - max_sym_count = 0; - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - size_t sz; - - sub->output_has_begun = false; - sz = obj_raw_syment_count (sub); - if (sz > max_sym_count) - max_sym_count = sz; - } - - /* Allocate some buffers used while linking. */ - finfo.internal_syms = ((struct internal_syment *) - bfd_malloc (max_sym_count - * sizeof (struct internal_syment))); - finfo.sec_ptrs = (asection **) bfd_malloc (max_sym_count - * sizeof (asection *)); - finfo.sym_indices = (long *) bfd_malloc (max_sym_count * sizeof (long)); - finfo.outsyms = ((bfd_byte *) - bfd_malloc ((size_t) ((max_sym_count + 1) * symesz))); - finfo.linenos = (bfd_byte *) bfd_malloc (max_lineno_count - * bfd_coff_linesz (abfd)); - finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size); - finfo.external_relocs = (bfd_byte *) bfd_malloc (max_reloc_count * relsz); - if (! info->relocateable) - finfo.internal_relocs = ((struct internal_reloc *) - bfd_malloc (max_reloc_count - * sizeof (struct internal_reloc))); - if ((finfo.internal_syms == NULL && max_sym_count > 0) - || (finfo.sec_ptrs == NULL && max_sym_count > 0) - || (finfo.sym_indices == NULL && max_sym_count > 0) - || finfo.outsyms == NULL - || (finfo.linenos == NULL && max_lineno_count > 0) - || (finfo.contents == NULL && max_contents_size > 0) - || (finfo.external_relocs == NULL && max_reloc_count > 0) - || (! info->relocateable - && finfo.internal_relocs == NULL - && max_reloc_count > 0)) - goto error_return; - - /* We now know the position of everything in the file, except that - we don't know the size of the symbol table and therefore we don't - know where the string table starts. We just build the string - table in memory as we go along. We process all the relocations - for a single input file at once. */ - obj_raw_syment_count (abfd) = 0; - - if (coff_backend_info (abfd)->_bfd_coff_start_final_link) - { - if (! bfd_coff_start_final_link (abfd, info)) - goto error_return; - } - - for (o = abfd->sections; o != NULL; o = o->next) - { - for (p = o->link_order_head; p != NULL; p = p->next) - { - if (p->type == bfd_indirect_link_order - && (bfd_get_flavour (p->u.indirect.section->owner) - == bfd_target_coff_flavour)) - { - sub = p->u.indirect.section->owner; - if (! sub->output_has_begun) - { - if (! _bfd_coff_link_input_bfd (&finfo, sub)) - goto error_return; - sub->output_has_begun = true; - } - } - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - { - if (! _bfd_coff_reloc_link_order (abfd, &finfo, o, p)) - goto error_return; - } - else - { - if (! _bfd_default_link_order (abfd, info, o, p)) - goto error_return; - } - } - } - - /* Free up the buffers used by _bfd_coff_link_input_bfd. */ - - coff_debug_merge_hash_table_free (&finfo.debug_merge); - debug_merge_allocated = false; - - if (finfo.internal_syms != NULL) - { - free (finfo.internal_syms); - finfo.internal_syms = NULL; - } - if (finfo.sec_ptrs != NULL) - { - free (finfo.sec_ptrs); - finfo.sec_ptrs = NULL; - } - if (finfo.sym_indices != NULL) - { - free (finfo.sym_indices); - finfo.sym_indices = NULL; - } - if (finfo.linenos != NULL) - { - free (finfo.linenos); - finfo.linenos = NULL; - } - if (finfo.contents != NULL) - { - free (finfo.contents); - finfo.contents = NULL; - } - if (finfo.external_relocs != NULL) - { - free (finfo.external_relocs); - finfo.external_relocs = NULL; - } - if (finfo.internal_relocs != NULL) - { - free (finfo.internal_relocs); - finfo.internal_relocs = NULL; - } - - /* The value of the last C_FILE symbol is supposed to be the symbol - index of the first external symbol. Write it out again if - necessary. */ - if (finfo.last_file_index != -1 - && (unsigned int) finfo.last_file.n_value != obj_raw_syment_count (abfd)) - { - finfo.last_file.n_value = obj_raw_syment_count (abfd); - bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file, - (PTR) finfo.outsyms); - if (bfd_seek (abfd, - (obj_sym_filepos (abfd) - + finfo.last_file_index * symesz), - SEEK_SET) != 0 - || bfd_write (finfo.outsyms, symesz, 1, abfd) != symesz) - return false; - } - - /* Write out the global symbols. */ - finfo.failed = false; - coff_link_hash_traverse (coff_hash_table (info), _bfd_coff_write_global_sym, - (PTR) &finfo); - if (finfo.failed) - goto error_return; - - /* The outsyms buffer is used by _bfd_coff_write_global_sym. */ - if (finfo.outsyms != NULL) - { - free (finfo.outsyms); - finfo.outsyms = NULL; - } - - if (info->relocateable) - { - /* Now that we have written out all the global symbols, we know - the symbol indices to use for relocs against them, and we can - finally write out the relocs. */ - external_relocs = ((bfd_byte *) - bfd_malloc (max_output_reloc_count * relsz)); - if (external_relocs == NULL) - goto error_return; - - for (o = abfd->sections; o != NULL; o = o->next) - { - struct internal_reloc *irel; - struct internal_reloc *irelend; - struct coff_link_hash_entry **rel_hash; - bfd_byte *erel; - - if (o->reloc_count == 0) - continue; - - irel = finfo.section_info[o->target_index].relocs; - irelend = irel + o->reloc_count; - rel_hash = finfo.section_info[o->target_index].rel_hashes; - erel = external_relocs; - for (; irel < irelend; irel++, rel_hash++, erel += relsz) - { - if (*rel_hash != NULL) - { - BFD_ASSERT ((*rel_hash)->indx >= 0); - irel->r_symndx = (*rel_hash)->indx; - } - bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel); - } - - if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0 - || bfd_write ((PTR) external_relocs, relsz, o->reloc_count, - abfd) != relsz * o->reloc_count) - goto error_return; - } - - free (external_relocs); - external_relocs = NULL; - } - - /* Free up the section information. */ - if (finfo.section_info != NULL) - { - unsigned int i; - - for (i = 0; i < abfd->section_count; i++) - { - if (finfo.section_info[i].relocs != NULL) - free (finfo.section_info[i].relocs); - if (finfo.section_info[i].rel_hashes != NULL) - free (finfo.section_info[i].rel_hashes); - } - free (finfo.section_info); - finfo.section_info = NULL; - } - - /* Write out the string table. */ - if (obj_raw_syment_count (abfd) != 0) - { - if (bfd_seek (abfd, - (obj_sym_filepos (abfd) - + obj_raw_syment_count (abfd) * symesz), - SEEK_SET) != 0) - return false; - -#if STRING_SIZE_SIZE == 4 - bfd_h_put_32 (abfd, - _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE, - (bfd_byte *) strbuf); -#else - #error Change bfd_h_put_32 -#endif - - if (bfd_write (strbuf, 1, STRING_SIZE_SIZE, abfd) != STRING_SIZE_SIZE) - return false; - - if (! _bfd_stringtab_emit (abfd, finfo.strtab)) - return false; - } - - _bfd_stringtab_free (finfo.strtab); - - /* Setting bfd_get_symcount to 0 will cause write_object_contents to - not try to write out the symbols. */ - bfd_get_symcount (abfd) = 0; - - return true; - - error_return: - if (debug_merge_allocated) - coff_debug_merge_hash_table_free (&finfo.debug_merge); - if (finfo.strtab != NULL) - _bfd_stringtab_free (finfo.strtab); - if (finfo.section_info != NULL) - { - unsigned int i; - - for (i = 0; i < abfd->section_count; i++) - { - if (finfo.section_info[i].relocs != NULL) - free (finfo.section_info[i].relocs); - if (finfo.section_info[i].rel_hashes != NULL) - free (finfo.section_info[i].rel_hashes); - } - free (finfo.section_info); - } - if (finfo.internal_syms != NULL) - free (finfo.internal_syms); - if (finfo.sec_ptrs != NULL) - free (finfo.sec_ptrs); - if (finfo.sym_indices != NULL) - free (finfo.sym_indices); - if (finfo.outsyms != NULL) - free (finfo.outsyms); - if (finfo.linenos != NULL) - free (finfo.linenos); - if (finfo.contents != NULL) - free (finfo.contents); - if (finfo.external_relocs != NULL) - free (finfo.external_relocs); - if (finfo.internal_relocs != NULL) - free (finfo.internal_relocs); - if (external_relocs != NULL) - free (external_relocs); - return false; -} - -/* parse out a -heap <reserved>,<commit> line */ - -static char * -dores_com (ptr, output_bfd, heap) - char *ptr; - bfd *output_bfd; - int heap; -{ - if (coff_data(output_bfd)->pe) - { - int val = strtoul (ptr, &ptr, 0); - if (heap) - pe_data(output_bfd)->pe_opthdr.SizeOfHeapReserve =val; - else - pe_data(output_bfd)->pe_opthdr.SizeOfStackReserve =val; - - if (ptr[0] == ',') - { - int val = strtoul (ptr+1, &ptr, 0); - if (heap) - pe_data(output_bfd)->pe_opthdr.SizeOfHeapCommit =val; - else - pe_data(output_bfd)->pe_opthdr.SizeOfStackCommit =val; - } - } - return ptr; -} - -static char *get_name(ptr, dst) -char *ptr; -char **dst; -{ - while (*ptr == ' ') - ptr++; - *dst = ptr; - while (*ptr && *ptr != ' ') - ptr++; - *ptr = 0; - return ptr+1; -} - -/* Process any magic embedded commands in a section called .drectve */ - -static int -process_embedded_commands (output_bfd, info, abfd) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *abfd; -{ - asection *sec = bfd_get_section_by_name (abfd, ".drectve"); - char *s; - char *e; - char *copy; - if (!sec) - return 1; - - copy = bfd_malloc ((size_t) sec->_raw_size); - if (!copy) - return 0; - if (! bfd_get_section_contents(abfd, sec, copy, 0, sec->_raw_size)) - { - free (copy); - return 0; - } - e = copy + sec->_raw_size; - for (s = copy; s < e ; ) - { - if (s[0]!= '-') { - s++; - continue; - } - if (strncmp (s,"-attr", 5) == 0) - { - char *name; - char *attribs; - asection *asec; - - int loop = 1; - int had_write = 0; - int had_read = 0; - int had_exec= 0; - int had_shared= 0; - s += 5; - s = get_name(s, &name); - s = get_name(s, &attribs); - while (loop) { - switch (*attribs++) - { - case 'W': - had_write = 1; - break; - case 'R': - had_read = 1; - break; - case 'S': - had_shared = 1; - break; - case 'X': - had_exec = 1; - break; - default: - loop = 0; - } - } - asec = bfd_get_section_by_name (abfd, name); - if (asec) { - if (had_exec) - asec->flags |= SEC_CODE; - if (!had_write) - asec->flags |= SEC_READONLY; - } - } - else if (strncmp (s,"-heap", 5) == 0) - { - s = dores_com (s+5, output_bfd, 1); - } - else if (strncmp (s,"-stack", 6) == 0) - { - s = dores_com (s+6, output_bfd, 0); - } - else - s++; - } - free (copy); - return 1; -} - -/* Link an input file into the linker output file. This function - handles all the sections and relocations of the input file at once. */ - -boolean -_bfd_coff_link_input_bfd (finfo, input_bfd) - struct coff_final_link_info *finfo; - bfd *input_bfd; -{ - boolean (*sym_is_global) PARAMS ((bfd *, struct internal_syment *)); - boolean (*adjust_symndx) PARAMS ((bfd *, struct bfd_link_info *, bfd *, - asection *, struct internal_reloc *, - boolean *)); - bfd *output_bfd; - const char *strings; - bfd_size_type syment_base; - unsigned int n_tmask; - unsigned int n_btshft; - boolean copy, hash; - bfd_size_type isymesz; - bfd_size_type osymesz; - bfd_size_type linesz; - bfd_byte *esym; - bfd_byte *esym_end; - struct internal_syment *isymp; - asection **secpp; - long *indexp; - unsigned long output_index; - bfd_byte *outsym; - struct coff_link_hash_entry **sym_hash; - asection *o; - - /* Move all the symbols to the output file. */ - - output_bfd = finfo->output_bfd; - sym_is_global = coff_backend_info (input_bfd)->_bfd_coff_sym_is_global; - strings = NULL; - syment_base = obj_raw_syment_count (output_bfd); - isymesz = bfd_coff_symesz (input_bfd); - osymesz = bfd_coff_symesz (output_bfd); - linesz = bfd_coff_linesz (input_bfd); - BFD_ASSERT (linesz == bfd_coff_linesz (output_bfd)); - - n_tmask = coff_data (input_bfd)->local_n_tmask; - n_btshft = coff_data (input_bfd)->local_n_btshft; - - /* Define macros so that ISFCN, et. al., macros work correctly. */ -#define N_TMASK n_tmask -#define N_BTSHFT n_btshft - - copy = false; - if (! finfo->info->keep_memory) - copy = true; - hash = true; - if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0) - hash = false; - - if (! _bfd_coff_get_external_symbols (input_bfd)) - return false; - - esym = (bfd_byte *) obj_coff_external_syms (input_bfd); - esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz; - isymp = finfo->internal_syms; - secpp = finfo->sec_ptrs; - indexp = finfo->sym_indices; - output_index = syment_base; - outsym = finfo->outsyms; - - if (coff_data(output_bfd)->pe) - { - if (!process_embedded_commands (output_bfd, finfo->info, input_bfd)) - return false; - } - - while (esym < esym_end) - { - struct internal_syment isym; - boolean skip; - boolean global; - int add; - - bfd_coff_swap_sym_in (input_bfd, (PTR) esym, (PTR) isymp); - - /* Make a copy of *isymp so that the relocate_section function - always sees the original values. This is more reliable than - always recomputing the symbol value even if we are stripping - the symbol. */ - isym = *isymp; - - if (isym.n_scnum != 0) - *secpp = coff_section_from_bfd_index (input_bfd, isym.n_scnum); - else - { - if (isym.n_value == 0) - *secpp = bfd_und_section_ptr; - else - *secpp = bfd_com_section_ptr; - } - - *indexp = -1; - - skip = false; - global = false; - add = 1 + isym.n_numaux; - - /* If we are stripping all symbols, we want to skip this one. */ - if (finfo->info->strip == strip_all) - skip = true; - - if (! skip) - { - if (isym.n_sclass == C_EXT - || (sym_is_global && (*sym_is_global) (input_bfd, &isym))) - { - /* This is a global symbol. Global symbols come at the - end of the symbol table, so skip them for now. - Function symbols, however, are an exception, and are - not moved to the end. */ - global = true; - if (! ISFCN (isym.n_type)) - skip = true; - } - else - { - /* This is a local symbol. Skip it if we are discarding - local symbols. */ - if (finfo->info->discard == discard_all) - skip = true; - } - } - - /* If we stripping debugging symbols, and this is a debugging - symbol, then skip it. */ - if (! skip - && finfo->info->strip == strip_debugger - && isym.n_scnum == N_DEBUG) - skip = true; - - /* If some symbols are stripped based on the name, work out the - name and decide whether to skip this symbol. */ - if (! skip - && (finfo->info->strip == strip_some - || finfo->info->discard == discard_l)) - { - const char *name; - char buf[SYMNMLEN + 1]; - - name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf); - if (name == NULL) - return false; - - if ((finfo->info->strip == strip_some - && (bfd_hash_lookup (finfo->info->keep_hash, name, false, - false) == NULL)) - || (! global - && finfo->info->discard == discard_l - && strncmp (name, finfo->info->lprefix, - finfo->info->lprefix_len) == 0)) - skip = true; - } - - /* If this is an enum, struct, or union tag, see if we have - already output an identical type. */ - if (! skip - && (finfo->output_bfd->flags & BFD_TRADITIONAL_FORMAT) == 0 - && (isym.n_sclass == C_ENTAG - || isym.n_sclass == C_STRTAG - || isym.n_sclass == C_UNTAG) - && isym.n_numaux == 1) - { - const char *name; - char buf[SYMNMLEN + 1]; - struct coff_debug_merge_hash_entry *mh; - struct coff_debug_merge_type *mt; - union internal_auxent aux; - struct coff_debug_merge_element **epp; - bfd_byte *esl, *eslend; - struct internal_syment *islp; - - name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf); - if (name == NULL) - return false; - - /* Ignore fake names invented by compiler; treat them all as - the same name. */ - if (*name == '~' || *name == '.' || *name == '$' - || (*name == bfd_get_symbol_leading_char (input_bfd) - && (name[1] == '~' || name[1] == '.' || name[1] == '$'))) - name = ""; - - mh = coff_debug_merge_hash_lookup (&finfo->debug_merge, name, - true, true); - if (mh == NULL) - return false; - - /* Allocate memory to hold type information. If this turns - out to be a duplicate, we pass this address to - bfd_release. */ - mt = ((struct coff_debug_merge_type *) - bfd_alloc (input_bfd, - sizeof (struct coff_debug_merge_type))); - if (mt == NULL) - return false; - mt->class = isym.n_sclass; - - /* Pick up the aux entry, which points to the end of the tag - entries. */ - bfd_coff_swap_aux_in (input_bfd, (PTR) (esym + isymesz), - isym.n_type, isym.n_sclass, 0, isym.n_numaux, - (PTR) &aux); - - /* Gather the elements. */ - epp = &mt->elements; - mt->elements = NULL; - islp = isymp + 2; - esl = esym + 2 * isymesz; - eslend = ((bfd_byte *) obj_coff_external_syms (input_bfd) - + aux.x_sym.x_fcnary.x_fcn.x_endndx.l * isymesz); - while (esl < eslend) - { - const char *elename; - char elebuf[SYMNMLEN + 1]; - char *copy; - - bfd_coff_swap_sym_in (input_bfd, (PTR) esl, (PTR) islp); - - *epp = ((struct coff_debug_merge_element *) - bfd_alloc (input_bfd, - sizeof (struct coff_debug_merge_element))); - if (*epp == NULL) - return false; - - elename = _bfd_coff_internal_syment_name (input_bfd, islp, - elebuf); - if (elename == NULL) - return false; - - copy = (char *) bfd_alloc (input_bfd, strlen (elename) + 1); - if (copy == NULL) - return false; - strcpy (copy, elename); - - (*epp)->name = copy; - (*epp)->type = islp->n_type; - (*epp)->tagndx = 0; - if (islp->n_numaux >= 1 - && islp->n_type != T_NULL - && islp->n_sclass != C_EOS) - { - union internal_auxent eleaux; - long indx; - - bfd_coff_swap_aux_in (input_bfd, (PTR) (esl + isymesz), - islp->n_type, islp->n_sclass, 0, - islp->n_numaux, (PTR) &eleaux); - indx = eleaux.x_sym.x_tagndx.l; - - /* FIXME: If this tagndx entry refers to a symbol - defined later in this file, we just ignore it. - Handling this correctly would be tedious, and may - not be required. */ - - if (indx > 0 - && (indx - < ((esym - - (bfd_byte *) obj_coff_external_syms (input_bfd)) - / (long) isymesz))) - { - (*epp)->tagndx = finfo->sym_indices[indx]; - if ((*epp)->tagndx < 0) - (*epp)->tagndx = 0; - } - } - epp = &(*epp)->next; - *epp = NULL; - - esl += (islp->n_numaux + 1) * isymesz; - islp += islp->n_numaux + 1; - } - - /* See if we already have a definition which matches this - type. We always output the type if it has no elements, - for simplicity. */ - if (mt->elements == NULL) - bfd_release (input_bfd, (PTR) mt); - else - { - struct coff_debug_merge_type *mtl; - - for (mtl = mh->types; mtl != NULL; mtl = mtl->next) - { - struct coff_debug_merge_element *me, *mel; - - if (mtl->class != mt->class) - continue; - - for (me = mt->elements, mel = mtl->elements; - me != NULL && mel != NULL; - me = me->next, mel = mel->next) - { - if (strcmp (me->name, mel->name) != 0 - || me->type != mel->type - || me->tagndx != mel->tagndx) - break; - } - - if (me == NULL && mel == NULL) - break; - } - - if (mtl == NULL || (bfd_size_type) mtl->indx >= syment_base) - { - /* This is the first definition of this type. */ - mt->indx = output_index; - mt->next = mh->types; - mh->types = mt; - } - else - { - /* This is a redefinition which can be merged. */ - bfd_release (input_bfd, (PTR) mt); - *indexp = mtl->indx; - add = (eslend - esym) / isymesz; - skip = true; - } - } - } - - /* We now know whether we are to skip this symbol or not. */ - if (! skip) - { - /* Adjust the symbol in order to output it. */ - - if (isym._n._n_n._n_zeroes == 0 - && isym._n._n_n._n_offset != 0) - { - const char *name; - bfd_size_type indx; - - /* This symbol has a long name. Enter it in the string - table we are building. Note that we do not check - bfd_coff_symname_in_debug. That is only true for - XCOFF, and XCOFF requires different linking code - anyhow. */ - name = _bfd_coff_internal_syment_name (input_bfd, &isym, - (char *) NULL); - if (name == NULL) - return false; - indx = _bfd_stringtab_add (finfo->strtab, name, hash, copy); - if (indx == (bfd_size_type) -1) - return false; - isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx; - } - - if (isym.n_scnum > 0) - { - isym.n_scnum = (*secpp)->output_section->target_index; - isym.n_value += ((*secpp)->output_section->vma - + (*secpp)->output_offset - - (*secpp)->vma); - } - - /* The value of a C_FILE symbol is the symbol index of the - next C_FILE symbol. The value of the last C_FILE symbol - is the symbol index to the first external symbol - (actually, coff_renumber_symbols does not get this - right--it just sets the value of the last C_FILE symbol - to zero--and nobody has ever complained about it). We - try to get this right, below, just before we write the - symbols out, but in the general case we may have to write - the symbol out twice. */ - if (isym.n_sclass == C_FILE) - { - if (finfo->last_file_index != -1 - && finfo->last_file.n_value != (long) output_index) - { - /* We must correct the value of the last C_FILE entry. */ - finfo->last_file.n_value = output_index; - if ((bfd_size_type) finfo->last_file_index >= syment_base) - { - /* The last C_FILE symbol is in this input file. */ - bfd_coff_swap_sym_out (output_bfd, - (PTR) &finfo->last_file, - (PTR) (finfo->outsyms - + ((finfo->last_file_index - - syment_base) - * osymesz))); - } - else - { - /* We have already written out the last C_FILE - symbol. We need to write it out again. We - borrow *outsym temporarily. */ - bfd_coff_swap_sym_out (output_bfd, - (PTR) &finfo->last_file, - (PTR) outsym); - if (bfd_seek (output_bfd, - (obj_sym_filepos (output_bfd) - + finfo->last_file_index * osymesz), - SEEK_SET) != 0 - || (bfd_write (outsym, osymesz, 1, output_bfd) - != osymesz)) - return false; - } - } - - finfo->last_file_index = output_index; - finfo->last_file = isym; - } - - /* Output the symbol. */ - - bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym); - - *indexp = output_index; - - if (global) - { - long indx; - struct coff_link_hash_entry *h; - - indx = ((esym - (bfd_byte *) obj_coff_external_syms (input_bfd)) - / isymesz); - h = obj_coff_sym_hashes (input_bfd)[indx]; - BFD_ASSERT (h != NULL); - h->indx = output_index; - } - - output_index += add; - outsym += add * osymesz; - } - - esym += add * isymesz; - isymp += add; - ++secpp; - ++indexp; - for (--add; add > 0; --add) - { - *secpp++ = NULL; - *indexp++ = -1; - } - } - - /* Fix up the aux entries. This must be done in a separate pass, - because we don't know the correct symbol indices until we have - already decided which symbols we are going to keep. */ - - esym = (bfd_byte *) obj_coff_external_syms (input_bfd); - esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz; - isymp = finfo->internal_syms; - indexp = finfo->sym_indices; - sym_hash = obj_coff_sym_hashes (input_bfd); - outsym = finfo->outsyms; - while (esym < esym_end) - { - int add; - - add = 1 + isymp->n_numaux; - - if ((*indexp < 0 - || (bfd_size_type) *indexp < syment_base) - && (*sym_hash == NULL - || (*sym_hash)->auxbfd != input_bfd)) - esym += add * isymesz; - else - { - struct coff_link_hash_entry *h; - int i; - - h = NULL; - if (*indexp < 0) - { - h = *sym_hash; - BFD_ASSERT (h->numaux == isymp->n_numaux); - } - - esym += isymesz; - - if (h == NULL) - outsym += osymesz; - - /* Handle the aux entries. This handling is based on - coff_pointerize_aux. I don't know if it always correct. */ - for (i = 0; i < isymp->n_numaux && esym < esym_end; i++) - { - union internal_auxent aux; - union internal_auxent *auxp; - - if (h != NULL) - auxp = h->aux + i; - else - { - bfd_coff_swap_aux_in (input_bfd, (PTR) esym, isymp->n_type, - isymp->n_sclass, i, isymp->n_numaux, - (PTR) &aux); - auxp = &aux; - } - - if (isymp->n_sclass == C_FILE) - { - /* If this is a long filename, we must put it in the - string table. */ - if (auxp->x_file.x_n.x_zeroes == 0 - && auxp->x_file.x_n.x_offset != 0) - { - const char *filename; - bfd_size_type indx; - - BFD_ASSERT (auxp->x_file.x_n.x_offset - >= STRING_SIZE_SIZE); - if (strings == NULL) - { - strings = _bfd_coff_read_string_table (input_bfd); - if (strings == NULL) - return false; - } - filename = strings + auxp->x_file.x_n.x_offset; - indx = _bfd_stringtab_add (finfo->strtab, filename, - hash, copy); - if (indx == (bfd_size_type) -1) - return false; - auxp->x_file.x_n.x_offset = STRING_SIZE_SIZE + indx; - } - } - else if (isymp->n_sclass != C_STAT || isymp->n_type != T_NULL) - { - unsigned long indx; - - if (ISFCN (isymp->n_type) - || ISTAG (isymp->n_sclass) - || isymp->n_sclass == C_BLOCK) - { - indx = auxp->x_sym.x_fcnary.x_fcn.x_endndx.l; - if (indx > 0 - && indx < obj_raw_syment_count (input_bfd)) - { - /* We look forward through the symbol for - the index of the next symbol we are going - to include. I don't know if this is - entirely right. */ - while ((finfo->sym_indices[indx] < 0 - || ((bfd_size_type) finfo->sym_indices[indx] - < syment_base)) - && indx < obj_raw_syment_count (input_bfd)) - ++indx; - if (indx >= obj_raw_syment_count (input_bfd)) - indx = output_index; - else - indx = finfo->sym_indices[indx]; - auxp->x_sym.x_fcnary.x_fcn.x_endndx.l = indx; - } - } - - indx = auxp->x_sym.x_tagndx.l; - if (indx > 0 && indx < obj_raw_syment_count (input_bfd)) - { - long symindx; - - symindx = finfo->sym_indices[indx]; - if (symindx < 0) - auxp->x_sym.x_tagndx.l = 0; - else - auxp->x_sym.x_tagndx.l = symindx; - } - } - - if (h == NULL) - { - bfd_coff_swap_aux_out (output_bfd, (PTR) auxp, isymp->n_type, - isymp->n_sclass, i, isymp->n_numaux, - (PTR) outsym); - outsym += osymesz; - } - - esym += isymesz; - } - } - - indexp += add; - isymp += add; - sym_hash += add; - } - - /* Relocate the line numbers, unless we are stripping them. */ - if (finfo->info->strip == strip_none - || finfo->info->strip == strip_some) - { - for (o = input_bfd->sections; o != NULL; o = o->next) - { - bfd_vma offset; - bfd_byte *eline; - bfd_byte *elineend; - - /* FIXME: If SEC_HAS_CONTENTS is not for the section, then - build_link_order in ldwrite.c will not have created a - link order, which means that we will not have seen this - input section in _bfd_coff_final_link, which means that - we will not have allocated space for the line numbers of - this section. I don't think line numbers can be - meaningful for a section which does not have - SEC_HAS_CONTENTS set, but, if they do, this must be - changed. */ - if (o->lineno_count == 0 - || (o->output_section->flags & SEC_HAS_CONTENTS) == 0) - continue; - - if (bfd_seek (input_bfd, o->line_filepos, SEEK_SET) != 0 - || bfd_read (finfo->linenos, linesz, o->lineno_count, - input_bfd) != linesz * o->lineno_count) - return false; - - offset = o->output_section->vma + o->output_offset - o->vma; - eline = finfo->linenos; - elineend = eline + linesz * o->lineno_count; - for (; eline < elineend; eline += linesz) - { - struct internal_lineno iline; - - bfd_coff_swap_lineno_in (input_bfd, (PTR) eline, (PTR) &iline); - - if (iline.l_lnno != 0) - iline.l_addr.l_paddr += offset; - else if (iline.l_addr.l_symndx >= 0 - && ((unsigned long) iline.l_addr.l_symndx - < obj_raw_syment_count (input_bfd))) - { - long indx; - - indx = finfo->sym_indices[iline.l_addr.l_symndx]; - - if (indx < 0) - { - /* These line numbers are attached to a symbol - which we are stripping. We should really - just discard the line numbers, but that would - be a pain because we have already counted - them. */ - indx = 0; - } - else - { - struct internal_syment is; - union internal_auxent ia; - - /* Fix up the lnnoptr field in the aux entry of - the symbol. It turns out that we can't do - this when we modify the symbol aux entries, - because gas sometimes screws up the lnnoptr - field and makes it an offset from the start - of the line numbers rather than an absolute - file index. */ - bfd_coff_swap_sym_in (output_bfd, - (PTR) (finfo->outsyms - + ((indx - syment_base) - * osymesz)), - (PTR) &is); - if ((ISFCN (is.n_type) - || is.n_sclass == C_BLOCK) - && is.n_numaux >= 1) - { - PTR auxptr; - - auxptr = (PTR) (finfo->outsyms - + ((indx - syment_base + 1) - * osymesz)); - bfd_coff_swap_aux_in (output_bfd, auxptr, - is.n_type, is.n_sclass, - 0, is.n_numaux, (PTR) &ia); - ia.x_sym.x_fcnary.x_fcn.x_lnnoptr = - (o->output_section->line_filepos - + o->output_section->lineno_count * linesz - + eline - finfo->linenos); - bfd_coff_swap_aux_out (output_bfd, (PTR) &ia, - is.n_type, is.n_sclass, 0, - is.n_numaux, auxptr); - } - } - - iline.l_addr.l_symndx = indx; - } - - bfd_coff_swap_lineno_out (output_bfd, (PTR) &iline, (PTR) eline); - } - - if (bfd_seek (output_bfd, - (o->output_section->line_filepos - + o->output_section->lineno_count * linesz), - SEEK_SET) != 0 - || bfd_write (finfo->linenos, linesz, o->lineno_count, - output_bfd) != linesz * o->lineno_count) - return false; - - o->output_section->lineno_count += o->lineno_count; - } - } - - /* If we swapped out a C_FILE symbol, guess that the next C_FILE - symbol will be the first symbol in the next input file. In the - normal case, this will save us from writing out the C_FILE symbol - again. */ - if (finfo->last_file_index != -1 - && (bfd_size_type) finfo->last_file_index >= syment_base) - { - finfo->last_file.n_value = output_index; - bfd_coff_swap_sym_out (output_bfd, (PTR) &finfo->last_file, - (PTR) (finfo->outsyms - + ((finfo->last_file_index - syment_base) - * osymesz))); - } - - /* Write the modified symbols to the output file. */ - if (outsym > finfo->outsyms) - { - if (bfd_seek (output_bfd, - obj_sym_filepos (output_bfd) + syment_base * osymesz, - SEEK_SET) != 0 - || (bfd_write (finfo->outsyms, outsym - finfo->outsyms, 1, - output_bfd) - != (bfd_size_type) (outsym - finfo->outsyms))) - return false; - - BFD_ASSERT ((obj_raw_syment_count (output_bfd) - + (outsym - finfo->outsyms) / osymesz) - == output_index); - - obj_raw_syment_count (output_bfd) = output_index; - } - - /* Relocate the contents of each section. */ - adjust_symndx = coff_backend_info (input_bfd)->_bfd_coff_adjust_symndx; - for (o = input_bfd->sections; o != NULL; o = o->next) - { - bfd_byte *contents; - - if ((o->flags & SEC_HAS_CONTENTS) == 0) - { - if ((o->flags & SEC_RELOC) != 0 - && o->reloc_count != 0) - { - ((*_bfd_error_handler) - ("%s: relocs in section `%s', but it has no contents", - bfd_get_filename (input_bfd), - bfd_get_section_name (input_bfd, o))); - bfd_set_error (bfd_error_no_contents); - return false; - } - - continue; - } - - if (coff_section_data (input_bfd, o) != NULL - && coff_section_data (input_bfd, o)->contents != NULL) - contents = coff_section_data (input_bfd, o)->contents; - else - { - if (! bfd_get_section_contents (input_bfd, o, finfo->contents, - (file_ptr) 0, o->_raw_size)) - return false; - contents = finfo->contents; - } - - if ((o->flags & SEC_RELOC) != 0) - { - int target_index; - struct internal_reloc *internal_relocs; - struct internal_reloc *irel; - - /* Read in the relocs. */ - target_index = o->output_section->target_index; - internal_relocs = (_bfd_coff_read_internal_relocs - (input_bfd, o, false, finfo->external_relocs, - finfo->info->relocateable, - (finfo->info->relocateable - ? (finfo->section_info[target_index].relocs - + o->output_section->reloc_count) - : finfo->internal_relocs))); - if (internal_relocs == NULL) - return false; - - /* Call processor specific code to relocate the section - contents. */ - if (! bfd_coff_relocate_section (output_bfd, finfo->info, - input_bfd, o, - contents, - internal_relocs, - finfo->internal_syms, - finfo->sec_ptrs)) - return false; - - if (finfo->info->relocateable) - { - bfd_vma offset; - struct internal_reloc *irelend; - struct coff_link_hash_entry **rel_hash; - - offset = o->output_section->vma + o->output_offset - o->vma; - irel = internal_relocs; - irelend = irel + o->reloc_count; - rel_hash = (finfo->section_info[target_index].rel_hashes - + o->output_section->reloc_count); - for (; irel < irelend; irel++, rel_hash++) - { - struct coff_link_hash_entry *h; - boolean adjusted; - - *rel_hash = NULL; - - /* Adjust the reloc address and symbol index. */ - - irel->r_vaddr += offset; - - if (irel->r_symndx == -1) - continue; - - if (adjust_symndx) - { - if (! (*adjust_symndx) (output_bfd, finfo->info, - input_bfd, o, irel, - &adjusted)) - return false; - if (adjusted) - continue; - } - - h = obj_coff_sym_hashes (input_bfd)[irel->r_symndx]; - if (h != NULL) - { - /* This is a global symbol. */ - if (h->indx >= 0) - irel->r_symndx = h->indx; - else - { - /* This symbol is being written at the end - of the file, and we do not yet know the - symbol index. We save the pointer to the - hash table entry in the rel_hash list. - We set the indx field to -2 to indicate - that this symbol must not be stripped. */ - *rel_hash = h; - h->indx = -2; - } - } - else - { - long indx; - - indx = finfo->sym_indices[irel->r_symndx]; - if (indx != -1) - irel->r_symndx = indx; - else - { - struct internal_syment *is; - const char *name; - char buf[SYMNMLEN + 1]; - - /* This reloc is against a symbol we are - stripping. It would be possible to - handle this case, but I don't think it's - worth it. */ - is = finfo->internal_syms + irel->r_symndx; - - name = (_bfd_coff_internal_syment_name - (input_bfd, is, buf)); - if (name == NULL) - return false; - - if (! ((*finfo->info->callbacks->unattached_reloc) - (finfo->info, name, input_bfd, o, - irel->r_vaddr))) - return false; - } - } - } - - o->output_section->reloc_count += o->reloc_count; - } - } - - /* Write out the modified section contents. */ - if (! bfd_set_section_contents (output_bfd, o->output_section, - contents, o->output_offset, - (o->_cooked_size != 0 - ? o->_cooked_size - : o->_raw_size))) - return false; - } - - if (! finfo->info->keep_memory) - { - if (! _bfd_coff_free_symbols (input_bfd)) - return false; - } - - return true; -} - -/* Write out a global symbol. Called via coff_link_hash_traverse. */ - -boolean -_bfd_coff_write_global_sym (h, data) - struct coff_link_hash_entry *h; - PTR data; -{ - struct coff_final_link_info *finfo = (struct coff_final_link_info *) data; - bfd *output_bfd; - struct internal_syment isym; - bfd_size_type symesz; - unsigned int i; - - output_bfd = finfo->output_bfd; - - if (h->indx >= 0) - return true; - - if (h->indx != -2 - && (finfo->info->strip == strip_all - || (finfo->info->strip == strip_some - && (bfd_hash_lookup (finfo->info->keep_hash, - h->root.root.string, false, false) - == NULL)))) - return true; - - switch (h->root.type) - { - default: - case bfd_link_hash_new: - abort (); - return false; - - case bfd_link_hash_undefined: - case bfd_link_hash_undefweak: - isym.n_scnum = N_UNDEF; - isym.n_value = 0; - break; - - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - { - asection *sec; - - sec = h->root.u.def.section->output_section; - if (bfd_is_abs_section (sec)) - isym.n_scnum = N_ABS; - else - isym.n_scnum = sec->target_index; - isym.n_value = (h->root.u.def.value - + sec->vma - + h->root.u.def.section->output_offset); - } - break; - - case bfd_link_hash_common: - isym.n_scnum = N_UNDEF; - isym.n_value = h->root.u.c.size; - break; - - case bfd_link_hash_indirect: - case bfd_link_hash_warning: - /* Just ignore these. They can't be handled anyhow. */ - return true; - } - - if (strlen (h->root.root.string) <= SYMNMLEN) - strncpy (isym._n._n_name, h->root.root.string, SYMNMLEN); - else - { - boolean hash; - bfd_size_type indx; - - hash = true; - if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0) - hash = false; - indx = _bfd_stringtab_add (finfo->strtab, h->root.root.string, hash, - false); - if (indx == (bfd_size_type) -1) - { - finfo->failed = true; - return false; - } - isym._n._n_n._n_zeroes = 0; - isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx; - } - - isym.n_sclass = h->class; - isym.n_type = h->type; - - if (isym.n_sclass == C_NULL) - isym.n_sclass = C_EXT; - - isym.n_numaux = h->numaux; - - bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) finfo->outsyms); - - symesz = bfd_coff_symesz (output_bfd); - - if (bfd_seek (output_bfd, - (obj_sym_filepos (output_bfd) - + obj_raw_syment_count (output_bfd) * symesz), - SEEK_SET) != 0 - || bfd_write (finfo->outsyms, symesz, 1, output_bfd) != symesz) - { - finfo->failed = true; - return false; - } - - h->indx = obj_raw_syment_count (output_bfd); - - ++obj_raw_syment_count (output_bfd); - - /* Write out any associated aux entries. There normally will be - none. If there are any, I have no idea how to modify them. */ - for (i = 0; i < isym.n_numaux; i++) - { - bfd_coff_swap_aux_out (output_bfd, (PTR) (h->aux + i), isym.n_type, - isym.n_sclass, i, isym.n_numaux, - (PTR) finfo->outsyms); - if (bfd_write (finfo->outsyms, symesz, 1, output_bfd) != symesz) - { - finfo->failed = true; - return false; - } - ++obj_raw_syment_count (output_bfd); - } - - return true; -} - -/* Handle a link order which is supposed to generate a reloc. */ - -boolean -_bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order) - bfd *output_bfd; - struct coff_final_link_info *finfo; - asection *output_section; - struct bfd_link_order *link_order; -{ - reloc_howto_type *howto; - struct internal_reloc *irel; - struct coff_link_hash_entry **rel_hash_ptr; - - howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); - if (howto == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - if (link_order->u.reloc.p->addend != 0) - { - bfd_size_type size; - bfd_byte *buf; - bfd_reloc_status_type rstat; - boolean ok; - - size = bfd_get_reloc_size (howto); - buf = (bfd_byte *) bfd_zmalloc (size); - if (buf == NULL) - return false; - - rstat = _bfd_relocate_contents (howto, output_bfd, - link_order->u.reloc.p->addend, buf); - switch (rstat) - { - case bfd_reloc_ok: - break; - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - if (! ((*finfo->info->callbacks->reloc_overflow) - (finfo->info, - (link_order->type == bfd_section_reloc_link_order - ? bfd_section_name (output_bfd, - link_order->u.reloc.p->u.section) - : link_order->u.reloc.p->u.name), - howto->name, link_order->u.reloc.p->addend, - (bfd *) NULL, (asection *) NULL, (bfd_vma) 0))) - { - free (buf); - return false; - } - break; - } - ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf, - (file_ptr) link_order->offset, size); - free (buf); - if (! ok) - return false; - } - - /* Store the reloc information in the right place. It will get - swapped and written out at the end of the final_link routine. */ - - irel = (finfo->section_info[output_section->target_index].relocs - + output_section->reloc_count); - rel_hash_ptr = (finfo->section_info[output_section->target_index].rel_hashes - + output_section->reloc_count); - - memset (irel, 0, sizeof (struct internal_reloc)); - *rel_hash_ptr = NULL; - - irel->r_vaddr = output_section->vma + link_order->offset; - - if (link_order->type == bfd_section_reloc_link_order) - { - /* We need to somehow locate a symbol in the right section. The - symbol must either have a value of zero, or we must adjust - the addend by the value of the symbol. FIXME: Write this - when we need it. The old linker couldn't handle this anyhow. */ - abort (); - *rel_hash_ptr = NULL; - irel->r_symndx = 0; - } - else - { - struct coff_link_hash_entry *h; - - h = ((struct coff_link_hash_entry *) - bfd_wrapped_link_hash_lookup (output_bfd, finfo->info, - link_order->u.reloc.p->u.name, - false, false, true)); - if (h != NULL) - { - if (h->indx >= 0) - irel->r_symndx = h->indx; - else - { - /* Set the index to -2 to force this symbol to get - written out. */ - h->indx = -2; - *rel_hash_ptr = h; - irel->r_symndx = 0; - } - } - else - { - if (! ((*finfo->info->callbacks->unattached_reloc) - (finfo->info, link_order->u.reloc.p->u.name, (bfd *) NULL, - (asection *) NULL, (bfd_vma) 0))) - return false; - irel->r_symndx = 0; - } - } - - /* FIXME: Is this always right? */ - irel->r_type = howto->type; - - /* r_size is only used on the RS/6000, which needs its own linker - routines anyhow. r_extern is only used for ECOFF. */ - - /* FIXME: What is the right value for r_offset? Is zero OK? */ - - ++output_section->reloc_count; - - return true; -} - -/* A basic reloc handling routine which may be used by processors with - simple relocs. */ - -boolean -_bfd_coff_generic_relocate_section (output_bfd, info, input_bfd, - input_section, contents, relocs, syms, - sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - struct internal_reloc *relocs; - struct internal_syment *syms; - asection **sections; -{ - struct internal_reloc *rel; - struct internal_reloc *relend; - - rel = relocs; - relend = rel + input_section->reloc_count; - for (; rel < relend; rel++) - { - long symndx; - struct coff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma addend; - bfd_vma val; - reloc_howto_type *howto; - bfd_reloc_status_type rstat; - - symndx = rel->r_symndx; - - if (symndx == -1) - { - h = NULL; - sym = NULL; - } - else - { - h = obj_coff_sym_hashes (input_bfd)[symndx]; - sym = syms + symndx; - } - - /* COFF treats common symbols in one of two ways. Either the - size of the symbol is included in the section contents, or it - is not. We assume that the size is not included, and force - the rtype_to_howto function to adjust the addend as needed. */ - - if (sym != NULL && sym->n_scnum != 0) - addend = - sym->n_value; - else - addend = 0; - - - howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h, - sym, &addend); - if (howto == NULL) - return false; - - val = 0; - - if (h == NULL) - { - asection *sec; - - if (symndx == -1) - { - sec = bfd_abs_section_ptr; - val = 0; - } - else - { - sec = sections[symndx]; - val = (sec->output_section->vma - + sec->output_offset - + sym->n_value - - sec->vma); - } - } - else - { - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - asection *sec; - - sec = h->root.u.def.section; - val = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - - else if (! info->relocateable) - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return false; - } - } - - if (info->base_file) - { - /* Emit a reloc if the backend thinks it needs it. */ - if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto)) - { - /* relocation to a symbol in a section which - isn't absolute - we output the address here - to a file */ - bfd_vma addr = rel->r_vaddr - - input_section->vma - + input_section->output_offset - + input_section->output_section->vma; - if (coff_data(output_bfd)->pe) - addr -= pe_data(output_bfd)->pe_opthdr.ImageBase; - fwrite (&addr, 1,4, (FILE *) info->base_file); - } - } - - rstat = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, - rel->r_vaddr - input_section->vma, - val, addend); - - switch (rstat) - { - default: - abort (); - case bfd_reloc_ok: - break; - case bfd_reloc_overflow: - { - const char *name; - char buf[SYMNMLEN + 1]; - - if (symndx == -1) - name = "*ABS*"; - else if (h != NULL) - name = h->root.root.string; - else - { - name = _bfd_coff_internal_syment_name (input_bfd, sym, buf); - if (name == NULL) - return false; - } - - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, input_bfd, - input_section, rel->r_vaddr - input_section->vma))) - return false; - } - } - } - return true; -} - diff --git a/contrib/gdb/bfd/configure.bat b/contrib/gdb/bfd/configure.bat deleted file mode 100644 index 78fe79e..0000000 --- a/contrib/gdb/bfd/configure.bat +++ /dev/null @@ -1,18 +0,0 @@ -@echo off
-if "%1" == "h8/300" goto h8300
-
-echo Configuring bfd for go32
-update hosts\go32.h sysdep.h
-update Makefile.dos Makefile
-echo s/@WORDSIZE@/32/g>config.sed
-sed -e s/^/s\/@VERSION@\// -e s/$/\/g/g version >>config.sed
-sed -f config.sed < bfd-in2.h > bfd.h2
-update bfd.h2 bfd.h
-goto exit
-
-:h8300
-echo Configuring bfd for H8/300
-update hosts\h-go32.h sysdep.h
-update Makefile.dos Makefile
-
-:exit
diff --git a/contrib/gdb/bfd/cpu-a29k.c b/contrib/gdb/bfd/cpu-a29k.c deleted file mode 100644 index 5bd25a4..0000000 --- a/contrib/gdb/bfd/cpu-a29k.c +++ /dev/null @@ -1,39 +0,0 @@ -/* BFD support for the AMD 29000 architecture. - Copyright 1992 Free Software Foundation, Inc. - Hacked by Steve Chamberlain of Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -const bfd_arch_info_type bfd_a29k_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_a29k, - 0, /* only 1 machine */ - "a29k", - "a29k", - 4, - true, /* the one and only */ - bfd_default_compatible, - bfd_default_scan , - 0, - }; diff --git a/contrib/gdb/bfd/cpu-alpha.c b/contrib/gdb/bfd/cpu-alpha.c deleted file mode 100644 index 0d66a8b..0000000 --- a/contrib/gdb/bfd/cpu-alpha.c +++ /dev/null @@ -1,38 +0,0 @@ -/* BFD support for the Alpha architecture. - Copyright 1992 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -const bfd_arch_info_type bfd_alpha_arch = - { - 64, /* 32 bits in a word */ - 64, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_alpha, - 0, /* only 1 machine */ - "alpha", - "alpha", - 3, - true, /* the one and only */ - bfd_default_compatible, - bfd_default_scan , - 0, - }; diff --git a/contrib/gdb/bfd/cpu-arm.c b/contrib/gdb/bfd/cpu-arm.c deleted file mode 100644 index 92103e6..0000000 --- a/contrib/gdb/bfd/cpu-arm.c +++ /dev/null @@ -1,39 +0,0 @@ -/* BFD support for the ARM processor - Copyright 1994 Free Software Foundation, Inc. - Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -const bfd_arch_info_type bfd_arm_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_arm, - 0, /* only 1 machine */ - "arm", - "arm", - 4, - true, /* the one and only */ - bfd_default_compatible, - bfd_default_scan , - 0, - }; diff --git a/contrib/gdb/bfd/cpu-h8300.c b/contrib/gdb/bfd/cpu-h8300.c deleted file mode 100644 index 380dfb5..0000000 --- a/contrib/gdb/bfd/cpu-h8300.c +++ /dev/null @@ -1,246 +0,0 @@ -/* BFD library support routines for the Hitachi H8/300 architecture. - Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc. - Hacked by Steve Chamberlain of Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#if 0 /* not used currently */ -/* -Relocations for the H8 - -*/ -static bfd_reloc_status_type -howto16_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd * abfd; - arelent * reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection * ignore_input_section; - bfd * ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_16 (abfd, (bfd_byte *) data + addr); - - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_16 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - - -static bfd_reloc_status_type -howto8_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd * abfd; - arelent * reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection * ignore_input_section; - bfd * ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_8 (abfd, (bfd_byte *) data + addr); - - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - - -static bfd_reloc_status_type -howto8_FFnn_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd * abfd; - arelent * reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection * ignore_input_section; - bfd * ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - - long x = bfd_get_8 (abfd, (bfd_byte *) data + addr); - abort (); - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - -static bfd_reloc_status_type -howto8_pcrel_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd * abfd; - arelent * reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection * ignore_input_section; - bfd * ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_8 (abfd, (bfd_byte *) data + addr); - abort (); - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - -static reloc_howto_type howto_16 -= NEWHOWTO (howto16_callback, "abs16", 1, false, false); -static reloc_howto_type howto_8 -= NEWHOWTO (howto8_callback, "abs8", 0, false, false); - -static reloc_howto_type howto_8_FFnn -= NEWHOWTO (howto8_FFnn_callback, "ff00+abs8", 0, false, false); - -static reloc_howto_type howto_8_pcrel -= NEWHOWTO (howto8_pcrel_callback, "pcrel8", 0, false, true); - -static reloc_howto_type * -local_bfd_reloc_type_lookup (arch, code) - const struct bfd_arch_info *arch; - bfd_reloc_code_real_type code; -{ - switch (code) - { - case BFD_RELOC_16: - return &howto_16; - case BFD_RELOC_8_FFnn: - return &howto_8_FFnn; - case BFD_RELOC_8: - return &howto_8; - case BFD_RELOC_8_PCREL: - return &howto_8_pcrel; - default: - return (reloc_howto_type *) NULL; - } - } -#endif - -int bfd_default_scan_num_mach (); - -static boolean -h8300_scan (info, string) - const struct bfd_arch_info *info; - const char *string; -{ - if (*string != 'h' && *string != 'H') - return false; - - string++; - if (*string != '8') - return false; - - string++; - if (*string == '/') - string++; - - if (*string != '3') - return false; - string++; - if (*string != '0') - return false; - string++; - if (*string != '0') - return false; - string++; - if (*string == '-') - string++; - if (*string == 'h' || *string == 'H') - { - return (info->mach == bfd_mach_h8300h); - } - else - { - return info->mach == bfd_mach_h8300; - } -} - - -/* This routine is provided two arch_infos and works out the - machine which would be compatible with both and returns a pointer - to its info structure */ - -static const bfd_arch_info_type * -compatible (in, out) - const bfd_arch_info_type * in; - const bfd_arch_info_type * out; -{ - /* If the output is non-H and the input is -H, that's bad */ - if (in->mach == bfd_mach_h8300h && - out->mach == bfd_mach_h8300) - return 0; - - /* If either is an -H, the answer is -H */ - if (in->mach == bfd_mach_h8300h) - return in; - return out; -} - -static const bfd_arch_info_type h8300_info_struct = -{ - 16, /* 16 bits in a word */ - 16, /* 16 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_h8300, - bfd_mach_h8300, - "h8300", /* arch_name */ - "h8300", /* printable name */ - 1, - true, /* the default machine */ - compatible, - h8300_scan, -/* local_bfd_reloc_type_lookup, */ - 0, -}; - - -const bfd_arch_info_type bfd_h8300_arch = -{ - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_h8300, - bfd_mach_h8300h, - "h8300h", /* arch_name */ - "h8300h", /* printable name */ - 1, - false, /* the default machine */ - compatible, - h8300_scan, -/* local_bfd_reloc_type_lookup, */ - &h8300_info_struct, -}; diff --git a/contrib/gdb/bfd/cpu-h8500.c b/contrib/gdb/bfd/cpu-h8500.c deleted file mode 100644 index e4abfd1..0000000 --- a/contrib/gdb/bfd/cpu-h8500.c +++ /dev/null @@ -1,199 +0,0 @@ -/* BFD library support routines for the H8/500 architecture. - Copyright (C) 1993 Free Software Foundation, Inc. - Hacked by Steve Chamberlain of Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#if 0 - -/* -Relocations for the Z8K - -*/ -static bfd_reloc_status_type -howto16_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection *ignore_input_section; - bfd *ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_16(abfd, (bfd_byte *)data + addr); - - HOWTO_PREPARE(relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_16(abfd, x, (bfd_byte *)data + addr); - return bfd_reloc_ok; -} - - -static bfd_reloc_status_type -howto8_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection *ignore_input_section; - bfd *ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_8(abfd, (bfd_byte *)data + addr); - - HOWTO_PREPARE(relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8(abfd, x, (bfd_byte *)data + addr); - return bfd_reloc_ok; -} - - -static bfd_reloc_status_type -howto8_FFnn_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection *ignore_input_section; - bfd *ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - - long x = bfd_get_8(abfd, (bfd_byte *)data + addr); - abort(); - HOWTO_PREPARE(relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8(abfd, x, (bfd_byte *)data + addr); - return bfd_reloc_ok; -} - -static bfd_reloc_status_type -howto8_pcrel_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection *ignore_input_section; - bfd *ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_8(abfd, (bfd_byte *)data + addr); - abort(); - HOWTO_PREPARE(relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8(abfd, x, (bfd_byte *)data + addr); - return bfd_reloc_ok; -} - - - -static reloc_howto_type howto_16 - = NEWHOWTO(howto16_callback,"abs16",1,false,false); -static reloc_howto_type howto_8 - = NEWHOWTO(howto8_callback,"abs8",0,false,false); - -static reloc_howto_type howto_8_FFnn - = NEWHOWTO(howto8_FFnn_callback,"ff00+abs8",0,false,false); - -static reloc_howto_type howto_8_pcrel - = NEWHOWTO(howto8_pcrel_callback,"pcrel8",0,false,true); - - -static reloc_howto_type * -local_bfd_reloc_type_lookup (arch, code) - const struct bfd_arch_info *arch; - bfd_reloc_code_real_type code; -{ - switch (code) { - case BFD_RELOC_16: - return &howto_16; - case BFD_RELOC_8_FFnn: - return &howto_8_FFnn; - case BFD_RELOC_8: - return &howto_8; - case BFD_RELOC_8_PCREL: - return &howto_8_pcrel; - } - return (reloc_howto_type *)NULL; -} -#endif - -int bfd_default_scan_num_mach(); - -static boolean -scan_mach (info, string) - const struct bfd_arch_info *info; - const char *string; -{ - if (strcmp(string,"h8/500") == 0) return true; - if (strcmp(string,"H8/500") == 0) return true; - if (strcmp(string,"h8500") == 0) return true; - if (strcmp(string,"H8500") == 0) return true; - return false; -} - - -#if 0 /* not used currently */ -/* This routine is provided two arch_infos and returns whether - they'd be compatible */ - -static const bfd_arch_info_type * -compatible (a,b) - const bfd_arch_info_type *a; - const bfd_arch_info_type *b; -{ - if (a->arch != b->arch || a->mach != b->mach) - return NULL; - return a; -} -#endif - -const bfd_arch_info_type bfd_h8500_arch = -{ - 16, /* 16 bits in a word */ - 24, /* 24 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_h8500, - 0, /* only 1 machine */ - "h8500", /* arch_name */ - "h8500", /* printable name */ - 1, - true, /* the default machine */ - bfd_default_compatible, - scan_mach, - 0, -}; diff --git a/contrib/gdb/bfd/cpu-hppa.c b/contrib/gdb/bfd/cpu-hppa.c deleted file mode 100644 index 5201008..0000000 --- a/contrib/gdb/bfd/cpu-hppa.c +++ /dev/null @@ -1,54 +0,0 @@ -/* BFD support for the HP Precision Architecture architecture. - Copyright 1992 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -static const bfd_arch_info_type bfd_hppa10_arch = -{ - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_hppa, - 10, /* By convention PA1.0 = 10 */ - "hppa", - "hppa1.0", - 3, - true, /* Unless we use 1.1 specific features */ - bfd_default_compatible, - bfd_default_scan , - 0, -}; - -const bfd_arch_info_type bfd_hppa_arch = -{ - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_hppa, - 11, /* By convention PA1.1 = 11 */ - "hppa", - "hppa1.1", - 3, - false, /* 1.1 specific features used */ - bfd_default_compatible, - bfd_default_scan , - &bfd_hppa10_arch, -}; diff --git a/contrib/gdb/bfd/cpu-i860.c b/contrib/gdb/bfd/cpu-i860.c deleted file mode 100644 index 57c867c..0000000 --- a/contrib/gdb/bfd/cpu-i860.c +++ /dev/null @@ -1,40 +0,0 @@ -/* BFD support for the Intel 860 architecture. - Copyright 1992, 1995 Free Software Foundation, Inc. - Created mostly by substituting "860" for "386" in cpu-i386.c - Harry Dolan <dolan@ssd.intel.com>, October 1995 - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -const bfd_arch_info_type bfd_i860_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_i860, - 0, /* only 1 machine */ - "i860", - "i860", - 3, - true, /* the one and only */ - bfd_default_compatible, - bfd_default_scan , - 0, - }; diff --git a/contrib/gdb/bfd/cpu-i960.c b/contrib/gdb/bfd/cpu-i960.c deleted file mode 100644 index 6970f89..0000000 --- a/contrib/gdb/bfd/cpu-i960.c +++ /dev/null @@ -1,162 +0,0 @@ -/* BFD library support routines for the i960 architecture. - Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Hacked by Steve Chamberlain of Cygnus Support. - -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. */ - - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - - -/* This routine is provided a string, and tries to work out if it - could possibly refer to the i960 machine pointed at in the - info_struct pointer */ - -static boolean -scan_960_mach (ap, string) - const bfd_arch_info_type *ap; - const char *string; -{ - unsigned long machine; - - /* Look for the string i960, or somesuch at the front of the string */ - - if (strncmp("i960",string,4) == 0) { - string+=4; - } - else { - /* no match, can be us */ - return false; - } - if (string[0] == 0) { - /* i960 on it's own means core to us*/ - if (ap->mach == bfd_mach_i960_core) return true; - return false; - } - - if (string[0] != ':') { - return false; - } - string++; - if (string[0] == '\0') - return false; - if (string[0] == 'c' && string[1] == 'o' && string[2] == 'r' && - string[3] == 'e' && string[4] == '\0') - machine = bfd_mach_i960_core; - else if (string[1] == '\0' || string[2] != '\0') /* rest are 2-char */ - return false; - else if (string[0] == 'k' && string[1] == 'b') - machine = bfd_mach_i960_kb_sb; - else if (string[0] == 's' && string[1] == 'b') - machine = bfd_mach_i960_kb_sb; - else if (string[0] == 'm' && string[1] == 'c') - machine = bfd_mach_i960_mc; - else if (string[0] == 'x' && string[1] == 'a') - machine = bfd_mach_i960_xa; - else if (string[0] == 'c' && string[1] == 'a') - machine = bfd_mach_i960_ca; - else if (string[0] == 'k' && string[1] == 'a') - machine = bfd_mach_i960_ka_sa; - else if (string[0] == 's' && string[1] == 'a') - machine = bfd_mach_i960_ka_sa; - else if (string[0] == 'j' && string[1] == 'x') - machine = bfd_mach_i960_jx; - else if (string[0] == 'h' && string[1] == 'x') - machine = bfd_mach_i960_hx; - else - return false; - if (machine == ap->mach) return true; - return false; -} - - - -/* This routine is provided two arch_infos and works out the i960 - machine which would be compatible with both and returns a pointer - to its info structure */ - -static const bfd_arch_info_type * -compatible (a,b) - const bfd_arch_info_type *a; - const bfd_arch_info_type *b; -{ - - /* The i960 has distinct subspecies which may not interbreed: - CORE CA - CORE KA KB MC XA - CORE HX JX - Any architecture on the same line is compatible, the one on - the right is the least restrictive. - - We represent this information in an array, each machine to a side */ - -#define ERROR 0 -#define CORE bfd_mach_i960_core /*1*/ -#define KA bfd_mach_i960_ka_sa /*2*/ -#define KB bfd_mach_i960_kb_sb /*3*/ -#define MC bfd_mach_i960_mc /*4*/ -#define XA bfd_mach_i960_xa /*5*/ -#define CA bfd_mach_i960_ca /*6*/ -#define JX bfd_mach_i960_jx /*7*/ -#define HX bfd_mach_i960_hx /*8*/ -#define MAX_ARCH ((int)HX) - - static CONST unsigned long matrix[MAX_ARCH+1][MAX_ARCH+1] = - { - { ERROR, CORE, KA, KB, MC, XA, CA, JX, HX }, - { CORE, CORE, KA, KB, MC, XA, CA, JX, HX }, - { KA, KA, KA, KB, MC, XA, ERROR, ERROR, ERROR}, - { KB, KB, KB, KB, MC, XA, ERROR, ERROR, ERROR}, - { MC, MC, MC, MC, MC, XA, ERROR, ERROR, ERROR}, - { XA, XA, XA, XA, XA, XA, ERROR, ERROR, ERROR}, - { CA, CA, ERROR, ERROR, ERROR, ERROR, CA, ERROR, ERROR}, - { JX, JX, ERROR, ERROR, ERROR, ERROR, ERROR, JX, HX }, - { HX, HX, ERROR, ERROR, ERROR, ERROR, ERROR, HX, HX }, - }; - - - if (a->arch != b->arch || matrix[a->mach][b->mach] == ERROR) - { - return NULL; - } - else - { - return (a->mach == matrix[a->mach][b->mach]) ? a : b; - } -} - - - -int bfd_default_scan_num_mach(); -#define N(a,b,d,n) \ -{ 32, 32, 8,bfd_arch_i960,a,"i960",b,3,d,compatible,scan_960_mach,n,} - -static const bfd_arch_info_type arch_info_struct[] = -{ - N(bfd_mach_i960_ka_sa,"i960:ka_sa",false, &arch_info_struct[1]), - N(bfd_mach_i960_kb_sb,"i960:kb_sb",false, &arch_info_struct[2]), - N(bfd_mach_i960_mc, "i960:mc", false, &arch_info_struct[3]), - N(bfd_mach_i960_xa, "i960:xa", false, &arch_info_struct[4]), - N(bfd_mach_i960_ca, "i960:ca", false, &arch_info_struct[5]), - N(bfd_mach_i960_jx, "i960:jx", false, &arch_info_struct[6]), - N(bfd_mach_i960_hx, "i960:hx", false, 0), -}; - -const bfd_arch_info_type bfd_i960_arch = - N(bfd_mach_i960_core, "i960:core", true, &arch_info_struct[0]); diff --git a/contrib/gdb/bfd/cpu-m68k.c b/contrib/gdb/bfd/cpu-m68k.c deleted file mode 100644 index 17a3739..0000000 --- a/contrib/gdb/bfd/cpu-m68k.c +++ /dev/null @@ -1,42 +0,0 @@ -/* BFD library support routines for architectures. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Hacked by Steve Chamberlain of Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -int bfd_default_scan_num_mach(); - - -#define N(name, print,d,next) \ -{ 32, 32, 8, bfd_arch_m68k, name, "m68k",print,2,d,bfd_default_compatible,bfd_default_scan, next, } - -static const bfd_arch_info_type arch_info_struct[] = -{ - N(68008,"m68k:68008",false, &arch_info_struct[1]), - N(68010,"m68k:68010",false, &arch_info_struct[2]), - N(68020,"m68k:68020",true, &arch_info_struct[3]), - N(68030,"m68k:68030",false, &arch_info_struct[4]), - N(68040,"m68k:68040",false, &arch_info_struct[5]), - N(68070,"m68k:68070",false, 0), -}; - -const bfd_arch_info_type bfd_m68k_arch = - N(68000,"m68k:68000",false, &arch_info_struct[0]); diff --git a/contrib/gdb/bfd/cpu-m88k.c b/contrib/gdb/bfd/cpu-m88k.c deleted file mode 100644 index c3716c5..0000000 --- a/contrib/gdb/bfd/cpu-m88k.c +++ /dev/null @@ -1,42 +0,0 @@ -/* bfd back-end for m88k support - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - - - - -const bfd_arch_info_type bfd_m88k_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_m88k, - 88100, /* only 1 machine */ - "m88k", - "m88k:88100", - 3, - true, /* the one and only */ - bfd_default_compatible, - bfd_default_scan , - 0, - }; diff --git a/contrib/gdb/bfd/cpu-mips.c b/contrib/gdb/bfd/cpu-mips.c deleted file mode 100644 index 5e19342..0000000 --- a/contrib/gdb/bfd/cpu-mips.c +++ /dev/null @@ -1,85 +0,0 @@ -/* bfd back-end for mips support - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -static const bfd_arch_info_type arch_info_struct[] = -{ - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_mips, - 6000, - "mips", - "mips:6000", - 3, - false, - bfd_default_compatible, - bfd_default_scan, - &arch_info_struct[1], - }, - { - 64, /* 64 bits in a word */ - 64, /* 64 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_mips, - 4000, - "mips", - "mips:4000", - 3, - false, - bfd_default_compatible, - bfd_default_scan , - &arch_info_struct[2], - }, - { - 64, /* 64 bits in a word */ - 64, /* 64 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_mips, - 8000, - "mips", - "mips:8000", - 3, - false, - bfd_default_compatible, - bfd_default_scan , - 0, - } -}; - -const bfd_arch_info_type bfd_mips_arch = -{ - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_mips, - 3000, - "mips", - "mips:3000", - 3, - true, - bfd_default_compatible, - bfd_default_scan, - &arch_info_struct[0], -}; diff --git a/contrib/gdb/bfd/cpu-ns32k.c b/contrib/gdb/bfd/cpu-ns32k.c deleted file mode 100644 index e18e3cf..0000000 --- a/contrib/gdb/bfd/cpu-ns32k.c +++ /dev/null @@ -1,868 +0,0 @@ -/* BFD support for the ns32k architecture. - Copyright (C) 1990, 1991, 1994, 1995 Free Software Foundation, Inc. - Almost totally rewritten by Ian Dall from initial work - by Andrew Cagney. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -long ns32k_get_displacement PARAMS ((bfd_byte *buffer, long offset, long size)); -int ns32k_put_displacement PARAMS ((long value, bfd_byte *buffer, long offset, long size)); -long ns32k_get_immediate PARAMS ((bfd_byte *buffer, long offset, long size)); -int ns32k_put_immediate PARAMS ((long value, bfd_byte *buffer, long offset, long size)); -bfd_reloc_status_type - ns32k_reloc_disp PARAMS ((bfd *abfd, arelent *reloc_entry, - struct symbol_cache_entry *symbol, - PTR data, - asection *input_section, - bfd *output_bfd, - char **error_message)); -bfd_reloc_status_type - ns32k_reloc_imm PARAMS ((bfd *abfd, - arelent *reloc_entry, - struct symbol_cache_entry *symbol, - PTR data, - asection *input_section, - bfd *output_bfd, - char **error_message)); -bfd_reloc_status_type ns32k_final_link_relocate PARAMS ((reloc_howto_type *howto, - bfd *input_bfd, - asection *input_section, - bfd_byte *contents, - bfd_vma address, - bfd_vma value, - bfd_vma addend )); -bfd_reloc_status_type ns32k_relocate_contents PARAMS ((reloc_howto_type *howto, - bfd *input_bfd, - bfd_vma relocation, - bfd_byte *location)); - -int bfd_default_scan_num_mach(); - -#define N(machine, printable, d, next) \ -{ 32, 32, 8, bfd_arch_ns32k, machine, "ns32k",printable,3,d,bfd_default_compatible,bfd_default_scan, next, } - -static const bfd_arch_info_type arch_info_struct[] = -{ - N(32532,"ns32k:32532",true, 0), /* the word ns32k will match this too */ -}; - -const bfd_arch_info_type bfd_ns32k_arch = - N(32032,"ns32k:32032",false, &arch_info_struct[0]); - -static long -ns32k_sign_extend(value, bits) - int value; - int bits; -{ - value = value & ((1 << bits) - 1); - return (value & (1 << (bits-1)) - ? value | (~((1 << bits) - 1)) - : value); -} - -long -ns32k_get_displacement(buffer, offset, size) - bfd_byte *buffer; - long offset; - long size; -{ - long value; - buffer += offset; - switch (size) - { - case 1: - value = ns32k_sign_extend (*buffer, 7); - break; - case 2: - value = ns32k_sign_extend(*buffer++, 6); - value = (value << 8) | (0xff & *buffer); - break; - case 4: - value = ns32k_sign_extend(*buffer++, 6); - value = (value << 8) | (0xff & *buffer++); - value = (value << 8) | (0xff & *buffer++); - value = (value << 8) | (0xff & *buffer); - break; - } - return value; -} - -int -ns32k_put_displacement(value, buffer, offset, size) - long value; - bfd_byte *buffer; - long offset; - long size; -{ - buffer += offset; - switch (size) - { - case 1: - if (value < -64 || value > 63) - return -1; - value&=0x7f; - *buffer++=value; - break; - case 2: - if (value < -8192 || value > 8191) - return -1; - value&=0x3fff; - value|=0x8000; - *buffer++=(value>>8); - *buffer++=value; - break; - case 4: - if (value < -0x1f000000 || value >= 0x20000000) - return -1; - value|=0xc0000000; - *buffer++=(value>>24); - *buffer++=(value>>16); - *buffer++=(value>>8); - *buffer++=value; - break; - default: - return -1; - } - return 0; -} - -long -ns32k_get_immediate(buffer, offset, size) - bfd_byte *buffer; - long offset; - long size; -{ - long value = 0; - buffer += offset; - switch (size) - { - case 4: - value = (value << 8) | (*buffer++ & 0xff); - case 3: - value = (value << 8) | (*buffer++ & 0xff); - case 2: - value = (value << 8) | (*buffer++ & 0xff); - case 1: - value = (value << 8) | (*buffer++ & 0xff); - } - return value; -} - -int -ns32k_put_immediate (value, buffer, offset, size) - long value; - bfd_byte *buffer; - long offset; - long size; -{ - buffer += offset + size - 1; - switch (size) - { - case 4: - *buffer-- = (value & 0xff); value >>= 8; - case 3: - *buffer-- = (value & 0xff); value >>= 8; - case 2: - *buffer-- = (value & 0xff); value >>= 8; - case 1: - *buffer-- = (value & 0xff); value >>= 8; - } - return 0; -} - -/* This is just like the standard perform_relocation except we - * use get_data and put_data which know about the ns32k - * storage methods. - * This is probably a lot more complicated than it needs to be! - */ -static bfd_reloc_status_type -do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, - error_message, get_data, put_data) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; - long (*get_data)(); - int (*put_data)(); -{ - int overflow = 0; - bfd_vma relocation; - bfd_reloc_status_type flag = bfd_reloc_ok; - bfd_size_type addr = reloc_entry->address; - bfd_vma output_base = 0; - reloc_howto_type *howto = reloc_entry->howto; - asection *reloc_target_output_section; - - if ((symbol->section == &bfd_abs_section) - && output_bfd != (bfd *) NULL) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* If we are not producing relocateable output, return an error if - the symbol is not defined. An undefined weak symbol is - considered to have a value of zero (SVR4 ABI, p. 4-27). */ - if (symbol->section == &bfd_und_section - && (symbol->flags & BSF_WEAK) == 0 - && output_bfd == (bfd *) NULL) - flag = bfd_reloc_undefined; - - - /* Is the address of the relocation really within the section? */ - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - /* Work out which section the relocation is targetted at and the - initial relocation command value. */ - - /* Get symbol value. (Common symbols are special.) */ - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - - reloc_target_output_section = symbol->section->output_section; - - /* Convert input-section-relative symbol value to absolute. */ - if (output_bfd && howto->partial_inplace == false) - output_base = 0; - else - output_base = reloc_target_output_section->vma; - - relocation += output_base + symbol->section->output_offset; - - /* Add in supplied addend. */ - relocation += reloc_entry->addend; - - /* Here the variable relocation holds the final address of the - symbol we are relocating against, plus any addend. */ - - if (howto->pc_relative == true) - { - /* This is a PC relative relocation. We want to set RELOCATION - to the distance between the address of the symbol and the - location. RELOCATION is already the address of the symbol. - - We start by subtracting the address of the section containing - the location. - - If pcrel_offset is set, we must further subtract the position - of the location within the section. Some targets arrange for - the addend to be the negative of the position of the location - within the section; for example, i386-aout does this. For - i386-aout, pcrel_offset is false. Some other targets do not - include the position of the location; for example, m88kbcs, - or ELF. For those targets, pcrel_offset is true. - - If we are producing relocateable output, then we must ensure - that this reloc will be correctly computed when the final - relocation is done. If pcrel_offset is false we want to wind - up with the negative of the location within the section, - which means we must adjust the existing addend by the change - in the location within the section. If pcrel_offset is true - we do not want to adjust the existing addend at all. - - FIXME: This seems logical to me, but for the case of - producing relocateable output it is not what the code - actually does. I don't want to change it, because it seems - far too likely that something will break. */ - - relocation -= - input_section->output_section->vma + input_section->output_offset; - - if (howto->pcrel_offset == true) - relocation -= reloc_entry->address; - } - - if (output_bfd != (bfd *) NULL) - { - if (howto->partial_inplace == false) - { - /* This is a partial relocation, and we want to apply the relocation - to the reloc entry rather than the raw data. Modify the reloc - inplace to reflect what we now know. */ - reloc_entry->addend = relocation; - reloc_entry->address += input_section->output_offset; - return flag; - } - else - { - /* This is a partial relocation, but inplace, so modify the - reloc record a bit. - - If we've relocated with a symbol with a section, change - into a ref to the section belonging to the symbol. */ - - reloc_entry->address += input_section->output_offset; - - /* WTF?? */ - if (abfd->xvec->flavour == bfd_target_coff_flavour - && strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0) - { -#if 1 - /* For m68k-coff, the addend was being subtracted twice during - relocation with -r. Removing the line below this comment - fixes that problem; see PR 2953. - -However, Ian wrote the following, regarding removing the line below, -which explains why it is still enabled: --djm - -If you put a patch like that into BFD you need to check all the COFF -linkers. I am fairly certain that patch will break coff-i386 (e.g., -SCO); see coff_i386_reloc in coff-i386.c where I worked around the -problem in a different way. There may very well be a reason that the -code works as it does. - -Hmmm. The first obvious point is that bfd_perform_relocation should -not have any tests that depend upon the flavour. It's seem like -entirely the wrong place for such a thing. The second obvious point -is that the current code ignores the reloc addend when producing -relocateable output for COFF. That's peculiar. In fact, I really -have no idea what the point of the line you want to remove is. - -A typical COFF reloc subtracts the old value of the symbol and adds in -the new value to the location in the object file (if it's a pc -relative reloc it adds the difference between the symbol value and the -location). When relocating we need to preserve that property. - -BFD handles this by setting the addend to the negative of the old -value of the symbol. Unfortunately it handles common symbols in a -non-standard way (it doesn't subtract the old value) but that's a -different story (we can't change it without losing backward -compatibility with old object files) (coff-i386 does subtract the old -value, to be compatible with existing coff-i386 targets, like SCO). - -So everything works fine when not producing relocateable output. When -we are producing relocateable output, logically we should do exactly -what we do when not producing relocateable output. Therefore, your -patch is correct. In fact, it should probably always just set -reloc_entry->addend to 0 for all cases, since it is, in fact, going to -add the value into the object file. This won't hurt the COFF code, -which doesn't use the addend; I'm not sure what it will do to other -formats (the thing to check for would be whether any formats both use -the addend and set partial_inplace). - -When I wanted to make coff-i386 produce relocateable output, I ran -into the problem that you are running into: I wanted to remove that -line. Rather than risk it, I made the coff-i386 relocs use a special -function; it's coff_i386_reloc in coff-i386.c. The function -specifically adds the addend field into the object file, knowing that -bfd_perform_relocation is not going to. If you remove that line, then -coff-i386.c will wind up adding the addend field in twice. It's -trivial to fix; it just needs to be done. - -The problem with removing the line is just that it may break some -working code. With BFD it's hard to be sure of anything. The right -way to deal with this is simply to build and test at least all the -supported COFF targets. It should be straightforward if time and disk -space consuming. For each target: - 1) build the linker - 2) generate some executable, and link it using -r (I would - probably use paranoia.o and link against newlib/libc.a, which - for all the supported targets would be available in - /usr/cygnus/progressive/H-host/target/lib/libc.a). - 3) make the change to reloc.c - 4) rebuild the linker - 5) repeat step 2 - 6) if the resulting object files are the same, you have at least - made it no worse - 7) if they are different you have to figure out which version is - right -*/ - relocation -= reloc_entry->addend; -#endif - reloc_entry->addend = 0; - } - else - { - reloc_entry->addend = relocation; - } - } - } - else - { - reloc_entry->addend = 0; - } - - /* FIXME: This overflow checking is incomplete, because the value - might have overflowed before we get here. For a correct check we - need to compute the value in a size larger than bitsize, but we - can't reasonably do that for a reloc the same size as a host - machine word. - FIXME: We should also do overflow checking on the result after - adding in the value contained in the object file. */ - if (howto->complain_on_overflow != complain_overflow_dont) - { - bfd_vma check; - - /* Get the value that will be used for the relocation, but - starting at bit position zero. */ - if (howto->rightshift > howto->bitpos) - check = relocation >> (howto->rightshift - howto->bitpos); - else - check = relocation << (howto->bitpos - howto->rightshift); - switch (howto->complain_on_overflow) - { - case complain_overflow_signed: - { - /* Assumes two's complement. */ - bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1; - bfd_signed_vma reloc_signed_min = ~reloc_signed_max; - - /* The above right shift is incorrect for a signed value. - Fix it up by forcing on the upper bits. */ - if (howto->rightshift > howto->bitpos - && (bfd_signed_vma) relocation < 0) - check |= ((bfd_vma) - 1 - & ~((bfd_vma) - 1 - >> (howto->rightshift - howto->bitpos))); - if ((bfd_signed_vma) check > reloc_signed_max - || (bfd_signed_vma) check < reloc_signed_min) - flag = bfd_reloc_overflow; - } - break; - case complain_overflow_unsigned: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_unsigned_max = - (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if ((bfd_vma) check > reloc_unsigned_max) - flag = bfd_reloc_overflow; - } - break; - case complain_overflow_bitfield: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if (((bfd_vma) check & ~reloc_bits) != 0 - && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits)) - { - /* The above right shift is incorrect for a signed - value. See if turning on the upper bits fixes the - overflow. */ - if (howto->rightshift > howto->bitpos - && (bfd_signed_vma) relocation < 0) - { - check |= ((bfd_vma) - 1 - & ~((bfd_vma) - 1 - >> (howto->rightshift - howto->bitpos))); - if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits)) - flag = bfd_reloc_overflow; - } - else - flag = bfd_reloc_overflow; - } - } - break; - default: - abort (); - } - } - - /* - Either we are relocating all the way, or we don't want to apply - the relocation to the reloc entry (probably because there isn't - any room in the output format to describe addends to relocs) - */ - - /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler - (OSF version 1.3, compiler version 3.11). It miscompiles the - following program: - - struct str - { - unsigned int i0; - } s = { 0 }; - - int - main () - { - unsigned long x; - - x = 0x100000000; - x <<= (unsigned long) s.i0; - if (x == 0) - printf ("failed\n"); - else - printf ("succeeded (%lx)\n", x); - } - */ - - relocation >>= (bfd_vma) howto->rightshift; - - /* Shift everything up to where it's going to be used */ - - relocation <<= (bfd_vma) howto->bitpos; - - /* Wait for the day when all have the mask in them */ - - /* What we do: - i instruction to be left alone - o offset within instruction - r relocation offset to apply - S src mask - D dst mask - N ~dst mask - A part 1 - B part 2 - R result - - Do this: - i i i i i o o o o o from bfd_get<size> - and S S S S S to get the size offset we want - + r r r r r r r r r r to get the final value to place - and D D D D D to chop to right size - ----------------------- - A A A A A - And this: - ... i i i i i o o o o o from bfd_get<size> - and N N N N N get instruction - ----------------------- - ... B B B B B - - And then: - B B B B B - or A A A A A - ----------------------- - R R R R R R R R R R put into bfd_put<size> - */ - -#define DOIT(x) \ - x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask)) - - switch (howto->size) - { - case 0: - { - char x = get_data (data, addr, 1); - DOIT (x); - overflow = put_data(x, data, addr, 1); - } - break; - - case 1: - if (relocation) - { - short x = get_data (data, addr, 2); - DOIT (x); - overflow = put_data(x, (unsigned char *) data, addr, 2); - } - break; - case 2: - if (relocation) - { - long x = get_data (data, addr, 4); - DOIT (x); - overflow = put_data(x, data, addr, 4); - } - break; - case -2: - { - long x = get_data(data, addr, 4); - relocation = -relocation; - DOIT(x); - overflow = put_data(x, data , addr, 4); - } - break; - - case 3: - /* Do nothing */ - break; - - case 4: -#ifdef BFD64 - if (relocation) - { - bfd_vma x = get_data (data, addr, 8); - DOIT (x); - overflow = put_data(x, data, addr, 8); - } -#else - abort (); -#endif - break; - default: - return bfd_reloc_other; - } - if ((howto->complain_on_overflow != complain_overflow_dont) && overflow) - return bfd_reloc_overflow; - - return flag; -} - -/* Relocate a given location using a given value and howto. */ - -bfd_reloc_status_type -do_ns32k_reloc_contents ( howto, input_bfd, relocation, location, get_data, - put_data) - reloc_howto_type *howto; - bfd *input_bfd; - bfd_vma relocation; - bfd_byte *location; - long (*get_data)(); - int (*put_data)(); -{ - int size; - bfd_vma x; - boolean overflow; - - /* If the size is negative, negate RELOCATION. This isn't very - general. */ - if (howto->size < 0) - relocation = -relocation; - - /* Get the value we are going to relocate. */ - size = bfd_get_reloc_size (howto); - switch (size) - { - default: - case 0: - abort (); - case 1: - case 2: - case 4: -#ifdef BFD64 - case 8: -#endif - x = get_data (location, 0, size); - break; - } - - /* Check for overflow. FIXME: We may drop bits during the addition - which we don't check for. We must either check at every single - operation, which would be tedious, or we must do the computations - in a type larger than bfd_vma, which would be inefficient. */ - overflow = false; - if (howto->complain_on_overflow != complain_overflow_dont) - { - bfd_vma check; - bfd_signed_vma signed_check; - bfd_vma add; - bfd_signed_vma signed_add; - - if (howto->rightshift == 0) - { - check = relocation; - signed_check = (bfd_signed_vma) relocation; - } - else - { - /* Drop unwanted bits from the value we are relocating to. */ - check = relocation >> howto->rightshift; - - /* If this is a signed value, the rightshift just dropped - leading 1 bits (assuming twos complement). */ - if ((bfd_signed_vma) relocation >= 0) - signed_check = check; - else - signed_check = (check - | ((bfd_vma) - 1 - & ~((bfd_vma) - 1 >> howto->rightshift))); - } - - /* Get the value from the object file. */ - add = x & howto->src_mask; - - /* Get the value from the object file with an appropriate sign. - The expression involving howto->src_mask isolates the upper - bit of src_mask. If that bit is set in the value we are - adding, it is negative, and we subtract out that number times - two. If src_mask includes the highest possible bit, then we - can not get the upper bit, but that does not matter since - signed_add needs no adjustment to become negative in that - case. */ - signed_add = add; - if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0) - signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1; - - /* Add the value from the object file, shifted so that it is a - straight number. */ - if (howto->bitpos == 0) - { - check += add; - signed_check += signed_add; - } - else - { - check += add >> howto->bitpos; - - /* For the signed case we use ADD, rather than SIGNED_ADD, - to avoid warnings from SVR4 cc. This is OK since we - explictly handle the sign bits. */ - if (signed_add >= 0) - signed_check += add >> howto->bitpos; - else - signed_check += ((add >> howto->bitpos) - | ((bfd_vma) - 1 - & ~((bfd_vma) - 1 >> howto->bitpos))); - } - - switch (howto->complain_on_overflow) - { - case complain_overflow_signed: - { - /* Assumes two's complement. */ - bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1; - bfd_signed_vma reloc_signed_min = ~reloc_signed_max; - - if (signed_check > reloc_signed_max - || signed_check < reloc_signed_min) - overflow = true; - } - break; - case complain_overflow_unsigned: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_unsigned_max = - (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if (check > reloc_unsigned_max) - overflow = true; - } - break; - case complain_overflow_bitfield: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if ((check & ~reloc_bits) != 0 - && (((bfd_vma) signed_check & ~reloc_bits) - != (-1 & ~reloc_bits))) - overflow = true; - } - break; - default: - abort (); - } - } - - /* Put RELOCATION in the right bits. */ - relocation >>= (bfd_vma) howto->rightshift; - relocation <<= (bfd_vma) howto->bitpos; - - /* Add RELOCATION to the right bits of X. */ - x = ((x & ~howto->dst_mask) - | (((x & howto->src_mask) + relocation) & howto->dst_mask)); - - /* Put the relocated value back in the object file. */ - switch (size) - { - default: - case 0: - abort (); - case 1: - case 2: - case 4: -#ifdef BFD64 - case 8: -#endif - put_data(x, location, 0, size); - break; - } - - return overflow ? bfd_reloc_overflow : bfd_reloc_ok; -} - -bfd_reloc_status_type -ns32k_reloc_disp(abfd, reloc_entry, symbol, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - return do_ns32k_reloc(abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message, ns32k_get_displacement, ns32k_put_displacement); -} - -bfd_reloc_status_type -ns32k_reloc_imm (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - return do_ns32k_reloc(abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message, ns32k_get_immediate, ns32k_put_immediate); -} - -bfd_reloc_status_type -ns32k_final_link_relocate (howto, input_bfd, input_section, contents, address, value, addend ) - reloc_howto_type *howto; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - bfd_vma address; - bfd_vma value; - bfd_vma addend; -{ - bfd_vma relocation; - - /* Sanity check the address. */ - if (address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - /* This function assumes that we are dealing with a basic relocation - against a symbol. We want to compute the value of the symbol to - relocate to. This is just VALUE, the value of the symbol, plus - ADDEND, any addend associated with the reloc. */ - relocation = value + addend; - - /* If the relocation is PC relative, we want to set RELOCATION to - the distance between the symbol (currently in RELOCATION) and the - location we are relocating. Some targets (e.g., i386-aout) - arrange for the contents of the section to be the negative of the - offset of the location within the section; for such targets - pcrel_offset is false. Other targets (e.g., m88kbcs or ELF) - simply leave the contents of the section as zero; for such - targets pcrel_offset is true. If pcrel_offset is false we do not - need to subtract out the offset of the location within the - section (which is just ADDRESS). */ - if (howto->pc_relative) - { - relocation -= (input_section->output_section->vma - + input_section->output_offset); - if (howto->pcrel_offset) - relocation -= address; - } - - return ns32k_relocate_contents (howto, input_bfd, relocation, - contents + address); -} diff --git a/contrib/gdb/bfd/cpu-powerpc.c b/contrib/gdb/bfd/cpu-powerpc.c deleted file mode 100644 index 11f0f80..0000000 --- a/contrib/gdb/bfd/cpu-powerpc.c +++ /dev/null @@ -1,124 +0,0 @@ -/* BFD PowerPC CPU definition - Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. - Contributed by Ian Lance Taylor, Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -/* The common PowerPC architecture is compatible with the RS/6000. */ - -static const bfd_arch_info_type *powerpc_compatible - PARAMS ((const bfd_arch_info_type *, const bfd_arch_info_type *)); - -static const bfd_arch_info_type * -powerpc_compatible (a,b) - const bfd_arch_info_type *a; - const bfd_arch_info_type *b; -{ - BFD_ASSERT (a->arch == bfd_arch_powerpc); - switch (b->arch) - { - default: - return NULL; - case bfd_arch_powerpc: - return bfd_default_compatible (a, b); - case bfd_arch_rs6000: - if (a->mach == 0) - return a; - return NULL; - } - /*NOTREACHED*/ -} - -static const bfd_arch_info_type arch_info_struct[] = -{ - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_powerpc, - 603, /* for the mpc603 */ - "powerpc", - "powerpc:603", - 3, - false, /* not the default */ - powerpc_compatible, - bfd_default_scan, - &arch_info_struct[1] - }, - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_powerpc, - 604, /* for the mpc604 */ - "powerpc", - "powerpc:604", - 3, - false, /* not the default */ - powerpc_compatible, - bfd_default_scan, - &arch_info_struct[2] - }, - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_powerpc, - 403, /* for the 403 */ - "powerpc", - "powerpc:403", - 3, - false, /* not the default */ - powerpc_compatible, - bfd_default_scan, - &arch_info_struct[3] - }, - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_powerpc, - 601, /* for the mpc601 */ - "powerpc", - "powerpc:601", - 3, - false, /* not the default */ - powerpc_compatible, - bfd_default_scan, - 0 - } -}; - -const bfd_arch_info_type bfd_powerpc_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_powerpc, - 0, /* for the POWER/PowerPC common architecture */ - "powerpc", - "powerpc:common", - 3, - true, /* the default */ - powerpc_compatible, - bfd_default_scan, - &arch_info_struct[0] - }; diff --git a/contrib/gdb/bfd/cpu-rs6000.c b/contrib/gdb/bfd/cpu-rs6000.c deleted file mode 100644 index 9852ae9..0000000 --- a/contrib/gdb/bfd/cpu-rs6000.c +++ /dev/null @@ -1,70 +0,0 @@ -/* BFD back-end for rs6000 support - Copyright (C) 1990, 1991 Free Software Foundation, Inc. - FIXME: Can someone provide a transliteration of this name into ASCII? - Using the following chars caused a compiler warning on HIUX (so I replaced - them with octal escapes), and isn't useful without an understanding of what - character set it is. - Written by Mimi Ph\373\364ng-Th\345o V\365 of IBM - and John Gilmore of Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -/* The RS/6000 architecture is compatible with the PowerPC common - architecture. */ - -static const bfd_arch_info_type *rs6000_compatible - PARAMS ((const bfd_arch_info_type *, const bfd_arch_info_type *)); - -static const bfd_arch_info_type * -rs6000_compatible (a,b) - const bfd_arch_info_type *a; - const bfd_arch_info_type *b; -{ - BFD_ASSERT (a->arch == bfd_arch_rs6000); - switch (b->arch) - { - default: - return NULL; - case bfd_arch_rs6000: - return bfd_default_compatible (a, b); - case bfd_arch_powerpc: - if (b->mach == 0) - return b; - return NULL; - } - /*NOTREACHED*/ -} - -const bfd_arch_info_type bfd_rs6000_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_rs6000, - 6000, /* only 1 machine */ - "rs6000", - "rs6000:6000", - 3, - true, /* the one and only */ - rs6000_compatible, - bfd_default_scan, - 0, - }; diff --git a/contrib/gdb/bfd/cpu-sh.c b/contrib/gdb/bfd/cpu-sh.c deleted file mode 100644 index 7f6dd68..0000000 --- a/contrib/gdb/bfd/cpu-sh.c +++ /dev/null @@ -1,68 +0,0 @@ -/* BFD library support routines for the Hitachi-SH architecture. - Copyright (C) 1993 Free Software Foundation, Inc. - Hacked by Steve Chamberlain of Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - - -int bfd_default_scan_num_mach(); - -static boolean -scan_mach (info, string) - const struct bfd_arch_info *info; - const char *string; -{ - if (strcmp(string,"sh") == 0) return true; - if (strcmp(string,"SH") == 0) return true; - return false; -} - - -#if 0 -/* This routine is provided two arch_infos and returns whether - they'd be compatible */ - -static const bfd_arch_info_type * -compatible (a,b) - const bfd_arch_info_type *a; - const bfd_arch_info_type *b; -{ - if (a->arch != b->arch || a->mach != b->mach) - return NULL; - return a; -} -#endif - -const bfd_arch_info_type bfd_sh_arch = -{ - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_sh, - 0, /* only 1 machine */ - "sh", /* arch_name */ - "sh", /* printable name */ - 1, - true, /* the default machine */ - bfd_default_compatible, - scan_mach, - 0, -}; diff --git a/contrib/gdb/bfd/cpu-sparc.c b/contrib/gdb/bfd/cpu-sparc.c deleted file mode 100644 index e48aa5e..0000000 --- a/contrib/gdb/bfd/cpu-sparc.c +++ /dev/null @@ -1,111 +0,0 @@ -/* BFD support for the SPARC architecture. - Copyright (C) 1992, 1995, 1996 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -/* Don't mix 32 bit and 64 bit files. */ - -static const bfd_arch_info_type * -sparc_compatible (a, b) - const bfd_arch_info_type *a; - const bfd_arch_info_type *b; -{ - if (a->bits_per_word != b->bits_per_word) - return NULL; - - return bfd_default_compatible (a, b); -} - -static const bfd_arch_info_type arch_info_struct[] = -{ - { - 32, /* bits in a word */ - 32, /* bits in an address */ - 8, /* bits in a byte */ - bfd_arch_sparc, - bfd_mach_sparc_v8plus, - "sparc", - "sparc:v8plus", - 3, - false, - sparc_compatible, - bfd_default_scan, - &arch_info_struct[1], - }, - { - 32, /* bits in a word */ - 32, /* bits in an address */ - 8, /* bits in a byte */ - bfd_arch_sparc, - bfd_mach_sparc_v8plusa, - "sparc", - "sparc:v8plusa", - 3, - false, - sparc_compatible, - bfd_default_scan, - &arch_info_struct[2], - }, - { - 64, /* bits in a word */ - 64, /* bits in an address */ - 8, /* bits in a byte */ - bfd_arch_sparc, - bfd_mach_sparc_v9, - "sparc", - "sparc:v9", - 3, - false, - sparc_compatible, - bfd_default_scan, - &arch_info_struct[3], - }, - { - 64, /* bits in a word */ - 64, /* bits in an address */ - 8, /* bits in a byte */ - bfd_arch_sparc, - bfd_mach_sparc_v9a, - "sparc", - "sparc:v9a", - 3, - false, - sparc_compatible, - bfd_default_scan, - 0, - } -}; - -const bfd_arch_info_type bfd_sparc_arch = - { - 32, /* bits in a word */ - 32, /* bits in an address */ - 8, /* bits in a byte */ - bfd_arch_sparc, - bfd_mach_sparc, - "sparc", - "sparc", - 3, - true, /* the default */ - sparc_compatible, - bfd_default_scan, - &arch_info_struct[0], - }; diff --git a/contrib/gdb/bfd/cpu-vax.c b/contrib/gdb/bfd/cpu-vax.c deleted file mode 100644 index bdc6d39..0000000 --- a/contrib/gdb/bfd/cpu-vax.c +++ /dev/null @@ -1,39 +0,0 @@ -/* bfd back-end for vax support - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -const bfd_arch_info_type bfd_vax_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_vax, - 0, /* only 1 machine */ - "vax", - "vax", - 3, - true, /* the one and only */ - bfd_default_compatible, - bfd_default_scan , - 0, - }; diff --git a/contrib/gdb/bfd/cpu-w65.c b/contrib/gdb/bfd/cpu-w65.c deleted file mode 100644 index c0bbf04..0000000 --- a/contrib/gdb/bfd/cpu-w65.c +++ /dev/null @@ -1,54 +0,0 @@ -/* BFD library support routines for the WDC 65816 architecture. - Copyright (C) 1995 Free Software Foundation, Inc. - Hacked by Steve Chamberlain of Cygnus Support. - -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 publiw65ed 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 w65ould 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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - - -int bfd_default_scan_num_mach(); - -static boolean -scan_mach (info, string) - const struct bfd_arch_info *info; - const char *string; -{ - if (strcmp(string,"w65") == 0) return true; - if (strcmp(string,"w65816") == 0) return true; - return false; -} - - - -const bfd_arch_info_type bfd_w65_arch = -{ - 16, /* 16 bits in a word */ - 24, /* 24 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_w65, - 0, /* only 1 machine */ - "w65", /* arch_name */ - "w65", /* printable name */ - 1, - true, /* the default machine */ - bfd_default_compatible, - scan_mach, - 0, -}; diff --git a/contrib/gdb/bfd/cpu-we32k.c b/contrib/gdb/bfd/cpu-we32k.c deleted file mode 100644 index a38cbc1..0000000 --- a/contrib/gdb/bfd/cpu-we32k.c +++ /dev/null @@ -1,39 +0,0 @@ -/* bfd back-end for we32k support - Copyright (C) 1992 Free Software Foundation, Inc. - Contributed by Brendan Kehoe (brendan@cs.widener.edu). - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -const bfd_arch_info_type bfd_we32k_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_we32k, - 32000, /* only 1 machine */ - "we32k", - "we32k:32000", - 3, - true, /* the one and only */ - bfd_default_compatible, - bfd_default_scan , - 0, - }; diff --git a/contrib/gdb/bfd/cpu-z8k.c b/contrib/gdb/bfd/cpu-z8k.c deleted file mode 100644 index 5cce8eb..0000000 --- a/contrib/gdb/bfd/cpu-z8k.c +++ /dev/null @@ -1,198 +0,0 @@ -/* BFD library support routines for the Z800n architecture. - Copyright (C) 1992 Free Software Foundation, Inc. - Hacked by Steve Chamberlain of Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - - -#if 0 /* not used currently */ -/* -Relocations for the Z8K - -*/ -static bfd_reloc_status_type -howto16_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection *ignore_input_section; - bfd *ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_16 (abfd, (bfd_byte *) data + addr); - - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_16 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - - -static bfd_reloc_status_type -howto8_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection *ignore_input_section; - bfd *ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_8 (abfd, (bfd_byte *) data + addr); - - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - - -static bfd_reloc_status_type -howto8_FFnn_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection *ignore_input_section; - bfd *ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - - long x = bfd_get_8 (abfd, (bfd_byte *) data + addr); - abort (); - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - -static bfd_reloc_status_type -howto8_pcrel_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection *ignore_input_section; - bfd *ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_8 (abfd, (bfd_byte *) data + addr); - abort (); - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - - - -static reloc_howto_type howto_16 -= NEWHOWTO (howto16_callback, "abs16", 1, false, false); -static reloc_howto_type howto_8 -= NEWHOWTO (howto8_callback, "abs8", 0, false, false); - -static reloc_howto_type howto_8_FFnn -= NEWHOWTO (howto8_FFnn_callback, "ff00+abs8", 0, false, false); - -static reloc_howto_type howto_8_pcrel -= NEWHOWTO (howto8_pcrel_callback, "pcrel8", 0, false, true); - - -static reloc_howto_type * -local_bfd_reloc_type_lookup (arch, code) - const struct bfd_arch_info *arch; - bfd_reloc_code_real_type code; -{ - switch (code) - { - case BFD_RELOC_16: - return &howto_16; - case BFD_RELOC_8_FFnn: - return &howto_8_FFnn; - case BFD_RELOC_8: - return &howto_8; - case BFD_RELOC_8_PCREL: - return &howto_8_pcrel; - default: - return (reloc_howto_type *) NULL; - } -} -#endif - -int bfd_default_scan_num_mach (); - -static boolean -scan_mach (info, string) - const struct bfd_arch_info *info; - const char *string; -{ - if (strcmp (string, "z8001") == 0 || strcmp (string, "z8k") == 0) - { - return bfd_mach_z8001 == info->mach; - } - if (strcmp (string, "z8002") == 0) - { - return bfd_mach_z8002 == info->mach; - } - return false; -} - - -/* This routine is provided two arch_infos and returns whether - they'd be compatible */ - -static const bfd_arch_info_type * -compatible (a, b) - const bfd_arch_info_type *a; - const bfd_arch_info_type *b; -{ - if (a->arch != b->arch || a->mach != b->mach) - return NULL; - return a; -} - - -static const bfd_arch_info_type arch_info_struct[] = -{ - {32, 32, 8, bfd_arch_z8k, bfd_mach_z8001, "z8k", "z8001", 1, false, compatible, scan_mach, 0,}, -}; - -const bfd_arch_info_type bfd_z8k_arch = -{ - 32, 16, 8, bfd_arch_z8k, bfd_mach_z8002, "z8k", "z8002", 1, true, compatible, scan_mach, &arch_info_struct[0], -}; diff --git a/contrib/gdb/bfd/demo64.c b/contrib/gdb/bfd/demo64.c deleted file mode 100644 index c91381d..0000000 --- a/contrib/gdb/bfd/demo64.c +++ /dev/null @@ -1,24 +0,0 @@ -/* BFD backend for demonstration 64-bit a.out binaries. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - -#define ARCH_SIZE 64 -#define MY(OP) CAT(demo_64_,OP) -#define TARGETNAME "demo64" -#include "aoutf1.h" diff --git a/contrib/gdb/bfd/ecoffswap.h b/contrib/gdb/bfd/ecoffswap.h deleted file mode 100644 index 0d28d16..0000000 --- a/contrib/gdb/bfd/ecoffswap.h +++ /dev/null @@ -1,853 +0,0 @@ -/* Generic ECOFF swapping routines, for BFD. - Copyright 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - -/* NOTE: This is a header file, but it contains executable routines. - This is done this way because these routines are substantially - similar, but are not identical, for all ECOFF targets. - - These are routines to swap the ECOFF symbolic information in and - out. The routines are defined statically. You can set breakpoints - on them in gdb by naming the including source file; e.g., - 'coff-mips.c':ecoff_swap_hdr_in. - - Before including this header file, one of ECOFF_32 or ECOFF_64 must - be defined. These are checked when swapping information that - depends upon the target size. This code works for 32 bit and 64 - bit ECOFF, but may need to be generalized in the future. - - Some header file which defines the external forms of these - structures must also be included before including this header file. - Currently this is either coff/mips.h or coff/alpha.h. - - If the symbol TEST is defined when this file is compiled, a - comparison is made to ensure that, in fact, the output is - bit-for-bit the same as the input. Of course, this symbol should - only be defined when deliberately testing the code on a machine - with the proper byte sex and such. */ - -#ifdef ECOFF_32 -#define ecoff_get_off bfd_h_get_32 -#define ecoff_put_off bfd_h_put_32 -#endif -#ifdef ECOFF_64 -#define ecoff_get_off bfd_h_get_64 -#define ecoff_put_off bfd_h_put_64 -#endif - -/* ECOFF auxiliary information swapping routines. These are the same - for all ECOFF targets, so they are defined in ecofflink.c. */ - -extern void _bfd_ecoff_swap_tir_in - PARAMS ((int, const struct tir_ext *, TIR *)); -extern void _bfd_ecoff_swap_tir_out - PARAMS ((int, const TIR *, struct tir_ext *)); -extern void _bfd_ecoff_swap_rndx_in - PARAMS ((int, const struct rndx_ext *, RNDXR *)); -extern void _bfd_ecoff_swap_rndx_out - PARAMS ((int, const RNDXR *, struct rndx_ext *)); - -/* Prototypes for functions defined in this file. */ - -static void ecoff_swap_hdr_in PARAMS ((bfd *, PTR, HDRR *)); -static void ecoff_swap_hdr_out PARAMS ((bfd *, const HDRR *, PTR)); -static void ecoff_swap_fdr_in PARAMS ((bfd *, PTR, FDR *)); -static void ecoff_swap_fdr_out PARAMS ((bfd *, const FDR *, PTR)); -static void ecoff_swap_pdr_in PARAMS ((bfd *, PTR, PDR *)); -static void ecoff_swap_pdr_out PARAMS ((bfd *, const PDR *, PTR)); -static void ecoff_swap_sym_in PARAMS ((bfd *, PTR, SYMR *)); -static void ecoff_swap_sym_out PARAMS ((bfd *, const SYMR *, PTR)); -static void ecoff_swap_ext_in PARAMS ((bfd *, PTR, EXTR *)); -static void ecoff_swap_ext_out PARAMS ((bfd *, const EXTR *, PTR)); -static void ecoff_swap_rfd_in PARAMS ((bfd *, PTR, RFDT *)); -static void ecoff_swap_rfd_out PARAMS ((bfd *, const RFDT *, PTR)); -static void ecoff_swap_opt_in PARAMS ((bfd *, PTR, OPTR *)); -static void ecoff_swap_opt_out PARAMS ((bfd *, const OPTR *, PTR)); -static void ecoff_swap_dnr_in PARAMS ((bfd *, PTR, DNR *)); -static void ecoff_swap_dnr_out PARAMS ((bfd *, const DNR *, PTR)); - -/* Swap in the symbolic header. */ - -static void -ecoff_swap_hdr_in (abfd, ext_copy, intern) - bfd *abfd; - PTR ext_copy; - HDRR *intern; -{ - struct hdr_ext ext[1]; - - *ext = *(struct hdr_ext *) ext_copy; - - intern->magic = bfd_h_get_signed_16 (abfd, (bfd_byte *)ext->h_magic); - intern->vstamp = bfd_h_get_signed_16 (abfd, (bfd_byte *)ext->h_vstamp); - intern->ilineMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ilineMax); - intern->cbLine = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbLine); - intern->cbLineOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbLineOffset); - intern->idnMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_idnMax); - intern->cbDnOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbDnOffset); - intern->ipdMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ipdMax); - intern->cbPdOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbPdOffset); - intern->isymMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_isymMax); - intern->cbSymOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbSymOffset); - intern->ioptMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ioptMax); - intern->cbOptOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbOptOffset); - intern->iauxMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_iauxMax); - intern->cbAuxOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbAuxOffset); - intern->issMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_issMax); - intern->cbSsOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbSsOffset); - intern->issExtMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_issExtMax); - intern->cbSsExtOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbSsExtOffset); - intern->ifdMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_ifdMax); - intern->cbFdOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbFdOffset); - intern->crfd = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_crfd); - intern->cbRfdOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbRfdOffset); - intern->iextMax = bfd_h_get_32 (abfd, (bfd_byte *)ext->h_iextMax); - intern->cbExtOffset = ecoff_get_off (abfd, (bfd_byte *)ext->h_cbExtOffset); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out the symbolic header. */ - -static void -ecoff_swap_hdr_out (abfd, intern_copy, ext_ptr) - bfd *abfd; - const HDRR *intern_copy; - PTR ext_ptr; -{ - struct hdr_ext *ext = (struct hdr_ext *) ext_ptr; - HDRR intern[1]; - - *intern = *intern_copy; - - bfd_h_put_signed_16 (abfd, intern->magic, (bfd_byte *)ext->h_magic); - bfd_h_put_signed_16 (abfd, intern->vstamp, (bfd_byte *)ext->h_vstamp); - bfd_h_put_32 (abfd, intern->ilineMax, (bfd_byte *)ext->h_ilineMax); - ecoff_put_off (abfd, intern->cbLine, (bfd_byte *)ext->h_cbLine); - ecoff_put_off (abfd, intern->cbLineOffset, (bfd_byte *)ext->h_cbLineOffset); - bfd_h_put_32 (abfd, intern->idnMax, (bfd_byte *)ext->h_idnMax); - ecoff_put_off (abfd, intern->cbDnOffset, (bfd_byte *)ext->h_cbDnOffset); - bfd_h_put_32 (abfd, intern->ipdMax, (bfd_byte *)ext->h_ipdMax); - ecoff_put_off (abfd, intern->cbPdOffset, (bfd_byte *)ext->h_cbPdOffset); - bfd_h_put_32 (abfd, intern->isymMax, (bfd_byte *)ext->h_isymMax); - ecoff_put_off (abfd, intern->cbSymOffset, (bfd_byte *)ext->h_cbSymOffset); - bfd_h_put_32 (abfd, intern->ioptMax, (bfd_byte *)ext->h_ioptMax); - ecoff_put_off (abfd, intern->cbOptOffset, (bfd_byte *)ext->h_cbOptOffset); - bfd_h_put_32 (abfd, intern->iauxMax, (bfd_byte *)ext->h_iauxMax); - ecoff_put_off (abfd, intern->cbAuxOffset, (bfd_byte *)ext->h_cbAuxOffset); - bfd_h_put_32 (abfd, intern->issMax, (bfd_byte *)ext->h_issMax); - ecoff_put_off (abfd, intern->cbSsOffset, (bfd_byte *)ext->h_cbSsOffset); - bfd_h_put_32 (abfd, intern->issExtMax, (bfd_byte *)ext->h_issExtMax); - ecoff_put_off (abfd, intern->cbSsExtOffset, (bfd_byte *)ext->h_cbSsExtOffset); - bfd_h_put_32 (abfd, intern->ifdMax, (bfd_byte *)ext->h_ifdMax); - ecoff_put_off (abfd, intern->cbFdOffset, (bfd_byte *)ext->h_cbFdOffset); - bfd_h_put_32 (abfd, intern->crfd, (bfd_byte *)ext->h_crfd); - ecoff_put_off (abfd, intern->cbRfdOffset, (bfd_byte *)ext->h_cbRfdOffset); - bfd_h_put_32 (abfd, intern->iextMax, (bfd_byte *)ext->h_iextMax); - ecoff_put_off (abfd, intern->cbExtOffset, (bfd_byte *)ext->h_cbExtOffset); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap in the file descriptor record. */ - -static void -ecoff_swap_fdr_in (abfd, ext_copy, intern) - bfd *abfd; - PTR ext_copy; - FDR *intern; -{ - struct fdr_ext ext[1]; - - *ext = *(struct fdr_ext *) ext_copy; - - intern->adr = ecoff_get_off (abfd, (bfd_byte *)ext->f_adr); - intern->rss = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_rss); -#ifdef ECOFF_64 - if (intern->rss == 0xffffffff) - intern->rss = -1; -#endif - intern->issBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_issBase); - intern->cbSs = ecoff_get_off (abfd, (bfd_byte *)ext->f_cbSs); - intern->isymBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_isymBase); - intern->csym = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_csym); - intern->ilineBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_ilineBase); - intern->cline = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_cline); - intern->ioptBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_ioptBase); - intern->copt = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_copt); -#ifdef ECOFF_32 - intern->ipdFirst = bfd_h_get_16 (abfd, (bfd_byte *)ext->f_ipdFirst); - intern->cpd = bfd_h_get_16 (abfd, (bfd_byte *)ext->f_cpd); -#endif -#ifdef ECOFF_64 - intern->ipdFirst = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_ipdFirst); - intern->cpd = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_cpd); -#endif - intern->iauxBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_iauxBase); - intern->caux = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_caux); - intern->rfdBase = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_rfdBase); - intern->crfd = bfd_h_get_32 (abfd, (bfd_byte *)ext->f_crfd); - - /* now the fun stuff... */ - if (bfd_header_big_endian (abfd)) { - intern->lang = (ext->f_bits1[0] & FDR_BITS1_LANG_BIG) - >> FDR_BITS1_LANG_SH_BIG; - intern->fMerge = 0 != (ext->f_bits1[0] & FDR_BITS1_FMERGE_BIG); - intern->fReadin = 0 != (ext->f_bits1[0] & FDR_BITS1_FREADIN_BIG); - intern->fBigendian = 0 != (ext->f_bits1[0] & FDR_BITS1_FBIGENDIAN_BIG); - intern->glevel = (ext->f_bits2[0] & FDR_BITS2_GLEVEL_BIG) - >> FDR_BITS2_GLEVEL_SH_BIG; - } else { - intern->lang = (ext->f_bits1[0] & FDR_BITS1_LANG_LITTLE) - >> FDR_BITS1_LANG_SH_LITTLE; - intern->fMerge = 0 != (ext->f_bits1[0] & FDR_BITS1_FMERGE_LITTLE); - intern->fReadin = 0 != (ext->f_bits1[0] & FDR_BITS1_FREADIN_LITTLE); - intern->fBigendian = 0 != (ext->f_bits1[0] & FDR_BITS1_FBIGENDIAN_LITTLE); - intern->glevel = (ext->f_bits2[0] & FDR_BITS2_GLEVEL_LITTLE) - >> FDR_BITS2_GLEVEL_SH_LITTLE; - } - intern->reserved = 0; - - intern->cbLineOffset = ecoff_get_off (abfd, (bfd_byte *)ext->f_cbLineOffset); - intern->cbLine = ecoff_get_off (abfd, (bfd_byte *)ext->f_cbLine); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out the file descriptor record. */ - -static void -ecoff_swap_fdr_out (abfd, intern_copy, ext_ptr) - bfd *abfd; - const FDR *intern_copy; - PTR ext_ptr; -{ - struct fdr_ext *ext = (struct fdr_ext *) ext_ptr; - FDR intern[1]; - - *intern = *intern_copy; /* Make it reasonable to do in-place. */ - - ecoff_put_off (abfd, intern->adr, (bfd_byte *)ext->f_adr); - bfd_h_put_32 (abfd, intern->rss, (bfd_byte *)ext->f_rss); - bfd_h_put_32 (abfd, intern->issBase, (bfd_byte *)ext->f_issBase); - ecoff_put_off (abfd, intern->cbSs, (bfd_byte *)ext->f_cbSs); - bfd_h_put_32 (abfd, intern->isymBase, (bfd_byte *)ext->f_isymBase); - bfd_h_put_32 (abfd, intern->csym, (bfd_byte *)ext->f_csym); - bfd_h_put_32 (abfd, intern->ilineBase, (bfd_byte *)ext->f_ilineBase); - bfd_h_put_32 (abfd, intern->cline, (bfd_byte *)ext->f_cline); - bfd_h_put_32 (abfd, intern->ioptBase, (bfd_byte *)ext->f_ioptBase); - bfd_h_put_32 (abfd, intern->copt, (bfd_byte *)ext->f_copt); -#ifdef ECOFF_32 - bfd_h_put_16 (abfd, intern->ipdFirst, (bfd_byte *)ext->f_ipdFirst); - bfd_h_put_16 (abfd, intern->cpd, (bfd_byte *)ext->f_cpd); -#endif -#ifdef ECOFF_64 - bfd_h_put_32 (abfd, intern->ipdFirst, (bfd_byte *)ext->f_ipdFirst); - bfd_h_put_32 (abfd, intern->cpd, (bfd_byte *)ext->f_cpd); -#endif - bfd_h_put_32 (abfd, intern->iauxBase, (bfd_byte *)ext->f_iauxBase); - bfd_h_put_32 (abfd, intern->caux, (bfd_byte *)ext->f_caux); - bfd_h_put_32 (abfd, intern->rfdBase, (bfd_byte *)ext->f_rfdBase); - bfd_h_put_32 (abfd, intern->crfd, (bfd_byte *)ext->f_crfd); - - /* now the fun stuff... */ - if (bfd_header_big_endian (abfd)) { - ext->f_bits1[0] = (((intern->lang << FDR_BITS1_LANG_SH_BIG) - & FDR_BITS1_LANG_BIG) - | (intern->fMerge ? FDR_BITS1_FMERGE_BIG : 0) - | (intern->fReadin ? FDR_BITS1_FREADIN_BIG : 0) - | (intern->fBigendian ? FDR_BITS1_FBIGENDIAN_BIG : 0)); - ext->f_bits2[0] = ((intern->glevel << FDR_BITS2_GLEVEL_SH_BIG) - & FDR_BITS2_GLEVEL_BIG); - ext->f_bits2[1] = 0; - ext->f_bits2[2] = 0; - } else { - ext->f_bits1[0] = (((intern->lang << FDR_BITS1_LANG_SH_LITTLE) - & FDR_BITS1_LANG_LITTLE) - | (intern->fMerge ? FDR_BITS1_FMERGE_LITTLE : 0) - | (intern->fReadin ? FDR_BITS1_FREADIN_LITTLE : 0) - | (intern->fBigendian ? FDR_BITS1_FBIGENDIAN_LITTLE : 0)); - ext->f_bits2[0] = ((intern->glevel << FDR_BITS2_GLEVEL_SH_LITTLE) - & FDR_BITS2_GLEVEL_LITTLE); - ext->f_bits2[1] = 0; - ext->f_bits2[2] = 0; - } - - ecoff_put_off (abfd, intern->cbLineOffset, (bfd_byte *)ext->f_cbLineOffset); - ecoff_put_off (abfd, intern->cbLine, (bfd_byte *)ext->f_cbLine); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -#ifndef MPW_C - -/* Swap in the procedure descriptor record. */ - -static void -ecoff_swap_pdr_in (abfd, ext_copy, intern) - bfd *abfd; - PTR ext_copy; - PDR *intern; -{ - struct pdr_ext ext[1]; - - *ext = *(struct pdr_ext *) ext_copy; - - memset ((PTR) intern, 0, sizeof (*intern)); - - intern->adr = ecoff_get_off (abfd, (bfd_byte *)ext->p_adr); - intern->isym = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_isym); - intern->iline = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_iline); - intern->regmask = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_regmask); - intern->regoffset = bfd_h_get_signed_32 (abfd, - (bfd_byte *)ext->p_regoffset); - intern->iopt = bfd_h_get_signed_32 (abfd, (bfd_byte *)ext->p_iopt); - intern->fregmask = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_fregmask); - intern->fregoffset = bfd_h_get_signed_32 (abfd, - (bfd_byte *)ext->p_fregoffset); - intern->frameoffset = bfd_h_get_signed_32 (abfd, - (bfd_byte *)ext->p_frameoffset); - intern->framereg = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_framereg); - intern->pcreg = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_pcreg); - intern->lnLow = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnLow); - intern->lnHigh = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnHigh); - intern->cbLineOffset = ecoff_get_off (abfd, (bfd_byte *)ext->p_cbLineOffset); - -#ifdef ECOFF_64 - intern->gp_prologue = bfd_h_get_8 (abfd, (bfd_byte *) ext->p_gp_prologue); - if (bfd_header_big_endian (abfd)) - { - intern->gp_used = 0 != (ext->p_bits1[0] & PDR_BITS1_GP_USED_BIG); - intern->reg_frame = 0 != (ext->p_bits1[0] & PDR_BITS1_REG_FRAME_BIG); - intern->prof = 0 != (ext->p_bits1[0] & PDR_BITS1_PROF_BIG); - intern->reserved = (((ext->p_bits1[0] & PDR_BITS1_RESERVED_BIG) - << PDR_BITS1_RESERVED_SH_LEFT_BIG) - | ((ext->p_bits2[0] & PDR_BITS2_RESERVED_BIG) - >> PDR_BITS2_RESERVED_SH_BIG)); - } - else - { - intern->gp_used = 0 != (ext->p_bits1[0] & PDR_BITS1_GP_USED_LITTLE); - intern->reg_frame = 0 != (ext->p_bits1[0] & PDR_BITS1_REG_FRAME_LITTLE); - intern->prof = 0 != (ext->p_bits1[0] & PDR_BITS1_PROF_LITTLE); - intern->reserved = (((ext->p_bits1[0] & PDR_BITS1_RESERVED_LITTLE) - >> PDR_BITS1_RESERVED_SH_LITTLE) - | ((ext->p_bits2[0] & PDR_BITS2_RESERVED_LITTLE) - << PDR_BITS2_RESERVED_SH_LEFT_LITTLE)); - } - intern->localoff = bfd_h_get_8 (abfd, (bfd_byte *) ext->p_localoff); -#endif - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out the procedure descriptor record. */ - -static void -ecoff_swap_pdr_out (abfd, intern_copy, ext_ptr) - bfd *abfd; - const PDR *intern_copy; - PTR ext_ptr; -{ - struct pdr_ext *ext = (struct pdr_ext *) ext_ptr; - PDR intern[1]; - - *intern = *intern_copy; /* Make it reasonable to do in-place. */ - - ecoff_put_off (abfd, intern->adr, (bfd_byte *)ext->p_adr); - bfd_h_put_32 (abfd, intern->isym, (bfd_byte *)ext->p_isym); - bfd_h_put_32 (abfd, intern->iline, (bfd_byte *)ext->p_iline); - bfd_h_put_32 (abfd, intern->regmask, (bfd_byte *)ext->p_regmask); - bfd_h_put_32 (abfd, intern->regoffset, (bfd_byte *)ext->p_regoffset); - bfd_h_put_32 (abfd, intern->iopt, (bfd_byte *)ext->p_iopt); - bfd_h_put_32 (abfd, intern->fregmask, (bfd_byte *)ext->p_fregmask); - bfd_h_put_32 (abfd, intern->fregoffset, (bfd_byte *)ext->p_fregoffset); - bfd_h_put_32 (abfd, intern->frameoffset, (bfd_byte *)ext->p_frameoffset); - bfd_h_put_16 (abfd, intern->framereg, (bfd_byte *)ext->p_framereg); - bfd_h_put_16 (abfd, intern->pcreg, (bfd_byte *)ext->p_pcreg); - bfd_h_put_32 (abfd, intern->lnLow, (bfd_byte *)ext->p_lnLow); - bfd_h_put_32 (abfd, intern->lnHigh, (bfd_byte *)ext->p_lnHigh); - ecoff_put_off (abfd, intern->cbLineOffset, (bfd_byte *)ext->p_cbLineOffset); - -#ifdef ECOFF_64 - bfd_h_put_8 (abfd, intern->gp_prologue, (bfd_byte *) ext->p_gp_prologue); - if (bfd_header_big_endian (abfd)) - { - ext->p_bits1[0] = ((intern->gp_used ? PDR_BITS1_GP_USED_BIG : 0) - | (intern->reg_frame ? PDR_BITS1_REG_FRAME_BIG : 0) - | (intern->prof ? PDR_BITS1_PROF_BIG : 0) - | ((intern->reserved - >> PDR_BITS1_RESERVED_SH_LEFT_BIG) - & PDR_BITS1_RESERVED_BIG)); - ext->p_bits2[0] = ((intern->reserved << PDR_BITS2_RESERVED_SH_BIG) - & PDR_BITS2_RESERVED_BIG); - } - else - { - ext->p_bits1[0] = ((intern->gp_used ? PDR_BITS1_GP_USED_LITTLE : 0) - | (intern->reg_frame ? PDR_BITS1_REG_FRAME_LITTLE : 0) - | (intern->prof ? PDR_BITS1_PROF_LITTLE : 0) - | ((intern->reserved << PDR_BITS1_RESERVED_SH_LITTLE) - & PDR_BITS1_RESERVED_LITTLE)); - ext->p_bits2[0] = ((intern->reserved >> - PDR_BITS2_RESERVED_SH_LEFT_LITTLE) - & PDR_BITS2_RESERVED_LITTLE); - } - bfd_h_put_8 (abfd, intern->localoff, (bfd_byte *) ext->p_localoff); -#endif - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -#else /* MPW_C */ -/* Same routines, but with ECOFF_64 code removed, so ^&%$#&! MPW C doesn't - corrupt itself and then freak out. */ -/* Swap in the procedure descriptor record. */ - -static void -ecoff_swap_pdr_in (abfd, ext_copy, intern) - bfd *abfd; - PTR ext_copy; - PDR *intern; -{ - struct pdr_ext ext[1]; - - *ext = *(struct pdr_ext *) ext_copy; - - intern->adr = ecoff_get_off (abfd, (bfd_byte *)ext->p_adr); - intern->isym = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_isym); - intern->iline = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_iline); - intern->regmask = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_regmask); - intern->regoffset = bfd_h_get_signed_32 (abfd, - (bfd_byte *)ext->p_regoffset); - intern->iopt = bfd_h_get_signed_32 (abfd, (bfd_byte *)ext->p_iopt); - intern->fregmask = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_fregmask); - intern->fregoffset = bfd_h_get_signed_32 (abfd, - (bfd_byte *)ext->p_fregoffset); - intern->frameoffset = bfd_h_get_signed_32 (abfd, - (bfd_byte *)ext->p_frameoffset); - intern->framereg = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_framereg); - intern->pcreg = bfd_h_get_16 (abfd, (bfd_byte *)ext->p_pcreg); - intern->lnLow = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnLow); - intern->lnHigh = bfd_h_get_32 (abfd, (bfd_byte *)ext->p_lnHigh); - intern->cbLineOffset = ecoff_get_off (abfd, (bfd_byte *)ext->p_cbLineOffset); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out the procedure descriptor record. */ - -static void -ecoff_swap_pdr_out (abfd, intern_copy, ext_ptr) - bfd *abfd; - const PDR *intern_copy; - PTR ext_ptr; -{ - struct pdr_ext *ext = (struct pdr_ext *) ext_ptr; - PDR intern[1]; - - *intern = *intern_copy; /* Make it reasonable to do in-place. */ - - ecoff_put_off (abfd, intern->adr, (bfd_byte *)ext->p_adr); - bfd_h_put_32 (abfd, intern->isym, (bfd_byte *)ext->p_isym); - bfd_h_put_32 (abfd, intern->iline, (bfd_byte *)ext->p_iline); - bfd_h_put_32 (abfd, intern->regmask, (bfd_byte *)ext->p_regmask); - bfd_h_put_32 (abfd, intern->regoffset, (bfd_byte *)ext->p_regoffset); - bfd_h_put_32 (abfd, intern->iopt, (bfd_byte *)ext->p_iopt); - bfd_h_put_32 (abfd, intern->fregmask, (bfd_byte *)ext->p_fregmask); - bfd_h_put_32 (abfd, intern->fregoffset, (bfd_byte *)ext->p_fregoffset); - bfd_h_put_32 (abfd, intern->frameoffset, (bfd_byte *)ext->p_frameoffset); - bfd_h_put_16 (abfd, intern->framereg, (bfd_byte *)ext->p_framereg); - bfd_h_put_16 (abfd, intern->pcreg, (bfd_byte *)ext->p_pcreg); - bfd_h_put_32 (abfd, intern->lnLow, (bfd_byte *)ext->p_lnLow); - bfd_h_put_32 (abfd, intern->lnHigh, (bfd_byte *)ext->p_lnHigh); - ecoff_put_off (abfd, intern->cbLineOffset, (bfd_byte *)ext->p_cbLineOffset); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} -#endif /* MPW_C */ - -/* Swap in a symbol record. */ - -static void -ecoff_swap_sym_in (abfd, ext_copy, intern) - bfd *abfd; - PTR ext_copy; - SYMR *intern; -{ - struct sym_ext ext[1]; - - *ext = *(struct sym_ext *) ext_copy; - - intern->iss = bfd_h_get_32 (abfd, (bfd_byte *)ext->s_iss); - intern->value = ecoff_get_off (abfd, (bfd_byte *)ext->s_value); - - /* now the fun stuff... */ - if (bfd_header_big_endian (abfd)) { - intern->st = (ext->s_bits1[0] & SYM_BITS1_ST_BIG) - >> SYM_BITS1_ST_SH_BIG; - intern->sc = ((ext->s_bits1[0] & SYM_BITS1_SC_BIG) - << SYM_BITS1_SC_SH_LEFT_BIG) - | ((ext->s_bits2[0] & SYM_BITS2_SC_BIG) - >> SYM_BITS2_SC_SH_BIG); - intern->reserved = 0 != (ext->s_bits2[0] & SYM_BITS2_RESERVED_BIG); - intern->index = ((ext->s_bits2[0] & SYM_BITS2_INDEX_BIG) - << SYM_BITS2_INDEX_SH_LEFT_BIG) - | (ext->s_bits3[0] << SYM_BITS3_INDEX_SH_LEFT_BIG) - | (ext->s_bits4[0] << SYM_BITS4_INDEX_SH_LEFT_BIG); - } else { - intern->st = (ext->s_bits1[0] & SYM_BITS1_ST_LITTLE) - >> SYM_BITS1_ST_SH_LITTLE; - intern->sc = ((ext->s_bits1[0] & SYM_BITS1_SC_LITTLE) - >> SYM_BITS1_SC_SH_LITTLE) - | ((ext->s_bits2[0] & SYM_BITS2_SC_LITTLE) - << SYM_BITS2_SC_SH_LEFT_LITTLE); - intern->reserved = 0 != (ext->s_bits2[0] & SYM_BITS2_RESERVED_LITTLE); - intern->index = ((ext->s_bits2[0] & SYM_BITS2_INDEX_LITTLE) - >> SYM_BITS2_INDEX_SH_LITTLE) - | (ext->s_bits3[0] << SYM_BITS3_INDEX_SH_LEFT_LITTLE) - | ((unsigned int) ext->s_bits4[0] - << SYM_BITS4_INDEX_SH_LEFT_LITTLE); - } - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out a symbol record. */ - -static void -ecoff_swap_sym_out (abfd, intern_copy, ext_ptr) - bfd *abfd; - const SYMR *intern_copy; - PTR ext_ptr; -{ - struct sym_ext *ext = (struct sym_ext *) ext_ptr; - SYMR intern[1]; - - *intern = *intern_copy; /* Make it reasonable to do in-place. */ - - bfd_h_put_32 (abfd, intern->iss, (bfd_byte *)ext->s_iss); - ecoff_put_off (abfd, intern->value, (bfd_byte *)ext->s_value); - - /* now the fun stuff... */ - if (bfd_header_big_endian (abfd)) { - ext->s_bits1[0] = (((intern->st << SYM_BITS1_ST_SH_BIG) - & SYM_BITS1_ST_BIG) - | ((intern->sc >> SYM_BITS1_SC_SH_LEFT_BIG) - & SYM_BITS1_SC_BIG)); - ext->s_bits2[0] = (((intern->sc << SYM_BITS2_SC_SH_BIG) - & SYM_BITS2_SC_BIG) - | (intern->reserved ? SYM_BITS2_RESERVED_BIG : 0) - | ((intern->index >> SYM_BITS2_INDEX_SH_LEFT_BIG) - & SYM_BITS2_INDEX_BIG)); - ext->s_bits3[0] = (intern->index >> SYM_BITS3_INDEX_SH_LEFT_BIG) & 0xff; - ext->s_bits4[0] = (intern->index >> SYM_BITS4_INDEX_SH_LEFT_BIG) & 0xff; - } else { - ext->s_bits1[0] = (((intern->st << SYM_BITS1_ST_SH_LITTLE) - & SYM_BITS1_ST_LITTLE) - | ((intern->sc << SYM_BITS1_SC_SH_LITTLE) - & SYM_BITS1_SC_LITTLE)); - ext->s_bits2[0] = (((intern->sc >> SYM_BITS2_SC_SH_LEFT_LITTLE) - & SYM_BITS2_SC_LITTLE) - | (intern->reserved ? SYM_BITS2_RESERVED_LITTLE : 0) - | ((intern->index << SYM_BITS2_INDEX_SH_LITTLE) - & SYM_BITS2_INDEX_LITTLE)); - ext->s_bits3[0] = (intern->index >> SYM_BITS3_INDEX_SH_LEFT_LITTLE) & 0xff; - ext->s_bits4[0] = (intern->index >> SYM_BITS4_INDEX_SH_LEFT_LITTLE) & 0xff; - } - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap in an external symbol record. */ - -static void -ecoff_swap_ext_in (abfd, ext_copy, intern) - bfd *abfd; - PTR ext_copy; - EXTR *intern; -{ - struct ext_ext ext[1]; - - *ext = *(struct ext_ext *) ext_copy; - - /* now the fun stuff... */ - if (bfd_header_big_endian (abfd)) { - intern->jmptbl = 0 != (ext->es_bits1[0] & EXT_BITS1_JMPTBL_BIG); - intern->cobol_main = 0 != (ext->es_bits1[0] & EXT_BITS1_COBOL_MAIN_BIG); - intern->weakext = 0 != (ext->es_bits1[0] & EXT_BITS1_WEAKEXT_BIG); - } else { - intern->jmptbl = 0 != (ext->es_bits1[0] & EXT_BITS1_JMPTBL_LITTLE); - intern->cobol_main = 0 != (ext->es_bits1[0] & EXT_BITS1_COBOL_MAIN_LITTLE); - intern->weakext = 0 != (ext->es_bits1[0] & EXT_BITS1_WEAKEXT_LITTLE); - } - intern->reserved = 0; - -#ifdef ECOFF_32 - intern->ifd = bfd_h_get_signed_16 (abfd, (bfd_byte *)ext->es_ifd); -#endif -#ifdef ECOFF_64 - intern->ifd = bfd_h_get_signed_32 (abfd, (bfd_byte *)ext->es_ifd); -#endif - - ecoff_swap_sym_in (abfd, &ext->es_asym, &intern->asym); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out an external symbol record. */ - -static void -ecoff_swap_ext_out (abfd, intern_copy, ext_ptr) - bfd *abfd; - const EXTR *intern_copy; - PTR ext_ptr; -{ - struct ext_ext *ext = (struct ext_ext *) ext_ptr; - EXTR intern[1]; - - *intern = *intern_copy; /* Make it reasonable to do in-place. */ - - /* now the fun stuff... */ - if (bfd_header_big_endian (abfd)) { - ext->es_bits1[0] = ((intern->jmptbl ? EXT_BITS1_JMPTBL_BIG : 0) - | (intern->cobol_main ? EXT_BITS1_COBOL_MAIN_BIG : 0) - | (intern->weakext ? EXT_BITS1_WEAKEXT_BIG : 0)); - ext->es_bits2[0] = 0; -#ifdef ECOFF_64 - ext->es_bits2[1] = 0; - ext->es_bits2[2] = 0; -#endif - } else { - ext->es_bits1[0] = ((intern->jmptbl ? EXT_BITS1_JMPTBL_LITTLE : 0) - | (intern->cobol_main ? EXT_BITS1_COBOL_MAIN_LITTLE : 0) - | (intern->weakext ? EXT_BITS1_WEAKEXT_LITTLE : 0)); - ext->es_bits2[0] = 0; -#ifdef ECOFF_64 - ext->es_bits2[1] = 0; - ext->es_bits2[2] = 0; -#endif - } - -#ifdef ECOFF_32 - bfd_h_put_signed_16 (abfd, intern->ifd, (bfd_byte *)ext->es_ifd); -#endif -#ifdef ECOFF_64 - bfd_h_put_signed_32 (abfd, intern->ifd, (bfd_byte *)ext->es_ifd); -#endif - - ecoff_swap_sym_out (abfd, &intern->asym, &ext->es_asym); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap in a relative file descriptor. */ - -static void -ecoff_swap_rfd_in (abfd, ext_ptr, intern) - bfd *abfd; - PTR ext_ptr; - RFDT *intern; -{ - struct rfd_ext *ext = (struct rfd_ext *) ext_ptr; - - *intern = bfd_h_get_32 (abfd, (bfd_byte *)ext->rfd); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out a relative file descriptor. */ - -static void -ecoff_swap_rfd_out (abfd, intern, ext_ptr) - bfd *abfd; - const RFDT *intern; - PTR ext_ptr; -{ - struct rfd_ext *ext = (struct rfd_ext *) ext_ptr; - - bfd_h_put_32 (abfd, *intern, (bfd_byte *)ext->rfd); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap in an optimization symbol. */ - -static void -ecoff_swap_opt_in (abfd, ext_copy, intern) - bfd *abfd; - PTR ext_copy; - OPTR *intern; -{ - struct opt_ext ext[1]; - - *ext = *(struct opt_ext *) ext_copy; - - if (bfd_header_big_endian (abfd)) - { - intern->ot = ext->o_bits1[0]; - intern->value = (((unsigned int) ext->o_bits2[0] - << OPT_BITS2_VALUE_SH_LEFT_BIG) - | ((unsigned int) ext->o_bits3[0] - << OPT_BITS2_VALUE_SH_LEFT_BIG) - | ((unsigned int) ext->o_bits4[0] - << OPT_BITS2_VALUE_SH_LEFT_BIG)); - } - else - { - intern->ot = ext->o_bits1[0]; - intern->value = ((ext->o_bits2[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE) - | (ext->o_bits3[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE) - | (ext->o_bits4[0] << OPT_BITS2_VALUE_SH_LEFT_LITTLE)); - } - - _bfd_ecoff_swap_rndx_in (bfd_header_big_endian (abfd), - &ext->o_rndx, &intern->rndx); - - intern->offset = bfd_h_get_32 (abfd, (bfd_byte *) ext->o_offset); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out an optimization symbol. */ - -static void -ecoff_swap_opt_out (abfd, intern_copy, ext_ptr) - bfd *abfd; - const OPTR *intern_copy; - PTR ext_ptr; -{ - struct opt_ext *ext = (struct opt_ext *) ext_ptr; - OPTR intern[1]; - - *intern = *intern_copy; /* Make it reasonable to do in-place. */ - - if (bfd_header_big_endian (abfd)) - { - ext->o_bits1[0] = intern->ot; - ext->o_bits2[0] = intern->value >> OPT_BITS2_VALUE_SH_LEFT_BIG; - ext->o_bits3[0] = intern->value >> OPT_BITS3_VALUE_SH_LEFT_BIG; - ext->o_bits4[0] = intern->value >> OPT_BITS4_VALUE_SH_LEFT_BIG; - } - else - { - ext->o_bits1[0] = intern->ot; - ext->o_bits2[0] = intern->value >> OPT_BITS2_VALUE_SH_LEFT_LITTLE; - ext->o_bits3[0] = intern->value >> OPT_BITS3_VALUE_SH_LEFT_LITTLE; - ext->o_bits4[0] = intern->value >> OPT_BITS4_VALUE_SH_LEFT_LITTLE; - } - - _bfd_ecoff_swap_rndx_out (bfd_header_big_endian (abfd), - &intern->rndx, &ext->o_rndx); - - bfd_h_put_32 (abfd, intern->value, (bfd_byte *) ext->o_offset); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap in a dense number. */ - -static void -ecoff_swap_dnr_in (abfd, ext_copy, intern) - bfd *abfd; - PTR ext_copy; - DNR *intern; -{ - struct dnr_ext ext[1]; - - *ext = *(struct dnr_ext *) ext_copy; - - intern->rfd = bfd_h_get_32 (abfd, (bfd_byte *) ext->d_rfd); - intern->index = bfd_h_get_32 (abfd, (bfd_byte *) ext->d_index); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out a dense number. */ - -static void -ecoff_swap_dnr_out (abfd, intern_copy, ext_ptr) - bfd *abfd; - const DNR *intern_copy; - PTR ext_ptr; -{ - struct dnr_ext *ext = (struct dnr_ext *) ext_ptr; - DNR intern[1]; - - *intern = *intern_copy; /* Make it reasonable to do in-place. */ - - bfd_h_put_32 (abfd, intern->rfd, (bfd_byte *) ext->d_rfd); - bfd_h_put_32 (abfd, intern->index, (bfd_byte *) ext->d_index); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} diff --git a/contrib/gdb/bfd/elf32-gen.c b/contrib/gdb/bfd/elf32-gen.c deleted file mode 100644 index 385fda2..0000000 --- a/contrib/gdb/bfd/elf32-gen.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Generic support for 32-bit ELF - Copyright 1993 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "elf-bfd.h" - -/* This does not include any relocations, but should be good enough - for GDB to read the file. */ - -#define TARGET_LITTLE_SYM bfd_elf32_little_generic_vec -#define TARGET_LITTLE_NAME "elf32-little" -#define TARGET_BIG_SYM bfd_elf32_big_generic_vec -#define TARGET_BIG_NAME "elf32-big" -#define ELF_ARCH bfd_arch_unknown -#define ELF_MACHINE_CODE EM_NONE -#define bfd_elf32_bfd_reloc_type_lookup bfd_default_reloc_type_lookup -#define elf_info_to_howto _bfd_elf_no_info_to_howto - -#include "elf32-target.h" diff --git a/contrib/gdb/bfd/elf32-hppa.c b/contrib/gdb/bfd/elf32-hppa.c deleted file mode 100644 index 2386731..0000000 --- a/contrib/gdb/bfd/elf32-hppa.c +++ /dev/null @@ -1,2984 +0,0 @@ -/* BFD back-end for HP PA-RISC ELF files. - Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc. - - Written by - - Center for Software Science - Department of Computer Science - University of Utah - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "obstack.h" -#include "elf-bfd.h" - -/* The internal type of a symbol table extension entry. */ -typedef unsigned long symext_entryS; - -/* The external type of a symbol table extension entry. */ -#define ELF32_PARISC_SX_SIZE (4) -#define ELF32_PARISC_SX_GET(bfd, addr) bfd_h_get_32 ((bfd), (addr)) -#define ELF32_PARISC_SX_PUT(bfd, val, addr) \ - bfd_h_put_32 ((bfd), (val), (addr)) - -/* HPPA symbol table extension entry types */ -enum elf32_hppa_symextn_types -{ - PARISC_SXT_NULL, - PARISC_SXT_SYMNDX, - PARISC_SXT_ARG_RELOC, -}; - -/* These macros compose and decompose the value of a symextn entry: - - entry_type = ELF32_PARISC_SX_TYPE(word); - entry_value = ELF32_PARISC_SX_VAL(word); - word = ELF32_PARISC_SX_WORD(type,val); */ - -#define ELF32_PARISC_SX_TYPE(p) ((p) >> 24) -#define ELF32_PARISC_SX_VAL(p) ((p) & 0xFFFFFF) -#define ELF32_PARISC_SX_WORD(type,val) (((type) << 24) + (val & 0xFFFFFF)) - -/* The following was added facilitate implementation of the .hppa_symextn - section. This section is built after the symbol table is built in the - elf_write_object_contents routine (called from bfd_close). It is built - so late because it requires information that is not known until - the symbol and string table sections have been allocated, and - the symbol table has been built. */ - -#define SYMEXTN_SECTION_NAME ".PARISC.symext" - -struct symext_chain - { - symext_entryS entry; - struct symext_chain *next; - }; - -typedef struct symext_chain symext_chainS; - -/* We use three different hash tables to hold information for - linking PA ELF objects. - - The first is the elf32_hppa_link_hash_table which is derived - from the standard ELF linker hash table. We use this as a place to - attach other hash tables and static information. - - The second is the stub hash table which is derived from the - base BFD hash table. The stub hash table holds the information - necessary to build the linker stubs during a link. - - The last hash table keeps track of argument location information needed - to build hash tables. Each function with nonzero argument location - bits will have an entry in this table. */ - -/* Hash table for linker stubs. */ - -struct elf32_hppa_stub_hash_entry -{ - /* Base hash table entry structure, we can get the name of the stub - (and thus know exactly what actions it performs) from the base - hash table entry. */ - struct bfd_hash_entry root; - - /* Offset of the beginning of this stub. */ - bfd_vma offset; - - /* Given the symbol's value and its section we can determine its final - value when building the stubs (so the stub knows where to jump. */ - symvalue target_value; - asection *target_section; -}; - -struct elf32_hppa_stub_hash_table -{ - /* The hash table itself. */ - struct bfd_hash_table root; - - /* The stub BFD. */ - bfd *stub_bfd; - - /* Where to place the next stub. */ - bfd_byte *location; - - /* Current offset in the stub section. */ - unsigned int offset; - -}; - -/* Hash table for argument location information. */ - -struct elf32_hppa_args_hash_entry -{ - /* Base hash table entry structure. */ - struct bfd_hash_entry root; - - /* The argument location bits for this entry. */ - int arg_bits; -}; - -struct elf32_hppa_args_hash_table -{ - /* The hash table itself. */ - struct bfd_hash_table root; -}; - -struct elf32_hppa_link_hash_entry -{ - struct elf_link_hash_entry root; -}; - -struct elf32_hppa_link_hash_table -{ - /* The main hash table. */ - struct elf_link_hash_table root; - - /* The stub hash table. */ - struct elf32_hppa_stub_hash_table *stub_hash_table; - - /* The argument relocation bits hash table. */ - struct elf32_hppa_args_hash_table *args_hash_table; - - /* A count of the number of output symbols. */ - unsigned int output_symbol_count; - - /* Stuff so we can handle DP relative relocations. */ - long global_value; - int global_sym_defined; -}; - -/* FIXME. */ -#define ARGUMENTS 0 -#define RETURN_VALUE 1 - -/* The various argument relocations that may be performed. */ -typedef enum -{ - /* No relocation. */ - NO, - /* Relocate 32 bits from GR to FP register. */ - GF, - /* Relocate 64 bits from a GR pair to FP pair. */ - GD, - /* Relocate 32 bits from FP to GR. */ - FG, - /* Relocate 64 bits from FP pair to GR pair. */ - DG, -} arg_reloc_type; - -/* What is being relocated (eg which argument or the return value). */ -typedef enum -{ - ARG0, ARG1, ARG2, ARG3, RET, -} arg_reloc_location; - - -/* ELF32/HPPA relocation support - - This file contains ELF32/HPPA relocation support as specified - in the Stratus FTX/Golf Object File Format (SED-1762) dated - February 1994. */ - -#include "elf32-hppa.h" -#include "hppa_stubs.h" - -static bfd_reloc_status_type hppa_elf_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); - -static unsigned long hppa_elf_relocate_insn - PARAMS ((bfd *, asection *, unsigned long, unsigned long, long, - long, unsigned long, unsigned long, unsigned long)); - -static bfd_reloc_status_type hppa_elf_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd*, char **)); - -static reloc_howto_type * elf_hppa_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); - -static boolean elf32_hppa_set_section_contents - PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type)); - -static void elf_info_to_howto - PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *)); - -static boolean elf32_hppa_backend_symbol_table_processing - PARAMS ((bfd *, elf_symbol_type *, unsigned int)); - -static void elf32_hppa_backend_begin_write_processing - PARAMS ((bfd *, struct bfd_link_info *)); - -static void elf32_hppa_backend_final_write_processing - PARAMS ((bfd *, boolean)); - -static void add_entry_to_symext_chain - PARAMS ((bfd *, unsigned int, unsigned int, symext_chainS **, - symext_chainS **)); - -static void -elf_hppa_tc_make_sections PARAMS ((bfd *, symext_chainS *)); - -static boolean hppa_elf_is_local_label PARAMS ((bfd *, asymbol *)); - -static boolean elf32_hppa_add_symbol_hook - PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, - const char **, flagword *, asection **, bfd_vma *)); - -static bfd_reloc_status_type elf32_hppa_bfd_final_link_relocate - PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *, - bfd_byte *, bfd_vma, bfd_vma, bfd_vma, struct bfd_link_info *, - asection *, const char *, int)); - -static struct bfd_link_hash_table *elf32_hppa_link_hash_table_create - PARAMS ((bfd *)); - -static struct bfd_hash_entry * -elf32_hppa_stub_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); - -static struct bfd_hash_entry * -elf32_hppa_args_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); - -static boolean -elf32_hppa_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, - bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); - -static boolean -elf32_hppa_stub_hash_table_init - PARAMS ((struct elf32_hppa_stub_hash_table *, bfd *, - struct bfd_hash_entry *(*) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)))); - -static boolean -elf32_hppa_build_one_stub PARAMS ((struct bfd_hash_entry *, PTR)); - -static boolean -elf32_hppa_read_symext_info - PARAMS ((bfd *, Elf_Internal_Shdr *, struct elf32_hppa_args_hash_table *, - Elf_Internal_Sym *)); - -static unsigned int elf32_hppa_size_of_stub - PARAMS ((unsigned int, unsigned int, bfd_vma, bfd_vma, const char *)); - -static boolean elf32_hppa_arg_reloc_needed - PARAMS ((unsigned int, unsigned int, arg_reloc_type [])); - -static void elf32_hppa_name_of_stub - PARAMS ((unsigned int, unsigned int, bfd_vma, bfd_vma, char *)); - -static boolean elf32_hppa_size_symext PARAMS ((struct bfd_hash_entry *, PTR)); - -static boolean elf32_hppa_link_output_symbol_hook - PARAMS ((bfd *, struct bfd_link_info *, const char *, - Elf_Internal_Sym *, asection *)); - -/* ELF/PA relocation howto entries. */ - -static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = -{ - {R_PARISC_NONE, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_NONE"}, - {R_PARISC_DIR32, 0, 0, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR32"}, - {R_PARISC_DIR21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR21L"}, - {R_PARISC_DIR17R, 0, 0, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR17R"}, - {R_PARISC_DIR17F, 0, 0, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR17F"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_DIR14R, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR14R"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_PCREL21L, 0, 0, 21, true, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PCREL21L"}, - {R_PARISC_PCREL17R, 0, 0, 17, true, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PCREL17R"}, - {R_PARISC_PCREL17F, 0, 0, 17, true, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PCREL17F"}, - {R_PARISC_PCREL17C, 0, 0, 17, true, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PCREL17C"}, - {R_PARISC_PCREL14R, 0, 0, 14, true, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PCREL14R"}, - {R_PARISC_PCREL14F, 0, 0, 14, true, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PCREL14F"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_DPREL21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DPREL21L"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_DPREL14R, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DPREL14R"}, - {R_PARISC_DPREL14F, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DPREL14F"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_DLTREL21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DLTREL21L"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_DLTREL14R, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DLTREL14R"}, - {R_PARISC_DLTREL14F, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DLTREL14F"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_DLTIND21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DLTIND21L"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_DLTIND14R, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DLTIND14R"}, - {R_PARISC_DLTIND14F, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DLTIND14F"}, - - {R_PARISC_SETBASE, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_SETBASE"}, - {R_PARISC_BASEREL32, 0, 0, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_BASEREL32"}, - {R_PARISC_BASEREL21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_BASEREL21L"}, - {R_PARISC_BASEREL17R, 0, 0, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_BASEREL17R"}, - {R_PARISC_BASEREL17F, 0, 0, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_BASEREL17F"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_BASEREL14R, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_BASEREL14R"}, - {R_PARISC_BASEREL14F, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_BASEREL14F"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_TEXTREL32, 0, 0, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_TEXTREL32"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_DATAREL32, 0, 0, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_PLABEL32, 0, 0, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PLABEL32"}, - {R_PARISC_PLABEL21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PLABEL21L"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_PLABEL14R, 0, 0, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PLABEL14R"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_PLTIND21L, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PLTIND21L"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_UNIMPLEMENTED"}, - {R_PARISC_PLTIND14R, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PLTIND14R"}, - {R_PARISC_PLTIND14F, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_PLTIND14F"}, - - - {R_PARISC_COPY, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_COPY"}, - {R_PARISC_GLOB_DAT, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_GLOB_DAT"}, - {R_PARISC_JMP_SLOT, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_JMP_SLOT"}, - {R_PARISC_RELATIVE, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_RELATIVE"}, - - {R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_PARISC_UNIMPLEMENTED"}, -}; - -/* Where (what register type) is an argument comming from? */ -typedef enum -{ - AR_NO, - AR_GR, - AR_FR, - AR_FU, - AR_FPDBL1, - AR_FPDBL2, -} arg_location; - -/* Horizontal represents the callee's argument location information, - vertical represents caller's argument location information. Value at a - particular X,Y location represents what (if any) argument relocation - needs to be performed to make caller and callee agree. */ - -static CONST arg_reloc_type arg_mismatches[6][6] = -{ - {NO, NO, NO, NO, NO, NO}, - {NO, NO, GF, NO, GD, NO}, - {NO, FG, NO, NO, NO, NO}, - {NO, NO, NO, NO, NO, NO}, - {NO, DG, NO, NO, NO, NO}, - {NO, DG, NO, NO, NO, NO}, -}; - -/* Likewise, but reversed for the return value. */ -static CONST arg_reloc_type ret_mismatches[6][6] = -{ - {NO, NO, NO, NO, NO, NO}, - {NO, NO, FG, NO, DG, NO}, - {NO, GF, NO, NO, NO, NO}, - {NO, NO, NO, NO, NO, NO}, - {NO, GD, NO, NO, NO, NO}, - {NO, GD, NO, NO, NO, NO}, -}; - -/* Misc static crud for symbol extension records. */ -static symext_chainS *symext_rootP; -static symext_chainS *symext_lastP; -static bfd_size_type symext_chain_size; - -/* FIXME: We should be able to try this static variable! */ -static bfd_byte *symextn_contents; - - -/* For linker stub hash tables. */ -#define elf32_hppa_stub_hash_lookup(table, string, create, copy) \ - ((struct elf32_hppa_stub_hash_entry *) \ - bfd_hash_lookup (&(table)->root, (string), (create), (copy))) - -#define elf32_hppa_stub_hash_traverse(table, func, info) \ - (bfd_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \ - (info))) - -/* For linker args hash tables. */ -#define elf32_hppa_args_hash_lookup(table, string, create, copy) \ - ((struct elf32_hppa_args_hash_entry *) \ - bfd_hash_lookup (&(table)->root, (string), (create), (copy))) - -#define elf32_hppa_args_hash_traverse(table, func, info) \ - (bfd_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \ - (info))) - -#define elf32_hppa_args_hash_table_init(table, newfunc) \ - (bfd_hash_table_init \ - (&(table)->root, \ - (struct bfd_hash_entry *(*) PARAMS ((struct bfd_hash_entry *, \ - struct bfd_hash_table *, \ - const char *))) (newfunc))) - -/* For HPPA linker hash table. */ - -#define elf32_hppa_link_hash_lookup(table, string, create, copy, follow)\ - ((struct elf32_hppa_link_hash_entry *) \ - elf_link_hash_lookup (&(table)->root, (string), (create), \ - (copy), (follow))) - -#define elf32_hppa_link_hash_traverse(table, func, info) \ - (elf_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the PA ELF linker hash table from a link_info structure. */ - -#define elf32_hppa_hash_table(p) \ - ((struct elf32_hppa_link_hash_table *) ((p)->hash)) - - -/* Extract specific argument location bits for WHICH from - the full argument location in AR. */ -#define EXTRACT_ARBITS(ar, which) ((ar) >> (8 - ((which) * 2))) & 3 - -/* Assorted hash table functions. */ - -/* Initialize an entry in the stub hash table. */ - -static struct bfd_hash_entry * -elf32_hppa_stub_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct elf32_hppa_stub_hash_entry *ret; - - ret = (struct elf32_hppa_stub_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == NULL) - ret = ((struct elf32_hppa_stub_hash_entry *) - bfd_hash_allocate (table, - sizeof (struct elf32_hppa_stub_hash_entry))); - if (ret == NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = ((struct elf32_hppa_stub_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - - if (ret) - { - /* Initialize the local fields. */ - ret->offset = 0; - ret->target_value = 0; - ret->target_section = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Initialize a stub hash table. */ - -static boolean -elf32_hppa_stub_hash_table_init (table, stub_bfd, newfunc) - struct elf32_hppa_stub_hash_table *table; - bfd *stub_bfd; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); -{ - table->offset = 0; - table->location = 0; - table->stub_bfd = stub_bfd; - return (bfd_hash_table_init (&table->root, newfunc)); -} - -/* Initialize an entry in the argument location hash table. */ - -static struct bfd_hash_entry * -elf32_hppa_args_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct elf32_hppa_args_hash_entry *ret; - - ret = (struct elf32_hppa_args_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == NULL) - ret = ((struct elf32_hppa_args_hash_entry *) - bfd_hash_allocate (table, - sizeof (struct elf32_hppa_args_hash_entry))); - if (ret == NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = ((struct elf32_hppa_args_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - - /* Initialize the local fields. */ - if (ret) - ret->arg_bits = 0; - - return (struct bfd_hash_entry *) ret; -} - -/* Create the derived linker hash table. The PA ELF port uses the derived - hash table to keep information specific to the PA ELF linker (without - using static variables). */ - -static struct bfd_link_hash_table * -elf32_hppa_link_hash_table_create (abfd) - bfd *abfd; -{ - struct elf32_hppa_link_hash_table *ret; - - ret = ((struct elf32_hppa_link_hash_table *) - bfd_alloc (abfd, sizeof (struct elf32_hppa_link_hash_table))); - if (ret == NULL) - return NULL; - if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, - _bfd_elf_link_hash_newfunc)) - { - bfd_release (abfd, ret); - return NULL; - } - ret->stub_hash_table = NULL; - ret->args_hash_table = NULL; - ret->output_symbol_count = 0; - ret->global_value = 0; - ret->global_sym_defined = 0; - - return &ret->root.root; -} - -/* Relocate the given INSN given the various input parameters. - - FIXME: endianness and sizeof (long) issues abound here. */ - -static unsigned long -hppa_elf_relocate_insn (abfd, input_sect, insn, address, sym_value, - r_addend, r_format, r_field, pcrel) - bfd *abfd; - asection *input_sect; - unsigned long insn; - unsigned long address; - long sym_value; - long r_addend; - unsigned long r_format; - unsigned long r_field; - unsigned long pcrel; -{ - unsigned char opcode = get_opcode (insn); - long constant_value; - - switch (opcode) - { - case LDO: - case LDB: - case LDH: - case LDW: - case LDWM: - case STB: - case STH: - case STW: - case STWM: - case COMICLR: - case SUBI: - case ADDIT: - case ADDI: - case LDIL: - case ADDIL: - constant_value = HPPA_R_CONSTANT (r_addend); - - if (pcrel) - sym_value -= address; - - sym_value = hppa_field_adjust (sym_value, constant_value, r_field); - return hppa_rebuild_insn (abfd, insn, sym_value, r_format); - - case BL: - case BE: - case BLE: - /* XXX computing constant_value is not needed??? */ - constant_value = assemble_17 ((insn & 0x001f0000) >> 16, - (insn & 0x00001ffc) >> 2, - insn & 1); - - constant_value = (constant_value << 15) >> 15; - if (pcrel) - { - sym_value -= - address + input_sect->output_offset - + input_sect->output_section->vma; - sym_value = hppa_field_adjust (sym_value, -8, r_field); - } - else - sym_value = hppa_field_adjust (sym_value, constant_value, r_field); - - return hppa_rebuild_insn (abfd, insn, sym_value >> 2, r_format); - - default: - if (opcode == 0) - { - constant_value = HPPA_R_CONSTANT (r_addend); - - if (pcrel) - sym_value -= address; - - return hppa_field_adjust (sym_value, constant_value, r_field); - } - else - abort (); - } -} - -/* Relocate an HPPA ELF section. */ - -static boolean -elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; -{ - Elf_Internal_Shdr *symtab_hdr; - Elf_Internal_Rela *rel; - Elf_Internal_Rela *relend; - - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - - rel = relocs; - relend = relocs + input_section->reloc_count; - for (; rel < relend; rel++) - { - int r_type; - reloc_howto_type *howto; - unsigned long r_symndx; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; - asection *sym_sec; - bfd_vma relocation; - bfd_reloc_status_type r; - const char *sym_name; - - r_type = ELF32_R_TYPE (rel->r_info); - if (r_type < 0 || r_type >= (int) R_PARISC_UNIMPLEMENTED) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - howto = elf_hppa_howto_table + r_type; - - r_symndx = ELF32_R_SYM (rel->r_info); - - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - sym_sec = local_sections[r_symndx]; - rel->r_addend += sym_sec->output_offset; - } - } - - continue; - } - - /* This is a final link. */ - h = NULL; - sym = NULL; - sym_sec = NULL; - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - sym_sec = local_sections[r_symndx]; - relocation = ((ELF_ST_TYPE (sym->st_info) == STT_SECTION - ? 0 : sym->st_value) - + sym_sec->output_offset - + sym_sec->output_section->vma); - } - else - { - long indx; - - indx = r_symndx - symtab_hdr->sh_info; - h = elf_sym_hashes (input_bfd)[indx]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sym_sec = h->root.u.def.section; - relocation = (h->root.u.def.value - + sym_sec->output_offset - + sym_sec->output_section->vma); - } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else - { - if (!((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset))) - return false; - break; - } - } - - if (h != NULL) - sym_name = h->root.root.string; - else - { - sym_name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - if (sym_name == NULL) - return false; - if (*sym_name == '\0') - sym_name = bfd_section_name (input_bfd, sym_sec); - } - - /* If args_hash_table is NULL, then we have encountered some - kind of link error (ex. undefined symbols). Do not try to - apply any relocations, continue the loop so we can notify - the user of several errors in a single attempted link. */ - if (elf32_hppa_hash_table (info)->args_hash_table == NULL) - continue; - - r = elf32_hppa_bfd_final_link_relocate (howto, input_bfd, output_bfd, - input_section, contents, - rel->r_offset, relocation, - rel->r_addend, info, sym_sec, - sym_name, h == NULL); - - if (r != bfd_reloc_ok) - { - switch (r) - { - /* This can happen for DP relative relocs if $global$ is - undefined. This is a panic situation so we don't try - to continue. */ - case bfd_reloc_undefined: - case bfd_reloc_notsupported: - if (!((*info->callbacks->undefined_symbol) - (info, "$global$", input_bfd, - input_section, rel->r_offset))) - return false; - return false; - case bfd_reloc_dangerous: - { - /* We use this return value to indicate that we performed - a "dangerous" relocation. This doesn't mean we did - the wrong thing, it just means there may be some cleanup - that needs to be done here. - - In particular we had to swap the last call insn and its - delay slot. If the delay slot insn needed a relocation, - then we'll need to adjust the next relocation entry's - offset to account for the fact that the insn moved. - - This hair wouldn't be necessary if we inserted stubs - between procedures and used a "bl" to get to the stub. */ - if (rel != relend) - { - Elf_Internal_Rela *next_rel = rel + 1; - - if (rel->r_offset + 4 == next_rel->r_offset) - next_rel->r_offset -= 4; - } - break; - } - default: - case bfd_reloc_outofrange: - case bfd_reloc_overflow: - { - if (!((*info->callbacks->reloc_overflow) - (info, sym_name, howto->name, (bfd_vma) 0, - input_bfd, input_section, rel->r_offset))) - return false; - } - break; - } - } - } - - return true; -} - -/* Return one (or more) BFD relocations which implement the base - relocation with modifications based on format and field. */ - -elf32_hppa_reloc_type ** -hppa_elf_gen_reloc_type (abfd, base_type, format, field, ignore) - bfd *abfd; - elf32_hppa_reloc_type base_type; - int format; - int field; - int ignore; -{ - elf32_hppa_reloc_type *finaltype; - elf32_hppa_reloc_type **final_types; - - /* Allocate slots for the BFD relocation. */ - final_types = (elf32_hppa_reloc_type **) - bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type *) * 2); - if (final_types == NULL) - return NULL; - - /* Allocate space for the relocation itself. */ - finaltype = (elf32_hppa_reloc_type *) - bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type)); - if (finaltype == NULL) - return NULL; - - /* Some reasonable defaults. */ - final_types[0] = finaltype; - final_types[1] = NULL; - -#define final_type finaltype[0] - - final_type = base_type; - - /* Just a tangle of nested switch statements to deal with the braindamage - that a different field selector means a completely different relocation - for PA ELF. */ - switch (base_type) - { - case R_HPPA: - case R_HPPA_ABS_CALL: - switch (format) - { - case 14: - switch (field) - { - case e_rsel: - case e_rrsel: - final_type = R_PARISC_DIR14R; - break; - case e_rtsel: - final_type = R_PARISC_DLTREL14R; - break; - case e_tsel: - final_type = R_PARISC_DLTREL14F; - break; - case e_rpsel: - final_type = R_PARISC_PLABEL14R; - break; - default: - return NULL; - } - break; - - case 17: - switch (field) - { - case e_fsel: - final_type = R_PARISC_DIR17F; - break; - case e_rsel: - case e_rrsel: - final_type = R_PARISC_DIR17R; - break; - default: - return NULL; - } - break; - - case 21: - switch (field) - { - case e_lsel: - case e_lrsel: - final_type = R_PARISC_DIR21L; - break; - case e_ltsel: - final_type = R_PARISC_DLTREL21L; - break; - case e_lpsel: - final_type = R_PARISC_PLABEL21L; - break; - default: - return NULL; - } - break; - - case 32: - switch (field) - { - case e_fsel: - final_type = R_PARISC_DIR32; - break; - case e_psel: - final_type = R_PARISC_PLABEL32; - break; - default: - return NULL; - } - break; - - default: - return NULL; - } - break; - - - case R_HPPA_GOTOFF: - switch (format) - { - case 14: - switch (field) - { - case e_rsel: - case e_rrsel: - final_type = R_PARISC_DPREL14R; - break; - case e_fsel: - final_type = R_PARISC_DPREL14F; - break; - default: - return NULL; - } - break; - - case 21: - switch (field) - { - case e_lrsel: - case e_lsel: - final_type = R_PARISC_DPREL21L; - break; - default: - return NULL; - } - break; - - default: - return NULL; - } - break; - - - case R_HPPA_PCREL_CALL: - switch (format) - { - case 14: - switch (field) - { - case e_rsel: - case e_rrsel: - final_type = R_PARISC_PCREL14R; - break; - case e_fsel: - final_type = R_PARISC_PCREL14F; - break; - default: - return NULL; - } - break; - - case 17: - switch (field) - { - case e_rsel: - case e_rrsel: - final_type = R_PARISC_PCREL17R; - break; - case e_fsel: - final_type = R_PARISC_PCREL17F; - break; - default: - return NULL; - } - break; - - case 21: - switch (field) - { - case e_lsel: - case e_lrsel: - final_type = R_PARISC_PCREL21L; - break; - default: - return NULL; - } - break; - - default: - return NULL; - } - break; - - default: - return NULL; - } - - return final_types; -} - -#undef final_type - -/* Set the contents of a particular section at a particular location. */ - -static boolean -elf32_hppa_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - /* Ignore write requests for the symbol extension section until we've - had the chance to rebuild it ourselves. */ - if (!strcmp (section->name, ".PARISC.symextn") && !symext_chain_size) - return true; - else - return _bfd_elf_set_section_contents (abfd, section, location, - offset, count); -} - -/* Translate from an elf into field into a howto relocation pointer. */ - -static void -elf_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf32_Internal_Rela *dst; -{ - BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_PARISC_UNIMPLEMENTED); - cache_ptr->howto = &elf_hppa_howto_table[ELF32_R_TYPE (dst->r_info)]; -} - - -/* Actually perform a relocation. NOTE this is (mostly) superceeded - by elf32_hppa_bfd_final_link_relocate which is called by the new - fast linker. */ - -static bfd_reloc_status_type -hppa_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol_in; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - /* It is no longer valid to call hppa_elf_reloc when creating - a final executable. */ - if (output_bfd) - { - reloc_entry->address += input_section->output_offset; - - /* Work around lossage in generic elf code to write relocations. - (maps different section symbols into the same symbol index). */ - if ((symbol_in->flags & BSF_SECTION_SYM) - && symbol_in->section) - reloc_entry->addend += symbol_in->section->output_offset; - return bfd_reloc_ok; - } - else - { - *error_message = (char *) "Unsupported call to hppa_elf_reloc"; - return bfd_reloc_notsupported; - } -} - -/* Actually perform a relocation as part of a final link. This can get - rather hairy when linker stubs are needed. */ - -static bfd_reloc_status_type -elf32_hppa_bfd_final_link_relocate (howto, input_bfd, output_bfd, - input_section, contents, offset, value, - addend, info, sym_sec, sym_name, is_local) - reloc_howto_type *howto; - bfd *input_bfd; - bfd *output_bfd; - asection *input_section; - bfd_byte *contents; - bfd_vma offset; - bfd_vma value; - bfd_vma addend; - struct bfd_link_info *info; - asection *sym_sec; - const char *sym_name; - int is_local; -{ - unsigned long insn; - unsigned long r_type = howto->type; - unsigned long r_format = howto->bitsize; - unsigned long r_field = e_fsel; - bfd_byte *hit_data = contents + offset; - boolean r_pcrel = howto->pc_relative; - - insn = bfd_get_32 (input_bfd, hit_data); - - /* Make sure we have a value for $global$. FIXME isn't this effectively - just like the gp pointer on MIPS? Can we use those routines for this - purpose? */ - if (!elf32_hppa_hash_table (info)->global_sym_defined) - { - struct elf_link_hash_entry *h; - asection *sec; - - h = elf_link_hash_lookup (elf_hash_table (info), "$global$", false, - false, false); - - /* If there isn't a $global$, then we're in deep trouble. */ - if (h == NULL) - return bfd_reloc_notsupported; - - /* If $global$ isn't a defined symbol, then we're still in deep - trouble. */ - if (h->root.type != bfd_link_hash_defined) - return bfd_reloc_undefined; - - sec = h->root.u.def.section; - elf32_hppa_hash_table (info)->global_value = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - elf32_hppa_hash_table (info)->global_sym_defined = 1; - } - - switch (r_type) - { - case R_PARISC_NONE: - break; - - case R_PARISC_DIR32: - case R_PARISC_DIR17F: - case R_PARISC_PCREL17C: - r_field = e_fsel; - goto do_basic_type_1; - case R_PARISC_DIR21L: - case R_PARISC_PCREL21L: - r_field = e_lrsel; - goto do_basic_type_1; - case R_PARISC_DIR17R: - case R_PARISC_PCREL17R: - case R_PARISC_DIR14R: - case R_PARISC_PCREL14R: - r_field = e_rrsel; - goto do_basic_type_1; - - /* For all the DP relative relocations, we need to examine the symbol's - section. If it's a code section, then "data pointer relative" makes - no sense. In that case we don't adjust the "value", and for 21 bit - addil instructions, we change the source addend register from %dp to - %r0. */ - case R_PARISC_DPREL21L: - r_field = e_lrsel; - if (sym_sec->flags & SEC_CODE) - { - if ((insn & 0xfc000000) >> 26 == 0xa - && (insn & 0x03e00000) >> 21 == 0x1b) - insn &= ~0x03e00000; - } - else - value -= elf32_hppa_hash_table (info)->global_value; - goto do_basic_type_1; - case R_PARISC_DPREL14R: - r_field = e_rrsel; - if ((sym_sec->flags & SEC_CODE) == 0) - value -= elf32_hppa_hash_table (info)->global_value; - goto do_basic_type_1; - case R_PARISC_DPREL14F: - r_field = e_fsel; - if ((sym_sec->flags & SEC_CODE) == 0) - value -= elf32_hppa_hash_table (info)->global_value; - goto do_basic_type_1; - - /* These cases are separate as they may involve a lot more work - to deal with linker stubs. */ - case R_PARISC_PLABEL32: - case R_PARISC_PLABEL21L: - case R_PARISC_PLABEL14R: - case R_PARISC_PCREL17F: - { - bfd_vma location; - unsigned int len, caller_args, callee_args; - arg_reloc_type arg_reloc_types[5]; - struct elf32_hppa_args_hash_table *args_hash_table; - struct elf32_hppa_args_hash_entry *args_hash; - char *new_name, *stub_name; - - /* Get the field selector right. We'll need it in a minute. */ - if (r_type == R_PARISC_PCREL17F - || r_type == R_PARISC_PLABEL32) - r_field = e_fsel; - else if (r_type == R_PARISC_PLABEL21L) - r_field = e_lrsel; - else if (r_type == R_PARISC_PLABEL14R) - r_field = e_rrsel; - - /* Find out where we are and where we're going. */ - location = (offset + - input_section->output_offset + - input_section->output_section->vma); - - /* Now look for the argument relocation bits associated with the - target. */ - len = strlen (sym_name) + 1; - if (is_local) - len += 9; - new_name = bfd_malloc (len); - if (!new_name) - return bfd_reloc_notsupported; - strcpy (new_name, sym_name); - - /* Local symbols have unique IDs. */ - if (is_local) - sprintf (new_name + len - 10, "_%08x", (int)sym_sec); - - args_hash_table = elf32_hppa_hash_table (info)->args_hash_table; - - args_hash = elf32_hppa_args_hash_lookup (args_hash_table, - new_name, false, false); - if (args_hash == NULL) - callee_args = 0; - else - callee_args = args_hash->arg_bits; - - /* If this is a CALL relocation, then get the caller's bits - from the addend. Else use the magic 0x155 value for PLABELS. - - Also we don't care about the destination (value) for PLABELS. */ - if (r_type == R_PARISC_PCREL17F) - caller_args = HPPA_R_ARG_RELOC (addend); - else - { - caller_args = 0x155; - location = value; - } - - /* Any kind of linker stub needed? */ - if (((int)(value - location) > 0x3ffff) - || ((int)(value - location) < (int)0xfffc0000) - || elf32_hppa_arg_reloc_needed (caller_args, callee_args, - arg_reloc_types)) - { - struct elf32_hppa_stub_hash_table *stub_hash_table; - struct elf32_hppa_stub_hash_entry *stub_hash; - asection *stub_section; - - /* Build a name for the stub. */ - - len = strlen (new_name); - len += 23; - stub_name = bfd_malloc (len); - if (!stub_name) - return bfd_reloc_notsupported; - elf32_hppa_name_of_stub (caller_args, callee_args, - location, value, stub_name); - strcat (stub_name, new_name); - free (new_name); - - stub_hash_table = elf32_hppa_hash_table (info)->stub_hash_table; - - stub_hash - = elf32_hppa_stub_hash_lookup (stub_hash_table, stub_name, - false, false); - - /* We're done with that name. */ - free (stub_name); - - /* The stub BFD only has one section. */ - stub_section = stub_hash_table->stub_bfd->sections; - - if (stub_hash != NULL) - { - - if (r_type == R_PARISC_PCREL17F) - { - unsigned long delay_insn; - unsigned int opcode, rtn_reg, ldo_target_reg, ldo_src_reg; - - /* We'll need to peek at the next insn. */ - delay_insn = bfd_get_32 (input_bfd, hit_data + 4); - opcode = get_opcode (delay_insn); - - /* We also need to know the return register for this - call. */ - rtn_reg = (insn & 0x03e00000) >> 21; - - ldo_src_reg = (delay_insn & 0x03e00000) >> 21; - ldo_target_reg = (delay_insn & 0x001f0000) >> 16; - - /* Munge up the value and other parameters for - hppa_elf_relocate_insn. */ - - value = (stub_hash->offset - + stub_section->output_offset - + stub_section->output_section->vma); - - r_format = 17; - r_field = e_fsel; - r_pcrel = 0; - addend = 0; - - /* We need to peek at the delay insn and determine if - we'll need to swap the branch and its delay insn. */ - if ((insn & 2) - || (opcode == LDO - && ldo_target_reg == rtn_reg) - || (delay_insn == 0x08000240)) - { - /* No need to swap the branch and its delay slot, but - we do need to make sure to jump past the return - pointer update in the stub. */ - value += 4; - - /* If the delay insn does a return pointer adjustment, - then we have to make sure it stays valid. */ - if (opcode == LDO - && ldo_target_reg == rtn_reg) - { - delay_insn &= 0xfc00ffff; - delay_insn |= ((31 << 21) | (31 << 16)); - bfd_put_32 (input_bfd, delay_insn, hit_data + 4); - } - /* Use a BLE to reach the stub. */ - insn = BLE_SR4_R0; - } - else - { - /* Wonderful, we have to swap the call insn and its - delay slot. */ - bfd_put_32 (input_bfd, delay_insn, hit_data); - /* Use a BLE,n to reach the stub. */ - insn = (BLE_SR4_R0 | 0x2); - bfd_put_32 (input_bfd, insn, hit_data + 4); - insn = hppa_elf_relocate_insn (input_bfd, - input_section, - insn, offset + 4, - value, addend, - r_format, r_field, - r_pcrel); - /* Update the instruction word. */ - bfd_put_32 (input_bfd, insn, hit_data + 4); - return bfd_reloc_dangerous; - } - } - else - { - /* PLABEL stuff is easy. */ - - value = (stub_hash->offset - + stub_section->output_offset - + stub_section->output_section->vma); - /* We don't need the RP adjustment for PLABELs. */ - value += 4; - if (r_type == R_PARISC_PLABEL32) - r_format = 32; - else if (r_type == R_PARISC_PLABEL21L) - r_format = 21; - else if (r_type == R_PARISC_PLABEL14R) - r_format = 14; - - r_pcrel = 0; - addend = 0; - } - } - else - return bfd_reloc_notsupported; - } - goto do_basic_type_1; - } - -do_basic_type_1: - insn = hppa_elf_relocate_insn (input_bfd, input_section, insn, - offset, value, addend, r_format, - r_field, r_pcrel); - break; - - /* Something we don't know how to handle. */ - default: - return bfd_reloc_notsupported; - } - - /* Update the instruction word. */ - bfd_put_32 (input_bfd, insn, hit_data); - return (bfd_reloc_ok); -} - -/* Return the address of the howto table entry to perform the CODE - relocation for an ARCH machine. */ - -static reloc_howto_type * -elf_hppa_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - if ((int) code < (int) R_PARISC_UNIMPLEMENTED) - { - BFD_ASSERT ((int) elf_hppa_howto_table[(int) code].type == (int) code); - return &elf_hppa_howto_table[(int) code]; - } - return NULL; -} - -/* Return true if SYM represents a local label symbol. */ - -static boolean -hppa_elf_is_local_label (abfd, sym) - bfd *abfd; - asymbol *sym; -{ - return (sym->name[0] == 'L' && sym->name[1] == '$'); -} - -/* Do any backend specific processing when beginning to write an object - file. For PA ELF we need to determine the size of the symbol extension - section *before* any other output processing happens. */ - -static void -elf32_hppa_backend_begin_write_processing (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - unsigned int i; - asection *symextn_sec; - - /* Size up the symbol extension section. */ - if ((abfd->outsymbols == NULL - && info == NULL) - || symext_chain_size != 0) - return; - - if (info == NULL) - { - /* We were not called from the BFD ELF linker code, so we need - to examine the output BFD's outsymbols. - - Note we can not build the symbol extensions now as the symbol - map hasn't been set up. */ - for (i = 0; i < abfd->symcount; i++) - { - elf_symbol_type *symbol = (elf_symbol_type *)abfd->outsymbols[i]; - - /* Only functions ever need an entry in the symbol extension - section. */ - if (!(symbol->symbol.flags & BSF_FUNCTION)) - continue; - - /* And only if they specify the locations of their arguments. */ - if (symbol->tc_data.hppa_arg_reloc == 0) - continue; - - /* Yup. This function symbol needs an entry. */ - symext_chain_size += 2 * ELF32_PARISC_SX_SIZE; - } - } - else if (info->relocateable == true) - { - struct elf32_hppa_args_hash_table *table; - table = elf32_hppa_hash_table (info)->args_hash_table; - - /* Determine the size of the symbol extension section. */ - elf32_hppa_args_hash_traverse (table, - elf32_hppa_size_symext, - &symext_chain_size); - } - - /* Now create the section and set its size. We'll fill in the - contents later. */ - symextn_sec = bfd_get_section_by_name (abfd, SYMEXTN_SECTION_NAME); - if (symextn_sec == NULL) - symextn_sec = bfd_make_section (abfd, SYMEXTN_SECTION_NAME); - - bfd_set_section_flags (abfd, symextn_sec, - SEC_LOAD | SEC_HAS_CONTENTS | SEC_DATA); - symextn_sec->output_section = symextn_sec; - symextn_sec->output_offset = 0; - bfd_set_section_alignment (abfd, symextn_sec, 2); - bfd_set_section_size (abfd, symextn_sec, symext_chain_size); -} - -/* Called for each entry in the args location hash table. For each - entry we bump the size pointer by 2 records (16 bytes). */ - -static boolean -elf32_hppa_size_symext (gen_entry, in_args) - struct bfd_hash_entry *gen_entry; - PTR in_args; -{ - bfd_size_type *sizep = (bfd_size_type *)in_args; - - *sizep += 2 * ELF32_PARISC_SX_SIZE; - return true; -} - -/* Backend routine called by the linker for each output symbol. - - For PA ELF we use this opportunity to add an appropriate entry - to the symbol extension chain for function symbols. */ - -static boolean -elf32_hppa_link_output_symbol_hook (abfd, info, name, sym, section) - bfd *abfd; - struct bfd_link_info *info; - const char *name; - Elf_Internal_Sym *sym; - asection *section; -{ - char *new_name; - unsigned int len, index; - struct elf32_hppa_args_hash_table *args_hash_table; - struct elf32_hppa_args_hash_entry *args_hash; - - /* If the args hash table is NULL, then we've encountered an error - of some sorts (for example, an undefined symbol). In that case - we've got nothing else to do. - - NOTE: elf_link_output_symbol will abort if we return false here! */ - if (elf32_hppa_hash_table (info)->args_hash_table == NULL) - return true; - - index = elf32_hppa_hash_table (info)->output_symbol_count++; - - /* We need to look up this symbol in the args hash table to see if - it has argument relocation bits. */ - if (ELF_ST_TYPE (sym->st_info) != STT_FUNC) - return true; - - /* We know it's a function symbol of some kind. */ - len = strlen (name) + 1; - if (ELF_ST_BIND (sym->st_info) == STB_LOCAL) - len += 9; - - new_name = bfd_malloc (len); - if (new_name == NULL) - return false; - - strcpy (new_name, name); - if (ELF_ST_BIND (sym->st_info) == STB_LOCAL) - sprintf (new_name + len - 10, "_%08x", (int)section); - - /* Now that we have the unique name, we can look it up in the - args hash table. */ - args_hash_table = elf32_hppa_hash_table (info)->args_hash_table; - args_hash = elf32_hppa_args_hash_lookup (args_hash_table, new_name, - false, false); - free (new_name); - if (args_hash == NULL) - return true; - - /* We know this symbol has arg reloc bits. */ - add_entry_to_symext_chain (abfd, args_hash->arg_bits, - index, &symext_rootP, &symext_lastP); - return true; -} - -/* Perform any processing needed late in the object file writing process. - For PA ELF we build and set the contents of the symbol extension - section. */ - -static void -elf32_hppa_backend_final_write_processing (abfd, linker) - bfd *abfd; - boolean linker; -{ - asection *symextn_sec; - unsigned int i; - - /* Now build the symbol extension section. */ - if (symext_chain_size == 0) - return; - - if (! linker) - { - /* We were not called from the backend linker, so we still need - to build the symbol extension chain. - - Look at each symbol, adding the appropriate information to the - symbol extension section list as necessary. */ - for (i = 0; i < abfd->symcount; i++) - { - elf_symbol_type *symbol = (elf_symbol_type *) abfd->outsymbols[i]; - - /* Only functions ever need an entry in the symbol extension - section. */ - if (!(symbol->symbol.flags & BSF_FUNCTION)) - continue; - - /* And only if they specify the locations of their arguments. */ - if (symbol->tc_data.hppa_arg_reloc == 0) - continue; - - /* Add this symbol's information to the chain. */ - add_entry_to_symext_chain (abfd, symbol->tc_data.hppa_arg_reloc, - symbol->symbol.udata.i, &symext_rootP, - &symext_lastP); - } - } - - /* Now fill in the contents of the symbol extension section. */ - elf_hppa_tc_make_sections (abfd, symext_rootP); - - /* And attach that as the section's contents. */ - symextn_sec = bfd_get_section_by_name (abfd, SYMEXTN_SECTION_NAME); - if (symextn_sec == (asection *) 0) - abort(); - - symextn_sec->contents = (void *)symextn_contents; - - bfd_set_section_contents (abfd, symextn_sec, symextn_sec->contents, - symextn_sec->output_offset, symextn_sec->_raw_size); -} - -/* Update the symbol extention chain to include the symbol pointed to - by SYMBOLP if SYMBOLP is a function symbol. Used internally and by GAS. */ - -static void -add_entry_to_symext_chain (abfd, arg_reloc, sym_idx, symext_root, symext_last) - bfd *abfd; - unsigned int arg_reloc; - unsigned int sym_idx; - symext_chainS **symext_root; - symext_chainS **symext_last; -{ - symext_chainS *symextP; - - /* Allocate memory and initialize this entry. */ - symextP = (symext_chainS *) bfd_alloc (abfd, sizeof (symext_chainS) * 2); - if (!symextP) - abort(); /* FIXME */ - - symextP[0].entry = ELF32_PARISC_SX_WORD (PARISC_SXT_SYMNDX, sym_idx); - symextP[0].next = &symextP[1]; - - symextP[1].entry = ELF32_PARISC_SX_WORD (PARISC_SXT_ARG_RELOC, arg_reloc); - symextP[1].next = NULL; - - /* Now update the chain itself so it can be walked later to build - the symbol extension section. */ - if (*symext_root == NULL) - { - *symext_root = &symextP[0]; - *symext_last = &symextP[1]; - } - else - { - (*symext_last)->next = &symextP[0]; - *symext_last = &symextP[1]; - } -} - -/* Build the symbol extension section. */ - -static void -elf_hppa_tc_make_sections (abfd, symext_root) - bfd *abfd; - symext_chainS *symext_root; -{ - symext_chainS *symextP; - unsigned int i; - asection *symextn_sec; - - symextn_sec = bfd_get_section_by_name (abfd, SYMEXTN_SECTION_NAME); - - /* Grab some memory for the contents of the symbol extension section - itself. */ - symextn_contents = (bfd_byte *) bfd_zalloc (abfd, - symextn_sec->_raw_size); - if (!symextn_contents) - abort(); /* FIXME */ - - /* Fill in the contents of the symbol extension chain. */ - for (i = 0, symextP = symext_root; symextP; symextP = symextP->next, ++i) - ELF32_PARISC_SX_PUT (abfd, (bfd_vma) symextP->entry, - symextn_contents + i * ELF32_PARISC_SX_SIZE); - - return; -} - -/* Do some PA ELF specific work after reading in the symbol table. - In particular attach the argument relocation from the - symbol extension section to the appropriate symbols. */ - -static boolean -elf32_hppa_backend_symbol_table_processing (abfd, esyms,symcnt) - bfd *abfd; - elf_symbol_type *esyms; - unsigned int symcnt; -{ - Elf32_Internal_Shdr *symextn_hdr = - bfd_elf_find_section (abfd, SYMEXTN_SECTION_NAME); - unsigned int i, current_sym_idx = 0; - - /* If no symbol extension existed, then all symbol extension information - is assumed to be zero. */ - if (symextn_hdr == NULL) - { - for (i = 0; i < symcnt; i++) - esyms[i].tc_data.hppa_arg_reloc = 0; - return (true); - } - - /* FIXME: Why not use bfd_get_section_contents here? Also should give - memory back when we're done. */ - /* Allocate a buffer of the appropriate size for the symextn section. */ - symextn_hdr->contents = bfd_zalloc(abfd,symextn_hdr->sh_size); - if (!symextn_hdr->contents) - return false; - - /* Read in the symextn section. */ - if (bfd_seek (abfd, symextn_hdr->sh_offset, SEEK_SET) == -1) - return false; - if (bfd_read ((PTR) symextn_hdr->contents, 1, symextn_hdr->sh_size, abfd) - != symextn_hdr->sh_size) - return false; - - /* Parse entries in the symbol extension section, updating the symtab - entries as we go */ - for (i = 0; i < symextn_hdr->sh_size / ELF32_PARISC_SX_SIZE; i++) - { - symext_entryS se = - ELF32_PARISC_SX_GET (abfd, - ((unsigned char *)symextn_hdr->contents - + i * ELF32_PARISC_SX_SIZE)); - unsigned int se_value = ELF32_PARISC_SX_VAL (se); - unsigned int se_type = ELF32_PARISC_SX_TYPE (se); - - switch (se_type) - { - case PARISC_SXT_NULL: - break; - - case PARISC_SXT_SYMNDX: - if (se_value >= symcnt) - { - bfd_set_error (bfd_error_bad_value); - return (false); - } - current_sym_idx = se_value - 1; - break; - - case PARISC_SXT_ARG_RELOC: - esyms[current_sym_idx].tc_data.hppa_arg_reloc = se_value; - break; - - default: - bfd_set_error (bfd_error_bad_value); - return (false); - } - } - return (true); -} - -/* Read and attach the symbol extension information for the symbols - in INPUT_BFD to the argument location hash table. Handle locals - if DO_LOCALS is true; likewise for globals when DO_GLOBALS is true. */ - -static boolean -elf32_hppa_read_symext_info (input_bfd, symtab_hdr, args_hash_table, local_syms) - bfd *input_bfd; - Elf_Internal_Shdr *symtab_hdr; - struct elf32_hppa_args_hash_table *args_hash_table; - Elf_Internal_Sym *local_syms; -{ - asection *symextn_sec; - bfd_byte *contents; - unsigned int i, n_entries, current_index = 0; - - /* Get the symbol extension section for this BFD. If no section exists - then there's nothing to do. Likewise if the section exists, but - has no contents. */ - symextn_sec = bfd_get_section_by_name (input_bfd, SYMEXTN_SECTION_NAME); - if (symextn_sec == NULL) - return true; - - /* Done separately so we can turn off SEC_HAS_CONTENTS (see below). */ - if (symextn_sec->_raw_size == 0) - { - symextn_sec->flags &= ~SEC_HAS_CONTENTS; - return true; - } - - contents = (bfd_byte *) bfd_malloc ((size_t) symextn_sec->_raw_size); - if (contents == NULL) - return false; - - /* How gross. We turn off SEC_HAS_CONTENTS for the input symbol extension - sections to keep the generic ELF/BFD code from trying to do anything - with them. We have to undo that hack temporarily so that we can read - in the contents with the generic code. */ - symextn_sec->flags |= SEC_HAS_CONTENTS; - if (bfd_get_section_contents (input_bfd, symextn_sec, contents, - 0, symextn_sec->_raw_size) == false) - { - symextn_sec->flags &= ~SEC_HAS_CONTENTS; - free (contents); - return false; - } - - /* Gross. Turn off SEC_HAS_CONTENTS for the input symbol extension - sections (see above). */ - symextn_sec->flags &= ~SEC_HAS_CONTENTS; - - n_entries = symextn_sec->_raw_size / ELF32_PARISC_SX_SIZE; - for (i = 0; i < n_entries; i++) - { - symext_entryS entry = - ELF32_PARISC_SX_GET (input_bfd, contents + i * ELF32_PARISC_SX_SIZE); - unsigned int value = ELF32_PARISC_SX_VAL (entry); - unsigned int type = ELF32_PARISC_SX_TYPE (entry); - struct elf32_hppa_args_hash_entry *args_hash; - - switch (type) - { - case PARISC_SXT_NULL: - break; - - case PARISC_SXT_SYMNDX: - if (value >= symtab_hdr->sh_size / sizeof (Elf32_External_Sym)) - { - bfd_set_error (bfd_error_bad_value); - free (contents); - return false; - } - current_index = value; - break; - - case PARISC_SXT_ARG_RELOC: - if (current_index < symtab_hdr->sh_info) - { - Elf_Internal_Shdr *hdr; - char *new_name; - const char *sym_name; - asection *sym_sec; - unsigned int len; - - hdr = elf_elfsections (input_bfd)[local_syms[current_index].st_shndx]; - sym_sec = hdr->bfd_section; - sym_name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - local_syms[current_index].st_name); - len = strlen (sym_name) + 10; - new_name = bfd_malloc (len); - if (new_name == NULL) - { - free (contents); - return false; - } - strcpy (new_name, sym_name); - sprintf (new_name + len - 10, "_%08x", (int)sym_sec); - - /* This is a global symbol with argument location info. - We need to enter it into the hash table. */ - args_hash = elf32_hppa_args_hash_lookup (args_hash_table, - new_name, true, - true); - free (new_name); - if (args_hash == NULL) - { - free (contents); - return false; - } - args_hash->arg_bits = value; - break; - } - else if (current_index >= symtab_hdr->sh_info) - { - struct elf_link_hash_entry *h; - - current_index -= symtab_hdr->sh_info; - h = elf_sym_hashes(input_bfd)[current_index]; - /* This is a global symbol with argument location - information. We need to enter it into the hash table. */ - args_hash = elf32_hppa_args_hash_lookup (args_hash_table, - h->root.root.string, - true, true); - if (args_hash == NULL) - { - bfd_set_error (bfd_error_bad_value); - free (contents); - return false; - } - args_hash->arg_bits = value; - break; - } - else - break; - - default: - bfd_set_error (bfd_error_bad_value); - free (contents); - return false; - } - } - free (contents); - return true; -} - -/* Undo the generic ELF code's subtraction of section->vma from the - value of each external symbol. */ - -static boolean -elf32_hppa_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) - bfd *abfd; - struct bfd_link_info *info; - const Elf_Internal_Sym *sym; - const char **namep; - flagword *flagsp; - asection **secp; - bfd_vma *valp; -{ - *valp += (*secp)->vma; - return true; -} - -/* Determine the name of the stub needed to perform a call assuming the - argument relocation bits for caller and callee are in CALLER and CALLEE - for a call from LOCATION to DESTINATION. Copy the name into STUB_NAME. */ - -static void -elf32_hppa_name_of_stub (caller, callee, location, destination, stub_name) - unsigned int caller, callee; - bfd_vma location, destination; - char *stub_name; -{ - arg_reloc_type arg_reloc_types[5]; - - if (elf32_hppa_arg_reloc_needed (caller, callee, arg_reloc_types)) - { - arg_reloc_location i; - /* Fill in the basic template. */ - strcpy (stub_name, "__XX_XX_XX_XX_XX_stub_"); - - /* Now fix the specifics. */ - for (i = ARG0; i <= RET; i++) - switch (arg_reloc_types[i]) - { - case NO: - stub_name[3 * i + 2] = 'N'; - stub_name[3 * i + 3] = 'O'; - break; - case GF: - stub_name[3 * i + 2] = 'G'; - stub_name[3 * i + 3] = 'F'; - break; - case FG: - stub_name[3 * i + 2] = 'F'; - stub_name[3 * i + 3] = 'G'; - break; - case GD: - stub_name[3 * i + 2] = 'G'; - stub_name[3 * i + 3] = 'D'; - break; - case DG: - stub_name[3 * i + 2] = 'D'; - stub_name[3 * i + 3] = 'G'; - break; - } - } - else - strcpy (stub_name, "_____long_branch_stub_"); -} - -/* Determine if an argument relocation stub is needed to perform a - call assuming the argument relocation bits for caller and callee - are in CALLER and CALLEE. Place the type of relocations (if any) - into stub_types_p. */ - -static boolean -elf32_hppa_arg_reloc_needed (caller, callee, stub_types) - unsigned int caller, callee; - arg_reloc_type stub_types[5]; -{ - /* Special case for no relocations. */ - if (caller == 0 || callee == 0) - return 0; - else - { - arg_location caller_loc[5]; - arg_location callee_loc[5]; - - /* Extract the location information for the argument and return - value on both the caller and callee sides. */ - caller_loc[ARG0] = EXTRACT_ARBITS (caller, ARG0); - callee_loc[ARG0] = EXTRACT_ARBITS (callee, ARG0); - caller_loc[ARG1] = EXTRACT_ARBITS (caller, ARG1); - callee_loc[ARG1] = EXTRACT_ARBITS (callee, ARG1); - caller_loc[ARG2] = EXTRACT_ARBITS (caller, ARG2); - callee_loc[ARG2] = EXTRACT_ARBITS (callee, ARG2); - caller_loc[ARG3] = EXTRACT_ARBITS (caller, ARG3); - callee_loc[ARG3] = EXTRACT_ARBITS (callee, ARG3); - caller_loc[RET] = EXTRACT_ARBITS (caller, RET); - callee_loc[RET] = EXTRACT_ARBITS (callee, RET); - - /* Check some special combinations. This is necessary to - deal with double precision FP arguments. */ - if (caller_loc[ARG0] == AR_FU || caller_loc[ARG1] == AR_FU) - { - caller_loc[ARG0] = AR_FPDBL1; - caller_loc[ARG1] = AR_NO; - } - if (caller_loc[ARG2] == AR_FU || caller_loc[ARG3] == AR_FU) - { - caller_loc[ARG2] = AR_FPDBL2; - caller_loc[ARG3] = AR_NO; - } - if (callee_loc[ARG0] == AR_FU || callee_loc[ARG1] == AR_FU) - { - callee_loc[ARG0] = AR_FPDBL1; - callee_loc[ARG1] = AR_NO; - } - if (callee_loc[ARG2] == AR_FU || callee_loc[ARG3] == AR_FU) - { - callee_loc[ARG2] = AR_FPDBL2; - callee_loc[ARG3] = AR_NO; - } - - /* Now look up any relocation needed for each argument and the - return value. */ - stub_types[ARG0] = arg_mismatches[caller_loc[ARG0]][callee_loc[ARG0]]; - stub_types[ARG1] = arg_mismatches[caller_loc[ARG1]][callee_loc[ARG1]]; - stub_types[ARG2] = arg_mismatches[caller_loc[ARG2]][callee_loc[ARG2]]; - stub_types[ARG3] = arg_mismatches[caller_loc[ARG3]][callee_loc[ARG3]]; - stub_types[RET] = ret_mismatches[caller_loc[RET]][callee_loc[RET]]; - - return (stub_types[ARG0] != NO - || stub_types[ARG1] != NO - || stub_types[ARG2] != NO - || stub_types[ARG3] != NO - || stub_types[RET] != NO); - } -} - -/* Compute the size of the stub needed to call from LOCATION to DESTINATION - (a function named SYM_NAME), with argument relocation bits CALLER and - CALLEE. Return zero if no stub is needed to perform such a call. */ - -static unsigned int -elf32_hppa_size_of_stub (callee, caller, location, destination, sym_name) - unsigned int callee, caller; - bfd_vma location, destination; - const char *sym_name; -{ - arg_reloc_type arg_reloc_types[5]; - - /* Determine if a long branch or argument relocation stub is needed. - If an argument relocation stub is needed, the relocation will be - stored into arg_reloc_types. */ - if (!(((int)(location - destination) > 0x3ffff) - || ((int)(location - destination) < (int)0xfffc0000) - || elf32_hppa_arg_reloc_needed (caller, callee, arg_reloc_types))) - return 0; - - /* Some kind of stub is needed. Determine how big it needs to be. - First check for argument relocation stubs as they also handle - long calls. Then check for long calls to millicode and finally - the normal long calls. */ - if (arg_reloc_types[ARG0] != NO - || arg_reloc_types[ARG1] != NO - || arg_reloc_types[ARG2] != NO - || arg_reloc_types[ARG3] != NO - || arg_reloc_types[RET] != NO) - { - /* Some kind of argument relocation stub is needed. */ - unsigned int len = 16; - arg_reloc_location i; - - /* Each GR or FG relocation takes 2 insns, each GD or DG - relocation takes 3 insns. Plus 4 more insns for the - RP adjustment, ldil & (be | ble) and copy. */ - for (i = ARG0; i <= RET; i++) - switch (arg_reloc_types[i]) - { - case GF: - case FG: - len += 8; - break; - - case GD: - case DG: - len += 12; - break; - - default: - break; - } - - /* Extra instructions are needed if we're relocating a return value. */ - if (arg_reloc_types[RET] != NO) - len += 12; - - return len; - } - else if (!strncmp ("$$", sym_name, 2) - && strcmp ("$$dyncall", sym_name)) - return 12; - else - return 16; -} - -/* Build one linker stub as defined by the stub hash table entry GEN_ENTRY. - IN_ARGS contains the stub BFD and link info pointers. */ - -static boolean -elf32_hppa_build_one_stub (gen_entry, in_args) - struct bfd_hash_entry *gen_entry; - PTR in_args; -{ - void **args = (void **)in_args; - bfd *stub_bfd = (bfd *)args[0]; - struct bfd_link_info *info = (struct bfd_link_info *)args[1]; - struct elf32_hppa_stub_hash_entry *entry; - struct elf32_hppa_stub_hash_table *stub_hash_table; - bfd_byte *loc; - symvalue sym_value; - const char *sym_name; - - /* Initialize pointers to the stub hash table, the particular entry we - are building a stub for, and where (in memory) we should place the stub - instructions. */ - entry = (struct elf32_hppa_stub_hash_entry *)gen_entry; - stub_hash_table = elf32_hppa_hash_table(info)->stub_hash_table; - loc = stub_hash_table->location; - - /* Make a note of the offset within the stubs for this entry. */ - entry->offset = stub_hash_table->offset; - - /* The symbol's name starts at offset 22. */ - sym_name = entry->root.string + 22; - - sym_value = (entry->target_value - + entry->target_section->output_offset - + entry->target_section->output_section->vma); - - if (strncmp ("_____long_branch_stub_", entry->root.string, 22)) - { - /* This must be an argument or return value relocation stub. */ - unsigned long insn; - arg_reloc_location i; - bfd_byte *begin_loc = loc; - - /* First the return pointer adjustment. Depending on exact calling - sequence this instruction may be skipped. */ - bfd_put_32 (stub_bfd, LDO_M4_R31_R31, loc); - loc += 4; - - /* If we are relocating a return value, then we're going to have - to return into the stub. So we have to save off the user's - return pointer into the stack at RP'. */ - if (strncmp (entry->root.string + 14, "NO", 2)) - { - bfd_put_32 (stub_bfd, STW_R31_M8R30, loc); - loc += 4; - } - - /* Iterate over the argument relocations, emitting instructions - to move them around as necessary. */ - for (i = ARG0; i <= ARG3; i++) - { - if (!strncmp (entry->root.string + 3 * i + 2, "GF", 2)) - { - bfd_put_32 (stub_bfd, STW_ARG_M16R30 | ((26 - i) << 16), loc); - bfd_put_32 (stub_bfd, FLDW_M16R30_FARG | (4 + i), loc + 4); - loc += 8; - } - else if (!strncmp (entry->root.string + 3 * i + 2, "FG", 2)) - { - bfd_put_32 (stub_bfd, FSTW_FARG_M16R30 | (4 + i), loc); - bfd_put_32 (stub_bfd, LDW_M16R30_ARG | ((26 - i) << 16), loc + 4); - loc += 8; - } - else if (!strncmp (entry->root.string + 3 * i + 2, "GD", 2)) - { - bfd_put_32 (stub_bfd, STW_ARG_M12R30 | ((26 - i) << 16), loc); - bfd_put_32 (stub_bfd, STW_ARG_M16R30 | ((25 - i) << 16), loc + 4); - bfd_put_32 (stub_bfd, FLDD_M16R30_FARG | (5 + i), loc + 8); - loc += 12; - } - else if (!strncmp (entry->root.string + 3 * i + 2, "DG", 2)) - { - bfd_put_32 (stub_bfd, FSTD_FARG_M16R30 | (5 + i), loc); - bfd_put_32 (stub_bfd, LDW_M12R30_ARG | ((26 - i) << 16), loc + 4); - bfd_put_32 (stub_bfd, LDW_M16R30_ARG | ((25 - i) << 16), loc + 8); - loc += 12; - } - } - - /* Load the high bits of the target address into %r1. */ - insn = hppa_rebuild_insn (stub_bfd, LDIL_R1, - hppa_field_adjust (sym_value, 0, e_lrsel), 21); - bfd_put_32 (stub_bfd, insn, loc); - loc += 4; - - /* If we are relocating a return value, then we're going to have - to return into the stub, then perform the return value relocation. */ - if (strncmp (entry->root.string + 14, "NO", 2)) - { - /* To return to the stub we "ble" to the target and copy the return - pointer from %r31 into %r2. */ - insn = hppa_rebuild_insn (stub_bfd, - BLE_SR4_R1, - hppa_field_adjust (sym_value, 0, - e_rrsel) >> 2, - 17); - bfd_put_32 (stub_bfd, insn, loc); - bfd_put_32 (stub_bfd, COPY_R31_R2, loc + 4); - - /* Reload the return pointer for our caller from the stack. */ - bfd_put_32 (stub_bfd, LDW_M8R30_R31, loc + 8); - loc += 12; - - /* Perform the return value relocation. */ - if (!strncmp (entry->root.string + 14, "GF", 2)) - { - bfd_put_32 (stub_bfd, STW_ARG_M16R30 | (28 << 16), loc); - bfd_put_32 (stub_bfd, FLDW_M16R30_FARG | 4, loc + 4); - loc += 8; - } - else if (!strncmp (entry->root.string + 14, "FG", 2)) - { - bfd_put_32 (stub_bfd, FSTW_FARG_M16R30 | 4, loc); - bfd_put_32 (stub_bfd, LDW_M16R30_ARG | (28 << 16), loc + 4); - loc += 8; - } - else if (!strncmp (entry->root.string + 2, "GD", 2)) - { - bfd_put_32 (stub_bfd, STW_ARG_M12R30 | (28 << 16), loc); - bfd_put_32 (stub_bfd, STW_ARG_M16R30 | (29 << 16), loc + 4); - bfd_put_32 (stub_bfd, FLDD_M16R30_FARG | 4, loc + 8); - loc += 12; - } - else if (!strncmp (entry->root.string + 2, "DG", 2)) - { - bfd_put_32 (stub_bfd, FSTD_FARG_M16R30 | 4, loc); - bfd_put_32 (stub_bfd, LDW_M12R30_ARG | (28 << 16), loc + 4); - bfd_put_32 (stub_bfd, LDW_M16R30_ARG | (29 << 16), loc + 8); - loc += 12; - } - /* Branch back to the user's code now. */ - bfd_put_32 (stub_bfd, BV_N_0_R31, loc); - loc += 4; - } - else - { - /* No return value relocation, so we can simply "be" to the - target and copy out return pointer into %r2. */ - insn = hppa_rebuild_insn (stub_bfd, BE_SR4_R1, - hppa_field_adjust (sym_value, 0, - e_rrsel) >> 2, 17); - bfd_put_32 (stub_bfd, insn, loc); - bfd_put_32 (stub_bfd, COPY_R31_R2, loc + 4); - loc += 8; - } - - /* Update the location and offsets. */ - stub_hash_table->location += (loc - begin_loc); - stub_hash_table->offset += (loc - begin_loc); - } - else - { - /* Create one of two variant long branch stubs. One for $$dyncall and - normal calls, the other for calls to millicode. */ - unsigned long insn; - int millicode_call = 0; - - if (!strncmp ("$$", sym_name, 2) && strcmp ("$$dyncall", sym_name)) - millicode_call = 1; - - /* First the return pointer adjustment. Depending on exact calling - sequence this instruction may be skipped. */ - bfd_put_32 (stub_bfd, LDO_M4_R31_R31, loc); - - /* The next two instructions are the long branch itself. A long branch - is formed with "ldil" loading the upper bits of the target address - into a register, then branching with "be" which adds in the lower bits. - Long branches to millicode nullify the delay slot of the "be". */ - insn = hppa_rebuild_insn (stub_bfd, LDIL_R1, - hppa_field_adjust (sym_value, 0, e_lrsel), 21); - bfd_put_32 (stub_bfd, insn, loc + 4); - insn = hppa_rebuild_insn (stub_bfd, BE_SR4_R1 | (millicode_call ? 2 : 0), - hppa_field_adjust (sym_value, 0, e_rrsel) >> 2, - 17); - bfd_put_32 (stub_bfd, insn, loc + 8); - - if (!millicode_call) - { - /* The sequence to call this stub places the return pointer into %r31, - the final target expects the return pointer in %r2, so copy the - return pointer into the proper register. */ - bfd_put_32 (stub_bfd, COPY_R31_R2, loc + 12); - - /* Update the location and offsets. */ - stub_hash_table->location += 16; - stub_hash_table->offset += 16; - } - else - { - /* Update the location and offsets. */ - stub_hash_table->location += 12; - stub_hash_table->offset += 12; - } - - } - return true; -} - -/* External entry points for sizing and building linker stubs. */ - -/* Build all the stubs associated with the current output file. The - stubs are kept in a hash table attached to the main linker hash - table. This is called via hppaelf_finish in the linker. */ - -boolean -elf32_hppa_build_stubs (stub_bfd, info) - bfd *stub_bfd; - struct bfd_link_info *info; -{ - /* The stub BFD only has one section. */ - asection *stub_sec = stub_bfd->sections; - struct elf32_hppa_stub_hash_table *table; - unsigned int size; - void *args[2]; - - /* So we can pass both the BFD for the stubs and the link info - structure to the routine which actually builds stubs. */ - args[0] = stub_bfd; - args[1] = info; - - /* Allocate memory to hold the linker stubs. */ - size = bfd_section_size (stub_bfd, stub_sec); - stub_sec->contents = (unsigned char *) bfd_zalloc (stub_bfd, size); - if (stub_sec->contents == NULL) - return false; - table = elf32_hppa_hash_table(info)->stub_hash_table; - table->location = stub_sec->contents; - - /* Build the stubs as directed by the stub hash table. */ - elf32_hppa_stub_hash_traverse (table, elf32_hppa_build_one_stub, args); - - return true; -} - -/* Determine and set the size of the stub section for a final link. - - The basic idea here is to examine all the relocations looking for - PC-relative calls to a target that is unreachable with a "bl" - instruction or calls where the caller and callee disagree on the - location of their arguments or return value. */ - -boolean -elf32_hppa_size_stubs (stub_bfd, output_bfd, link_info) - bfd *stub_bfd; - bfd *output_bfd; - struct bfd_link_info *link_info; -{ - bfd *input_bfd; - asection *section, *stub_sec = 0; - Elf_Internal_Shdr *symtab_hdr; - Elf_Internal_Sym *local_syms, *isym, **all_local_syms; - Elf32_External_Sym *ext_syms, *esym; - unsigned int i, index, bfd_count = 0; - struct elf32_hppa_stub_hash_table *stub_hash_table = 0; - struct elf32_hppa_args_hash_table *args_hash_table = 0; - - /* Create and initialize the stub hash table. */ - stub_hash_table = ((struct elf32_hppa_stub_hash_table *) - bfd_malloc (sizeof (struct elf32_hppa_stub_hash_table))); - if (!stub_hash_table) - goto error_return; - - if (!elf32_hppa_stub_hash_table_init (stub_hash_table, stub_bfd, - elf32_hppa_stub_hash_newfunc)) - goto error_return; - - /* Likewise for the argument location hash table. */ - args_hash_table = ((struct elf32_hppa_args_hash_table *) - bfd_malloc (sizeof (struct elf32_hppa_args_hash_table))); - if (!args_hash_table) - goto error_return; - - if (!elf32_hppa_args_hash_table_init (args_hash_table, - elf32_hppa_args_hash_newfunc)) - goto error_return; - - /* Attach the hash tables to the main hash table. */ - elf32_hppa_hash_table(link_info)->stub_hash_table = stub_hash_table; - elf32_hppa_hash_table(link_info)->args_hash_table = args_hash_table; - - /* Count the number of input BFDs. */ - for (input_bfd = link_info->input_bfds; - input_bfd != NULL; - input_bfd = input_bfd->link_next) - bfd_count++; - - /* We want to read in symbol extension records only once. To do this - we need to read in the local symbols in parallel and save them for - later use; so hold pointers to the local symbols in an array. */ - all_local_syms - = (Elf_Internal_Sym **) bfd_malloc (sizeof (Elf_Internal_Sym *) - * bfd_count); - if (all_local_syms == NULL) - goto error_return; - memset (all_local_syms, 0, sizeof (Elf_Internal_Sym *) * bfd_count); - - /* Walk over all the input BFDs adding entries to the args hash table - for all the external functions. */ - for (input_bfd = link_info->input_bfds, index = 0; - input_bfd != NULL; - input_bfd = input_bfd->link_next, index++) - { - /* We'll need the symbol table in a second. */ - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - if (symtab_hdr->sh_info == 0) - continue; - - /* We need an array of the local symbols attached to the input bfd. - Unfortunately, we're going to have to read & swap them in. */ - local_syms - = (Elf_Internal_Sym *) bfd_malloc (symtab_hdr->sh_info - * sizeof (Elf_Internal_Sym)); - if (local_syms == NULL) - { - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - all_local_syms[index] = local_syms; - - ext_syms - = (Elf32_External_Sym *) bfd_malloc (symtab_hdr->sh_info - * sizeof (Elf32_External_Sym)); - if (ext_syms == NULL) - { - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - - if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0 - || bfd_read (ext_syms, 1, - (symtab_hdr->sh_info - * sizeof (Elf32_External_Sym)), input_bfd) - != (symtab_hdr->sh_info * sizeof (Elf32_External_Sym))) - { - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - free (ext_syms); - goto error_return; - } - - /* Swap the local symbols in. */ - isym = local_syms; - esym = ext_syms; - for (i = 0; i < symtab_hdr->sh_info; i++, esym++, isym++) - bfd_elf32_swap_symbol_in (input_bfd, esym, isym); - - /* Now we can free the external symbols. */ - free (ext_syms); - - if (elf32_hppa_read_symext_info (input_bfd, symtab_hdr, args_hash_table, - local_syms) == false) - { - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - } - - /* Magic as we know the stub bfd only has one section. */ - stub_sec = stub_bfd->sections; - - /* If generating a relocateable output file, then we don't - have to examine the relocs. */ - if (link_info->relocateable) - { - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - return true; - } - - /* Now that we have argument location information for all the global - functions we can start looking for stubs. */ - for (input_bfd = link_info->input_bfds, index = 0; - input_bfd != NULL; - input_bfd = input_bfd->link_next, index++) - { - /* We'll need the symbol table in a second. */ - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - if (symtab_hdr->sh_info == 0) - continue; - - local_syms = all_local_syms[index]; - - /* Walk over each section attached to the input bfd. */ - for (section = input_bfd->sections; - section != NULL; - section = section->next) - { - Elf_Internal_Shdr *input_rel_hdr; - Elf32_External_Rela *external_relocs, *erelaend, *erela; - Elf_Internal_Rela *internal_relocs, *irelaend, *irela; - - /* If there aren't any relocs, then there's nothing to do. */ - if ((section->flags & SEC_RELOC) == 0 - || section->reloc_count == 0) - continue; - - /* Allocate space for the external relocations. */ - external_relocs - = ((Elf32_External_Rela *) - bfd_malloc (section->reloc_count - * sizeof (Elf32_External_Rela))); - if (external_relocs == NULL) - { - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - - /* Likewise for the internal relocations. */ - internal_relocs - = ((Elf_Internal_Rela *) - bfd_malloc (section->reloc_count * sizeof (Elf_Internal_Rela))); - if (internal_relocs == NULL) - { - free (external_relocs); - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - - /* Read in the external relocs. */ - input_rel_hdr = &elf_section_data (section)->rel_hdr; - if (bfd_seek (input_bfd, input_rel_hdr->sh_offset, SEEK_SET) != 0 - || bfd_read (external_relocs, 1, input_rel_hdr->sh_size, - input_bfd) != input_rel_hdr->sh_size) - { - free (external_relocs); - free (internal_relocs); - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - - /* Swap in the relocs. */ - erela = external_relocs; - erelaend = erela + section->reloc_count; - irela = internal_relocs; - for (; erela < erelaend; erela++, irela++) - bfd_elf32_swap_reloca_in (input_bfd, erela, irela); - - /* We're done with the external relocs, free them. */ - free (external_relocs); - - /* Now examine each relocation. */ - irela = internal_relocs; - irelaend = irela + section->reloc_count; - for (; irela < irelaend; irela++) - { - long r_type, callee_args, caller_args, size_of_stub; - unsigned long r_index; - struct elf_link_hash_entry *hash; - struct elf32_hppa_stub_hash_entry *stub_hash; - struct elf32_hppa_args_hash_entry *args_hash; - Elf_Internal_Sym *sym; - asection *sym_sec; - const char *sym_name; - symvalue sym_value; - bfd_vma location, destination; - char *new_name = NULL; - - r_type = ELF32_R_TYPE (irela->r_info); - r_index = ELF32_R_SYM (irela->r_info); - - if (r_type < 0 || r_type >= (int) R_PARISC_UNIMPLEMENTED) - { - bfd_set_error (bfd_error_bad_value); - free (internal_relocs); - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - - /* Only look for stubs on call instructions or plabel - references. */ - if (r_type != R_PARISC_PCREL17F - && r_type != R_PARISC_PLABEL32 - && r_type != R_PARISC_PLABEL21L - && r_type != R_PARISC_PLABEL14R) - continue; - - /* Now determine the call target, its name, value, section - and argument relocation bits. */ - hash = NULL; - sym = NULL; - sym_sec = NULL; - if (r_index < symtab_hdr->sh_info) - { - /* It's a local symbol. */ - Elf_Internal_Shdr *hdr; - - sym = local_syms + r_index; - hdr = elf_elfsections (input_bfd)[sym->st_shndx]; - sym_sec = hdr->bfd_section; - sym_name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - sym_value = (ELF_ST_TYPE (sym->st_info) == STT_SECTION - ? 0 : sym->st_value); - destination = (sym_value - + sym_sec->output_offset - + sym_sec->output_section->vma); - - /* Tack on an ID so we can uniquely identify this local - symbol in the stub or arg info hash tables. */ - new_name = bfd_malloc (strlen (sym_name) + 10); - if (new_name == 0) - { - free (internal_relocs); - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - sprintf (new_name, "%s_%08x", sym_name, (int)sym_sec); - sym_name = new_name; - } - else - { - /* It's an external symbol. */ - long index; - - index = r_index - symtab_hdr->sh_info; - hash = elf_sym_hashes (input_bfd)[index]; - if (hash->root.type == bfd_link_hash_defined - || hash->root.type == bfd_link_hash_defweak) - { - sym_sec = hash->root.u.def.section; - sym_name = hash->root.root.string; - sym_value = hash->root.u.def.value; - destination = (sym_value - + sym_sec->output_offset - + sym_sec->output_section->vma); - } - else - { - bfd_set_error (bfd_error_bad_value); - free (internal_relocs); - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - } - - args_hash = elf32_hppa_args_hash_lookup (args_hash_table, - sym_name, false, false); - - /* Get both caller and callee argument information. */ - if (args_hash == NULL) - callee_args = 0; - else - callee_args = args_hash->arg_bits; - - /* For calls get the caller's bits from the addend of - the call relocation. For PLABELS the caller's bits - are assumed to have all args & return values in general - registers (0x155). */ - if (r_type == R_PARISC_PCREL17F) - caller_args = HPPA_R_ARG_RELOC (irela->r_addend); - else - caller_args = 0x155; - - /* Now determine where the call point is. */ - location = (section->output_offset - + section->output_section->vma - + irela->r_offset); - - /* We only care about the destination for PCREL function - calls (eg. we don't care for PLABELS). */ - if (r_type != R_PARISC_PCREL17F) - location = destination; - - /* Determine what (if any) linker stub is needed and its - size (in bytes). */ - size_of_stub = elf32_hppa_size_of_stub (callee_args, - caller_args, - location, - destination, - sym_name); - if (size_of_stub != 0) - { - char *stub_name; - unsigned int len; - - /* Get the name of this stub. */ - len = strlen (sym_name); - len += 23; - - stub_name = bfd_malloc (len); - if (!stub_name) - { - /* Because sym_name was mallocd above for local - symbols. */ - if (r_index < symtab_hdr->sh_info) - free (new_name); - - free (internal_relocs); - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - elf32_hppa_name_of_stub (caller_args, callee_args, - location, destination, stub_name); - strcat (stub_name + 22, sym_name); - - /* Because sym_name was malloced above for local symbols. */ - if (r_index < symtab_hdr->sh_info) - free (new_name); - - stub_hash - = elf32_hppa_stub_hash_lookup (stub_hash_table, stub_name, - false, false); - if (stub_hash != NULL) - { - /* The proper stub has already been created, nothing - else to do. */ - free (stub_name); - } - else - { - bfd_set_section_size (stub_bfd, stub_sec, - (bfd_section_size (stub_bfd, - stub_sec) - + size_of_stub)); - - /* Enter this entry into the linker stub hash table. */ - stub_hash - = elf32_hppa_stub_hash_lookup (stub_hash_table, - stub_name, true, true); - if (stub_hash == NULL) - { - free (stub_name); - free (internal_relocs); - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - goto error_return; - } - - /* We'll need these to determine the address that the - stub will branch to. */ - stub_hash->target_value = sym_value; - stub_hash->target_section = sym_sec; - } - free (stub_name); - } - } - /* We're done with the internal relocs, free them. */ - free (internal_relocs); - } - } - /* We're done with the local symbols, free them. */ - for (i = 0; i < bfd_count; i++) - if (all_local_syms[i]) - free (all_local_syms[i]); - free (all_local_syms); - return true; - -error_return: - /* Return gracefully, avoiding dangling references to the hash tables. */ - if (stub_hash_table) - { - elf32_hppa_hash_table(link_info)->stub_hash_table = NULL; - free (stub_hash_table); - } - if (args_hash_table) - { - elf32_hppa_hash_table(link_info)->args_hash_table = NULL; - free (args_hash_table); - } - /* Set the size of the stub section to zero since we're never going - to create them. Avoids losing when we try to get its contents - too. */ - bfd_set_section_size (stub_bfd, stub_sec, 0); - return false; -} - -/* Misc BFD support code. */ -#define bfd_elf32_bfd_reloc_type_lookup elf_hppa_reloc_type_lookup -#define bfd_elf32_bfd_is_local_label hppa_elf_is_local_label - -/* Symbol extension stuff. */ -#define bfd_elf32_set_section_contents elf32_hppa_set_section_contents -#define elf_backend_symbol_table_processing \ - elf32_hppa_backend_symbol_table_processing -#define elf_backend_begin_write_processing \ - elf32_hppa_backend_begin_write_processing -#define elf_backend_final_write_processing \ - elf32_hppa_backend_final_write_processing - -/* Stuff for the BFD linker. */ -#define elf_backend_relocate_section elf32_hppa_relocate_section -#define elf_backend_add_symbol_hook elf32_hppa_add_symbol_hook -#define elf_backend_link_output_symbol_hook \ - elf32_hppa_link_output_symbol_hook -#define bfd_elf32_bfd_link_hash_table_create \ - elf32_hppa_link_hash_table_create - -#define TARGET_BIG_SYM bfd_elf32_hppa_vec -#define TARGET_BIG_NAME "elf32-hppa" -#define ELF_ARCH bfd_arch_hppa -#define ELF_MACHINE_CODE EM_PARISC -#define ELF_MAXPAGESIZE 0x1000 - -#include "elf32-target.h" diff --git a/contrib/gdb/bfd/elf32-hppa.h b/contrib/gdb/bfd/elf32-hppa.h deleted file mode 100644 index 63ee522..0000000 --- a/contrib/gdb/bfd/elf32-hppa.h +++ /dev/null @@ -1,152 +0,0 @@ -/* ELF32/HPPA support - - This file contains ELF32/HPPA relocation support as specified - in the Stratus FTX/Golf Object File Format (SED-1762) dated - February 1994. - - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - - Written by: - - Center for Software Science - Department of Computer Science - University of Utah - - 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. */ - -#ifndef _ELF32_HPPA_H -#define _ELF32_HPPA_H - -#include "elf-bfd.h" -#include "libhppa.h" -#include "elf/hppa.h" - -/* ELF/HPPA relocation types */ - -typedef enum - { - /* Address relocation types - These relocation types do simple base + offset relocations. */ - - R_PARISC_NONE = 0x00, - R_PARISC_DIR32 = 0x01, - R_PARISC_DIR21L = 0x02, - R_PARISC_DIR17R = 0x03, - R_PARISC_DIR17F = 0x04, - R_PARISC_DIR14R = 0x06, - - /* PC-relative relocation types - Typically used for calls. - Note PCREL17C and PCREL17F differ only in overflow handling. - PCREL17C never reports a relocation error. - - When supporting argument relocations, function calls must be - accompanied by parameter relocation information. This information is - carried in the ten high-order bits of the addend field. The remaining - 22 bits of of the addend field are sign-extended to form the Addend. - - Note the code to build argument relocations depends on the - addend being zero. A consequence of this limitation is GAS - can not perform relocation reductions for function symbols. */ - R_PARISC_PCREL21L = 0x0a, - R_PARISC_PCREL17R = 0x0b, - R_PARISC_PCREL17F = 0x0c, - R_PARISC_PCREL17C = 0x0d, - R_PARISC_PCREL14R = 0x0e, - R_PARISC_PCREL14F = 0x0f, - - /* DP-relative relocation types. */ - R_PARISC_DPREL21L = 0x12, - R_PARISC_DPREL14R = 0x16, - R_PARISC_DPREL14F = 0x17, - - /* Data linkage table (DLT) relocation types - - SOM DLT_REL fixup requests are used to for static data references - from position-independent code within shared libraries. They are - similar to the GOT relocation types in some SVR4 implementations. */ - - R_PARISC_DLTREL21L = 0x1a, - R_PARISC_DLTREL14R = 0x1e, - R_PARISC_DLTREL14F = 0x1f, - - /* DLT indirect relocation types */ - R_PARISC_DLTIND21L = 0x22, - R_PARISC_DLTIND14R = 0x26, - R_PARISC_DLTIND14F = 0x27, - - /* Base relative relocation types. Ugh. These imply lots of state */ - R_PARISC_SETBASE = 0x28, - R_PARISC_BASEREL32 = 0x29, - R_PARISC_BASEREL21L = 0x2a, - R_PARISC_BASEREL17R = 0x2b, - R_PARISC_BASEREL17F = 0x2c, - R_PARISC_BASEREL14R = 0x2e, - R_PARISC_BASEREL14F = 0x2f, - - /* Segment relative relocation types. */ - R_PARISC_TEXTREL32 = 0x31, - R_PARISC_DATAREL32 = 0x39, - - /* Plabel relocation types. */ - R_PARISC_PLABEL32 = 0x41, - R_PARISC_PLABEL21L = 0x42, - R_PARISC_PLABEL14R = 0x46, - - /* PLT relocations. */ - R_PARISC_PLTIND21L = 0x82, - R_PARISC_PLTIND14R = 0x86, - R_PARISC_PLTIND14F = 0x87, - - /* Misc relocation types. */ - R_PARISC_COPY = 0x88, - R_PARISC_GLOB_DAT = 0x89, - R_PARISC_JMP_SLOT = 0x8a, - R_PARISC_RELATIVE = 0x8b, - R_PARISC_UNIMPLEMENTED, - } -elf32_hppa_reloc_type; - -#define ELF_HOWTO_TABLE_SIZE R_PARISC_UNIMPLEMENTED + 1 -#define N_PARISC_RELOCS R_PARISC_UNIMPLEMENTED + 1 - -/* Define groups of basic relocations. FIXME: These should - be the only basic relocations created by GAS. The rest - should be internal to the BFD backend. - - The idea is both SOM and ELF define these basic relocation - types so they map into a SOM or ELF specific relocation - as appropriate. This allows GAS to share much more code - between the two target object formats. */ - -#define R_HPPA_NONE R_PARISC_NONE -#define R_HPPA R_PARISC_DIR32 -#define R_HPPA_GOTOFF R_PARISC_DPREL21L -#define R_HPPA_PCREL_CALL R_PARISC_PCREL21L -#define R_HPPA_ABS_CALL R_PARISC_DIR17F -#define R_HPPA_COMPLEX R_PARISC_UNIMPLEMENTED - -elf32_hppa_reloc_type **hppa_elf_gen_reloc_type - PARAMS ((bfd *, elf32_hppa_reloc_type, int, int, int)); - -boolean elf32_hppa_size_stubs - PARAMS ((bfd *, bfd *, struct bfd_link_info *)); - -boolean elf32_hppa_build_stubs - PARAMS ((bfd *, struct bfd_link_info *)); - -#endif /* _ELF32_HPPA_H */ diff --git a/contrib/gdb/bfd/elf32-i386.c b/contrib/gdb/bfd/elf32-i386.c deleted file mode 100644 index 3b39aac..0000000 --- a/contrib/gdb/bfd/elf32-i386.c +++ /dev/null @@ -1,1546 +0,0 @@ -/* Intel 80386/80486-specific support for 32-bit ELF - Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "elf-bfd.h" - -static reloc_howto_type *elf_i386_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static void elf_i386_info_to_howto - PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *)); -static void elf_i386_info_to_howto_rel - PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *)); -static boolean elf_i386_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static boolean elf_i386_adjust_dynamic_symbol - PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); -static boolean elf_i386_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf_i386_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static boolean elf_i386_finish_dynamic_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, - Elf_Internal_Sym *)); -static boolean elf_i386_finish_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); - -#define USE_REL 1 /* 386 uses REL relocations instead of RELA */ - -enum reloc_type - { - R_386_NONE = 0, - R_386_32, - R_386_PC32, - R_386_GOT32, - R_386_PLT32, - R_386_COPY, - R_386_GLOB_DAT, - R_386_JUMP_SLOT, - R_386_RELATIVE, - R_386_GOTOFF, - R_386_GOTPC, - R_386_max - }; - -#if 0 -static CONST char *CONST reloc_type_names[] = -{ - "R_386_NONE", - "R_386_32", - "R_386_PC32", - "R_386_GOT32", - "R_386_PLT32", - "R_386_COPY", - "R_386_GLOB_DAT", - "R_386_JUMP_SLOT", - "R_386_RELATIVE", - "R_386_GOTOFF", - "R_386_GOTPC", -}; -#endif - -static reloc_howto_type elf_howto_table[]= -{ - HOWTO(R_386_NONE, 0,0, 0,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_NONE", true,0x00000000,0x00000000,false), - HOWTO(R_386_32, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_32", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_PC32, 0,2,32,true, 0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_PC32", true,0xffffffff,0xffffffff,true), - HOWTO(R_386_GOT32, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GOT32", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_PLT32, 0,2,32,true,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_PLT32", true,0xffffffff,0xffffffff,true), - HOWTO(R_386_COPY, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_COPY", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_GLOB_DAT, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GLOB_DAT", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_JUMP_SLOT, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_JUMP_SLOT",true,0xffffffff,0xffffffff,false), - HOWTO(R_386_RELATIVE, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_RELATIVE", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_GOTOFF, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GOTOFF", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_GOTPC, 0,2,32,true,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GOTPC", true,0xffffffff,0xffffffff,true), -}; - -#ifdef DEBUG_GEN_RELOC -#define TRACE(str) fprintf (stderr, "i386 bfd reloc lookup %d (%s)\n", code, str) -#else -#define TRACE(str) -#endif - -static reloc_howto_type * -elf_i386_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - switch (code) - { - case BFD_RELOC_NONE: - TRACE ("BFD_RELOC_NONE"); - return &elf_howto_table[ (int)R_386_NONE ]; - - case BFD_RELOC_32: - TRACE ("BFD_RELOC_32"); - return &elf_howto_table[ (int)R_386_32 ]; - - case BFD_RELOC_32_PCREL: - TRACE ("BFD_RELOC_PC32"); - return &elf_howto_table[ (int)R_386_PC32 ]; - - case BFD_RELOC_386_GOT32: - TRACE ("BFD_RELOC_386_GOT32"); - return &elf_howto_table[ (int)R_386_GOT32 ]; - - case BFD_RELOC_386_PLT32: - TRACE ("BFD_RELOC_386_PLT32"); - return &elf_howto_table[ (int)R_386_PLT32 ]; - - case BFD_RELOC_386_COPY: - TRACE ("BFD_RELOC_386_COPY"); - return &elf_howto_table[ (int)R_386_COPY ]; - - case BFD_RELOC_386_GLOB_DAT: - TRACE ("BFD_RELOC_386_GLOB_DAT"); - return &elf_howto_table[ (int)R_386_GLOB_DAT ]; - - case BFD_RELOC_386_JUMP_SLOT: - TRACE ("BFD_RELOC_386_JUMP_SLOT"); - return &elf_howto_table[ (int)R_386_JUMP_SLOT ]; - - case BFD_RELOC_386_RELATIVE: - TRACE ("BFD_RELOC_386_RELATIVE"); - return &elf_howto_table[ (int)R_386_RELATIVE ]; - - case BFD_RELOC_386_GOTOFF: - TRACE ("BFD_RELOC_386_GOTOFF"); - return &elf_howto_table[ (int)R_386_GOTOFF ]; - - case BFD_RELOC_386_GOTPC: - TRACE ("BFD_RELOC_386_GOTPC"); - return &elf_howto_table[ (int)R_386_GOTPC ]; - - default: - break; - } - - TRACE ("Unknown"); - return 0; -} - -static void -elf_i386_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf32_Internal_Rela *dst; -{ - BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_386_max); - - cache_ptr->howto = &elf_howto_table[ELF32_R_TYPE(dst->r_info)]; -} - -static void -elf_i386_info_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf32_Internal_Rel *dst; -{ - BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_386_max); - - cache_ptr->howto = &elf_howto_table[ELF32_R_TYPE(dst->r_info)]; -} - -/* Functions for the i386 ELF linker. */ - -/* The name of the dynamic interpreter. This is put in the .interp - section. */ - -#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1" - -/* The size in bytes of an entry in the procedure linkage table. */ - -#define PLT_ENTRY_SIZE 16 - -/* The first entry in an absolute procedure linkage table looks like - this. See the SVR4 ABI i386 supplement to see how this works. */ - -static const bfd_byte elf_i386_plt0_entry[PLT_ENTRY_SIZE] = -{ - 0xff, 0x35, /* pushl contents of address */ - 0, 0, 0, 0, /* replaced with address of .got + 4. */ - 0xff, 0x25, /* jmp indirect */ - 0, 0, 0, 0, /* replaced with address of .got + 8. */ - 0, 0, 0, 0 /* pad out to 16 bytes. */ -}; - -/* Subsequent entries in an absolute procedure linkage table look like - this. */ - -static const bfd_byte elf_i386_plt_entry[PLT_ENTRY_SIZE] = -{ - 0xff, 0x25, /* jmp indirect */ - 0, 0, 0, 0, /* replaced with address of this symbol in .got. */ - 0x68, /* pushl immediate */ - 0, 0, 0, 0, /* replaced with offset into relocation table. */ - 0xe9, /* jmp relative */ - 0, 0, 0, 0 /* replaced with offset to start of .plt. */ -}; - -/* The first entry in a PIC procedure linkage table look like this. */ - -static const bfd_byte elf_i386_pic_plt0_entry[PLT_ENTRY_SIZE] = -{ - 0xff, 0xb3, 4, 0, 0, 0, /* pushl 4(%ebx) */ - 0xff, 0xa3, 8, 0, 0, 0, /* jmp *8(%ebx) */ - 0, 0, 0, 0 /* pad out to 16 bytes. */ -}; - -/* Subsequent entries in a PIC procedure linkage table look like this. */ - -static const bfd_byte elf_i386_pic_plt_entry[PLT_ENTRY_SIZE] = -{ - 0xff, 0xa3, /* jmp *offset(%ebx) */ - 0, 0, 0, 0, /* replaced with offset of this symbol in .got. */ - 0x68, /* pushl immediate */ - 0, 0, 0, 0, /* replaced with offset into relocation table. */ - 0xe9, /* jmp relative */ - 0, 0, 0, 0 /* replaced with offset to start of .plt. */ -}; - -/* Look through the relocs for a section during the first phase, and - allocate space in the global offset table or procedure linkage - table. */ - -static boolean -elf_i386_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; -{ - bfd *dynobj; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - bfd_vma *local_got_offsets; - const Elf_Internal_Rela *rel; - const Elf_Internal_Rela *rel_end; - asection *sgot; - asection *srelgot; - asection *sreloc; - - if (info->relocateable) - return true; - - dynobj = elf_hash_table (info)->dynobj; - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (abfd); - local_got_offsets = elf_local_got_offsets (abfd); - - sgot = NULL; - srelgot = NULL; - sreloc = NULL; - - rel_end = relocs + sec->reloc_count; - for (rel = relocs; rel < rel_end; rel++) - { - unsigned long r_symndx; - struct elf_link_hash_entry *h; - - r_symndx = ELF32_R_SYM (rel->r_info); - - if (r_symndx < symtab_hdr->sh_info) - h = NULL; - else - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - - /* Some relocs require a global offset table. */ - if (dynobj == NULL) - { - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_386_GOT32: - case R_386_GOTOFF: - case R_386_GOTPC: - elf_hash_table (info)->dynobj = dynobj = abfd; - if (! _bfd_elf_create_got_section (dynobj, info)) - return false; - break; - - default: - break; - } - } - - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_386_GOT32: - /* This symbol requires a global offset table entry. */ - - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - } - - if (srelgot == NULL - && (h != NULL || info->shared)) - { - srelgot = bfd_get_section_by_name (dynobj, ".rel.got"); - if (srelgot == NULL) - { - srelgot = bfd_make_section (dynobj, ".rel.got"); - if (srelgot == NULL - || ! bfd_set_section_flags (dynobj, srelgot, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, srelgot, 2)) - return false; - } - } - - if (h != NULL) - { - if (h->got_offset != (bfd_vma) -1) - { - /* We have already allocated space in the .got. */ - break; - } - h->got_offset = sgot->_raw_size; - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - srelgot->_raw_size += sizeof (Elf32_External_Rel); - } - else - { - /* This is a global offset table entry for a local - symbol. */ - if (local_got_offsets == NULL) - { - size_t size; - register unsigned int i; - - size = symtab_hdr->sh_info * sizeof (bfd_vma); - local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size); - if (local_got_offsets == NULL) - return false; - elf_local_got_offsets (abfd) = local_got_offsets; - for (i = 0; i < symtab_hdr->sh_info; i++) - local_got_offsets[i] = (bfd_vma) -1; - } - if (local_got_offsets[r_symndx] != (bfd_vma) -1) - { - /* We have already allocated space in the .got. */ - break; - } - local_got_offsets[r_symndx] = sgot->_raw_size; - - if (info->shared) - { - /* If we are generating a shared object, we need to - output a R_386_RELATIVE reloc so that the dynamic - linker can adjust this GOT entry. */ - srelgot->_raw_size += sizeof (Elf32_External_Rel); - } - } - - sgot->_raw_size += 4; - - break; - - case R_386_PLT32: - /* This symbol requires a procedure linkage table entry. We - actually build the entry in adjust_dynamic_symbol, - because this might be a case of linking PIC code which is - never referenced by a dynamic object, in which case we - don't need to generate a procedure linkage table entry - after all. */ - - /* If this is a local symbol, we resolve it directly without - creating a procedure linkage table entry. */ - if (h == NULL) - continue; - - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; - - break; - - case R_386_32: - case R_386_PC32: - if (info->shared - && (sec->flags & SEC_ALLOC) != 0 - && (ELF32_R_TYPE (rel->r_info) != R_386_PC32 || h != NULL)) - { - /* When creating a shared object, we must copy these - reloc types into the output file. We create a reloc - section in dynobj and make room for this reloc. */ - if (sreloc == NULL) - { - const char *name; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return false; - - BFD_ASSERT (strncmp (name, ".rel", 4) == 0 - && strcmp (bfd_get_section_name (abfd, sec), - name + 4) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - if (sreloc == NULL) - { - sreloc = bfd_make_section (dynobj, name); - if (sreloc == NULL - || ! bfd_set_section_flags (dynobj, sreloc, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, sreloc, 2)) - return false; - } - } - - sreloc->_raw_size += sizeof (Elf32_External_Rel); - } - - break; - - default: - break; - } - } - - return true; -} - -/* Adjust a symbol defined by a dynamic object and referenced by a - regular object. The current definition is in some section of the - dynamic object, but we're not including those sections. We have to - change the definition to something the rest of the link can - understand. */ - -static boolean -elf_i386_adjust_dynamic_symbol (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; -{ - bfd *dynobj; - asection *s; - unsigned int power_of_two; - - dynobj = elf_hash_table (info)->dynobj; - - /* Make sure we know what is going on here. */ - BFD_ASSERT (dynobj != NULL - && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) - || h->weakdef != NULL - || ((h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_REF_REGULAR) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0))); - - /* If this is a function, put it in the procedure linkage table. We - will fill in the contents of the procedure linkage table later, - when we know the address of the .got section. */ - if (h->type == STT_FUNC - || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) - { - if (! info->shared - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0) - { - /* This case can occur if we saw a PLT32 reloc in an input - file, but the symbol was never referred to by a dynamic - object. In such a case, we don't actually need to build - a procedure linkage table, and we can just do a PC32 - reloc instead. */ - BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0); - return true; - } - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - s = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (s != NULL); - - /* If this is the first .plt entry, make room for the special - first entry. */ - if (s->_raw_size == 0) - s->_raw_size += PLT_ENTRY_SIZE; - - /* If this symbol is not defined in a regular file, and we are - not generating a shared library, then set the symbol to this - location in the .plt. This is required to make function - pointers compare as equal between the normal executable and - the shared library. */ - if (! info->shared - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; - } - - h->plt_offset = s->_raw_size; - - /* Make room for this entry. */ - s->_raw_size += PLT_ENTRY_SIZE; - - /* We also need to make an entry in the .got.plt section, which - will be placed in the .got section by the linker script. */ - - s = bfd_get_section_by_name (dynobj, ".got.plt"); - BFD_ASSERT (s != NULL); - s->_raw_size += 4; - - /* We also need to make an entry in the .rel.plt section. */ - - s = bfd_get_section_by_name (dynobj, ".rel.plt"); - BFD_ASSERT (s != NULL); - s->_raw_size += sizeof (Elf32_External_Rel); - - return true; - } - - /* If this is a weak symbol, and there is a real definition, the - processor independent code will have arranged for us to see the - real definition first, and we can just use the same value. */ - if (h->weakdef != NULL) - { - BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined - || h->weakdef->root.type == bfd_link_hash_defweak); - h->root.u.def.section = h->weakdef->root.u.def.section; - h->root.u.def.value = h->weakdef->root.u.def.value; - return true; - } - - /* This is a reference to a symbol defined by a dynamic object which - is not a function. */ - - /* If we are creating a shared library, we must presume that the - only references to the symbol are via the global offset table. - For such cases we need not do anything here; the relocations will - be handled correctly by relocate_section. */ - if (info->shared) - return true; - - /* We must allocate the symbol in our .dynbss section, which will - become part of the .bss section of the executable. There will be - an entry for this symbol in the .dynsym section. The dynamic - object will contain position independent code, so all references - from the dynamic object to this symbol will go through the global - offset table. The dynamic linker will use the .dynsym entry to - determine the address it must put in the global offset table, so - both the dynamic object and the regular object will refer to the - same memory location for the variable. */ - - s = bfd_get_section_by_name (dynobj, ".dynbss"); - BFD_ASSERT (s != NULL); - - /* If the symbol is currently defined in the .bss section of the - dynamic object, then it is OK to simply initialize it to zero. - If the symbol is in some other section, we must generate a - R_386_COPY reloc to tell the dynamic linker to copy the initial - value out of the dynamic object and into the runtime process - image. We need to remember the offset into the .rel.bss section - we are going to use. */ - if ((h->root.u.def.section->flags & SEC_LOAD) != 0) - { - asection *srel; - - srel = bfd_get_section_by_name (dynobj, ".rel.bss"); - BFD_ASSERT (srel != NULL); - srel->_raw_size += sizeof (Elf32_External_Rel); - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY; - } - - /* We need to figure out the alignment required for this symbol. I - have no idea how ELF linkers handle this. */ - power_of_two = bfd_log2 (h->size); - if (power_of_two > 3) - power_of_two = 3; - - /* Apply the required alignment. */ - s->_raw_size = BFD_ALIGN (s->_raw_size, - (bfd_size_type) (1 << power_of_two)); - if (power_of_two > bfd_get_section_alignment (dynobj, s)) - { - if (! bfd_set_section_alignment (dynobj, s, power_of_two)) - return false; - } - - /* Define the symbol as being at this point in the section. */ - h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; - - /* Increment the section size to make room for the symbol. */ - s->_raw_size += h->size; - - return true; -} - -/* Set the sizes of the dynamic sections. */ - -static boolean -elf_i386_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *s; - boolean plt; - boolean relocs; - boolean reltext; - - dynobj = elf_hash_table (info)->dynobj; - BFD_ASSERT (dynobj != NULL); - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Set the contents of the .interp section to the interpreter. */ - if (! info->shared) - { - s = bfd_get_section_by_name (dynobj, ".interp"); - BFD_ASSERT (s != NULL); - s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; - s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; - } - } - else - { - /* We may have created entries in the .rel.got section. - However, if we are not creating the dynamic sections, we will - not actually use these entries. Reset the size of .rel.got, - which will cause it to get stripped from the output file - below. */ - s = bfd_get_section_by_name (dynobj, ".rel.got"); - if (s != NULL) - s->_raw_size = 0; - } - - /* The check_relocs and adjust_dynamic_symbol entry points have - determined the sizes of the various dynamic sections. Allocate - memory for them. */ - plt = false; - relocs = false; - reltext = false; - for (s = dynobj->sections; s != NULL; s = s->next) - { - const char *name; - boolean strip; - - if ((s->flags & SEC_IN_MEMORY) == 0) - continue; - - /* It's OK to base decisions on the section name, because none - of the dynobj section names depend upon the input files. */ - name = bfd_get_section_name (dynobj, s); - - strip = false; - - if (strcmp (name, ".plt") == 0) - { - if (s->_raw_size == 0) - { - /* Strip this section if we don't need it; see the - comment below. */ - strip = true; - } - else - { - /* Remember whether there is a PLT. */ - plt = true; - } - } - else if (strncmp (name, ".rel", 4) == 0) - { - if (s->_raw_size == 0) - { - /* If we don't need this section, strip it from the - output file. This is mostly to handle .rel.bss and - .rel.plt. We must create both sections in - create_dynamic_sections, because they must be created - before the linker maps input sections to output - sections. The linker does that before - adjust_dynamic_symbol is called, and it is that - function which decides whether anything needs to go - into these sections. */ - strip = true; - } - else - { - asection *target; - - /* Remember whether there are any reloc sections other - than .rel.plt. */ - if (strcmp (name, ".rel.plt") != 0) - { - relocs = true; - - /* If this relocation section applies to a read only - section, then we probably need a DT_TEXTREL - entry. The entries in the .rel.plt section - really apply to the .got section, which we - created ourselves and so know is not readonly. */ - target = bfd_get_section_by_name (output_bfd, name + 4); - if (target != NULL - && (target->flags & SEC_READONLY) != 0) - reltext = true; - } - - /* We use the reloc_count field as a counter if we need - to copy relocs into the output file. */ - s->reloc_count = 0; - } - } - else if (strncmp (name, ".got", 4) != 0) - { - /* It's not one of our sections, so don't allocate space. */ - continue; - } - - if (strip) - { - asection **spp; - - for (spp = &s->output_section->owner->sections; - *spp != s->output_section; - spp = &(*spp)->next) - ; - *spp = s->output_section->next; - --s->output_section->owner->section_count; - - continue; - } - - /* Allocate memory for the section contents. */ - s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) - return false; - } - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in elf_i386_finish_dynamic_sections, but we - must add the entries now so that we get the correct size for - the .dynamic section. The DT_DEBUG entry is filled in by the - dynamic linker and used by the debugger. */ - if (! info->shared) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0)) - return false; - } - - if (plt) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_REL) - || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0)) - return false; - } - - if (relocs) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_REL, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_RELSZ, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_RELENT, - sizeof (Elf32_External_Rel))) - return false; - } - - if (reltext) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0)) - return false; - } - } - - return true; -} - -/* Relocate an i386 ELF section. */ - -static boolean -elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; -{ - bfd *dynobj; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - bfd_vma *local_got_offsets; - asection *sgot; - asection *splt; - asection *sreloc; - Elf_Internal_Rela *rel; - Elf_Internal_Rela *relend; - - dynobj = elf_hash_table (info)->dynobj; - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (input_bfd); - local_got_offsets = elf_local_got_offsets (input_bfd); - - sgot = NULL; - splt = NULL; - sreloc = NULL; - - rel = relocs; - relend = relocs + input_section->reloc_count; - for (; rel < relend; rel++) - { - int r_type; - reloc_howto_type *howto; - unsigned long r_symndx; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; - asection *sec; - bfd_vma relocation; - bfd_reloc_status_type r; - - r_type = ELF32_R_TYPE (rel->r_info); - if (r_type < 0 || r_type >= (int) R_386_max) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - howto = elf_howto_table + r_type; - - r_symndx = ELF32_R_SYM (rel->r_info); - - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - bfd_vma val; - - sec = local_sections[r_symndx]; - val = bfd_get_32 (input_bfd, contents + rel->r_offset); - val += sec->output_offset + sym->st_value; - bfd_put_32 (input_bfd, val, contents + rel->r_offset); - } - } - - continue; - } - - /* This is a final link. */ - h = NULL; - sym = NULL; - sec = NULL; - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); - } - else - { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - if (r_type == R_386_GOTPC - || (r_type == R_386_PLT32 - && h->plt_offset != (bfd_vma) -1) - || (r_type == R_386_GOT32 - && elf_hash_table (info)->dynamic_sections_created - && (! info->shared - || ! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)) - || (info->shared - && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0) - && (r_type == R_386_32 - || r_type == R_386_PC32) - && (input_section->flags & SEC_ALLOC) != 0)) - { - /* In these cases, we don't need the relocation - value. We check specially because in some - obscure cases sec->output_section will be NULL. */ - relocation = 0; - } - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else if (info->shared && !info->symbolic) - relocation = 0; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset))) - return false; - relocation = 0; - } - } - - switch (r_type) - { - case R_386_GOT32: - /* Relocation is to the entry for this symbol in the global - offset table. */ - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - } - - if (h != NULL) - { - bfd_vma off; - - off = h->got_offset; - BFD_ASSERT (off != (bfd_vma) -1); - - if (! elf_hash_table (info)->dynamic_sections_created - || (info->shared - && info->symbolic - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) - { - /* This is actually a static link, or it is a - -Bsymbolic link and the symbol is defined - locally. We must initialize this entry in the - global offset table. Since the offset must - always be a multiple of 4, we use the least - significant bit to record whether we have - initialized it already. - - When doing a dynamic link, we create a .rel.got - relocation entry to initialize the value. This - is done in the finish_dynamic_symbol routine. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_32 (output_bfd, relocation, - sgot->contents + off); - h->got_offset |= 1; - } - } - - relocation = sgot->output_offset + off; - } - else - { - bfd_vma off; - - BFD_ASSERT (local_got_offsets != NULL - && local_got_offsets[r_symndx] != (bfd_vma) -1); - - off = local_got_offsets[r_symndx]; - - /* The offset must always be a multiple of 4. We use - the least significant bit to record whether we have - already generated the necessary reloc. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_32 (output_bfd, relocation, sgot->contents + off); - - if (info->shared) - { - asection *srelgot; - Elf_Internal_Rel outrel; - - srelgot = bfd_get_section_by_name (dynobj, ".rel.got"); - BFD_ASSERT (srelgot != NULL); - - outrel.r_offset = (sgot->output_section->vma - + sgot->output_offset - + off); - outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); - bfd_elf32_swap_reloc_out (output_bfd, &outrel, - (((Elf32_External_Rel *) - srelgot->contents) - + srelgot->reloc_count)); - ++srelgot->reloc_count; - } - - local_got_offsets[r_symndx] |= 1; - } - - relocation = sgot->output_offset + off; - } - - break; - - case R_386_GOTOFF: - /* Relocation is relative to the start of the global offset - table. */ - - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - } - - /* Note that sgot->output_offset is not involved in this - calculation. We always want the start of .got. If we - defined _GLOBAL_OFFSET_TABLE in a different way, as is - permitted by the ABI, we might have to change this - calculation. */ - relocation -= sgot->output_section->vma; - - break; - - case R_386_GOTPC: - /* Use global offset table as symbol value. */ - - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - } - - relocation = sgot->output_section->vma; - - break; - - case R_386_PLT32: - /* Relocation is to the entry for this symbol in the - procedure linkage table. */ - - /* Resolve a PLT32 reloc again a local symbol directly, - without using the procedure linkage table. */ - if (h == NULL) - break; - - if (h->plt_offset == (bfd_vma) -1) - { - /* We didn't make a PLT entry for this symbol. This - happens when statically linking PIC code, or when - using -Bsymbolic. */ - break; - } - - if (splt == NULL) - { - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL); - } - - relocation = (splt->output_section->vma - + splt->output_offset - + h->plt_offset); - - break; - - case R_386_32: - case R_386_PC32: - if (info->shared - && (input_section->flags & SEC_ALLOC) != 0 - && (r_type != R_386_PC32 - || (h != NULL - && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)))) - { - Elf_Internal_Rel outrel; - boolean relocate; - - /* When generating a shared object, these relocations - are copied into the output file to be resolved at run - time. */ - - if (sreloc == NULL) - { - const char *name; - - name = (bfd_elf_string_from_elf_section - (input_bfd, - elf_elfheader (input_bfd)->e_shstrndx, - elf_section_data (input_section)->rel_hdr.sh_name)); - if (name == NULL) - return false; - - BFD_ASSERT (strncmp (name, ".rel", 4) == 0 - && strcmp (bfd_get_section_name (input_bfd, - input_section), - name + 4) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - BFD_ASSERT (sreloc != NULL); - } - - outrel.r_offset = (rel->r_offset - + input_section->output_section->vma - + input_section->output_offset); - if (r_type == R_386_PC32) - { - BFD_ASSERT (h != NULL && h->dynindx != -1); - relocate = false; - outrel.r_info = ELF32_R_INFO (h->dynindx, R_386_PC32); - } - else - { - if (h == NULL - || (info->symbolic - && (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) != 0)) - { - relocate = true; - outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); - } - else - { - BFD_ASSERT (h->dynindx != -1); - relocate = false; - outrel.r_info = ELF32_R_INFO (h->dynindx, R_386_32); - } - } - - bfd_elf32_swap_reloc_out (output_bfd, &outrel, - (((Elf32_External_Rel *) - sreloc->contents) - + sreloc->reloc_count)); - ++sreloc->reloc_count; - - /* If this reloc is against an external symbol, we do - not want to fiddle with the addend. Otherwise, we - need to include the symbol value so that it becomes - an addend for the dynamic reloc. */ - if (! relocate) - continue; - } - - break; - - default: - break; - } - - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, - relocation, (bfd_vma) 0); - - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (h != NULL) - name = h->root.root.string; - else - { - name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - if (name == NULL) - return false; - if (*name == '\0') - name = bfd_section_name (input_bfd, sec); - } - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, - input_bfd, input_section, rel->r_offset))) - return false; - } - break; - } - } - } - - return true; -} - -/* Finish up dynamic symbol handling. We set the contents of various - dynamic sections here. */ - -static boolean -elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym) - bfd *output_bfd; - struct bfd_link_info *info; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; -{ - bfd *dynobj; - - dynobj = elf_hash_table (info)->dynobj; - - if (h->plt_offset != (bfd_vma) -1) - { - asection *splt; - asection *sgot; - asection *srel; - bfd_vma plt_index; - bfd_vma got_offset; - Elf_Internal_Rel rel; - - /* This symbol has an entry in the procedure linkage table. Set - it up. */ - - BFD_ASSERT (h->dynindx != -1); - - splt = bfd_get_section_by_name (dynobj, ".plt"); - sgot = bfd_get_section_by_name (dynobj, ".got.plt"); - srel = bfd_get_section_by_name (dynobj, ".rel.plt"); - BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL); - - /* Get the index in the procedure linkage table which - corresponds to this symbol. This is the index of this symbol - in all the symbols for which we are making plt entries. The - first entry in the procedure linkage table is reserved. */ - plt_index = h->plt_offset / PLT_ENTRY_SIZE - 1; - - /* Get the offset into the .got table of the entry that - corresponds to this function. Each .got entry is 4 bytes. - The first three are reserved. */ - got_offset = (plt_index + 3) * 4; - - /* Fill in the entry in the procedure linkage table. */ - if (! info->shared) - { - memcpy (splt->contents + h->plt_offset, elf_i386_plt_entry, - PLT_ENTRY_SIZE); - bfd_put_32 (output_bfd, - (sgot->output_section->vma - + sgot->output_offset - + got_offset), - splt->contents + h->plt_offset + 2); - } - else - { - memcpy (splt->contents + h->plt_offset, elf_i386_pic_plt_entry, - PLT_ENTRY_SIZE); - bfd_put_32 (output_bfd, got_offset, - splt->contents + h->plt_offset + 2); - } - - bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel), - splt->contents + h->plt_offset + 7); - bfd_put_32 (output_bfd, - (h->plt_offset + PLT_ENTRY_SIZE), - splt->contents + h->plt_offset + 12); - - /* Fill in the entry in the global offset table. */ - bfd_put_32 (output_bfd, - (splt->output_section->vma - + splt->output_offset - + h->plt_offset - + 6), - sgot->contents + got_offset); - - /* Fill in the entry in the .rel.plt section. */ - rel.r_offset = (sgot->output_section->vma - + sgot->output_offset - + got_offset); - rel.r_info = ELF32_R_INFO (h->dynindx, R_386_JUMP_SLOT); - bfd_elf32_swap_reloc_out (output_bfd, &rel, - ((Elf32_External_Rel *) srel->contents - + plt_index)); - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - /* Mark the symbol as undefined, rather than as defined in - the .plt section. Leave the value alone. */ - sym->st_shndx = SHN_UNDEF; - } - } - - if (h->got_offset != (bfd_vma) -1) - { - asection *sgot; - asection *srel; - Elf_Internal_Rel rel; - - /* This symbol has an entry in the global offset table. Set it - up. */ - - BFD_ASSERT (h->dynindx != -1); - - sgot = bfd_get_section_by_name (dynobj, ".got"); - srel = bfd_get_section_by_name (dynobj, ".rel.got"); - BFD_ASSERT (sgot != NULL && srel != NULL); - - rel.r_offset = (sgot->output_section->vma - + sgot->output_offset - + (h->got_offset &~ 1)); - - /* If this is a -Bsymbolic link, and the symbol is defined - locally, we just want to emit a RELATIVE reloc. The entry in - the global offset table will already have been initialized in - the relocate_section function. */ - if (info->shared - && info->symbolic - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) - rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); - else - { - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got_offset); - rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT); - } - - bfd_elf32_swap_reloc_out (output_bfd, &rel, - ((Elf32_External_Rel *) srel->contents - + srel->reloc_count)); - ++srel->reloc_count; - } - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0) - { - asection *s; - Elf_Internal_Rel rel; - - /* This symbol needs a copy reloc. Set it up. */ - - BFD_ASSERT (h->dynindx != -1 - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)); - - s = bfd_get_section_by_name (h->root.u.def.section->owner, - ".rel.bss"); - BFD_ASSERT (s != NULL); - - rel.r_offset = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - rel.r_info = ELF32_R_INFO (h->dynindx, R_386_COPY); - bfd_elf32_swap_reloc_out (output_bfd, &rel, - ((Elf32_External_Rel *) s->contents - + s->reloc_count)); - ++s->reloc_count; - } - - /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ - if (strcmp (h->root.root.string, "_DYNAMIC") == 0 - || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) - sym->st_shndx = SHN_ABS; - - return true; -} - -/* Finish up the dynamic sections. */ - -static boolean -elf_i386_finish_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *sgot; - asection *sdyn; - - dynobj = elf_hash_table (info)->dynobj; - - sgot = bfd_get_section_by_name (dynobj, ".got.plt"); - BFD_ASSERT (sgot != NULL); - sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); - - if (elf_hash_table (info)->dynamic_sections_created) - { - asection *splt; - Elf32_External_Dyn *dyncon, *dynconend; - - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL && sdyn != NULL); - - dyncon = (Elf32_External_Dyn *) sdyn->contents; - dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size); - for (; dyncon < dynconend; dyncon++) - { - Elf_Internal_Dyn dyn; - const char *name; - asection *s; - - bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn); - - switch (dyn.d_tag) - { - default: - break; - - case DT_PLTGOT: - name = ".got"; - goto get_vma; - case DT_JMPREL: - name = ".rel.plt"; - get_vma: - s = bfd_get_section_by_name (output_bfd, name); - BFD_ASSERT (s != NULL); - dyn.d_un.d_ptr = s->vma; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_PLTRELSZ: - s = bfd_get_section_by_name (output_bfd, ".rel.plt"); - BFD_ASSERT (s != NULL); - if (s->_cooked_size != 0) - dyn.d_un.d_val = s->_cooked_size; - else - dyn.d_un.d_val = s->_raw_size; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_RELSZ: - /* My reading of the SVR4 ABI indicates that the - procedure linkage table relocs (DT_JMPREL) should be - included in the overall relocs (DT_REL). This is - what Solaris does. However, UnixWare can not handle - that case. Therefore, we override the DT_RELSZ entry - here to make it not include the JMPREL relocs. Since - the linker script arranges for .rel.plt to follow all - other relocation sections, we don't have to worry - about changing the DT_REL entry. */ - s = bfd_get_section_by_name (output_bfd, ".rel.plt"); - if (s != NULL) - { - if (s->_cooked_size != 0) - dyn.d_un.d_val -= s->_cooked_size; - else - dyn.d_un.d_val -= s->_raw_size; - } - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - } - } - - /* Fill in the first entry in the procedure linkage table. */ - if (splt->_raw_size > 0) - { - if (info->shared) - memcpy (splt->contents, elf_i386_pic_plt0_entry, PLT_ENTRY_SIZE); - else - { - memcpy (splt->contents, elf_i386_plt0_entry, PLT_ENTRY_SIZE); - bfd_put_32 (output_bfd, - sgot->output_section->vma + sgot->output_offset + 4, - splt->contents + 2); - bfd_put_32 (output_bfd, - sgot->output_section->vma + sgot->output_offset + 8, - splt->contents + 8); - } - } - - /* UnixWare sets the entsize of .plt to 4, although that doesn't - really seem like the right value. */ - elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4; - } - - /* Fill in the first three entries in the global offset table. */ - if (sgot->_raw_size > 0) - { - if (sdyn == NULL) - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents); - else - bfd_put_32 (output_bfd, - sdyn->output_section->vma + sdyn->output_offset, - sgot->contents); - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4); - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8); - } - - elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4; - - return true; -} - -#define TARGET_LITTLE_SYM bfd_elf32_i386_vec -#define TARGET_LITTLE_NAME "elf32-i386" -#define ELF_ARCH bfd_arch_i386 -#define ELF_MACHINE_CODE EM_386 -#define elf_info_to_howto elf_i386_info_to_howto -#define elf_info_to_howto_rel elf_i386_info_to_howto_rel -#define bfd_elf32_bfd_reloc_type_lookup elf_i386_reloc_type_lookup -#define ELF_MAXPAGESIZE 0x1000 -#define elf_backend_create_dynamic_sections \ - _bfd_elf_create_dynamic_sections -#define elf_backend_check_relocs elf_i386_check_relocs -#define elf_backend_adjust_dynamic_symbol \ - elf_i386_adjust_dynamic_symbol -#define elf_backend_size_dynamic_sections \ - elf_i386_size_dynamic_sections -#define elf_backend_relocate_section elf_i386_relocate_section -#define elf_backend_finish_dynamic_symbol \ - elf_i386_finish_dynamic_symbol -#define elf_backend_finish_dynamic_sections \ - elf_i386_finish_dynamic_sections -#define elf_backend_want_got_plt 1 -#define elf_backend_plt_readonly 1 -#define elf_backend_want_plt_sym 0 - -#include "elf32-target.h" diff --git a/contrib/gdb/bfd/elf32-i860.c b/contrib/gdb/bfd/elf32-i860.c deleted file mode 100644 index a8537a7..0000000 --- a/contrib/gdb/bfd/elf32-i860.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Intel 860 specific support for 32-bit ELF - Copyright 1993 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "elf-bfd.h" - -#define bfd_elf32_bfd_reloc_type_lookup bfd_default_reloc_type_lookup -#define elf_info_to_howto _bfd_elf_no_info_to_howto - -#define TARGET_BIG_SYM bfd_elf32_i860_vec -#define TARGET_BIG_NAME "elf32-i860" -#define ELF_ARCH bfd_arch_i860 -#define ELF_MACHINE_CODE EM_860 - -#include "elf32-target.h" diff --git a/contrib/gdb/bfd/elf32-m68k.c b/contrib/gdb/bfd/elf32-m68k.c deleted file mode 100644 index 752dfae..0000000 --- a/contrib/gdb/bfd/elf32-m68k.c +++ /dev/null @@ -1,1600 +0,0 @@ -/* Motorola 68k series support for 32-bit ELF - Copyright 1993, 1995, 1996 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "elf-bfd.h" - -static reloc_howto_type *reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static void rtype_to_howto - PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *)); -static void rtype_to_howto_rel - PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *)); -static boolean elf_m68k_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static boolean elf_m68k_adjust_dynamic_symbol - PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); -static boolean elf_m68k_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf_m68k_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static boolean elf_m68k_finish_dynamic_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, - Elf_Internal_Sym *)); -static boolean elf_m68k_finish_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); - -/* elf32 m68k code, generated by elf.el */ -enum reloc_type { - R_68K_NONE = 0, - R_68K_32 = 1, - R_68K_16 = 2, - R_68K_8 = 3, - R_68K_PC32 = 4, - R_68K_PC16 = 5, - R_68K_PC8 = 6, - R_68K_GOT32 = 7, - R_68K_GOT16 = 8, - R_68K_GOT8 = 9, - R_68K_GOT32O = 10, - R_68K_GOT16O = 11, - R_68K_GOT8O = 12, - R_68K_PLT32 = 13, - R_68K_PLT16 = 14, - R_68K_PLT8 = 15, - R_68K_PLT32O = 16, - R_68K_PLT16O = 17, - R_68K_PLT8O = 18, - R_68K_COPY = 19, - R_68K_GLOB_DAT = 20, - R_68K_JMP_SLOT = 21, - R_68K_RELATIVE = 22, - R_68K__max -}; - -static reloc_howto_type howto_table[] = { - HOWTO(R_68K_NONE, 0, 0, 0, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_NONE", false, 0, 0x00000000,false), - HOWTO(R_68K_32, 0, 2,32, false,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_32", false, 0, 0xffffffff,false), - HOWTO(R_68K_16, 0, 1,16, false,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_16", false, 0, 0x0000ffff,false), - HOWTO(R_68K_8, 0, 0, 8, false,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_8", false, 0, 0x000000ff,false), - HOWTO(R_68K_PC32, 0, 2,32, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PC32", false, 0, 0xffffffff,true), - HOWTO(R_68K_PC16, 0, 1,16, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PC16", false, 0, 0x0000ffff,true), - HOWTO(R_68K_PC8, 0, 0, 8, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PC8", false, 0, 0x000000ff,true), - HOWTO(R_68K_GOT32, 0, 2,32, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT32", false, 0, 0xffffffff,true), - HOWTO(R_68K_GOT16, 0, 1,16, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT16", false, 0, 0x0000ffff,true), - HOWTO(R_68K_GOT8, 0, 0, 8, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT8", false, 0, 0x000000ff,true), - HOWTO(R_68K_GOT32O, 0, 2,32, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT32O", false, 0, 0xffffffff,false), - HOWTO(R_68K_GOT16O, 0, 1,16, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT16O", false, 0, 0x0000ffff,false), - HOWTO(R_68K_GOT8O, 0, 0, 8, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_GOT8O", false, 0, 0x000000ff,false), - HOWTO(R_68K_PLT32, 0, 2,32, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT32", false, 0, 0xffffffff,true), - HOWTO(R_68K_PLT16, 0, 1,16, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT16", false, 0, 0x0000ffff,true), - HOWTO(R_68K_PLT8, 0, 0, 8, true, 0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT8", false, 0, 0x000000ff,true), - HOWTO(R_68K_PLT32O, 0, 2,32, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT32O", false, 0, 0xffffffff,false), - HOWTO(R_68K_PLT16O, 0, 1,16, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT16O", false, 0, 0x0000ffff,false), - HOWTO(R_68K_PLT8O, 0, 0, 8, false,0, complain_overflow_signed, bfd_elf_generic_reloc, "R_68K_PLT8O", false, 0, 0x000000ff,false), - HOWTO(R_68K_COPY, 0, 0, 0, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_COPY", false, 0, 0xffffffff,false), - HOWTO(R_68K_GLOB_DAT, 0, 2,32, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_GLOB_DAT", false, 0, 0xffffffff,false), - HOWTO(R_68K_JMP_SLOT, 0, 2,32, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_JMP_SLOT", false, 0, 0xffffffff,false), - HOWTO(R_68K_RELATIVE, 0, 2,32, false,0, complain_overflow_dont, bfd_elf_generic_reloc, "R_68K_RELATIVE", false, 0, 0xffffffff,false), -}; - -static void -rtype_to_howto (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf_Internal_Rela *dst; -{ - BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_68K__max); - cache_ptr->howto = &howto_table[ELF32_R_TYPE(dst->r_info)]; -} - -static void -rtype_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf_Internal_Rel *dst; -{ - BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_68K__max); - cache_ptr->howto = &howto_table[ELF32_R_TYPE(dst->r_info)]; -} - -#define elf_info_to_howto rtype_to_howto -#define elf_info_to_howto_rel rtype_to_howto_rel - -static const struct { unsigned char bfd_val, elf_val; } reloc_map[] = { - { BFD_RELOC_NONE, R_68K_NONE }, - { BFD_RELOC_32, R_68K_32 }, - { BFD_RELOC_16, R_68K_16 }, - { BFD_RELOC_8, R_68K_8 }, - { BFD_RELOC_32_PCREL, R_68K_PC32 }, - { BFD_RELOC_16_PCREL, R_68K_PC16 }, - { BFD_RELOC_8_PCREL, R_68K_PC8 }, - { BFD_RELOC_32_GOT_PCREL, R_68K_GOT32 }, - { BFD_RELOC_16_GOT_PCREL, R_68K_GOT16 }, - { BFD_RELOC_8_GOT_PCREL, R_68K_GOT8 }, - { BFD_RELOC_32_GOTOFF, R_68K_GOT32O }, - { BFD_RELOC_16_GOTOFF, R_68K_GOT16O }, - { BFD_RELOC_8_GOTOFF, R_68K_GOT8O }, - { BFD_RELOC_32_PLT_PCREL, R_68K_PLT32 }, - { BFD_RELOC_16_PLT_PCREL, R_68K_PLT16 }, - { BFD_RELOC_8_PLT_PCREL, R_68K_PLT8 }, - { BFD_RELOC_32_PLTOFF, R_68K_PLT32O }, - { BFD_RELOC_16_PLTOFF, R_68K_PLT16O }, - { BFD_RELOC_8_PLTOFF, R_68K_PLT8O }, - { BFD_RELOC_NONE, R_68K_COPY }, - { BFD_RELOC_68K_GLOB_DAT, R_68K_GLOB_DAT }, - { BFD_RELOC_68K_JMP_SLOT, R_68K_JMP_SLOT }, - { BFD_RELOC_68K_RELATIVE, R_68K_RELATIVE }, - { BFD_RELOC_CTOR, R_68K_32 }, -}; - -static reloc_howto_type * -reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - unsigned int i; - for (i = 0; i < sizeof (reloc_map) / sizeof (reloc_map[0]); i++) - { - if (reloc_map[i].bfd_val == code) - return &howto_table[(int) reloc_map[i].elf_val]; - } - return 0; -} - -#define bfd_elf32_bfd_reloc_type_lookup reloc_type_lookup -#define ELF_ARCH bfd_arch_m68k -/* end code generated by elf.el */ - -#define USE_RELA - - -/* Functions for the m68k ELF linker. */ - -/* The name of the dynamic interpreter. This is put in the .interp - section. */ - -#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1" - -/* The size in bytes of an entry in the procedure linkage table. */ - -#define PLT_ENTRY_SIZE 20 - -/* The first entry in a procedure linkage table looks like this. See - the SVR4 ABI m68k supplement to see how this works. */ - -static const bfd_byte elf_m68k_plt0_entry[PLT_ENTRY_SIZE] = -{ - 0x2f, 0x3b, 0x01, 0x70, /* move.l (%pc,addr),-(%sp) */ - 0, 0, 0, 0, /* replaced with offset to .got + 4. */ - 0x4e, 0xfb, 0x01, 0x71, /* jmp ([%pc,addr]) */ - 0, 0, 0, 0, /* replaced with offset to .got + 8. */ - 0, 0, 0, 0 /* pad out to 20 bytes. */ -}; - -/* Subsequent entries in a procedure linkage table look like this. */ - -static const bfd_byte elf_m68k_plt_entry[PLT_ENTRY_SIZE] = -{ - 0x4e, 0xfb, 0x01, 0x71, /* jmp ([%pc,symbol@GOTPC]) */ - 0, 0, 0, 0, /* replaced with offset to symbol's .got entry. */ - 0x2f, 0x3c, /* move.l #offset,-(%sp) */ - 0, 0, 0, 0, /* replaced with offset into relocation table. */ - 0x60, 0xff, /* bra.l .plt */ - 0, 0, 0, 0 /* replaced with offset to start of .plt. */ -}; - -/* Look through the relocs for a section during the first phase, and - allocate space in the global offset table or procedure linkage - table. */ - -static boolean -elf_m68k_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; -{ - bfd *dynobj; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - bfd_vma *local_got_offsets; - const Elf_Internal_Rela *rel; - const Elf_Internal_Rela *rel_end; - asection *sgot; - asection *srelgot; - asection *sreloc; - - if (info->relocateable) - return true; - - dynobj = elf_hash_table (info)->dynobj; - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (abfd); - local_got_offsets = elf_local_got_offsets (abfd); - - sgot = NULL; - srelgot = NULL; - sreloc = NULL; - - rel_end = relocs + sec->reloc_count; - for (rel = relocs; rel < rel_end; rel++) - { - unsigned long r_symndx; - struct elf_link_hash_entry *h; - - r_symndx = ELF32_R_SYM (rel->r_info); - - if (r_symndx < symtab_hdr->sh_info) - h = NULL; - else - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_68K_GOT8: - case R_68K_GOT16: - case R_68K_GOT32: - if (h != NULL - && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) - break; - /* Fall through. */ - case R_68K_GOT8O: - case R_68K_GOT16O: - case R_68K_GOT32O: - /* This symbol requires a global offset table entry. */ - - if (dynobj == NULL) - { - /* Create the .got section. */ - elf_hash_table (info)->dynobj = dynobj = abfd; - if (!_bfd_elf_create_got_section (dynobj, info)) - return false; - } - - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - } - - if (srelgot == NULL - && (h != NULL || info->shared)) - { - srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); - if (srelgot == NULL) - { - srelgot = bfd_make_section (dynobj, ".rela.got"); - if (srelgot == NULL - || !bfd_set_section_flags (dynobj, srelgot, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || !bfd_set_section_alignment (dynobj, srelgot, 2)) - return false; - } - } - - if (h != NULL) - { - if (h->got_offset != (bfd_vma) -1) - { - /* We have already allocated space in the .got. */ - break; - } - h->got_offset = sgot->_raw_size; - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (!bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - srelgot->_raw_size += sizeof (Elf32_External_Rela); - } - else - { - /* This is a global offset table entry for a local - symbol. */ - if (local_got_offsets == NULL) - { - size_t size; - register unsigned int i; - - size = symtab_hdr->sh_info * sizeof (bfd_vma); - local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size); - if (local_got_offsets == NULL) - return false; - elf_local_got_offsets (abfd) = local_got_offsets; - for (i = 0; i < symtab_hdr->sh_info; i++) - local_got_offsets[i] = (bfd_vma) -1; - } - if (local_got_offsets[r_symndx] != (bfd_vma) -1) - { - /* We have already allocated space in the .got. */ - break; - } - local_got_offsets[r_symndx] = sgot->_raw_size; - - if (info->shared) - { - /* If we are generating a shared object, we need to - output a R_68K_RELATIVE reloc so that the dynamic - linker can adjust this GOT entry. */ - srelgot->_raw_size += sizeof (Elf32_External_Rela); - } - } - - sgot->_raw_size += 4; - break; - - case R_68K_PLT8: - case R_68K_PLT16: - case R_68K_PLT32: - /* This symbol requires a procedure linkage table entry. We - actually build the entry in adjust_dynamic_symbol, - because this might be a case of linking PIC code which is - never referenced by a dynamic object, in which case we - don't need to generate a procedure linkage table entry - after all. */ - - /* If this is a local symbol, we resolve it directly without - creating a procedure linkage table entry. */ - if (h == NULL) - continue; - - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; - break; - - case R_68K_PLT8O: - case R_68K_PLT16O: - case R_68K_PLT32O: - /* This symbol requires a procedure linkage table entry. */ - - if (h == NULL) - { - /* It does not make sense to have this relocation for a - local symbol. FIXME: does it? How to handle it if - it does make sense? */ - bfd_set_error (bfd_error_bad_value); - return false; - } - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (!bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; - break; - - case R_68K_PC8: - case R_68K_PC16: - case R_68K_PC32: - if (h == NULL) - break; - /* Fall through. */ - case R_68K_8: - case R_68K_16: - case R_68K_32: - if (info->shared - && (sec->flags & SEC_ALLOC) != 0 - && ((ELF32_R_TYPE (rel->r_info) != R_68K_PC8 - && ELF32_R_TYPE (rel->r_info) != R_68K_PC16 - && ELF32_R_TYPE (rel->r_info) != R_68K_PC32) - || (!info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0))) - { - /* When creating a shared object, we must copy these - reloc types into the output file. We create a reloc - section in dynobj and make room for this reloc. */ - if (sreloc == NULL) - { - const char *name; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return false; - - BFD_ASSERT (strncmp (name, ".rela", 5) == 0 - && strcmp (bfd_get_section_name (abfd, sec), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - if (sreloc == NULL) - { - sreloc = bfd_make_section (dynobj, name); - if (sreloc == NULL - || !bfd_set_section_flags (dynobj, sreloc, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || !bfd_set_section_alignment (dynobj, sreloc, 2)) - return false; - } - } - - sreloc->_raw_size += sizeof (Elf32_External_Rela); - } - - break; - - default: - break; - } - } - - return true; -} - -/* Adjust a symbol defined by a dynamic object and referenced by a - regular object. The current definition is in some section of the - dynamic object, but we're not including those sections. We have to - change the definition to something the rest of the link can - understand. */ - -static boolean -elf_m68k_adjust_dynamic_symbol (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; -{ - bfd *dynobj; - asection *s; - unsigned int power_of_two; - - dynobj = elf_hash_table (info)->dynobj; - - /* Make sure we know what is going on here. */ - BFD_ASSERT (dynobj != NULL - && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) - || h->weakdef != NULL - || ((h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_REF_REGULAR) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0))); - - /* If this is a function, put it in the procedure linkage table. We - will fill in the contents of the procedure linkage table later, - when we know the address of the .got section. */ - if (h->type == STT_FUNC - || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) - { - if (! info->shared - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0 - /* We must always create the plt entry if it was referenced - by a PLTxxO relocation. In this case we already recorded - it as a dynamic symbol. */ - && h->dynindx == -1) - { - /* This case can occur if we saw a PLTxx reloc in an input - file, but the symbol was never referred to by a dynamic - object. In such a case, we don't actually need to build - a procedure linkage table, and we can just do a PCxx - reloc instead. */ - BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0); - return true; - } - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - s = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (s != NULL); - - /* If this is the first .plt entry, make room for the special - first entry. */ - if (s->_raw_size == 0) - s->_raw_size += PLT_ENTRY_SIZE; - - /* If this symbol is not defined in a regular file, and we are - not generating a shared library, then set the symbol to this - location in the .plt. This is required to make function - pointers compare as equal between the normal executable and - the shared library. */ - if (!info->shared - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; - } - - h->plt_offset = s->_raw_size; - - /* Make room for this entry. */ - s->_raw_size += PLT_ENTRY_SIZE; - - /* We also need to make an entry in the .got.plt section, which - will be placed in the .got section by the linker script. */ - - s = bfd_get_section_by_name (dynobj, ".got.plt"); - BFD_ASSERT (s != NULL); - s->_raw_size += 4; - - /* We also need to make an entry in the .rela.plt section. */ - - s = bfd_get_section_by_name (dynobj, ".rela.plt"); - BFD_ASSERT (s != NULL); - s->_raw_size += sizeof (Elf32_External_Rela); - - return true; - } - - /* If this is a weak symbol, and there is a real definition, the - processor independent code will have arranged for us to see the - real definition first, and we can just use the same value. */ - if (h->weakdef != NULL) - { - BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined - || h->weakdef->root.type == bfd_link_hash_defweak); - h->root.u.def.section = h->weakdef->root.u.def.section; - h->root.u.def.value = h->weakdef->root.u.def.value; - return true; - } - - /* This is a reference to a symbol defined by a dynamic object which - is not a function. */ - - /* If we are creating a shared library, we must presume that the - only references to the symbol are via the global offset table. - For such cases we need not do anything here; the relocations will - be handled correctly by relocate_section. */ - if (info->shared) - return true; - - /* We must allocate the symbol in our .dynbss section, which will - become part of the .bss section of the executable. There will be - an entry for this symbol in the .dynsym section. The dynamic - object will contain position independent code, so all references - from the dynamic object to this symbol will go through the global - offset table. The dynamic linker will use the .dynsym entry to - determine the address it must put in the global offset table, so - both the dynamic object and the regular object will refer to the - same memory location for the variable. */ - - s = bfd_get_section_by_name (dynobj, ".dynbss"); - BFD_ASSERT (s != NULL); - - /* If the symbol is currently defined in the .bss section of the - dynamic object, then it is OK to simply initialize it to zero. - If the symbol is in some other section, we must generate a - R_68K_COPY reloc to tell the dynamic linker to copy the initial - value out of the dynamic object and into the runtime process - image. We need to remember the offset into the .rela.bss section - we are going to use. */ - if ((h->root.u.def.section->flags & SEC_LOAD) != 0) - { - asection *srel; - - srel = bfd_get_section_by_name (dynobj, ".rela.bss"); - BFD_ASSERT (srel != NULL); - srel->_raw_size += sizeof (Elf32_External_Rela); - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY; - } - - /* We need to figure out the alignment required for this symbol. I - have no idea how ELF linkers handle this. */ - power_of_two = bfd_log2 (h->size); - if (power_of_two > 3) - power_of_two = 3; - - /* Apply the required alignment. */ - s->_raw_size = BFD_ALIGN (s->_raw_size, - (bfd_size_type) (1 << power_of_two)); - if (power_of_two > bfd_get_section_alignment (dynobj, s)) - { - if (!bfd_set_section_alignment (dynobj, s, power_of_two)) - return false; - } - - /* Define the symbol as being at this point in the section. */ - h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; - - /* Increment the section size to make room for the symbol. */ - s->_raw_size += h->size; - - return true; -} - -/* Set the sizes of the dynamic sections. */ - -static boolean -elf_m68k_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *s; - boolean plt; - boolean relocs; - boolean reltext; - - dynobj = elf_hash_table (info)->dynobj; - BFD_ASSERT (dynobj != NULL); - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Set the contents of the .interp section to the interpreter. */ - if (!info->shared) - { - s = bfd_get_section_by_name (dynobj, ".interp"); - BFD_ASSERT (s != NULL); - s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; - s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; - } - } - else - { - /* We may have created entries in the .rela.got section. - However, if we are not creating the dynamic sections, we will - not actually use these entries. Reset the size of .rela.got, - which will cause it to get stripped from the output file - below. */ - s = bfd_get_section_by_name (dynobj, ".rela.got"); - if (s != NULL) - s->_raw_size = 0; - } - - /* The check_relocs and adjust_dynamic_symbol entry points have - determined the sizes of the various dynamic sections. Allocate - memory for them. */ - plt = false; - relocs = false; - reltext = false; - for (s = dynobj->sections; s != NULL; s = s->next) - { - const char *name; - boolean strip; - - if ((s->flags & SEC_IN_MEMORY) == 0) - continue; - - /* It's OK to base decisions on the section name, because none - of the dynobj section names depend upon the input files. */ - name = bfd_get_section_name (dynobj, s); - - strip = false; - - if (strcmp (name, ".plt") == 0) - { - if (s->_raw_size == 0) - { - /* Strip this section if we don't need it; see the - comment below. */ - strip = true; - } - else - { - /* Remember whether there is a PLT. */ - plt = true; - } - } - else if (strncmp (name, ".rela", 5) == 0) - { - if (s->_raw_size == 0) - { - /* If we don't need this section, strip it from the - output file. This is mostly to handle .rela.bss and - .rela.plt. We must create both sections in - create_dynamic_sections, because they must be created - before the linker maps input sections to output - sections. The linker does that before - adjust_dynamic_symbol is called, and it is that - function which decides whether anything needs to go - into these sections. */ - strip = true; - } - else - { - asection *target; - - /* Remember whether there are any reloc sections other - than .rela.plt. */ - if (strcmp (name, ".rela.plt") != 0) - { - relocs = true; - - /* If this relocation section applies to a read only - section, then we probably need a DT_TEXTREL - entry. .rela.plt is actually associated with - .got.plt, which is never readonly. */ - target = bfd_get_section_by_name (output_bfd, name + 5); - if (target != NULL - && (target->flags & SEC_READONLY) != 0) - reltext = true; - } - - /* We use the reloc_count field as a counter if we need - to copy relocs into the output file. */ - s->reloc_count = 0; - } - } - else if (strncmp (name, ".got", 4) != 0) - { - /* It's not one of our sections, so don't allocate space. */ - continue; - } - - if (strip) - { - asection **spp; - - for (spp = &s->output_section->owner->sections; - *spp != s->output_section; - spp = &(*spp)->next) - ; - *spp = s->output_section->next; - --s->output_section->owner->section_count; - - continue; - } - - /* Allocate memory for the section contents. */ - s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) - return false; - } - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in elf_m68k_finish_dynamic_sections, but we - must add the entries now so that we get the correct size for - the .dynamic section. The DT_DEBUG entry is filled in by the - dynamic linker and used by the debugger. */ - if (!info->shared) - { - if (!bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0)) - return false; - } - - if (plt) - { - if (!bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0) - || !bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0) - || !bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_RELA) - || !bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0)) - return false; - } - - if (relocs) - { - if (!bfd_elf32_add_dynamic_entry (info, DT_RELA, 0) - || !bfd_elf32_add_dynamic_entry (info, DT_RELASZ, 0) - || !bfd_elf32_add_dynamic_entry (info, DT_RELAENT, - sizeof (Elf32_External_Rela))) - return false; - } - - if (reltext) - { - if (!bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0)) - return false; - } - } - - return true; -} - -/* Relocate an M68K ELF section. */ - -static boolean -elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; -{ - bfd *dynobj; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - bfd_vma *local_got_offsets; - asection *sgot; - asection *splt; - asection *sreloc; - Elf_Internal_Rela *rel; - Elf_Internal_Rela *relend; - - dynobj = elf_hash_table (info)->dynobj; - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (input_bfd); - local_got_offsets = elf_local_got_offsets (input_bfd); - - sgot = NULL; - splt = NULL; - sreloc = NULL; - - rel = relocs; - relend = relocs + input_section->reloc_count; - for (; rel < relend; rel++) - { - int r_type; - reloc_howto_type *howto; - unsigned long r_symndx; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; - asection *sec; - bfd_vma relocation; - bfd_reloc_status_type r; - - r_type = ELF32_R_TYPE (rel->r_info); - if (r_type < 0 || r_type >= (int) R_68K__max) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - howto = howto_table + r_type; - - r_symndx = ELF32_R_SYM (rel->r_info); - - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - sec = local_sections[r_symndx]; - rel->r_addend += sec->output_offset + sym->st_value; - } - } - - continue; - } - - /* This is a final link. */ - h = NULL; - sym = NULL; - sec = NULL; - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); - } - else - { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - if (((r_type == R_68K_PLT8 - || r_type == R_68K_PLT16 - || r_type == R_68K_PLT32 - || r_type == R_68K_PLT8O - || r_type == R_68K_PLT16O - || r_type == R_68K_PLT32O) - && h->plt_offset != (bfd_vma) -1) - || ((r_type == R_68K_GOT8O - || r_type == R_68K_GOT16O - || r_type == R_68K_GOT32O - || ((r_type == R_68K_GOT8 - || r_type == R_68K_GOT16 - || r_type == R_68K_GOT32) - && strcmp (h->root.root.string, - "_GLOBAL_OFFSET_TABLE_") != 0)) - && elf_hash_table (info)->dynamic_sections_created - && (! info->shared - || ! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)) - || (info->shared - && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0) - && (input_section->flags & SEC_ALLOC) != 0 - && (r_type == R_68K_8 - || r_type == R_68K_16 - || r_type == R_68K_32 - || r_type == R_68K_PC8 - || r_type == R_68K_PC16 - || r_type == R_68K_PC32))) - { - /* In these cases, we don't need the relocation - value. We check specially because in some - obscure cases sec->output_section will be NULL. */ - relocation = 0; - } - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else if (info->shared && !info->symbolic) - relocation = 0; - else - { - if (!(info->callbacks->undefined_symbol - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset))) - return false; - relocation = 0; - } - } - - switch (r_type) - { - case R_68K_GOT8: - case R_68K_GOT16: - case R_68K_GOT32: - /* Relocation is to the address of the entry for this symbol - in the global offset table. */ - if (h != NULL - && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) - break; - /* Fall through. */ - case R_68K_GOT8O: - case R_68K_GOT16O: - case R_68K_GOT32O: - /* Relocation is the offset of the entry for this symbol in - the global offset table. */ - - { - bfd_vma off; - - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - } - - if (h != NULL) - { - off = h->got_offset; - BFD_ASSERT (off != (bfd_vma) -1); - - if (!elf_hash_table (info)->dynamic_sections_created - || (info->shared - && info->symbolic - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) - { - /* This is actually a static link, or it is a - -Bsymbolic link and the symbol is defined - locally. We must initialize this entry in the - global offset table. Since the offset must - always be a multiple of 4, we use the least - significant bit to record whether we have - initialized it already. - - When doing a dynamic link, we create a .rela.got - relocation entry to initialize the value. This - is done in the finish_dynamic_symbol routine. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_32 (output_bfd, relocation, - sgot->contents + off); - h->got_offset |= 1; - } - } - } - else - { - BFD_ASSERT (local_got_offsets != NULL - && local_got_offsets[r_symndx] != (bfd_vma) -1); - - off = local_got_offsets[r_symndx]; - - /* The offset must always be a multiple of 4. We use - the least significant bit to record whether we have - already generated the necessary reloc. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_32 (output_bfd, relocation, sgot->contents + off); - - if (info->shared) - { - asection *srelgot; - Elf_Internal_Rela outrel; - - srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); - BFD_ASSERT (srelgot != NULL); - - outrel.r_offset = (sgot->output_section->vma - + sgot->output_offset - + off); - outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE); - outrel.r_addend = relocation; - bfd_elf32_swap_reloca_out (output_bfd, &outrel, - (((Elf32_External_Rela *) - srelgot->contents) - + srelgot->reloc_count)); - ++srelgot->reloc_count; - } - - local_got_offsets[r_symndx] |= 1; - } - } - - relocation = sgot->output_offset + off; - if (r_type == R_68K_GOT8O - || r_type == R_68K_GOT16O - || r_type == R_68K_GOT32O) - { - /* This relocation does not use the addend. */ - rel->r_addend = 0; - } - else - relocation += sgot->output_section->vma; - } - break; - - case R_68K_PLT8: - case R_68K_PLT16: - case R_68K_PLT32: - /* Relocation is to the entry for this symbol in the - procedure linkage table. */ - - /* Resolve a PLTxx reloc against a local symbol directly, - without using the procedure linkage table. */ - if (h == NULL) - break; - - if (h->plt_offset == (bfd_vma) -1) - { - /* We didn't make a PLT entry for this symbol. This - happens when statically linking PIC code, or when - using -Bsymbolic. */ - break; - } - - if (splt == NULL) - { - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL); - } - - relocation = (splt->output_section->vma - + splt->output_offset - + h->plt_offset); - break; - - case R_68K_PLT8O: - case R_68K_PLT16O: - case R_68K_PLT32O: - /* Relocation is the offset of the entry for this symbol in - the procedure linkage table. */ - BFD_ASSERT (h != NULL && h->plt_offset == (bfd_vma) -1); - - if (splt == NULL) - { - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL); - } - - relocation = h->plt_offset; - - /* This relocation does not use the addend. */ - rel->r_addend = 0; - - break; - - case R_68K_PC8: - case R_68K_PC16: - case R_68K_PC32: - if (h == NULL) - break; - /* Fall through. */ - case R_68K_8: - case R_68K_16: - case R_68K_32: - if (info->shared - && (input_section->flags & SEC_ALLOC) != 0 - && ((r_type != R_68K_PC8 - && r_type != R_68K_PC16 - && r_type != R_68K_PC32) - || (!info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0))) - { - Elf_Internal_Rela outrel; - int relocate; - - /* When generating a shared object, these relocations - are copied into the output file to be resolved at run - time. */ - - if (sreloc == NULL) - { - const char *name; - - name = (bfd_elf_string_from_elf_section - (input_bfd, - elf_elfheader (input_bfd)->e_shstrndx, - elf_section_data (input_section)->rel_hdr.sh_name)); - if (name == NULL) - return false; - - BFD_ASSERT (strncmp (name, ".rela", 5) == 0 - && strcmp (bfd_get_section_name (input_bfd, - input_section), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - BFD_ASSERT (sreloc != NULL); - } - - outrel.r_offset = (rel->r_offset - + input_section->output_section->vma - + input_section->output_offset); - if (h != NULL - && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)) - { - BFD_ASSERT (h->dynindx != -1); - relocate = false; - outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); - outrel.r_addend = relocation + rel->r_addend; - } - else - { - if (r_type == R_68K_32) - { - relocate = true; - outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE); - outrel.r_addend = relocation + rel->r_addend; - } - else - { - long indx; - - if (h == NULL) - sec = local_sections[r_symndx]; - else - { - BFD_ASSERT (h->root.type == bfd_link_hash_defined - || (h->root.type - == bfd_link_hash_defweak)); - sec = h->root.u.def.section; - } - if (sec != NULL && bfd_is_abs_section (sec)) - indx = 0; - else if (sec == NULL || sec->owner == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - else - { - asection *osec; - - osec = sec->output_section; - indx = elf_section_data (osec)->dynindx; - if (indx == 0) - abort (); - } - - relocate = false; - outrel.r_info = ELF32_R_INFO (indx, r_type); - outrel.r_addend = relocation + rel->r_addend; - } - } - - bfd_elf32_swap_reloca_out (output_bfd, &outrel, - (((Elf32_External_Rela *) - sreloc->contents) - + sreloc->reloc_count)); - ++sreloc->reloc_count; - - /* This reloc will be computed at runtime, so there's no - need to do anything now, except for R_68K_32 - relocations that have been turned into - R_68K_RELATIVE. */ - if (!relocate) - continue; - } - - break; - - default: - break; - } - - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, - relocation, rel->r_addend); - - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (h != NULL) - name = h->root.root.string; - else - { - name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - if (name == NULL) - return false; - if (*name == '\0') - name = bfd_section_name (input_bfd, sec); - } - if (!(info->callbacks->reloc_overflow - (info, name, howto->name, (bfd_vma) 0, - input_bfd, input_section, rel->r_offset))) - return false; - } - break; - } - } - } - - return true; -} - -/* Finish up dynamic symbol handling. We set the contents of various - dynamic sections here. */ - -static boolean -elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym) - bfd *output_bfd; - struct bfd_link_info *info; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; -{ - bfd *dynobj; - - dynobj = elf_hash_table (info)->dynobj; - - if (h->plt_offset != (bfd_vma) -1) - { - asection *splt; - asection *sgot; - asection *srela; - bfd_vma plt_index; - bfd_vma got_offset; - Elf_Internal_Rela rela; - - /* This symbol has an entry in the procedure linkage table. Set - it up. */ - - BFD_ASSERT (h->dynindx != -1); - - splt = bfd_get_section_by_name (dynobj, ".plt"); - sgot = bfd_get_section_by_name (dynobj, ".got.plt"); - srela = bfd_get_section_by_name (dynobj, ".rela.plt"); - BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL); - - /* Get the index in the procedure linkage table which - corresponds to this symbol. This is the index of this symbol - in all the symbols for which we are making plt entries. The - first entry in the procedure linkage table is reserved. */ - plt_index = h->plt_offset / PLT_ENTRY_SIZE - 1; - - /* Get the offset into the .got table of the entry that - corresponds to this function. Each .got entry is 4 bytes. - The first three are reserved. */ - got_offset = (plt_index + 3) * 4; - - /* Fill in the entry in the procedure linkage table. */ - memcpy (splt->contents + h->plt_offset, elf_m68k_plt_entry, - PLT_ENTRY_SIZE); - /* The offset is relative to the first extension word. */ - bfd_put_32 (output_bfd, - (sgot->output_section->vma - + sgot->output_offset - + got_offset - - (splt->output_section->vma - + h->plt_offset + 2)), - splt->contents + h->plt_offset + 4); - - bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela), - splt->contents + h->plt_offset + 10); - bfd_put_32 (output_bfd, - (h->plt_offset + 16), - splt->contents + h->plt_offset + 16); - - /* Fill in the entry in the global offset table. */ - bfd_put_32 (output_bfd, - (splt->output_section->vma - + splt->output_offset - + h->plt_offset - + 8), - sgot->contents + got_offset); - - /* Fill in the entry in the .rela.plt section. */ - rela.r_offset = (sgot->output_section->vma - + sgot->output_offset - + got_offset); - rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_JMP_SLOT); - rela.r_addend = 0; - bfd_elf32_swap_reloca_out (output_bfd, &rela, - ((Elf32_External_Rela *) srela->contents - + plt_index)); - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - /* Mark the symbol as undefined, rather than as defined in - the .plt section. Leave the value alone. */ - sym->st_shndx = SHN_UNDEF; - } - } - - if (h->got_offset != (bfd_vma) -1) - { - asection *sgot; - asection *srela; - Elf_Internal_Rela rela; - - /* This symbol has an entry in the global offset table. Set it - up. */ - - BFD_ASSERT (h->dynindx != -1); - - sgot = bfd_get_section_by_name (dynobj, ".got"); - srela = bfd_get_section_by_name (dynobj, ".rela.got"); - BFD_ASSERT (sgot != NULL && srela != NULL); - - rela.r_offset = (sgot->output_section->vma - + sgot->output_offset - + (h->got_offset &~ 1)); - - /* If this is a -Bsymbolic link, and the symbol is defined - locally, we just want to emit a RELATIVE reloc. The entry in - the global offset table will already have been initialized in - the relocate_section function. */ - if (info->shared - && info->symbolic - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) - { - rela.r_info = ELF32_R_INFO (0, R_68K_RELATIVE); - rela.r_addend = bfd_get_32 (output_bfd, - sgot->contents + (h->got_offset & ~1)); - } - else - { - bfd_put_32 (output_bfd, (bfd_vma) 0, - sgot->contents + (h->got_offset & ~1)); - rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_GLOB_DAT); - rela.r_addend = 0; - } - - bfd_elf32_swap_reloca_out (output_bfd, &rela, - ((Elf32_External_Rela *) srela->contents - + srela->reloc_count)); - ++srela->reloc_count; - } - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0) - { - asection *s; - Elf_Internal_Rela rela; - - /* This symbol needs a copy reloc. Set it up. */ - - BFD_ASSERT (h->dynindx != -1 - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)); - - s = bfd_get_section_by_name (h->root.u.def.section->owner, - ".rela.bss"); - BFD_ASSERT (s != NULL); - - rela.r_offset = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_COPY); - rela.r_addend = 0; - bfd_elf32_swap_reloca_out (output_bfd, &rela, - ((Elf32_External_Rela *) s->contents - + s->reloc_count)); - ++s->reloc_count; - } - - /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ - if (strcmp (h->root.root.string, "_DYNAMIC") == 0 - || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) - sym->st_shndx = SHN_ABS; - - return true; -} - -/* Finish up the dynamic sections. */ - -static boolean -elf_m68k_finish_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *sgot; - asection *sdyn; - - dynobj = elf_hash_table (info)->dynobj; - - sgot = bfd_get_section_by_name (dynobj, ".got.plt"); - BFD_ASSERT (sgot != NULL); - sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); - - if (elf_hash_table (info)->dynamic_sections_created) - { - asection *splt; - Elf32_External_Dyn *dyncon, *dynconend; - - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL && sdyn != NULL); - - dyncon = (Elf32_External_Dyn *) sdyn->contents; - dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size); - for (; dyncon < dynconend; dyncon++) - { - Elf_Internal_Dyn dyn; - const char *name; - asection *s; - - bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn); - - switch (dyn.d_tag) - { - default: - break; - - case DT_PLTGOT: - name = ".got"; - goto get_vma; - case DT_JMPREL: - name = ".rela.plt"; - get_vma: - s = bfd_get_section_by_name (output_bfd, name); - BFD_ASSERT (s != NULL); - dyn.d_un.d_ptr = s->vma; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_PLTRELSZ: - s = bfd_get_section_by_name (output_bfd, ".rela.plt"); - BFD_ASSERT (s != NULL); - if (s->_cooked_size != 0) - dyn.d_un.d_val = s->_cooked_size; - else - dyn.d_un.d_val = s->_raw_size; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_RELASZ: - /* The procedure linkage table relocs (DT_JMPREL) should - not be included in the overall relocs (DT_RELA). - Therefore, we override the DT_RELASZ entry here to - make it not include the JMPREL relocs. Since the - linker script arranges for .rela.plt to follow all - other relocation sections, we don't have to worry - about changing the DT_RELA entry. */ - s = bfd_get_section_by_name (output_bfd, ".rela.plt"); - if (s != NULL) - { - if (s->_cooked_size != 0) - dyn.d_un.d_val -= s->_cooked_size; - else - dyn.d_un.d_val -= s->_raw_size; - } - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - } - } - - /* Fill in the first entry in the procedure linkage table. */ - if (splt->_raw_size > 0) - { - memcpy (splt->contents, elf_m68k_plt0_entry, PLT_ENTRY_SIZE); - bfd_put_32 (output_bfd, - (sgot->output_section->vma - + sgot->output_offset + 4 - - (splt->output_section->vma + 2)), - splt->contents + 4); - bfd_put_32 (output_bfd, - (sgot->output_section->vma - + sgot->output_offset + 8 - - (splt->output_section->vma + 10)), - splt->contents + 12); - } - - elf_section_data (splt->output_section)->this_hdr.sh_entsize - = PLT_ENTRY_SIZE; - } - - /* Fill in the first three entries in the global offset table. */ - if (sgot->_raw_size > 0) - { - if (sdyn == NULL) - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents); - else - bfd_put_32 (output_bfd, - sdyn->output_section->vma + sdyn->output_offset, - sgot->contents); - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4); - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8); - } - - elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4; - - return true; -} - -#define TARGET_BIG_SYM bfd_elf32_m68k_vec -#define TARGET_BIG_NAME "elf32-m68k" -#define ELF_MACHINE_CODE EM_68K -#define ELF_MAXPAGESIZE 0x2000 -#define elf_backend_create_dynamic_sections \ - _bfd_elf_create_dynamic_sections -#define elf_backend_check_relocs elf_m68k_check_relocs -#define elf_backend_adjust_dynamic_symbol \ - elf_m68k_adjust_dynamic_symbol -#define elf_backend_size_dynamic_sections \ - elf_m68k_size_dynamic_sections -#define elf_backend_relocate_section elf_m68k_relocate_section -#define elf_backend_finish_dynamic_symbol \ - elf_m68k_finish_dynamic_symbol -#define elf_backend_finish_dynamic_sections \ - elf_m68k_finish_dynamic_sections -#define elf_backend_want_got_plt 1 -#define elf_backend_plt_readonly 1 -#define elf_backend_want_plt_sym 0 - -#include "elf32-target.h" diff --git a/contrib/gdb/bfd/elf32-m88k.c b/contrib/gdb/bfd/elf32-m88k.c deleted file mode 100644 index f3c535e..0000000 --- a/contrib/gdb/bfd/elf32-m88k.c +++ /dev/null @@ -1,35 +0,0 @@ -/* Motorola 88k-specific support for 32-bit ELF - Copyright 1993 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "elf-bfd.h" - -/* This does not include any relocations, but should be good enough - for GDB. */ - -#define TARGET_BIG_SYM bfd_elf32_m88k_vec -#define TARGET_BIG_NAME "elf32-m88k" -#define ELF_ARCH bfd_arch_m88k -#define ELF_MACHINE_CODE EM_88K -#define bfd_elf32_bfd_reloc_type_lookup bfd_default_reloc_type_lookup -#define elf_info_to_howto _bfd_elf_no_info_to_howto - -#include "elf32-target.h" diff --git a/contrib/gdb/bfd/elf32-mips.c b/contrib/gdb/bfd/elf32-mips.c deleted file mode 100644 index ced0000..0000000 --- a/contrib/gdb/bfd/elf32-mips.c +++ /dev/null @@ -1,5867 +0,0 @@ -/* MIPS-specific support for 32-bit ELF - Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - - Most of the information added by Ian Lance Taylor, Cygnus Support, - <ian@cygnus.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 handles MIPS ELF targets. SGI Irix 5 uses a slightly - different MIPS ELF from other targets. This matters when linking. - This file supports both, switching at runtime. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "genlink.h" -#include "elf-bfd.h" -#include "elf/mips.h" - -/* Get the ECOFF swapping routines. */ -#include "coff/sym.h" -#include "coff/symconst.h" -#include "coff/internal.h" -#include "coff/ecoff.h" -#include "coff/mips.h" -#define ECOFF_32 -#include "ecoffswap.h" - -static bfd_reloc_status_type mips_elf_hi16_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_elf_got16_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_elf_lo16_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_elf_gprel16_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static bfd_reloc_status_type mips_elf_gprel32_reloc PARAMS ((bfd *abfd, - arelent *reloc, - asymbol *symbol, - PTR data, - asection *section, - bfd *output_bfd, - char **error)); -static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static void mips_info_to_howto_rel - PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *)); -static void bfd_mips_elf32_swap_gptab_in - PARAMS ((bfd *, const Elf32_External_gptab *, Elf32_gptab *)); -static void bfd_mips_elf32_swap_gptab_out - PARAMS ((bfd *, const Elf32_gptab *, Elf32_External_gptab *)); -static boolean mips_elf_sym_is_global PARAMS ((bfd *, asymbol *)); -static boolean mips_elf_object_p PARAMS ((bfd *)); -static boolean mips_elf_create_procedure_table - PARAMS ((PTR, bfd *, struct bfd_link_info *, asection *, - struct ecoff_debug_info *)); -static int mips_elf_additional_program_headers PARAMS ((bfd *)); -static boolean mips_elf_modify_segment_map PARAMS ((bfd *)); -static void mips_elf_final_write_processing - PARAMS ((bfd *, boolean)); -static boolean mips_elf_set_private_flags PARAMS ((bfd *, flagword)); -static boolean mips_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *)); -static boolean mips_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *)); -static boolean mips_elf_section_from_shdr - PARAMS ((bfd *, Elf32_Internal_Shdr *, char *)); -static boolean mips_elf_fake_sections - PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *)); -static boolean mips_elf_section_from_bfd_section - PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *, int *)); -static boolean mips_elf_section_processing - PARAMS ((bfd *, Elf32_Internal_Shdr *)); -static void mips_elf_symbol_processing PARAMS ((bfd *, asymbol *)); -static boolean mips_elf_read_ecoff_info - PARAMS ((bfd *, asection *, struct ecoff_debug_info *)); -static boolean mips_elf_is_local_label - PARAMS ((bfd *, asymbol *)); -static boolean mips_elf_find_nearest_line - PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **, - const char **, unsigned int *)); -static struct bfd_hash_entry *mips_elf_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static struct bfd_link_hash_table *mips_elf_link_hash_table_create - PARAMS ((bfd *)); -static int gptab_compare PARAMS ((const void *, const void *)); -static boolean mips_elf_final_link - PARAMS ((bfd *, struct bfd_link_info *)); -static void mips_elf_relocate_hi16 - PARAMS ((bfd *, Elf_Internal_Rela *, Elf_Internal_Rela *, bfd_byte *, - bfd_vma)); -static void mips_elf_relocate_got_local - PARAMS ((bfd *, bfd *, asection *, Elf_Internal_Rela *, - Elf_Internal_Rela *, bfd_byte *, bfd_vma)); -static void mips_elf_relocate_global_got - PARAMS ((bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_vma)); -static boolean mips_elf_adjust_dynindx - PARAMS ((struct elf_link_hash_entry *, PTR)); -static boolean mips_elf_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static boolean mips_elf_create_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean mips_elf_create_compact_rel_section - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean mips_elf_create_got_section - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean mips_elf_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static boolean mips_elf_adjust_dynamic_symbol - PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); -static boolean mips_elf_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean mips_elf_finish_dynamic_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, - Elf_Internal_Sym *)); -static boolean mips_elf_finish_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean mips_elf_add_symbol_hook - PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, - const char **, flagword *, asection **, bfd_vma *)); -static bfd_reloc_status_type mips_elf_final_gp - PARAMS ((bfd *, asymbol *, boolean, char **, bfd_vma *)); -static bfd_byte *elf32_mips_get_relocated_section_contents - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *, boolean, asymbol **)); - -/* This is true for Irix 5 executables, false for normal MIPS ELF ABI - executables. FIXME: At the moment, we default to always generating - Irix 5 executables. */ - -#define SGI_COMPAT(abfd) (1) - -/* This structure is used to hold .got information when linking. It - is stored in the tdata field of the bfd_elf_section_data structure. */ - -struct mips_got_info -{ - /* The symbol index of the first global .got symbol. */ - unsigned long global_gotsym; - /* The number of local .got entries. */ - unsigned int local_gotno; -}; - -/* The number of local .got entries we reserve. */ -#define MIPS_RESERVED_GOTNO (2) - -/* Instructions which appear in a stub. For some reason the stub is - slightly different on an SGI system. */ -#define ELF_MIPS_GP_OFFSET(abfd) (SGI_COMPAT (abfd) ? 0x7ff0 : 0x8000) -#define STUB_LW(abfd) \ - (SGI_COMPAT (abfd) \ - ? 0x8f998010 /* lw t9,0x8010(gp) */ \ - : 0x8f998000) /* lw t9,0x8000(gp) */ -#define STUB_MOVE 0x03e07825 /* move t7,ra */ -#define STUB_JALR 0x0320f809 /* jal t9 */ -#define STUB_LI16 0x34180000 /* ori t8,zero,0 */ -#define MIPS_FUNCTION_STUB_SIZE (16) - -/* Names of sections which appear in the .dynsym section in an Irix 5 - executable. */ - -static const char * const mips_elf_dynsym_sec_names[] = -{ - ".text", - ".init", - ".fini", - ".data", - ".rodata", - ".sdata", - ".sbss", - ".bss", - NULL -}; - -#define SIZEOF_MIPS_DYNSYM_SECNAMES \ - (sizeof mips_elf_dynsym_sec_names / sizeof mips_elf_dynsym_sec_names[0]) - -/* The number of entries in mips_elf_dynsym_sec_names which go in the - text segment. */ - -#define MIPS_TEXT_DYNSYM_SECNO (3) - -/* The names of the runtime procedure table symbols used on Irix 5. */ - -static const char * const mips_elf_dynsym_rtproc_names[] = -{ - "_procedure_table", - "_procedure_string_table", - "_procedure_table_size", - NULL -}; - -/* These structures are used to generate the .compact_rel section on - Irix 5. */ - -typedef struct -{ - unsigned long id1; /* Always one? */ - unsigned long num; /* Number of compact relocation entries. */ - unsigned long id2; /* Always two? */ - unsigned long offset; /* The file offset of the first relocation. */ - unsigned long reserved0; /* Zero? */ - unsigned long reserved1; /* Zero? */ -} Elf32_compact_rel; - -typedef struct -{ - bfd_byte id1[4]; - bfd_byte num[4]; - bfd_byte id2[4]; - bfd_byte offset[4]; - bfd_byte reserved0[4]; - bfd_byte reserved1[4]; -} Elf32_External_compact_rel; - -typedef struct -{ - unsigned int ctype : 1; /* 1: long 0: short format. See below. */ - unsigned int rtype : 4; /* Relocation types. See below. */ - unsigned int dist2to : 8; - unsigned int relvaddr : 19; /* (VADDR - vaddr of the previous entry)/ 4 */ - unsigned long konst; /* KONST field. See below. */ - unsigned long vaddr; /* VADDR to be relocated. */ -} Elf32_crinfo; - -typedef struct -{ - unsigned int ctype : 1; /* 1: long 0: short format. See below. */ - unsigned int rtype : 4; /* Relocation types. See below. */ - unsigned int dist2to : 8; - unsigned int relvaddr : 19; /* (VADDR - vaddr of the previous entry)/ 4 */ - unsigned long konst; /* KONST field. See below. */ -} Elf32_crinfo2; - -typedef struct -{ - bfd_byte info[4]; - bfd_byte konst[4]; - bfd_byte vaddr[4]; -} Elf32_External_crinfo; - -typedef struct -{ - bfd_byte info[4]; - bfd_byte konst[4]; -} Elf32_External_crinfo2; - -/* These are the constants used to swap the bitfields in a crinfo. */ - -#define CRINFO_CTYPE (0x1) -#define CRINFO_CTYPE_SH (31) -#define CRINFO_RTYPE (0xf) -#define CRINFO_RTYPE_SH (27) -#define CRINFO_DIST2TO (0xff) -#define CRINFO_DIST2TO_SH (19) -#define CRINFO_RELVADDR (0x7ffff) -#define CRINFO_RELVADDR_SH (0) - -/* A compact relocation info has long (3 words) or short (2 words) - formats. A short format doesn't have VADDR field and relvaddr - fields contains ((VADDR - vaddr of the previous entry) >> 2). */ -#define CRF_MIPS_LONG 1 -#define CRF_MIPS_SHORT 0 - -/* There are 4 types of compact relocation at least. The value KONST - has different meaning for each type: - - (type) (konst) - CT_MIPS_REL32 Address in data - CT_MIPS_WORD Address in word (XXX) - CT_MIPS_GPHI_LO GP - vaddr - CT_MIPS_JMPAD Address to jump - */ - -#define CRT_MIPS_REL32 0xa -#define CRT_MIPS_WORD 0xb -#define CRT_MIPS_GPHI_LO 0xc -#define CRT_MIPS_JMPAD 0xd - -#define mips_elf_set_cr_format(x,format) ((x).ctype = (format)) -#define mips_elf_set_cr_type(x,type) ((x).rtype = (type)) -#define mips_elf_set_cr_dist2to(x,v) ((x).dist2to = (v)) -#define mips_elf_set_cr_relvaddr(x,d) ((x).relvaddr = (d)<<2) - -static void bfd_elf32_swap_compact_rel_out - PARAMS ((bfd *, const Elf32_compact_rel *, Elf32_External_compact_rel *)); -static void bfd_elf32_swap_crinfo_out - PARAMS ((bfd *, const Elf32_crinfo *, Elf32_External_crinfo *)); - -#define USE_REL 1 /* MIPS uses REL relocations instead of RELA */ - -enum reloc_type -{ - R_MIPS_NONE = 0, - R_MIPS_16, R_MIPS_32, - R_MIPS_REL32, R_MIPS_26, - R_MIPS_HI16, R_MIPS_LO16, - R_MIPS_GPREL16, R_MIPS_LITERAL, - R_MIPS_GOT16, R_MIPS_PC16, - R_MIPS_CALL16, R_MIPS_GPREL32, - /* The remaining relocs are defined on Irix, although they are not - in the MIPS ELF ABI. */ - R_MIPS_UNUSED1, R_MIPS_UNUSED2, - R_MIPS_UNUSED3, - R_MIPS_SHIFT5, R_MIPS_SHIFT6, - R_MIPS_64, R_MIPS_GOT_DISP, - R_MIPS_GOT_PAGE, R_MIPS_GOT_OFST, - R_MIPS_GOT_HI16, R_MIPS_GOT_LO16, - R_MIPS_SUB, R_MIPS_INSERT_A, - R_MIPS_INSERT_B, R_MIPS_DELETE, - R_MIPS_HIGHER, R_MIPS_HIGHEST, - R_MIPS_CALL_HI16, R_MIPS_CALL_LO16, - R_MIPS_max -}; - -static reloc_howto_type elf_mips_howto_table[] = -{ - /* No relocation. */ - HOWTO (R_MIPS_NONE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_NONE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit relocation. */ - HOWTO (R_MIPS_16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32 bit relocation. */ - HOWTO (R_MIPS_32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32 bit symbol relative relocation. */ - HOWTO (R_MIPS_REL32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_REL32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 26 bit branch address. */ - HOWTO (R_MIPS_26, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - /* This needs complex overflow - detection, because the upper four - bits must match the PC. */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_26", /* name */ - true, /* partial_inplace */ - 0x3ffffff, /* src_mask */ - 0x3ffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* High 16 bits of symbol value. */ - HOWTO (R_MIPS_HI16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - mips_elf_hi16_reloc, /* special_function */ - "R_MIPS_HI16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Low 16 bits of symbol value. */ - HOWTO (R_MIPS_LO16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - mips_elf_lo16_reloc, /* special_function */ - "R_MIPS_LO16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* GP relative reference. */ - HOWTO (R_MIPS_GPREL16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - mips_elf_gprel16_reloc, /* special_function */ - "R_MIPS_GPREL16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Reference to literal section. */ - HOWTO (R_MIPS_LITERAL, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - mips_elf_gprel16_reloc, /* special_function */ - "R_MIPS_LITERAL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Reference to global offset table. */ - HOWTO (R_MIPS_GOT16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - mips_elf_got16_reloc, /* special_function */ - "R_MIPS_GOT16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit PC relative reference. */ - HOWTO (R_MIPS_PC16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_PC16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit call through global offset table. */ - /* FIXME: This is not handled correctly. */ - HOWTO (R_MIPS_CALL16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_CALL16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32 bit GP relative reference. */ - HOWTO (R_MIPS_GPREL32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - mips_elf_gprel32_reloc, /* special_function */ - "R_MIPS_GPREL32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* The remaining relocs are defined on Irix 5, although they are - not defined by the ABI. */ - { 13 }, - { 14 }, - { 15 }, - - /* A 5 bit shift field. */ - HOWTO (R_MIPS_SHIFT5, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 5, /* bitsize */ - false, /* pc_relative */ - 6, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_SHIFT5", /* name */ - true, /* partial_inplace */ - 0x000007c0, /* src_mask */ - 0x000007c0, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 6 bit shift field. */ - /* FIXME: This is not handled correctly; a special function is - needed to put the most significant bit in the right place. */ - HOWTO (R_MIPS_SHIFT6, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 6, /* bitsize */ - false, /* pc_relative */ - 6, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_SHIFT6", /* name */ - true, /* partial_inplace */ - 0x000007c4, /* src_mask */ - 0x000007c4, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 64 bit relocation. Presumably not used in 32 bit ELF. */ - { R_MIPS_64 }, - - /* Displacement in the global offset table. */ - /* FIXME: Not handled correctly. */ - HOWTO (R_MIPS_GOT_DISP, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_GOT_DISP", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Displacement to page pointer in the global offset table. */ - /* FIXME: Not handled correctly. */ - HOWTO (R_MIPS_GOT_PAGE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_GOT_PAGE", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Offset from page pointer in the global offset table. */ - /* FIXME: Not handled correctly. */ - HOWTO (R_MIPS_GOT_OFST, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_GOT_OFST", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* High 16 bits of displacement in global offset table. */ - /* FIXME: Not handled correctly. */ - HOWTO (R_MIPS_GOT_HI16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_GOT_HI16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Low 16 bits of displacement in global offset table. */ - /* FIXME: Not handled correctly. */ - HOWTO (R_MIPS_GOT_LO16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_GOT_LO16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 64 bit subtraction. Presumably not used in 32 bit ELF. */ - { R_MIPS_SUB }, - - /* Used to cause the linker to insert and delete instructions? */ - { R_MIPS_INSERT_A }, - { R_MIPS_INSERT_B }, - { R_MIPS_DELETE }, - - /* Get the higher values of a 64 bit addend. Presumably not used in - 32 bit ELF. */ - { R_MIPS_HIGHER }, - { R_MIPS_HIGHEST }, - - /* High 16 bits of displacement in global offset table. */ - /* FIXME: Not handled correctly. */ - HOWTO (R_MIPS_CALL_HI16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_CALL_HI16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Low 16 bits of displacement in global offset table. */ - /* FIXME: Not handled correctly. */ - HOWTO (R_MIPS_CALL_LO16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_MIPS_CALL_LO16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - false) /* pcrel_offset */ -}; - -/* Do a R_MIPS_HI16 relocation. This has to be done in combination - with a R_MIPS_LO16 reloc, because there is a carry from the LO16 to - the HI16. Here we just save the information we need; we do the - actual relocation when we see the LO16. MIPS ELF requires that the - LO16 immediately follow the HI16, so this ought to work. */ - -static bfd_byte *mips_hi16_addr; -static bfd_vma mips_hi16_addend; - -static bfd_reloc_status_type -mips_elf_hi16_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_reloc_status_type ret; - bfd_vma relocation; - - /* If we're relocating, and this an external symbol, we don't want - to change anything. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - ret = bfd_reloc_ok; - - if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0) - { - boolean relocateable; - bfd_vma gp; - - if (ret == bfd_reloc_undefined) - abort (); - - if (output_bfd != NULL) - relocateable = true; - else - { - relocateable = false; - output_bfd = symbol->section->output_section->owner; - } - - ret = mips_elf_final_gp (output_bfd, symbol, relocateable, - error_message, &gp); - if (ret != bfd_reloc_ok) - return ret; - - relocation = gp - reloc_entry->address; - } - else - { - if (bfd_is_und_section (symbol->section) - && output_bfd == (bfd *) NULL) - ret = bfd_reloc_undefined; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - } - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - /* Save the information, and let LO16 do the actual relocation. */ - mips_hi16_addr = (bfd_byte *) data + reloc_entry->address; - mips_hi16_addend = relocation; - - if (output_bfd != (bfd *) NULL) - reloc_entry->address += input_section->output_offset; - - return ret; -} - -/* Do a R_MIPS_LO16 relocation. This is a straightforward 16 bit - inplace relocation; this function exists in order to do the - R_MIPS_HI16 relocation described above. */ - -static bfd_reloc_status_type -mips_elf_lo16_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - arelent gp_disp_relent; - - if (mips_hi16_addr != (bfd_byte *) NULL) - { - unsigned long insn; - unsigned long val; - unsigned long vallo; - - /* Do the HI16 relocation. Note that we actually don't need to - know anything about the LO16 itself, except where to find the - low 16 bits of the addend needed by the LO16. */ - insn = bfd_get_32 (abfd, mips_hi16_addr); - vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address) - & 0xffff); - val = ((insn & 0xffff) << 16) + vallo; - val += mips_hi16_addend; - - /* The low order 16 bits are always treated as a signed value. - Therefore, a negative value in the low order bits requires an - adjustment in the high order bits. We need to make this - adjustment in two ways: once for the bits we took from the - data, and once for the bits we are putting back in to the - data. */ - if ((vallo & 0x8000) != 0) - val -= 0x10000; - if ((val & 0x8000) != 0) - val += 0x10000; - - insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff); - bfd_put_32 (abfd, insn, mips_hi16_addr); - - mips_hi16_addr = (bfd_byte *) NULL; - - if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0) - { - gp_disp_relent = *reloc_entry; - reloc_entry = &gp_disp_relent; - reloc_entry->addend = mips_hi16_addend; - } - } - else if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0) - { - bfd_reloc_status_type ret; - bfd_vma gp, relocation; - - /* FIXME: Does this case ever occur? */ - - ret = mips_elf_final_gp (output_bfd, symbol, true, error_message, &gp); - if (ret != bfd_reloc_ok) - return ret; - - relocation = gp - reloc_entry->address; - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - gp_disp_relent = *reloc_entry; - reloc_entry = &gp_disp_relent; - reloc_entry->addend = relocation - 4; - } - - /* Now do the LO16 reloc in the usual way. */ - return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message); -} - -/* Do a R_MIPS_GOT16 reloc. This is a reloc against the global offset - table used for PIC code. If the symbol is an external symbol, the - instruction is modified to contain the offset of the appropriate - entry in the global offset table. If the symbol is a section - symbol, the next reloc is a R_MIPS_LO16 reloc. The two 16 bit - addends are combined to form the real addend against the section - symbol; the GOT16 is modified to contain the offset of an entry in - the global offset table, and the LO16 is modified to offset it - appropriately. Thus an offset larger than 16 bits requires a - modified value in the global offset table. - - This implementation suffices for the assembler, but the linker does - not yet know how to create global offset tables. */ - -static bfd_reloc_status_type -mips_elf_got16_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - /* If we're relocating, and this an external symbol, we don't want - to change anything. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* If we're relocating, and this is a local symbol, we can handle it - just like HI16. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) != 0) - return mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data, - input_section, output_bfd, error_message); - - abort (); -} - -/* We have to figure out the gp value, so that we can adjust the - symbol value correctly. We look up the symbol _gp in the output - BFD. If we can't find it, we're stuck. We cache it in the ELF - target data. We don't need to adjust the symbol value for an - external symbol if we are producing relocateable output. */ - -static bfd_reloc_status_type -mips_elf_final_gp (output_bfd, symbol, relocateable, error_message, pgp) - bfd *output_bfd; - asymbol *symbol; - boolean relocateable; - char **error_message; - bfd_vma *pgp; -{ - if (bfd_is_und_section (symbol->section) - && ! relocateable) - { - *pgp = 0; - return bfd_reloc_undefined; - } - - *pgp = _bfd_get_gp_value (output_bfd); - if (*pgp == 0 - && (! relocateable - || (symbol->flags & BSF_SECTION_SYM) != 0)) - { - if (relocateable) - { - /* Make up a value. */ - *pgp = symbol->section->output_section->vma + 0x4000; - _bfd_set_gp_value (output_bfd, *pgp); - } - else - { - unsigned int count; - asymbol **sym; - unsigned int i; - - count = bfd_get_symcount (output_bfd); - sym = bfd_get_outsymbols (output_bfd); - - if (sym == (asymbol **) NULL) - i = count; - else - { - for (i = 0; i < count; i++, sym++) - { - register CONST char *name; - - name = bfd_asymbol_name (*sym); - if (*name == '_' && strcmp (name, "_gp") == 0) - { - *pgp = bfd_asymbol_value (*sym); - _bfd_set_gp_value (output_bfd, *pgp); - break; - } - } - } - - if (i >= count) - { - /* Only get the error once. */ - *pgp = 4; - _bfd_set_gp_value (output_bfd, *pgp); - *error_message = - (char *) "GP relative relocation when _gp not defined"; - return bfd_reloc_dangerous; - } - } - } - - return bfd_reloc_ok; -} - -/* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must - become the offset from the gp register. This function also handles - R_MIPS_LITERAL relocations, although those can be handled more - cleverly because the entries in the .lit8 and .lit4 sections can be - merged. */ - -static bfd_reloc_status_type gprel16_with_gp PARAMS ((bfd *, asymbol *, - arelent *, asection *, - boolean, PTR, bfd_vma)); - -static bfd_reloc_status_type -mips_elf_gprel16_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - boolean relocateable; - bfd_reloc_status_type ret; - bfd_vma gp; - - /* If we're relocating, and this is an external symbol with no - addend, we don't want to change anything. We will only have an - addend if this is a newly created reloc, not read from an ELF - file. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - if (output_bfd != (bfd *) NULL) - relocateable = true; - else - { - relocateable = false; - output_bfd = symbol->section->output_section->owner; - } - - ret = mips_elf_final_gp (output_bfd, symbol, relocateable, error_message, - &gp); - if (ret != bfd_reloc_ok) - return ret; - - return gprel16_with_gp (abfd, symbol, reloc_entry, input_section, - relocateable, data, gp); -} - -static bfd_reloc_status_type -gprel16_with_gp (abfd, symbol, reloc_entry, input_section, relocateable, data, - gp) - bfd *abfd; - asymbol *symbol; - arelent *reloc_entry; - asection *input_section; - boolean relocateable; - PTR data; - bfd_vma gp; -{ - bfd_vma relocation; - unsigned long insn; - unsigned long val; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); - - /* Set val to the offset into the section or symbol. */ - val = ((insn & 0xffff) + reloc_entry->addend) & 0xffff; - if (val & 0x8000) - val -= 0x10000; - - /* Adjust val for the final section location and GP value. If we - are producing relocateable output, we don't want to do this for - an external symbol. */ - if (! relocateable - || (symbol->flags & BSF_SECTION_SYM) != 0) - val += relocation - gp; - - insn = (insn &~ 0xffff) | (val & 0xffff); - bfd_put_32 (abfd, insn, (bfd_byte *) data + reloc_entry->address); - - if (relocateable) - reloc_entry->address += input_section->output_offset; - - /* Make sure it fit in 16 bits. */ - if (val >= 0x8000 && val < 0xffff8000) - return bfd_reloc_overflow; - - return bfd_reloc_ok; -} - -/* Do a R_MIPS_GPREL32 relocation. Is this 32 bit value the offset - from the gp register? XXX */ - -static bfd_reloc_status_type gprel32_with_gp PARAMS ((bfd *, asymbol *, - arelent *, asection *, - boolean, PTR, bfd_vma)); - -static bfd_reloc_status_type -mips_elf_gprel32_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - boolean relocateable; - bfd_reloc_status_type ret; - bfd_vma gp; - - /* If we're relocating, and this is an external symbol with no - addend, we don't want to change anything. We will only have an - addend if this is a newly created reloc, not read from an ELF - file. */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && reloc_entry->addend == 0) - { - *error_message = (char *) - "32bits gp relative relocation occurs for an external symbol"; - return bfd_reloc_outofrange; - } - - if (output_bfd != (bfd *) NULL) - { - relocateable = true; - gp = _bfd_get_gp_value (output_bfd); - } - else - { - relocateable = false; - output_bfd = symbol->section->output_section->owner; - - ret = mips_elf_final_gp (output_bfd, symbol, relocateable, - error_message, &gp); - if (ret != bfd_reloc_ok) - return ret; - } - - return gprel32_with_gp (abfd, symbol, reloc_entry, input_section, - relocateable, data, gp); -} - -static bfd_reloc_status_type -gprel32_with_gp (abfd, symbol, reloc_entry, input_section, relocateable, data, - gp) - bfd *abfd; - asymbol *symbol; - arelent *reloc_entry; - asection *input_section; - boolean relocateable; - PTR data; - bfd_vma gp; -{ - bfd_vma relocation; - unsigned long val; - - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - val = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address); - - /* Set val to the offset into the section or symbol. */ - val += reloc_entry->addend; - - /* Adjust val for the final section location and GP value. If we - are producing relocateable output, we don't want to do this for - an external symbol. */ - if (! relocateable - || (symbol->flags & BSF_SECTION_SYM) != 0) - val += relocation - gp; - - bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address); - - if (relocateable) - reloc_entry->address += input_section->output_offset; - - return bfd_reloc_ok; -} - -/* A mapping from BFD reloc types to MIPS ELF reloc types. */ - -struct elf_reloc_map { - bfd_reloc_code_real_type bfd_reloc_val; - enum reloc_type elf_reloc_val; -}; - -static CONST struct elf_reloc_map mips_reloc_map[] = -{ - { BFD_RELOC_NONE, R_MIPS_NONE, }, - { BFD_RELOC_16, R_MIPS_16 }, - { BFD_RELOC_32, R_MIPS_32 }, - { BFD_RELOC_CTOR, R_MIPS_32 }, - { BFD_RELOC_32_PCREL, R_MIPS_REL32 }, - { BFD_RELOC_MIPS_JMP, R_MIPS_26 }, - { BFD_RELOC_HI16_S, R_MIPS_HI16 }, - { BFD_RELOC_LO16, R_MIPS_LO16 }, - { BFD_RELOC_MIPS_GPREL, R_MIPS_GPREL16 }, - { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL }, - { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 }, - { BFD_RELOC_16_PCREL, R_MIPS_PC16 }, - { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 }, - { BFD_RELOC_MIPS_GPREL32, R_MIPS_GPREL32 }, - { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 }, - { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 }, - { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 }, - { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 } -}; - -/* Given a BFD reloc type, return a howto structure. */ - -static reloc_howto_type * -bfd_elf32_bfd_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - unsigned int i; - - for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map); i++) - { - if (mips_reloc_map[i].bfd_reloc_val == code) - return &elf_mips_howto_table[(int) mips_reloc_map[i].elf_reloc_val]; - } - return NULL; -} - -/* Given a MIPS reloc type, fill in an arelent structure. */ - -static void -mips_info_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf32_Internal_Rel *dst; -{ - unsigned int r_type; - - r_type = ELF32_R_TYPE (dst->r_info); - BFD_ASSERT (r_type < (unsigned int) R_MIPS_max); - cache_ptr->howto = &elf_mips_howto_table[r_type]; - - /* The addend for a GPREL16 or LITERAL relocation comes from the GP - value for the object file. We get the addend now, rather than - when we do the relocation, because the symbol manipulations done - by the linker may cause us to lose track of the input BFD. */ - if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0 - && (r_type == (unsigned int) R_MIPS_GPREL16 - || r_type == (unsigned int) R_MIPS_LITERAL)) - cache_ptr->addend = elf_gp (abfd); -} - -/* A .reginfo section holds a single Elf32_RegInfo structure. These - routines swap this structure in and out. They are used outside of - BFD, so they are globally visible. */ - -void -bfd_mips_elf32_swap_reginfo_in (abfd, ex, in) - bfd *abfd; - const Elf32_External_RegInfo *ex; - Elf32_RegInfo *in; -{ - in->ri_gprmask = bfd_h_get_32 (abfd, (bfd_byte *) ex->ri_gprmask); - 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_32 (abfd, (bfd_byte *) ex->ri_gp_value); -} - -void -bfd_mips_elf32_swap_reginfo_out (abfd, in, ex) - bfd *abfd; - const Elf32_RegInfo *in; - Elf32_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_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_32 (abfd, (bfd_vma) in->ri_gp_value, - (bfd_byte *) ex->ri_gp_value); -} - -/* Swap an entry in a .gptab section. Note that these routines rely - on the equivalence of the two elements of the union. */ - -static void -bfd_mips_elf32_swap_gptab_in (abfd, ex, in) - bfd *abfd; - const Elf32_External_gptab *ex; - Elf32_gptab *in; -{ - in->gt_entry.gt_g_value = bfd_h_get_32 (abfd, ex->gt_entry.gt_g_value); - in->gt_entry.gt_bytes = bfd_h_get_32 (abfd, ex->gt_entry.gt_bytes); -} - -static void -bfd_mips_elf32_swap_gptab_out (abfd, in, ex) - bfd *abfd; - const Elf32_gptab *in; - Elf32_External_gptab *ex; -{ - bfd_h_put_32 (abfd, (bfd_vma) in->gt_entry.gt_g_value, - ex->gt_entry.gt_g_value); - bfd_h_put_32 (abfd, (bfd_vma) in->gt_entry.gt_bytes, - ex->gt_entry.gt_bytes); -} - -static void -bfd_elf32_swap_compact_rel_out (abfd, in, ex) - bfd *abfd; - const Elf32_compact_rel *in; - Elf32_External_compact_rel *ex; -{ - bfd_h_put_32 (abfd, (bfd_vma) in->id1, ex->id1); - bfd_h_put_32 (abfd, (bfd_vma) in->num, ex->num); - bfd_h_put_32 (abfd, (bfd_vma) in->id2, ex->id2); - bfd_h_put_32 (abfd, (bfd_vma) in->offset, ex->offset); - bfd_h_put_32 (abfd, (bfd_vma) in->reserved0, ex->reserved0); - bfd_h_put_32 (abfd, (bfd_vma) in->reserved1, ex->reserved1); -} - -static void -bfd_elf32_swap_crinfo_out (abfd, in, ex) - bfd *abfd; - const Elf32_crinfo *in; - Elf32_External_crinfo *ex; -{ - unsigned long l; - - l = (((in->ctype & CRINFO_CTYPE) << CRINFO_CTYPE_SH) - | ((in->rtype & CRINFO_RTYPE) << CRINFO_RTYPE_SH) - | ((in->dist2to & CRINFO_DIST2TO) << CRINFO_DIST2TO_SH) - | ((in->relvaddr & CRINFO_RELVADDR) << CRINFO_RELVADDR_SH)); - bfd_h_put_32 (abfd, (bfd_vma) l, ex->info); - bfd_h_put_32 (abfd, (bfd_vma) in->konst, ex->konst); - bfd_h_put_32 (abfd, (bfd_vma) in->vaddr, ex->vaddr); -} - -/* Determine whether a symbol is global for the purposes of splitting - the symbol table into global symbols and local symbols. At least - on Irix 5, this split must be between section symbols and all other - symbols. On most ELF targets the split is between static symbols - and externally visible symbols. */ - -/*ARGSUSED*/ -static boolean -mips_elf_sym_is_global (abfd, sym) - bfd *abfd; - asymbol *sym; -{ - return (sym->flags & BSF_SECTION_SYM) == 0 ? true : false; -} - -/* Set the right machine number for a MIPS ELF file. */ - -static boolean -mips_elf_object_p (abfd) - bfd *abfd; -{ - switch (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) - { - default: - case E_MIPS_ARCH_1: - /* Just use the default, which was set in elfcode.h. */ - break; - - case E_MIPS_ARCH_2: - (void) bfd_default_set_arch_mach (abfd, bfd_arch_mips, 6000); - break; - - case E_MIPS_ARCH_3: - (void) bfd_default_set_arch_mach (abfd, bfd_arch_mips, 4000); - break; - } - - /* Irix 5 is broken. Object file symbol tables are not always - sorted correctly such that local symbols precede global symbols, - and the sh_info field in the symbol table is not always right. */ - elf_bad_symtab (abfd) = true; - - return true; -} - -/* The final processing done just before writing out a MIPS ELF object - file. This gets the MIPS architecture right based on the machine - number. */ - -/*ARGSUSED*/ -static void -mips_elf_final_write_processing (abfd, linker) - bfd *abfd; - boolean linker; -{ - unsigned long val; - unsigned int i; - Elf_Internal_Shdr **hdrpp; - - switch (bfd_get_mach (abfd)) - { - case 3000: - val = E_MIPS_ARCH_1; - break; - - case 6000: - val = E_MIPS_ARCH_2; - break; - - case 4000: - val = E_MIPS_ARCH_3; - break; - - default: - val = 0; - break; - } - - elf_elfheader (abfd)->e_flags &=~ EF_MIPS_ARCH; - elf_elfheader (abfd)->e_flags |= val; - - /* Set the sh_info field for .gptab sections. */ - for (i = 1, hdrpp = elf_elfsections (abfd) + 1; - i < elf_elfheader (abfd)->e_shnum; - i++, hdrpp++) - { - if ((*hdrpp)->sh_type == SHT_MIPS_GPTAB) - { - const char *name; - asection *sec; - - BFD_ASSERT ((*hdrpp)->bfd_section != NULL); - name = bfd_get_section_name (abfd, (*hdrpp)->bfd_section); - BFD_ASSERT (name != NULL - && strncmp (name, ".gptab.", sizeof ".gptab." - 1) == 0); - sec = bfd_get_section_by_name (abfd, name + sizeof ".gptab" - 1); - BFD_ASSERT (sec != NULL); - (*hdrpp)->sh_info = elf_section_data (sec)->this_idx; - } - } -} - -/* Function to keep MIPS specific file flags like as EF_MIPS_PIC. */ - -static boolean -mips_elf_set_private_flags (abfd, flags) - bfd *abfd; - flagword flags; -{ - BFD_ASSERT (!elf_flags_init (abfd) - || elf_elfheader (abfd)->e_flags == flags); - - elf_elfheader (abfd)->e_flags = flags; - elf_flags_init (abfd) = true; - return true; -} - -/* Copy backend specific data from one object module to another */ - -static boolean -mips_elf_copy_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; -{ - /* This function is selected based on the input vector. We only - want to copy information over if the output BFD also uses Elf - format. */ - if (bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return true; - - BFD_ASSERT (!elf_flags_init (obfd) - || (elf_elfheader (obfd)->e_flags - == elf_elfheader (ibfd)->e_flags)); - - elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; - elf_flags_init (obfd) = true; - return true; -} - -/* Merge backend specific data from an object file to the output - object file when linking. */ - -static boolean -mips_elf_merge_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; -{ - flagword old_flags; - flagword new_flags; - - /* Check if we have the same endianess */ - if (ibfd->xvec->byteorder != obfd->xvec->byteorder - && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN) - { - (*_bfd_error_handler) - ("%s: compiled for a %s endian system and target is %s endian", - bfd_get_filename (ibfd), - bfd_big_endian (ibfd) ? "big" : "little", - bfd_big_endian (obfd) ? "big" : "little"); - - bfd_set_error (bfd_error_wrong_format); - return false; - } - - /* This function is selected based on the input vector. We only - want to copy information over if the output BFD also uses Elf - format. */ - if (bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return true; - - new_flags = elf_elfheader (ibfd)->e_flags; - elf_elfheader (obfd)->e_flags |= new_flags & EF_MIPS_NOREORDER; - old_flags = elf_elfheader (obfd)->e_flags; - - if (!elf_flags_init (obfd)) /* First call, no flags set */ - { - elf_flags_init (obfd) = true; - elf_elfheader (obfd)->e_flags = new_flags; - } - else if (((new_flags ^ old_flags) & ~EF_MIPS_NOREORDER) - == 0) /* Compatible flags are ok */ - ; - else /* Incompatible flags */ - { - /* Warn about -fPIC mismatch */ - if ((new_flags & EF_MIPS_PIC) != (old_flags & EF_MIPS_PIC)) - { - new_flags &= ~EF_MIPS_PIC; - (*_bfd_error_handler) - ("%s: needs all files compiled with -fPIC", - bfd_get_filename (ibfd)); - } - - if ((new_flags & EF_MIPS_CPIC) != (old_flags & EF_MIPS_CPIC)) - { - new_flags &= ~EF_MIPS_CPIC; - (*_bfd_error_handler) - ("%s: needs all files compiled with -mabicalls", - bfd_get_filename (ibfd)); - } - - /* Warn about any other mismatches */ - if (new_flags != old_flags) - (*_bfd_error_handler) - ("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)", - bfd_get_filename (ibfd), (unsigned long) new_flags, - (unsigned long) old_flags); - - bfd_set_error (bfd_error_bad_value); - return false; - } - - return true; -} - -/* Handle a MIPS specific section when reading an object file. This - is called when elfcode.h finds a section with an unknown type. - FIXME: We need to handle the SHF_MIPS_GPREL flag, but I'm not sure - how to. */ - -static boolean -mips_elf_section_from_shdr (abfd, hdr, name) - bfd *abfd; - Elf32_Internal_Shdr *hdr; - char *name; -{ - asection *newsect; - - /* There ought to be a place to keep ELF backend specific flags, but - at the moment there isn't one. We just keep track of the - sections by their name, instead. Fortunately, the ABI gives - suggested names for all the MIPS specific sections, so we will - probably get away with this. */ - switch (hdr->sh_type) - { - case SHT_MIPS_LIBLIST: - if (strcmp (name, ".liblist") != 0) - return false; - break; - case SHT_MIPS_MSYM: - if (strcmp (name, ".msym") != 0) - return false; - break; - case SHT_MIPS_CONFLICT: - if (strcmp (name, ".conflict") != 0) - return false; - break; - case SHT_MIPS_GPTAB: - if (strncmp (name, ".gptab.", sizeof ".gptab." - 1) != 0) - return false; - break; - case SHT_MIPS_UCODE: - if (strcmp (name, ".ucode") != 0) - return false; - break; - case SHT_MIPS_DEBUG: - if (strcmp (name, ".mdebug") != 0) - return false; - break; - case SHT_MIPS_REGINFO: - if (strcmp (name, ".reginfo") != 0 - || hdr->sh_size != sizeof (Elf32_External_RegInfo)) - return false; - break; - case SHT_MIPS_OPTIONS: - if (strcmp (name, ".options") != 0) - return false; - break; - case SHT_MIPS_DWARF: - if (strncmp (name, ".debug_", sizeof ".debug_" - 1) != 0) - return false; - break; - case SHT_MIPS_EVENTS: - if (strncmp (name, ".MIPS.events.", sizeof ".MIPS.events." - 1) != 0) - return false; - break; - default: - return false; - } - - if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) - return false; - newsect = hdr->bfd_section; - - if (hdr->sh_type == SHT_MIPS_DEBUG) - { - if (! bfd_set_section_flags (abfd, newsect, - (bfd_get_section_flags (abfd, newsect) - | SEC_DEBUGGING))) - return false; - } - - /* FIXME: We should record sh_info for a .gptab section. */ - - /* For a .reginfo section, set the gp value in the tdata information - from the contents of this section. We need the gp value while - processing relocs, so we just get it now. */ - if (hdr->sh_type == SHT_MIPS_REGINFO) - { - Elf32_External_RegInfo ext; - Elf32_RegInfo s; - - if (! bfd_get_section_contents (abfd, newsect, (PTR) &ext, - (file_ptr) 0, sizeof ext)) - return false; - bfd_mips_elf32_swap_reginfo_in (abfd, &ext, &s); - elf_gp (abfd) = s.ri_gp_value; - } - - return true; -} - -/* Set the correct type for a MIPS ELF section. We do this by the - section name, which is a hack, but ought to work. */ - -static boolean -mips_elf_fake_sections (abfd, hdr, sec) - bfd *abfd; - Elf32_Internal_Shdr *hdr; - asection *sec; -{ - register const char *name; - - name = bfd_get_section_name (abfd, sec); - - if (strcmp (name, ".liblist") == 0) - { - hdr->sh_type = SHT_MIPS_LIBLIST; - hdr->sh_info = sec->_raw_size / sizeof (Elf32_Lib); - /* FIXME: Set the sh_link field. */ - } - else if (strcmp (name, ".msym") == 0) - { - hdr->sh_type = SHT_MIPS_MSYM; - hdr->sh_entsize = 8; - /* FIXME: Set the sh_info field. */ - } - else if (strcmp (name, ".conflict") == 0) - hdr->sh_type = SHT_MIPS_CONFLICT; - else if (strncmp (name, ".gptab.", sizeof ".gptab." - 1) == 0) - { - hdr->sh_type = SHT_MIPS_GPTAB; - hdr->sh_entsize = sizeof (Elf32_External_gptab); - /* The sh_info field is set in mips_elf_final_write_processing. */ - } - else if (strcmp (name, ".ucode") == 0) - hdr->sh_type = SHT_MIPS_UCODE; - else if (strcmp (name, ".mdebug") == 0) - { - hdr->sh_type = SHT_MIPS_DEBUG; - /* In a shared object on Irix 5.3, the .mdebug section has an - entsize of 0. FIXME: Does this matter? */ - if (SGI_COMPAT (abfd) && (abfd->flags & DYNAMIC) != 0) - hdr->sh_entsize = 0; - else - hdr->sh_entsize = 1; - } - else if (strcmp (name, ".reginfo") == 0) - { - hdr->sh_type = SHT_MIPS_REGINFO; - /* In a shared object on Irix 5.3, the .reginfo section has an - entsize of 0x18. FIXME: Does this matter? */ - if (SGI_COMPAT (abfd) && (abfd->flags & DYNAMIC) != 0) - hdr->sh_entsize = sizeof (Elf32_External_RegInfo); - else - hdr->sh_entsize = 1; - - /* Force the section size to the correct value, even if the - linker thinks it is larger. The link routine below will only - write out this much data for .reginfo. */ - hdr->sh_size = sec->_raw_size = sizeof (Elf32_External_RegInfo); - } - else if (SGI_COMPAT (abfd) - && (strcmp (name, ".hash") == 0 - || strcmp (name, ".dynamic") == 0 - || strcmp (name, ".dynstr") == 0)) - { - hdr->sh_entsize = 0; - hdr->sh_info = SIZEOF_MIPS_DYNSYM_SECNAMES; - } - else if (strcmp (name, ".got") == 0 - || strcmp (name, ".sdata") == 0 - || strcmp (name, ".sbss") == 0 - || strcmp (name, ".lit4") == 0 - || strcmp (name, ".lit8") == 0) - hdr->sh_flags |= SHF_MIPS_GPREL; - else if (strcmp (name, ".options") == 0) - { - hdr->sh_type = SHT_MIPS_OPTIONS; - hdr->sh_entsize = 1; - } - else if (strncmp (name, ".debug_", sizeof ".debug_" - 1) == 0) - hdr->sh_type = SHT_MIPS_DWARF; - else if (strncmp (name, ".MIPS.events.", sizeof ".MIPS.events." - 1) == 0) - hdr->sh_type = SHT_MIPS_EVENTS; - - return true; -} - -/* Given a BFD section, try to locate the corresponding ELF section - index. */ - -static boolean -mips_elf_section_from_bfd_section (abfd, hdr, sec, retval) - bfd *abfd; - Elf32_Internal_Shdr *hdr; - asection *sec; - int *retval; -{ - if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0) - { - *retval = SHN_MIPS_SCOMMON; - return true; - } - if (strcmp (bfd_get_section_name (abfd, sec), ".acommon") == 0) - { - *retval = SHN_MIPS_ACOMMON; - return true; - } - return false; -} - -/* Work over a section just before writing it out. We update the GP - value in the .reginfo section based on the value we are using. - FIXME: We recognize sections that need the SHF_MIPS_GPREL flag by - name; there has to be a better way. */ - -static boolean -mips_elf_section_processing (abfd, hdr) - bfd *abfd; - Elf32_Internal_Shdr *hdr; -{ - if (hdr->sh_type == SHT_MIPS_REGINFO) - { - bfd_byte buf[4]; - - BFD_ASSERT (hdr->sh_size == sizeof (Elf32_External_RegInfo)); - BFD_ASSERT (hdr->contents == NULL); - - if (bfd_seek (abfd, - hdr->sh_offset + sizeof (Elf32_External_RegInfo) - 4, - SEEK_SET) == -1) - return false; - bfd_h_put_32 (abfd, (bfd_vma) elf_gp (abfd), buf); - if (bfd_write (buf, (bfd_size_type) 1, (bfd_size_type) 4, abfd) != 4) - return false; - } - - if (hdr->bfd_section != NULL) - { - const char *name = bfd_get_section_name (abfd, hdr->bfd_section); - - if (strcmp (name, ".sdata") == 0) - { - hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL; - hdr->sh_type = SHT_PROGBITS; - } - else if (strcmp (name, ".sbss") == 0) - { - hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL; - hdr->sh_type = SHT_NOBITS; - } - else if (strcmp (name, ".lit8") == 0 - || strcmp (name, ".lit4") == 0) - { - hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL; - hdr->sh_type = SHT_PROGBITS; - } - else if (strcmp (name, ".compact_rel") == 0) - { - hdr->sh_flags = 0; - hdr->sh_type = SHT_PROGBITS; - } - else if (strcmp (name, ".rtproc") == 0) - { - if (hdr->sh_addralign != 0 && hdr->sh_entsize == 0) - { - unsigned int adjust; - - adjust = hdr->sh_size % hdr->sh_addralign; - if (adjust != 0) - hdr->sh_size += hdr->sh_addralign - adjust; - } - } - } - - return true; -} - -/* MIPS ELF uses two common sections. One is the usual one, and the - other is for small objects. All the small objects are kept - together, and then referenced via the gp pointer, which yields - faster assembler code. This is what we use for the small common - section. This approach is copied from ecoff.c. */ -static asection mips_elf_scom_section; -static asymbol mips_elf_scom_symbol; -static asymbol *mips_elf_scom_symbol_ptr; - -/* MIPS ELF also uses an acommon section, which represents an - allocated common symbol which may be overridden by a - definition in a shared library. */ -static asection mips_elf_acom_section; -static asymbol mips_elf_acom_symbol; -static asymbol *mips_elf_acom_symbol_ptr; - -/* The Irix 5 support uses two virtual sections, which represent - text/data symbols defined in dynamic objects. */ -static asection mips_elf_text_section; -static asection *mips_elf_text_section_ptr; -static asymbol mips_elf_text_symbol; -static asymbol *mips_elf_text_symbol_ptr; - -static asection mips_elf_data_section; -static asection *mips_elf_data_section_ptr; -static asymbol mips_elf_data_symbol; -static asymbol *mips_elf_data_symbol_ptr; - -/* Handle the special MIPS section numbers that a symbol may use. */ - -static void -mips_elf_symbol_processing (abfd, asym) - bfd *abfd; - asymbol *asym; -{ - elf_symbol_type *elfsym; - - elfsym = (elf_symbol_type *) asym; - switch (elfsym->internal_elf_sym.st_shndx) - { - case SHN_MIPS_ACOMMON: - /* This section is used in a dynamically linked executable file. - It is an allocated common section. The dynamic linker can - either resolve these symbols to something in a shared - library, or it can just leave them here. For our purposes, - we can consider these symbols to be in a new section. */ - if (mips_elf_acom_section.name == NULL) - { - /* Initialize the acommon section. */ - mips_elf_acom_section.name = ".acommon"; - mips_elf_acom_section.flags = SEC_ALLOC; - mips_elf_acom_section.output_section = &mips_elf_acom_section; - mips_elf_acom_section.symbol = &mips_elf_acom_symbol; - mips_elf_acom_section.symbol_ptr_ptr = &mips_elf_acom_symbol_ptr; - mips_elf_acom_symbol.name = ".acommon"; - mips_elf_acom_symbol.flags = BSF_SECTION_SYM; - mips_elf_acom_symbol.section = &mips_elf_acom_section; - mips_elf_acom_symbol_ptr = &mips_elf_acom_symbol; - } - asym->section = &mips_elf_acom_section; - break; - - case SHN_COMMON: - /* Common symbols less than the GP size are automatically - treated as SHN_MIPS_SCOMMON symbols. */ - if (asym->value > elf_gp_size (abfd)) - break; - /* Fall through. */ - case SHN_MIPS_SCOMMON: - if (mips_elf_scom_section.name == NULL) - { - /* Initialize the small common section. */ - mips_elf_scom_section.name = ".scommon"; - mips_elf_scom_section.flags = SEC_IS_COMMON; - mips_elf_scom_section.output_section = &mips_elf_scom_section; - mips_elf_scom_section.symbol = &mips_elf_scom_symbol; - mips_elf_scom_section.symbol_ptr_ptr = &mips_elf_scom_symbol_ptr; - mips_elf_scom_symbol.name = ".scommon"; - mips_elf_scom_symbol.flags = BSF_SECTION_SYM; - mips_elf_scom_symbol.section = &mips_elf_scom_section; - mips_elf_scom_symbol_ptr = &mips_elf_scom_symbol; - } - asym->section = &mips_elf_scom_section; - asym->value = elfsym->internal_elf_sym.st_size; - break; - - case SHN_MIPS_SUNDEFINED: - asym->section = bfd_und_section_ptr; - break; - -#if 0 /* for SGI_COMPAT */ - case SHN_MIPS_TEXT: - asym->section = mips_elf_text_section_ptr; - break; - - case SHN_MIPS_DATA: - asym->section = mips_elf_data_section_ptr; - break; -#endif - } -} - -/* When creating an Irix 5 executable, we need REGINFO and RTPROC - segments. */ - -static int -mips_elf_additional_program_headers (abfd) - bfd *abfd; -{ - asection *s; - int ret; - - ret = 0; - - if (! SGI_COMPAT (abfd)) - return ret; - - s = bfd_get_section_by_name (abfd, ".reginfo"); - if (s != NULL && (s->flags & SEC_LOAD) != 0) - { - /* We need a PT_MIPS_REGINFO segment. */ - ++ret; - } - - if (bfd_get_section_by_name (abfd, ".dynamic") != NULL - && bfd_get_section_by_name (abfd, ".mdebug") != NULL) - { - /* We need a PT_MIPS_RTPROC segment. */ - ++ret; - } - - return ret; -} - -/* Modify the segment map for an Irix 5 executable. */ - -static boolean -mips_elf_modify_segment_map (abfd) - bfd *abfd; -{ - asection *s; - struct elf_segment_map *m, **pm; - - if (! SGI_COMPAT (abfd)) - return true; - - /* If there is a .reginfo section, we need a PT_MIPS_REGINFO - segment. */ - s = bfd_get_section_by_name (abfd, ".reginfo"); - if (s != NULL && (s->flags & SEC_LOAD) != 0) - { - for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) - if (m->p_type == PT_MIPS_REGINFO) - break; - if (m == NULL) - { - m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m); - if (m == NULL) - return false; - - m->p_type = PT_MIPS_REGINFO; - m->count = 1; - m->sections[0] = s; - - /* We want to put it after the PHDR and INTERP segments. */ - pm = &elf_tdata (abfd)->segment_map; - while (*pm != NULL - && ((*pm)->p_type == PT_PHDR - || (*pm)->p_type == PT_INTERP)) - pm = &(*pm)->next; - - m->next = *pm; - *pm = m; - } - } - - /* If there are .dynamic and .mdebug sections, we make a room for - the RTPROC header. FIXME: Rewrite without section names. */ - if (bfd_get_section_by_name (abfd, ".interp") == NULL - && bfd_get_section_by_name (abfd, ".dynamic") != NULL - && bfd_get_section_by_name (abfd, ".mdebug") != NULL) - { - for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) - if (m->p_type == PT_MIPS_RTPROC) - break; - if (m == NULL) - { - m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m); - if (m == NULL) - return false; - - m->p_type = PT_MIPS_RTPROC; - - s = bfd_get_section_by_name (abfd, ".rtproc"); - if (s == NULL) - { - m->count = 0; - m->p_flags = 0; - m->p_flags_valid = 1; - } - else - { - m->count = 1; - m->sections[0] = s; - } - - /* We want to put it after the DYNAMIC segment. */ - pm = &elf_tdata (abfd)->segment_map; - while (*pm != NULL && (*pm)->p_type != PT_DYNAMIC) - pm = &(*pm)->next; - if (*pm != NULL) - pm = &(*pm)->next; - - m->next = *pm; - *pm = m; - } - } - - /* On Irix 5, the PT_DYNAMIC segment includes the .dynamic, .dynstr, - .dynsym, and .hash sections, and everything in between. */ - for (pm = &elf_tdata (abfd)->segment_map; *pm != NULL; pm = &(*pm)->next) - if ((*pm)->p_type == PT_DYNAMIC) - break; - m = *pm; - if (m != NULL - && m->count == 1 - && strcmp (m->sections[0]->name, ".dynamic") == 0) - { - static const char *sec_names[] = - { ".dynamic", ".dynstr", ".dynsym", ".hash" }; - bfd_vma low, high; - unsigned int i, c; - struct elf_segment_map *n; - - low = 0xffffffff; - high = 0; - for (i = 0; i < sizeof sec_names / sizeof sec_names[0]; i++) - { - s = bfd_get_section_by_name (abfd, sec_names[i]); - if (s != NULL && (s->flags & SEC_LOAD) != 0) - { - bfd_size_type sz; - - if (low > s->vma) - low = s->vma; - sz = s->_cooked_size; - if (sz == 0) - sz = s->_raw_size; - if (high < s->vma + sz) - high = s->vma + sz; - } - } - - c = 0; - for (s = abfd->sections; s != NULL; s = s->next) - if ((s->flags & SEC_LOAD) != 0 - && s->vma >= low - && ((s->vma - + (s->_cooked_size != 0 ? s->_cooked_size : s->_raw_size)) - <= high)) - ++c; - - n = ((struct elf_segment_map *) - bfd_zalloc (abfd, sizeof *n + (c - 1) * sizeof (asection *))); - if (n == NULL) - return false; - *n = *m; - n->count = c; - - i = 0; - for (s = abfd->sections; s != NULL; s = s->next) - { - if ((s->flags & SEC_LOAD) != 0 - && s->vma >= low - && ((s->vma - + (s->_cooked_size != 0 ? s->_cooked_size : s->_raw_size)) - <= high)) - { - n->sections[i] = s; - ++i; - } - } - - *pm = n; - } - - return true; -} - -/* The structure of the runtime procedure descriptor created by the - loader for use by the static exception system. */ - -typedef struct runtime_pdr { - bfd_vma adr; /* memory address of start of procedure */ - long regmask; /* save register mask */ - long regoffset; /* save register offset */ - long fregmask; /* save floating point register mask */ - long fregoffset; /* save floating point register offset */ - long frameoffset; /* frame size */ - short framereg; /* frame pointer register */ - short pcreg; /* offset or reg of return pc */ - long irpss; /* index into the runtime string table */ - long reserved; - struct exception_info *exception_info;/* pointer to exception array */ -} RPDR, *pRPDR; -#define cbRPDR sizeof(RPDR) -#define rpdNil ((pRPDR) 0) - -/* Swap RPDR (runtime procedure table entry) for output. */ - -static void ecoff_swap_rpdr_out - PARAMS ((bfd *, const RPDR *, struct rpdr_ext *)); - -static void -ecoff_swap_rpdr_out (abfd, in, ex) - bfd *abfd; - const RPDR *in; - struct rpdr_ext *ex; -{ - /* ecoff_put_off was defined in ecoffswap.h. */ - ecoff_put_off (abfd, in->adr, (bfd_byte *) ex->p_adr); - bfd_h_put_32 (abfd, in->regmask, (bfd_byte *) ex->p_regmask); - bfd_h_put_32 (abfd, in->regoffset, (bfd_byte *) ex->p_regoffset); - bfd_h_put_32 (abfd, in->fregmask, (bfd_byte *) ex->p_fregmask); - bfd_h_put_32 (abfd, in->fregoffset, (bfd_byte *) ex->p_fregoffset); - bfd_h_put_32 (abfd, in->frameoffset, (bfd_byte *) ex->p_frameoffset); - - bfd_h_put_16 (abfd, in->framereg, (bfd_byte *) ex->p_framereg); - bfd_h_put_16 (abfd, in->pcreg, (bfd_byte *) ex->p_pcreg); - - bfd_h_put_32 (abfd, in->irpss, (bfd_byte *) ex->p_irpss); -#if 0 /* FIXME */ - ecoff_put_off (abfd, in->exception_info, (bfd_byte *) ex->p_exception_info); -#endif -} - -/* Read ECOFF debugging information from a .mdebug section into a - ecoff_debug_info structure. */ - -static boolean -mips_elf_read_ecoff_info (abfd, section, debug) - bfd *abfd; - asection *section; - struct ecoff_debug_info *debug; -{ - HDRR *symhdr; - const struct ecoff_debug_swap *swap; - char *ext_hdr = NULL; - - swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; - - ext_hdr = (char *) bfd_malloc ((size_t) swap->external_hdr_size); - if (ext_hdr == NULL && swap->external_hdr_size != 0) - goto error_return; - - if (bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0, - swap->external_hdr_size) - == false) - goto error_return; - - symhdr = &debug->symbolic_header; - (*swap->swap_hdr_in) (abfd, ext_hdr, symhdr); - - /* The symbolic header contains absolute file offsets and sizes to - read. */ -#define READ(ptr, offset, count, size, type) \ - if (symhdr->count == 0) \ - debug->ptr = NULL; \ - else \ - { \ - debug->ptr = (type) bfd_malloc ((size_t) (size * symhdr->count)); \ - if (debug->ptr == NULL) \ - goto error_return; \ - if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \ - || (bfd_read (debug->ptr, size, symhdr->count, \ - abfd) != size * symhdr->count)) \ - goto error_return; \ - } - - READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *); - READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR); - READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR); - READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR); - READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR); - READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext), - union aux_ext *); - READ (ss, cbSsOffset, issMax, sizeof (char), char *); - READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *); - READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR); - READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR); - READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, PTR); -#undef READ - - debug->fdr = NULL; - debug->adjust = NULL; - - return true; - - error_return: - if (ext_hdr != NULL) - free (ext_hdr); - if (debug->line != NULL) - free (debug->line); - if (debug->external_dnr != NULL) - free (debug->external_dnr); - if (debug->external_pdr != NULL) - free (debug->external_pdr); - if (debug->external_sym != NULL) - free (debug->external_sym); - if (debug->external_opt != NULL) - free (debug->external_opt); - if (debug->external_aux != NULL) - free (debug->external_aux); - if (debug->ss != NULL) - free (debug->ss); - if (debug->ssext != NULL) - free (debug->ssext); - if (debug->external_fdr != NULL) - free (debug->external_fdr); - if (debug->external_rfd != NULL) - free (debug->external_rfd); - if (debug->external_ext != NULL) - free (debug->external_ext); - return false; -} - -/* MIPS ELF local labels start with '$', not 'L'. */ - -/*ARGSUSED*/ -static boolean -mips_elf_is_local_label (abfd, symbol) - bfd *abfd; - asymbol *symbol; -{ - return symbol->name[0] == '$'; -} - -/* MIPS ELF uses a special find_nearest_line routine in order the - handle the ECOFF debugging information. */ - -struct mips_elf_find_line -{ - struct ecoff_debug_info d; - struct ecoff_find_line i; -}; - -static boolean -mips_elf_find_nearest_line (abfd, section, symbols, offset, filename_ptr, - functionname_ptr, line_ptr) - bfd *abfd; - asection *section; - asymbol **symbols; - bfd_vma offset; - const char **filename_ptr; - const char **functionname_ptr; - unsigned int *line_ptr; -{ - asection *msec; - - msec = bfd_get_section_by_name (abfd, ".mdebug"); - if (msec != NULL) - { - flagword origflags; - struct mips_elf_find_line *fi; - const struct ecoff_debug_swap * const swap = - get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; - - /* If we are called during a link, mips_elf_final_link may have - cleared the SEC_HAS_CONTENTS field. We force it back on here - if appropriate (which it normally will be). */ - origflags = msec->flags; - if (elf_section_data (msec)->this_hdr.sh_type != SHT_NOBITS) - msec->flags |= SEC_HAS_CONTENTS; - - fi = elf_tdata (abfd)->find_line_info; - if (fi == NULL) - { - bfd_size_type external_fdr_size; - char *fraw_src; - char *fraw_end; - struct fdr *fdr_ptr; - - fi = ((struct mips_elf_find_line *) - bfd_alloc (abfd, sizeof (struct mips_elf_find_line))); - if (fi == NULL) - { - msec->flags = origflags; - return false; - } - - memset (fi, 0, sizeof (struct mips_elf_find_line)); - - if (! mips_elf_read_ecoff_info (abfd, msec, &fi->d)) - { - msec->flags = origflags; - return false; - } - - /* Swap in the FDR information. */ - fi->d.fdr = ((struct fdr *) - bfd_alloc (abfd, - (fi->d.symbolic_header.ifdMax * - sizeof (struct fdr)))); - if (fi->d.fdr == NULL) - { - msec->flags = origflags; - return false; - } - external_fdr_size = swap->external_fdr_size; - fdr_ptr = fi->d.fdr; - fraw_src = (char *) fi->d.external_fdr; - fraw_end = (fraw_src - + fi->d.symbolic_header.ifdMax * external_fdr_size); - for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++) - (*swap->swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr); - - elf_tdata (abfd)->find_line_info = fi; - - /* Note that we don't bother to ever free this information. - find_nearest_line is either called all the time, as in - objdump -l, so the information should be saved, or it is - rarely called, as in ld error messages, so the memory - wasted is unimportant. Still, it would probably be a - good idea for free_cached_info to throw it away. */ - } - - if (_bfd_ecoff_locate_line (abfd, section, offset, &fi->d, swap, - &fi->i, filename_ptr, functionname_ptr, - line_ptr)) - { - msec->flags = origflags; - return true; - } - - msec->flags = origflags; - } - - /* Fall back on the generic ELF find_nearest_line routine. */ - - return _bfd_elf_find_nearest_line (abfd, section, symbols, offset, - filename_ptr, functionname_ptr, - line_ptr); -} - -/* The MIPS ELF linker needs additional information for each symbol in - the global hash table. */ - -struct mips_elf_link_hash_entry -{ - struct elf_link_hash_entry root; - - /* External symbol information. */ - EXTR esym; -}; - -/* MIPS ELF linker hash table. */ - -struct mips_elf_link_hash_table -{ - struct elf_link_hash_table root; - /* String section indices for the dynamic section symbols. */ - bfd_size_type dynsym_sec_strindex[SIZEOF_MIPS_DYNSYM_SECNAMES]; - /* The number of .rtproc entries. */ - bfd_size_type procedure_count; - /* The size of the .compact_rel section (if SGI_COMPAT). */ - bfd_size_type compact_rel_size; -}; - -/* Look up an entry in a MIPS ELF linker hash table. */ - -#define mips_elf_link_hash_lookup(table, string, create, copy, follow) \ - ((struct mips_elf_link_hash_entry *) \ - elf_link_hash_lookup (&(table)->root, (string), (create), \ - (copy), (follow))) - -/* Traverse a MIPS ELF linker hash table. */ - -#define mips_elf_link_hash_traverse(table, func, info) \ - (elf_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the MIPS ELF linker hash table from a link_info structure. */ - -#define mips_elf_hash_table(p) \ - ((struct mips_elf_link_hash_table *) ((p)->hash)) - -static boolean mips_elf_output_extsym - PARAMS ((struct mips_elf_link_hash_entry *, PTR)); - -/* Create an entry in a MIPS ELF linker hash table. */ - -static struct bfd_hash_entry * -mips_elf_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct mips_elf_link_hash_entry *ret = - (struct mips_elf_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct mips_elf_link_hash_entry *) NULL) - ret = ((struct mips_elf_link_hash_entry *) - bfd_hash_allocate (table, - sizeof (struct mips_elf_link_hash_entry))); - if (ret == (struct mips_elf_link_hash_entry *) NULL) - return (struct bfd_hash_entry *) ret; - - /* Call the allocation method of the superclass. */ - ret = ((struct mips_elf_link_hash_entry *) - _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, - table, string)); - if (ret != (struct mips_elf_link_hash_entry *) NULL) - { - /* Set local fields. */ - memset (&ret->esym, 0, sizeof (EXTR)); - /* We use -2 as a marker to indicate that the information has - not been set. -1 means there is no associated ifd. */ - ret->esym.ifd = -2; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Create a MIPS ELF linker hash table. */ - -static struct bfd_link_hash_table * -mips_elf_link_hash_table_create (abfd) - bfd *abfd; -{ - struct mips_elf_link_hash_table *ret; - unsigned int i; - - ret = ((struct mips_elf_link_hash_table *) - bfd_alloc (abfd, sizeof (struct mips_elf_link_hash_table))); - if (ret == (struct mips_elf_link_hash_table *) NULL) - return NULL; - - if (! _bfd_elf_link_hash_table_init (&ret->root, abfd, - mips_elf_link_hash_newfunc)) - { - bfd_release (abfd, ret); - return NULL; - } - - for (i = 0; i < SIZEOF_MIPS_DYNSYM_SECNAMES; i++) - ret->dynsym_sec_strindex[i] = (bfd_size_type) -1; - ret->procedure_count = 0; - ret->compact_rel_size = 0; - - return &ret->root.root; -} - -/* Hook called by the linker routine which adds symbols from an object - file. We must handle the special MIPS section numbers here. */ - -/*ARGSUSED*/ -static boolean -mips_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) - bfd *abfd; - struct bfd_link_info *info; - const Elf_Internal_Sym *sym; - const char **namep; - flagword *flagsp; - asection **secp; - bfd_vma *valp; -{ - if (SGI_COMPAT (abfd) - && (abfd->flags & DYNAMIC) != 0 - && strcmp (*namep, "_rld_new_interface") == 0) - { - /* Skip Irix 5 rld entry name. */ - *namep = NULL; - return true; - } - - switch (sym->st_shndx) - { - case SHN_COMMON: - /* Common symbols less than the GP size are automatically - treated as SHN_MIPS_SCOMMON symbols. */ - if (sym->st_size > elf_gp_size (abfd)) - break; - /* Fall through. */ - case SHN_MIPS_SCOMMON: - *secp = bfd_make_section_old_way (abfd, ".scommon"); - (*secp)->flags |= SEC_IS_COMMON; - *valp = sym->st_size; - break; - - case SHN_MIPS_TEXT: - /* This section is used in a shared object. */ - if (mips_elf_text_section_ptr == NULL) - { - /* Initialize the section. */ - mips_elf_text_section.name = ".text"; - mips_elf_text_section.flags = SEC_NO_FLAGS; - mips_elf_text_section.output_section = NULL; - mips_elf_text_section.owner = abfd; - mips_elf_text_section.symbol = &mips_elf_text_symbol; - mips_elf_text_section.symbol_ptr_ptr = &mips_elf_text_symbol_ptr; - mips_elf_text_symbol.name = ".text"; - mips_elf_text_symbol.flags = BSF_SECTION_SYM; - mips_elf_text_symbol.section = &mips_elf_text_section; - mips_elf_text_symbol_ptr = &mips_elf_text_symbol; - mips_elf_text_section_ptr = &mips_elf_text_section; - } - if (info->shared) - *secp = bfd_und_section_ptr; - else - *secp = mips_elf_text_section_ptr; - break; - - case SHN_MIPS_ACOMMON: - /* Fall through. XXX Can we treat this as allocated data? */ - case SHN_MIPS_DATA: - /* This section is used in a shared object. */ - if (mips_elf_data_section_ptr == NULL) - { - /* Initialize the section. */ - mips_elf_data_section.name = ".data"; - mips_elf_data_section.flags = SEC_NO_FLAGS; - mips_elf_data_section.output_section = NULL; - mips_elf_data_section.owner = abfd; - mips_elf_data_section.symbol = &mips_elf_data_symbol; - mips_elf_data_section.symbol_ptr_ptr = &mips_elf_data_symbol_ptr; - mips_elf_data_symbol.name = ".data"; - mips_elf_data_symbol.flags = BSF_SECTION_SYM; - mips_elf_data_symbol.section = &mips_elf_data_section; - mips_elf_data_symbol_ptr = &mips_elf_data_symbol; - mips_elf_data_section_ptr = &mips_elf_data_section; - } - if (info->shared) - *secp = bfd_und_section_ptr; - else - *secp = mips_elf_data_section_ptr; - break; - - case SHN_MIPS_SUNDEFINED: - *secp = bfd_und_section_ptr; - break; - } - - return true; -} - -/* Structure used to pass information to mips_elf_output_extsym. */ - -struct extsym_info -{ - bfd *abfd; - struct bfd_link_info *info; - struct ecoff_debug_info *debug; - const struct ecoff_debug_swap *swap; - boolean failed; -}; - -/* This routine is used to write out ECOFF debugging external symbol - information. It is called via mips_elf_link_hash_traverse. The - ECOFF external symbol information must match the ELF external - symbol information. Unfortunately, at this point we don't know - whether a symbol is required by reloc information, so the two - tables may wind up being different. We must sort out the external - symbol information before we can set the final size of the .mdebug - section, and we must set the size of the .mdebug section before we - can relocate any sections, and we can't know which symbols are - required by relocation until we relocate the sections. - Fortunately, it is relatively unlikely that any symbol will be - stripped but required by a reloc. In particular, it can not happen - when generating a final executable. */ - -static boolean -mips_elf_output_extsym (h, data) - struct mips_elf_link_hash_entry *h; - PTR data; -{ - struct extsym_info *einfo = (struct extsym_info *) data; - boolean strip; - asection *sec, *output_section; - - if (h->root.indx == -2) - strip = false; - else if (((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - || (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0) - && (h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 - && (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) - strip = true; - else if (einfo->info->strip == strip_all - || (einfo->info->strip == strip_some - && bfd_hash_lookup (einfo->info->keep_hash, - h->root.root.root.string, - false, false) == NULL)) - strip = true; - else - strip = false; - - if (strip) - return true; - - if (h->esym.ifd == -2) - { - h->esym.jmptbl = 0; - h->esym.cobol_main = 0; - h->esym.weakext = 0; - h->esym.reserved = 0; - h->esym.ifd = ifdNil; - h->esym.asym.value = 0; - h->esym.asym.st = stGlobal; - - if (SGI_COMPAT (einfo->abfd) - && (h->root.root.type == bfd_link_hash_undefined - || h->root.root.type == bfd_link_hash_undefweak)) - { - const char *name; - - /* Use undefined class. Also, set class and type for some - special symbols. */ - name = h->root.root.root.string; - if (strcmp (name, mips_elf_dynsym_rtproc_names[0]) == 0 - || strcmp (name, mips_elf_dynsym_rtproc_names[1]) == 0) - { - h->esym.asym.sc = scData; - h->esym.asym.st = stLabel; - h->esym.asym.value = 0; - } - else if (strcmp (name, mips_elf_dynsym_rtproc_names[2]) == 0) - { - h->esym.asym.sc = scAbs; - h->esym.asym.st = stLabel; - h->esym.asym.value = - mips_elf_hash_table (einfo->info)->procedure_count; - } - else if (strcmp (name, "_gp_disp") == 0) - { - h->esym.asym.sc = scAbs; - h->esym.asym.st = stLabel; - h->esym.asym.value = elf_gp (einfo->abfd); - } - else - h->esym.asym.sc = scUndefined; - } - else if (h->root.root.type != bfd_link_hash_defined - && h->root.root.type != bfd_link_hash_defweak) - h->esym.asym.sc = scAbs; - else - { - const char *name; - - sec = h->root.root.u.def.section; - output_section = sec->output_section; - - /* When making a shared library and symbol h is the one from - the another shared library, OUTPUT_SECTION may be null. */ - if (output_section == NULL) - h->esym.asym.sc = scUndefined; - else - { - name = bfd_section_name (output_section->owner, output_section); - - if (strcmp (name, ".text") == 0) - h->esym.asym.sc = scText; - else if (strcmp (name, ".data") == 0) - h->esym.asym.sc = scData; - else if (strcmp (name, ".sdata") == 0) - h->esym.asym.sc = scSData; - else if (strcmp (name, ".rodata") == 0 - || strcmp (name, ".rdata") == 0) - h->esym.asym.sc = scRData; - else if (strcmp (name, ".bss") == 0) - h->esym.asym.sc = scBss; - else if (strcmp (name, ".sbss") == 0) - h->esym.asym.sc = scSBss; - else if (strcmp (name, ".init") == 0) - h->esym.asym.sc = scInit; - else if (strcmp (name, ".fini") == 0) - h->esym.asym.sc = scFini; - else - h->esym.asym.sc = scAbs; - } - } - - h->esym.asym.reserved = 0; - h->esym.asym.index = indexNil; - } - - if (h->root.root.type == bfd_link_hash_common) - h->esym.asym.value = h->root.root.u.c.size; - else if (h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak) - { - if (h->esym.asym.sc == scCommon) - h->esym.asym.sc = scBss; - else if (h->esym.asym.sc == scSCommon) - h->esym.asym.sc = scSBss; - - sec = h->root.root.u.def.section; - output_section = sec->output_section; - if (output_section != NULL) - h->esym.asym.value = (h->root.root.u.def.value - + sec->output_offset - + output_section->vma); - else - h->esym.asym.value = 0; - } - else if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) - { - /* Set type and value for a symbol with a function stub. */ - h->esym.asym.st = stProc; - sec = h->root.root.u.def.section; - if (sec == NULL) - h->esym.asym.value = 0; - else - { - output_section = sec->output_section; - if (output_section != NULL) - h->esym.asym.value = (h->root.plt_offset - + sec->output_offset - + output_section->vma); - else - h->esym.asym.value = 0; - } -#if 0 /* FIXME? */ - h->esym.ifd = 0; -#endif - } - - if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap, - h->root.root.root.string, - &h->esym)) - { - einfo->failed = true; - return false; - } - - return true; -} - -/* Create a runtime procedure table from the .mdebug section. */ - -static boolean -mips_elf_create_procedure_table (handle, abfd, info, s, debug) - PTR handle; - bfd *abfd; - struct bfd_link_info *info; - asection *s; - struct ecoff_debug_info *debug; -{ - const struct ecoff_debug_swap *swap; - HDRR *hdr = &debug->symbolic_header; - RPDR *rpdr, *rp; - struct rpdr_ext *erp; - PTR rtproc; - struct pdr_ext *epdr; - struct sym_ext *esym; - char *ss, **sv; - char *str; - unsigned long size, count; - unsigned long sindex; - unsigned long i; - PDR pdr; - SYMR sym; - const char *no_name_func = "static procedure (no name)"; - - epdr = NULL; - rpdr = NULL; - esym = NULL; - ss = NULL; - sv = NULL; - - swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; - - sindex = strlen (no_name_func) + 1; - count = hdr->ipdMax; - if (count > 0) - { - size = swap->external_pdr_size; - - epdr = (struct pdr_ext *) bfd_malloc (size * count); - if (epdr == NULL) - goto error_return; - - if (! _bfd_ecoff_get_accumulated_pdr (handle, (PTR) epdr)) - goto error_return; - - size = sizeof (RPDR); - rp = rpdr = (RPDR *) bfd_malloc (size * count); - if (rpdr == NULL) - goto error_return; - - sv = (char **) bfd_malloc (sizeof (char *) * count); - if (sv == NULL) - goto error_return; - - count = hdr->isymMax; - size = swap->external_sym_size; - esym = (struct sym_ext *) bfd_malloc (size * count); - if (esym == NULL) - goto error_return; - - if (! _bfd_ecoff_get_accumulated_sym (handle, (PTR) esym)) - goto error_return; - - count = hdr->issMax; - ss = (char *) bfd_malloc (count); - if (ss == NULL) - goto error_return; - if (! _bfd_ecoff_get_accumulated_ss (handle, (PTR) ss)) - goto error_return; - - count = hdr->ipdMax; - for (i = 0; i < count; i++, rp++) - { - (*swap->swap_pdr_in) (abfd, (PTR) (epdr + i), &pdr); - (*swap->swap_sym_in) (abfd, (PTR) &esym[pdr.isym], &sym); - rp->adr = sym.value; - rp->regmask = pdr.regmask; - rp->regoffset = pdr.regoffset; - rp->fregmask = pdr.fregmask; - rp->fregoffset = pdr.fregoffset; - rp->frameoffset = pdr.frameoffset; - rp->framereg = pdr.framereg; - rp->pcreg = pdr.pcreg; - rp->irpss = sindex; - sv[i] = ss + sym.iss; - sindex += strlen (sv[i]) + 1; - } - } - - size = sizeof (struct rpdr_ext) * (count + 2) + sindex; - size = BFD_ALIGN (size, 16); - rtproc = (PTR) bfd_alloc (abfd, size); - if (rtproc == NULL) - { - mips_elf_hash_table (info)->procedure_count = 0; - goto error_return; - } - - mips_elf_hash_table (info)->procedure_count = count + 2; - - erp = (struct rpdr_ext *) rtproc; - memset (erp, 0, sizeof (struct rpdr_ext)); - erp++; - str = (char *) rtproc + sizeof (struct rpdr_ext) * (count + 2); - strcpy (str, no_name_func); - str += strlen (no_name_func) + 1; - for (i = 0; i < count; i++) - { - ecoff_swap_rpdr_out (abfd, rpdr + i, erp + i); - strcpy (str, sv[i]); - str += strlen (sv[i]) + 1; - } - ecoff_put_off (abfd, (bfd_vma) -1, (bfd_byte *) (erp + count)->p_adr); - - /* Set the size and contents of .rtproc section. */ - s->_raw_size = size; - s->contents = rtproc; - - /* Skip this section later on (I don't think this currently - matters, but someday it might). */ - s->link_order_head = (struct bfd_link_order *) NULL; - - if (epdr != NULL) - free (epdr); - if (rpdr != NULL) - free (rpdr); - if (esym != NULL) - free (esym); - if (ss != NULL) - free (ss); - if (sv != NULL) - free (sv); - - return true; - - error_return: - if (epdr != NULL) - free (epdr); - if (rpdr != NULL) - free (rpdr); - if (esym != NULL) - free (esym); - if (ss != NULL) - free (ss); - if (sv != NULL) - free (sv); - return false; -} - -/* A comparison routine used to sort .gptab entries. */ - -static int -gptab_compare (p1, p2) - const PTR p1; - const PTR p2; -{ - const Elf32_gptab *a1 = (const Elf32_gptab *) p1; - const Elf32_gptab *a2 = (const Elf32_gptab *) p2; - - return a1->gt_entry.gt_g_value - a2->gt_entry.gt_g_value; -} - -/* We need to use a special link routine to handle the .reginfo and - the .mdebug sections. We need to merge all instances of these - sections together, not write them all out sequentially. */ - -static boolean -mips_elf_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - asection **secpp; - asection *o; - struct bfd_link_order *p; - asection *reginfo_sec, *mdebug_sec, *gptab_data_sec, *gptab_bss_sec; - asection *rtproc_sec; - Elf32_RegInfo reginfo; - struct ecoff_debug_info debug; - const struct ecoff_debug_swap *swap - = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; - HDRR *symhdr = &debug.symbolic_header; - PTR mdebug_handle = NULL; - - /* Drop the .options section, since it has special semantics which I - haven't bothered to figure out. */ - for (secpp = &abfd->sections; *secpp != NULL; secpp = &(*secpp)->next) - { - if (strcmp ((*secpp)->name, ".options") == 0) - { - for (p = (*secpp)->link_order_head; p != NULL; p = p->next) - if (p->type == bfd_indirect_link_order) - p->u.indirect.section->flags &=~ SEC_HAS_CONTENTS; - (*secpp)->link_order_head = NULL; - *secpp = (*secpp)->next; - --abfd->section_count; - break; - } - } - - /* Get a value for the GP register. */ - if (elf_gp (abfd) == 0) - { - struct bfd_link_hash_entry *h; - - h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true); - if (h != (struct bfd_link_hash_entry *) NULL - && h->type == bfd_link_hash_defined) - elf_gp (abfd) = (h->u.def.value - + h->u.def.section->output_section->vma - + h->u.def.section->output_offset); - else if (info->relocateable) - { - bfd_vma lo; - - /* Make up a value. */ - lo = (bfd_vma) -1; - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - if (o->vma < lo - && (strcmp (o->name, ".sbss") == 0 - || strcmp (o->name, ".sdata") == 0 - || strcmp (o->name, ".lit4") == 0 - || strcmp (o->name, ".lit8") == 0)) - lo = o->vma; - } - elf_gp (abfd) = lo + ELF_MIPS_GP_OFFSET (abfd); - } - else - { - /* If the relocate_section function needs to do a reloc - involving the GP value, it should make a reloc_dangerous - callback to warn that GP is not defined. */ - } - } - - /* Go through the sections and collect the .reginfo and .mdebug - information. */ - reginfo_sec = NULL; - mdebug_sec = NULL; - gptab_data_sec = NULL; - gptab_bss_sec = NULL; - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - if (strcmp (o->name, ".reginfo") == 0) - { - memset (®info, 0, sizeof reginfo); - - /* We have found the .reginfo section in the output file. - Look through all the link_orders comprising it and merge - the information together. */ - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - { - asection *input_section; - bfd *input_bfd; - Elf32_External_RegInfo ext; - Elf32_RegInfo sub; - - if (p->type != bfd_indirect_link_order) - { - if (p->type == bfd_fill_link_order) - continue; - abort (); - } - - input_section = p->u.indirect.section; - input_bfd = input_section->owner; - - /* The linker emulation code has probably clobbered the - size to be zero bytes. */ - if (input_section->_raw_size == 0) - input_section->_raw_size = sizeof (Elf32_External_RegInfo); - - if (! bfd_get_section_contents (input_bfd, input_section, - (PTR) &ext, - (file_ptr) 0, - sizeof ext)) - return false; - - bfd_mips_elf32_swap_reginfo_in (input_bfd, &ext, &sub); - - reginfo.ri_gprmask |= sub.ri_gprmask; - reginfo.ri_cprmask[0] |= sub.ri_cprmask[0]; - reginfo.ri_cprmask[1] |= sub.ri_cprmask[1]; - reginfo.ri_cprmask[2] |= sub.ri_cprmask[2]; - reginfo.ri_cprmask[3] |= sub.ri_cprmask[3]; - - /* ri_gp_value is set by the function - mips_elf_section_processing when the section is - finally written out. */ - - /* Hack: reset the SEC_HAS_CONTENTS flag so that - elf_link_input_bfd ignores this section. */ - input_section->flags &=~ SEC_HAS_CONTENTS; - } - - /* Force the section size to the value we want. */ - o->_raw_size = sizeof (Elf32_External_RegInfo); - - /* Skip this section later on (I don't think this currently - matters, but someday it might). */ - o->link_order_head = (struct bfd_link_order *) NULL; - - reginfo_sec = o; - } - - if (strcmp (o->name, ".mdebug") == 0) - { - struct extsym_info einfo; - - /* We have found the .mdebug section in the output file. - Look through all the link_orders comprising it and merge - the information together. */ - symhdr->magic = swap->sym_magic; - /* FIXME: What should the version stamp be? */ - symhdr->vstamp = 0; - symhdr->ilineMax = 0; - symhdr->cbLine = 0; - symhdr->idnMax = 0; - symhdr->ipdMax = 0; - symhdr->isymMax = 0; - symhdr->ioptMax = 0; - symhdr->iauxMax = 0; - symhdr->issMax = 0; - symhdr->issExtMax = 0; - symhdr->ifdMax = 0; - symhdr->crfd = 0; - symhdr->iextMax = 0; - - /* We accumulate the debugging information itself in the - debug_info structure. */ - debug.line = NULL; - debug.external_dnr = NULL; - debug.external_pdr = NULL; - debug.external_sym = NULL; - debug.external_opt = NULL; - debug.external_aux = NULL; - debug.ss = NULL; - debug.ssext = debug.ssext_end = NULL; - debug.external_fdr = NULL; - debug.external_rfd = NULL; - debug.external_ext = debug.external_ext_end = NULL; - - mdebug_handle = bfd_ecoff_debug_init (abfd, &debug, swap, info); - if (mdebug_handle == (PTR) NULL) - return false; - - if (SGI_COMPAT (abfd)) - { - asection *s; - EXTR esym; - bfd_vma last; - unsigned int i; - static const char * const name[] = - { ".text", ".init", ".fini", ".data", - ".rodata", ".sdata", ".sbss", ".bss" }; - static const int sc[] = { scText, scInit, scFini, scData, - scRData, scSData, scSBss, scBss }; - - esym.jmptbl = 0; - esym.cobol_main = 0; - esym.weakext = 0; - esym.reserved = 0; - esym.ifd = ifdNil; - esym.asym.iss = issNil; - esym.asym.st = stLocal; - esym.asym.reserved = 0; - esym.asym.index = indexNil; - for (i = 0; i < 8; i++) - { - esym.asym.sc = sc[i]; - s = bfd_get_section_by_name (abfd, name[i]); - if (s != NULL) - { - esym.asym.value = s->vma; - last = s->vma + s->_raw_size; - } - else - esym.asym.value = last; - - if (! bfd_ecoff_debug_one_external (abfd, &debug, swap, - name[i], &esym)) - return false; - } - } - - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - { - asection *input_section; - bfd *input_bfd; - const struct ecoff_debug_swap *input_swap; - struct ecoff_debug_info input_debug; - char *eraw_src; - char *eraw_end; - - if (p->type != bfd_indirect_link_order) - { - if (p->type == bfd_fill_link_order) - continue; - abort (); - } - - input_section = p->u.indirect.section; - input_bfd = input_section->owner; - - if (bfd_get_flavour (input_bfd) != bfd_target_elf_flavour - || (get_elf_backend_data (input_bfd) - ->elf_backend_ecoff_debug_swap) == NULL) - { - /* I don't know what a non MIPS ELF bfd would be - doing with a .mdebug section, but I don't really - want to deal with it. */ - continue; - } - - input_swap = (get_elf_backend_data (input_bfd) - ->elf_backend_ecoff_debug_swap); - - BFD_ASSERT (p->size == input_section->_raw_size); - - /* The ECOFF linking code expects that we have already - read in the debugging information and set up an - ecoff_debug_info structure, so we do that now. */ - if (! mips_elf_read_ecoff_info (input_bfd, input_section, - &input_debug)) - return false; - - if (! (bfd_ecoff_debug_accumulate - (mdebug_handle, abfd, &debug, swap, input_bfd, - &input_debug, input_swap, info))) - return false; - - /* Loop through the external symbols. For each one with - interesting information, try to find the symbol in - the linker global hash table and save the information - for the output external symbols. */ - eraw_src = input_debug.external_ext; - eraw_end = (eraw_src - + (input_debug.symbolic_header.iextMax - * input_swap->external_ext_size)); - for (; - eraw_src < eraw_end; - eraw_src += input_swap->external_ext_size) - { - EXTR ext; - const char *name; - struct mips_elf_link_hash_entry *h; - - (*input_swap->swap_ext_in) (input_bfd, (PTR) eraw_src, &ext); - if (ext.asym.sc == scNil - || ext.asym.sc == scUndefined - || ext.asym.sc == scSUndefined) - continue; - - name = input_debug.ssext + ext.asym.iss; - h = mips_elf_link_hash_lookup (mips_elf_hash_table (info), - name, false, false, true); - if (h == NULL || h->esym.ifd != -2) - continue; - - if (ext.ifd != -1) - { - BFD_ASSERT (ext.ifd - < input_debug.symbolic_header.ifdMax); - ext.ifd = input_debug.ifdmap[ext.ifd]; - } - - h->esym = ext; - } - - /* Free up the information we just read. */ - free (input_debug.line); - free (input_debug.external_dnr); - free (input_debug.external_pdr); - free (input_debug.external_sym); - free (input_debug.external_opt); - free (input_debug.external_aux); - free (input_debug.ss); - free (input_debug.ssext); - free (input_debug.external_fdr); - free (input_debug.external_rfd); - free (input_debug.external_ext); - - /* Hack: reset the SEC_HAS_CONTENTS flag so that - elf_link_input_bfd ignores this section. */ - input_section->flags &=~ SEC_HAS_CONTENTS; - } - - if (SGI_COMPAT (abfd) && info->shared) - { - /* Create .rtproc section. */ - rtproc_sec = bfd_get_section_by_name (abfd, ".rtproc"); - if (rtproc_sec == NULL) - { - flagword flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY - | SEC_READONLY); - - rtproc_sec = bfd_make_section (abfd, ".rtproc"); - if (rtproc_sec == NULL - || ! bfd_set_section_flags (abfd, rtproc_sec, flags) - || ! bfd_set_section_alignment (abfd, rtproc_sec, 12)) - return false; - } - - if (! mips_elf_create_procedure_table (mdebug_handle, abfd, - info, rtproc_sec, &debug)) - return false; - } - - /* Build the external symbol information. */ - einfo.abfd = abfd; - einfo.info = info; - einfo.debug = &debug; - einfo.swap = swap; - einfo.failed = false; - mips_elf_link_hash_traverse (mips_elf_hash_table (info), - mips_elf_output_extsym, - (PTR) &einfo); - if (einfo.failed) - return false; - - /* Set the size of the .mdebug section. */ - o->_raw_size = bfd_ecoff_debug_size (abfd, &debug, swap); - - /* Skip this section later on (I don't think this currently - matters, but someday it might). */ - o->link_order_head = (struct bfd_link_order *) NULL; - - mdebug_sec = o; - } - - if (strncmp (o->name, ".gptab.", sizeof ".gptab." - 1) == 0) - { - const char *subname; - unsigned int c; - Elf32_gptab *tab; - Elf32_External_gptab *ext_tab; - unsigned int i; - - /* The .gptab.sdata and .gptab.sbss sections hold - information describing how the small data area would - change depending upon the -G switch. These sections - not used in executables files. */ - if (! info->relocateable) - { - asection **secpp; - - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - { - asection *input_section; - - if (p->type != bfd_indirect_link_order) - { - if (p->type == bfd_fill_link_order) - continue; - abort (); - } - - input_section = p->u.indirect.section; - - /* Hack: reset the SEC_HAS_CONTENTS flag so that - elf_link_input_bfd ignores this section. */ - input_section->flags &=~ SEC_HAS_CONTENTS; - } - - /* Skip this section later on (I don't think this - currently matters, but someday it might). */ - o->link_order_head = (struct bfd_link_order *) NULL; - - /* Really remove the section. */ - for (secpp = &abfd->sections; - *secpp != o; - secpp = &(*secpp)->next) - ; - *secpp = (*secpp)->next; - --abfd->section_count; - - continue; - } - - /* There is one gptab for initialized data, and one for - uninitialized data. */ - if (strcmp (o->name, ".gptab.sdata") == 0) - gptab_data_sec = o; - else if (strcmp (o->name, ".gptab.sbss") == 0) - gptab_bss_sec = o; - else - { - (*_bfd_error_handler) - ("%s: illegal section name `%s'", - bfd_get_filename (abfd), o->name); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; - } - - /* The linker script always combines .gptab.data and - .gptab.sdata into .gptab.sdata, and likewise for - .gptab.bss and .gptab.sbss. It is possible that there is - no .sdata or .sbss section in the output file, in which - case we must change the name of the output section. */ - subname = o->name + sizeof ".gptab" - 1; - if (bfd_get_section_by_name (abfd, subname) == NULL) - { - if (o == gptab_data_sec) - o->name = ".gptab.data"; - else - o->name = ".gptab.bss"; - subname = o->name + sizeof ".gptab" - 1; - BFD_ASSERT (bfd_get_section_by_name (abfd, subname) != NULL); - } - - /* Set up the first entry. */ - c = 1; - tab = (Elf32_gptab *) bfd_malloc (c * sizeof (Elf32_gptab)); - if (tab == NULL) - return false; - tab[0].gt_header.gt_current_g_value = elf_gp_size (abfd); - tab[0].gt_header.gt_unused = 0; - - /* Combine the input sections. */ - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - { - asection *input_section; - bfd *input_bfd; - bfd_size_type size; - unsigned long last; - bfd_size_type gpentry; - - if (p->type != bfd_indirect_link_order) - { - if (p->type == bfd_fill_link_order) - continue; - abort (); - } - - input_section = p->u.indirect.section; - input_bfd = input_section->owner; - - /* Combine the gptab entries for this input section one - by one. We know that the input gptab entries are - sorted by ascending -G value. */ - size = bfd_section_size (input_bfd, input_section); - last = 0; - for (gpentry = sizeof (Elf32_External_gptab); - gpentry < size; - gpentry += sizeof (Elf32_External_gptab)) - { - Elf32_External_gptab ext_gptab; - Elf32_gptab int_gptab; - unsigned long val; - unsigned long add; - boolean exact; - unsigned int look; - - if (! (bfd_get_section_contents - (input_bfd, input_section, (PTR) &ext_gptab, - gpentry, sizeof (Elf32_External_gptab)))) - { - free (tab); - return false; - } - - bfd_mips_elf32_swap_gptab_in (input_bfd, &ext_gptab, - &int_gptab); - val = int_gptab.gt_entry.gt_g_value; - add = int_gptab.gt_entry.gt_bytes - last; - - exact = false; - for (look = 1; look < c; look++) - { - if (tab[look].gt_entry.gt_g_value >= val) - tab[look].gt_entry.gt_bytes += add; - - if (tab[look].gt_entry.gt_g_value == val) - exact = true; - } - - if (! exact) - { - Elf32_gptab *new_tab; - unsigned int max; - - /* We need a new table entry. */ - new_tab = ((Elf32_gptab *) - bfd_realloc ((PTR) tab, - (c + 1) * sizeof (Elf32_gptab))); - if (new_tab == NULL) - { - free (tab); - return false; - } - tab = new_tab; - tab[c].gt_entry.gt_g_value = val; - tab[c].gt_entry.gt_bytes = add; - - /* Merge in the size for the next smallest -G - value, since that will be implied by this new - value. */ - max = 0; - for (look = 1; look < c; look++) - { - if (tab[look].gt_entry.gt_g_value < val - && (max == 0 - || (tab[look].gt_entry.gt_g_value - > tab[max].gt_entry.gt_g_value))) - max = look; - } - if (max != 0) - tab[c].gt_entry.gt_bytes += - tab[max].gt_entry.gt_bytes; - - ++c; - } - - last = int_gptab.gt_entry.gt_bytes; - } - - /* Hack: reset the SEC_HAS_CONTENTS flag so that - elf_link_input_bfd ignores this section. */ - input_section->flags &=~ SEC_HAS_CONTENTS; - } - - /* The table must be sorted by -G value. */ - if (c > 2) - qsort (tab + 1, c - 1, sizeof (tab[0]), gptab_compare); - - /* Swap out the table. */ - ext_tab = ((Elf32_External_gptab *) - bfd_alloc (abfd, c * sizeof (Elf32_External_gptab))); - if (ext_tab == NULL) - { - free (tab); - return false; - } - - for (i = 0; i < c; i++) - bfd_mips_elf32_swap_gptab_out (abfd, tab + i, ext_tab + i); - free (tab); - - o->_raw_size = c * sizeof (Elf32_External_gptab); - o->contents = (bfd_byte *) ext_tab; - - /* Skip this section later on (I don't think this currently - matters, but someday it might). */ - o->link_order_head = (struct bfd_link_order *) NULL; - } - } - - /* Invoke the regular ELF backend linker to do all the work. */ - if (! bfd_elf32_bfd_final_link (abfd, info)) - return false; - - /* Now write out the computed sections. */ - - if (reginfo_sec != (asection *) NULL) - { - Elf32_External_RegInfo ext; - - bfd_mips_elf32_swap_reginfo_out (abfd, ®info, &ext); - if (! bfd_set_section_contents (abfd, reginfo_sec, (PTR) &ext, - (file_ptr) 0, sizeof ext)) - return false; - } - - if (mdebug_sec != (asection *) NULL) - { - BFD_ASSERT (abfd->output_has_begun); - if (! bfd_ecoff_write_accumulated_debug (mdebug_handle, abfd, &debug, - swap, info, - mdebug_sec->filepos)) - return false; - - bfd_ecoff_debug_free (mdebug_handle, abfd, &debug, swap, info); - } - - if (gptab_data_sec != (asection *) NULL) - { - if (! bfd_set_section_contents (abfd, gptab_data_sec, - gptab_data_sec->contents, - (file_ptr) 0, - gptab_data_sec->_raw_size)) - return false; - } - - if (gptab_bss_sec != (asection *) NULL) - { - if (! bfd_set_section_contents (abfd, gptab_bss_sec, - gptab_bss_sec->contents, - (file_ptr) 0, - gptab_bss_sec->_raw_size)) - return false; - } - - if (SGI_COMPAT (abfd)) - { - rtproc_sec = bfd_get_section_by_name (abfd, ".rtproc"); - if (rtproc_sec != NULL) - { - if (! bfd_set_section_contents (abfd, rtproc_sec, - rtproc_sec->contents, - (file_ptr) 0, - rtproc_sec->_raw_size)) - return false; - } - } - - return true; -} - -/* Handle a MIPS ELF HI16 reloc. */ - -static void -mips_elf_relocate_hi16 (input_bfd, relhi, rello, contents, addend) - bfd *input_bfd; - Elf_Internal_Rela *relhi; - Elf_Internal_Rela *rello; - bfd_byte *contents; - bfd_vma addend; -{ - bfd_vma insn; - bfd_vma addlo; - - insn = bfd_get_32 (input_bfd, contents + relhi->r_offset); - - addlo = bfd_get_32 (input_bfd, contents + rello->r_offset); - addlo &= 0xffff; - - addend += ((insn & 0xffff) << 16) + addlo; - - if ((addlo & 0x8000) != 0) - addend -= 0x10000; - if ((addend & 0x8000) != 0) - addend += 0x10000; - - bfd_put_32 (input_bfd, - (insn & 0xffff0000) | ((addend >> 16) & 0xffff), - contents + relhi->r_offset); -} - -/* Handle a MIPS ELF local GOT16 reloc. */ - -static void -mips_elf_relocate_got_local (output_bfd, input_bfd, sgot, relhi, rello, - contents, addend) - bfd *output_bfd; - bfd *input_bfd; - asection *sgot; - Elf_Internal_Rela *relhi; - Elf_Internal_Rela *rello; - bfd_byte *contents; - bfd_vma addend; -{ - int local_gotno; - int i; - bfd_vma insn; - bfd_vma addlo; - bfd_vma address; - bfd_vma hipage; - bfd_byte *got_contents; - struct mips_got_info *g; - - insn = bfd_get_32 (input_bfd, contents + relhi->r_offset); - - addlo = bfd_get_32 (input_bfd, contents + rello->r_offset); - addlo &= 0xffff; - - addend += ((insn & 0xffff) << 16) + addlo; - - if ((addlo & 0x8000) != 0) - addend -= 0x10000; - if ((addend & 0x8000) != 0) - addend += 0x10000; - - /* Get a got entry representing requested hipage. */ - BFD_ASSERT (elf_section_data (sgot) != NULL); - g = (struct mips_got_info *) elf_section_data (sgot)->tdata; - BFD_ASSERT (g != NULL); - - local_gotno = g->local_gotno; - got_contents = sgot->contents; - hipage = addend & 0xffff0000; - - for (i = MIPS_RESERVED_GOTNO; i < local_gotno; i++) - { - address = bfd_get_32 (input_bfd, got_contents + i * 4); - if (hipage == (address & 0xffff0000)) - break; - if (address == (bfd_vma) 0) - { - bfd_put_32 (input_bfd, hipage, got_contents + i * 4); - break; - } - } - - BFD_ASSERT (i < local_gotno); -#if 1 - if (i == local_gotno) - (*_bfd_error_handler) - ("ELF MIPS linker: more got entries are needed for hipage: %x", - hipage); -#endif - - i = - ELF_MIPS_GP_OFFSET (output_bfd) + i * 4; - bfd_put_32 (input_bfd, (insn & 0xffff0000) | (i & 0xffff), - contents + relhi->r_offset); -} - -/* Handle MIPS ELF CALL16 reloc and global GOT16 reloc. */ - -static void -mips_elf_relocate_global_got (input_bfd, rel, contents, offset) - bfd *input_bfd; - Elf_Internal_Rela *rel; - bfd_byte *contents; - bfd_vma offset; -{ - bfd_vma insn; - - insn = bfd_get_32 (input_bfd, contents + rel->r_offset); - bfd_put_32 (input_bfd, - (insn & 0xffff0000) | (offset & 0xffff), - contents + rel->r_offset); -} - -/* Relocate a MIPS ELF section. */ - -static boolean -mips_elf_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; -{ - Elf_Internal_Shdr *symtab_hdr; - size_t locsymcount; - size_t extsymoff; - asection *sgot, *sreloc, *scpt; - bfd *dynobj; - bfd_vma gp; - Elf_Internal_Rela *rel; - Elf_Internal_Rela *relend; - struct mips_got_info *g; - - dynobj = elf_hash_table (info)->dynobj; - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - - sgot = NULL; - sreloc = NULL; - if (dynobj == NULL || ! SGI_COMPAT (output_bfd)) - scpt = NULL; - else - scpt = bfd_get_section_by_name (dynobj, ".compact_rel"); - g = NULL; - - if (elf_bad_symtab (input_bfd)) - { - locsymcount = symtab_hdr->sh_size / sizeof (Elf32_External_Sym); - extsymoff = 0; - } - else - { - locsymcount = symtab_hdr->sh_info; - extsymoff = symtab_hdr->sh_info; - } - - gp = _bfd_get_gp_value (output_bfd); - - rel = relocs; - relend = relocs + input_section->reloc_count; - for (; rel < relend; rel++) - { - int r_type; - reloc_howto_type *howto; - unsigned long r_symndx; - bfd_vma addend; - struct elf_link_hash_entry *h; - asection *sec; - Elf_Internal_Sym *sym; - bfd_reloc_status_type r; - - r_type = ELF32_R_TYPE (rel->r_info); - if (r_type < 0 || r_type >= (int) R_MIPS_max) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - howto = elf_mips_howto_table + r_type; - - if (dynobj != NULL - && (r_type == R_MIPS_CALL16 - || r_type == R_MIPS_GOT16 - || r_type == R_MIPS_CALL_HI16 - || r_type == R_MIPS_CALL_LO16 - || r_type == R_MIPS_GOT_HI16 - || r_type == R_MIPS_GOT_LO16)) - { - /* We need the .got section. */ - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - BFD_ASSERT (elf_section_data (sgot) != NULL); - g = (struct mips_got_info *) elf_section_data (sgot)->tdata; - BFD_ASSERT (g != NULL); - } - } - - r_symndx = ELF32_R_SYM (rel->r_info); - - /* Mix in the change in GP address for a GP relative reloc. */ - if (r_type != R_MIPS_GPREL16 - && r_type != R_MIPS_LITERAL - && r_type != R_MIPS_GPREL32) - addend = 0; - else - { - if (gp == 0) - { - if (! ((*info->callbacks->reloc_dangerous) - (info, - "GP relative relocation when GP not defined", - input_bfd, input_section, - rel->r_offset))) - return false; - /* Only give the error once per link. */ - gp = 4; - _bfd_set_gp_value (output_bfd, gp); - } - - if (r_symndx < extsymoff - || (elf_bad_symtab (input_bfd) - && local_sections[r_symndx] != NULL)) - { - /* This is a relocation against a section. The current - addend in the instruction is the difference between - INPUT_SECTION->vma and the GP value of INPUT_BFD. We - must change this to be the difference between the - final definition (which will end up in RELOCATION) - and the GP value of OUTPUT_BFD (which is in GP). */ - addend = elf_gp (input_bfd) - gp; - } - else if (! info->relocateable) - { - /* We are doing a final link. The current addend in the - instruction is simply the desired offset into the - symbol (normally zero). We want the instruction to - hold the difference between the final definition of - the symbol (which will end up in RELOCATION) and the - GP value of OUTPUT_BFD (which is in GP). */ - addend = - gp; - } - else - { - /* We are generating relocateable output, and we aren't - going to define this symbol, so we just leave the - instruction alone. */ - addend = 0; - } - } - - h = NULL; - sym = NULL; - sec = NULL; - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx >= locsymcount - || (elf_bad_symtab (input_bfd) - && local_sections[r_symndx] == NULL)) - r = bfd_reloc_ok; - else - { - sym = local_syms + r_symndx; - if (ELF_ST_TYPE (sym->st_info) != STT_SECTION) - r = bfd_reloc_ok; - else - { - sec = local_sections[r_symndx]; - - /* It would be logical to add sym->st_value here, - but Irix 5 sometimes generates a garbage symbol - value. */ - addend += sec->output_offset; - - /* If this is HI16 or GOT16 with an associated LO16, - adjust the addend accordingly. Otherwise, just - relocate. */ - if ((r_type != R_MIPS_HI16 && r_type != R_MIPS_GOT16) - || (rel + 1) >= relend - || ELF32_R_TYPE ((rel + 1)->r_info) != R_MIPS_LO16) - r = _bfd_relocate_contents (howto, input_bfd, - addend, - contents + rel->r_offset); - else - { - mips_elf_relocate_hi16 (input_bfd, rel, rel + 1, - contents, addend); - r = bfd_reloc_ok; - } - } - } - } - else - { - bfd_vma relocation; - boolean local; - - /* This is a final link. */ - sym = NULL; - if (r_symndx < extsymoff - || (elf_bad_symtab (input_bfd) - && local_sections[r_symndx] != NULL)) - { - local = true; - sym = local_syms + r_symndx; - sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset); - - /* It would be logical to always add sym->st_value here, - but Irix 5 sometimes generates a garbage symbol - value. */ - if (ELF_ST_TYPE (sym->st_info) != STT_SECTION) - relocation += sym->st_value; - } - else - { - long indx; - - local = false; - indx = r_symndx - extsymoff; - h = elf_sym_hashes (input_bfd)[indx]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (strcmp (h->root.root.string, "_gp_disp") == 0) - { - if (gp == 0) - { - if (! ((*info->callbacks->reloc_dangerous) - (info, - "_gp_disp used when GP not defined", - input_bfd, input_section, - rel->r_offset))) - return false; - /* Only give the error once per link. */ - gp = 4; - _bfd_set_gp_value (output_bfd, gp); - relocation = 0; - } - else - { - sec = input_section; - if (sec->output_section != NULL) - relocation = (gp - - (rel->r_offset - + sec->output_section->vma - + sec->output_offset)); - else - relocation = gp - rel->r_offset; - if (r_type == R_MIPS_LO16) - relocation += 4; - } - } - else if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - if (sec->output_section == NULL) - relocation = 0; - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else if (info->shared && ! info->symbolic) - relocation = 0; - else if (strcmp (h->root.root.string, "_DYNAMIC_LINK") == 0) - { - /* If this is a dynamic link, we should have created - a _DYNAMIC_LINK symbol in - mips_elf_create_dynamic_sections. Otherwise, we - should define the symbol with a value of 0. - FIXME: It should probably get into the symbol - table somehow as well. */ - BFD_ASSERT (! info->shared); - BFD_ASSERT (bfd_get_section_by_name (output_bfd, - ".dynamic") == NULL); - relocation = 0; - } - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset))) - return false; - relocation = 0; - } - } - - if (r_type == R_MIPS_HI16 - && (rel + 1) < relend - && ELF32_R_TYPE ((rel + 1)->r_info) == R_MIPS_LO16) - { - mips_elf_relocate_hi16 (input_bfd, rel, rel + 1, - contents, relocation + addend); - r = bfd_reloc_ok; - } - else if (r_type == R_MIPS_GOT16 && local) - { - /* GOT16 must be also with associated LO16 in the local - case. In this case, the addend is extracted and the - section in which the referenced object is determined. - Then the final address of the object is computed and - the GOT entry for the hipage (an aligned 64kb chunk) - is added to .got section if needed. The offset field - of the GOT16-relocated instruction is replaced by the - index of this GOT entry for the hipage. */ - if ((rel + 1) < relend - && ELF32_R_TYPE ((rel + 1)->r_info) == R_MIPS_LO16) - { - mips_elf_relocate_got_local (output_bfd, input_bfd, sgot, - rel, rel + 1, - contents, - relocation + addend); - r = bfd_reloc_ok; - } - else - r = bfd_reloc_outofrange; - } - else if (r_type == R_MIPS_CALL16 - || r_type == R_MIPS_GOT16 - || r_type == R_MIPS_CALL_LO16 - || r_type == R_MIPS_GOT_LO16) - { - bfd_vma offset; - - /* This symbol must be registered as a global symbol - having the corresponding got entry. */ - BFD_ASSERT (h->got_offset != (bfd_vma) -1); - - offset = (h->dynindx - g->global_gotsym + g->local_gotno) * 4; - BFD_ASSERT (g->local_gotno <= offset - && offset < sgot->_raw_size); - bfd_put_32 (output_bfd, relocation + addend, - sgot->contents + offset); - offset = (sgot->output_section->vma + sgot->output_offset - + offset - gp); - mips_elf_relocate_global_got (input_bfd, rel, contents, - offset); - r = bfd_reloc_ok; - } - else if (r_type == R_MIPS_CALL_HI16 - || r_type == R_MIPS_GOT_HI16) - { - bfd_vma offset; - - /* This must be a global symbol with a got entry. The - next reloc must be the corresponding LO16 reloc. */ - BFD_ASSERT (h != NULL && h->got_offset != (bfd_vma) -1); - BFD_ASSERT ((rel + 1) < relend); - BFD_ASSERT (ELF32_R_TYPE ((rel + 1)->r_info) - == (r_type == R_MIPS_CALL_HI16 - ? R_MIPS_CALL_LO16 - : R_MIPS_GOT_LO16)); - - offset = (h->dynindx - g->global_gotsym + g->local_gotno) * 4; - BFD_ASSERT (g->local_gotno <= offset - && offset < sgot->_raw_size); - bfd_put_32 (output_bfd, relocation + addend, - sgot->contents + offset); - offset = (sgot->output_section->vma + sgot->output_offset - + offset - gp); - mips_elf_relocate_hi16 (input_bfd, rel, rel + 1, contents, - offset); - r = bfd_reloc_ok; - } - else if (r_type == R_MIPS_REL32 - || r_type == R_MIPS_32) - { - Elf_Internal_Rel outrel; - Elf32_crinfo cptrel; - bfd_byte *cr; - - if (info->shared - && (input_section->flags & SEC_ALLOC) != 0) - { - /* When generating a shared object, these - relocations are copied into the output file to be - resolved at run time. */ - if (sreloc == NULL) - { - sreloc = bfd_get_section_by_name (dynobj, ".rel.dyn"); - BFD_ASSERT (sreloc != NULL); - } - - outrel.r_offset = (rel->r_offset - + input_section->output_section->vma - + input_section->output_offset); - - addend = bfd_get_32 (input_bfd, contents + rel->r_offset); - - if (h != NULL - && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)) - { - BFD_ASSERT (h->dynindx != -1); - outrel.r_info = ELF32_R_INFO (h->dynindx, R_MIPS_REL32); - sec = input_section; - } - else - { - long indx; - - if (h == NULL) - sec = local_sections[r_symndx]; - else - { - BFD_ASSERT (h->root.type == bfd_link_hash_defined - || (h->root.type - == bfd_link_hash_defweak)); - sec = h->root.u.def.section; - } - if (sec != NULL && bfd_is_abs_section (sec)) - indx = 0; - else if (sec == NULL || sec->owner == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - else - { - asection *osec; - - osec = sec->output_section; - indx = elf_section_data (osec)->dynindx; - if (indx == 0) - abort (); - } - - outrel.r_info = ELF32_R_INFO (indx, R_MIPS_REL32); - addend += relocation; - } - - bfd_put_32 (output_bfd, addend, contents + rel->r_offset); - bfd_elf32_swap_reloc_out (output_bfd, &outrel, - (((Elf32_External_Rel *) - sreloc->contents) - + sreloc->reloc_count)); - ++sreloc->reloc_count; - - if (SGI_COMPAT (output_bfd)) - { - if (scpt == NULL) - continue; - - /* Make an entry of compact relocation info. */ - mips_elf_set_cr_format (cptrel, CRF_MIPS_LONG); - cptrel.vaddr = (rel->r_offset - + input_section->output_section->vma - + input_section->output_offset); - if (r_type == R_MIPS_REL32) - mips_elf_set_cr_type (cptrel, CRT_MIPS_REL32); - else - mips_elf_set_cr_type (cptrel, CRT_MIPS_WORD); - mips_elf_set_cr_dist2to (cptrel, 0); - cptrel.konst = addend; - - cr = (scpt->contents - + sizeof (Elf32_External_compact_rel)); - bfd_elf32_swap_crinfo_out (output_bfd, &cptrel, - ((Elf32_External_crinfo *) cr - + scpt->reloc_count)); - ++scpt->reloc_count; - } - - /* This reloc will be computed at runtime, so - there's no need to do anything now. */ - continue; - } - else - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, - relocation, addend); - } - else - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, - relocation, addend); - - if (SGI_COMPAT (abfd) - && scpt != NULL - && (input_section->flags & SEC_ALLOC) != 0) - { - Elf32_crinfo cptrel; - bfd_byte *cr; - - /* Make an entry of compact relocation info. */ - mips_elf_set_cr_format (cptrel, CRF_MIPS_LONG); - cptrel.vaddr = (rel->r_offset - + input_section->output_section->vma - + input_section->output_offset); - - switch (r_type) - { - case R_MIPS_26: - mips_elf_set_cr_type (cptrel, CRT_MIPS_JMPAD); - /* XXX How should we set dist2to in this case. */ - mips_elf_set_cr_dist2to (cptrel, 8); - cptrel.konst = addend + relocation; - cr = scpt->contents + sizeof (Elf32_External_compact_rel); - bfd_elf32_swap_crinfo_out (output_bfd, &cptrel, - ((Elf32_External_crinfo *) cr - + scpt->reloc_count)); - ++scpt->reloc_count; - break; - - case R_MIPS_GPREL16: - case R_MIPS_LITERAL: - case R_MIPS_GPREL32: - mips_elf_set_cr_type (cptrel, CRT_MIPS_GPHI_LO); - cptrel.konst = gp - cptrel.vaddr; - mips_elf_set_cr_dist2to (cptrel, 4); - cr = scpt->contents + sizeof (Elf32_External_compact_rel); - bfd_elf32_swap_crinfo_out (output_bfd, &cptrel, - ((Elf32_External_crinfo *) cr - + scpt->reloc_count)); - ++scpt->reloc_count; - break; - - default: - break; - } - } - } - - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (h != NULL) - name = h->root.root.string; - else - { - name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - if (name == NULL) - return false; - if (*name == '\0') - name = bfd_section_name (input_bfd, sec); - } - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, - input_bfd, input_section, rel->r_offset))) - return false; - } - break; - } - } - } - - return true; -} - -/* Functions for the dynamic linker. */ - -/* The name of the dynamic interpreter. This is put in the .interp - section. */ - -#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1" - -/* Create dynamic sections when linking against a dynamic object. */ - -static boolean -mips_elf_create_dynamic_sections (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - struct elf_link_hash_entry *h; - flagword flags; - register asection *s; - const char * const *namep; - - flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY - | SEC_READONLY); - - /* Mips ABI requests the .dynamic section to be read only. */ - s = bfd_get_section_by_name (abfd, ".dynamic"); - if (s != NULL) - { - if (! bfd_set_section_flags (abfd, s, flags)) - return false; - } - - /* We need to create .got section. */ - if (! mips_elf_create_got_section (abfd, info)) - return false; - - /* Create .stub section. */ - if (bfd_get_section_by_name (abfd, ".stub") == NULL) - { - s = bfd_make_section (abfd, ".stub"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - } - - if (SGI_COMPAT (abfd)) - { - for (namep = mips_elf_dynsym_rtproc_names; *namep != NULL; namep++) - { - h = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, *namep, BSF_GLOBAL, bfd_und_section_ptr, - (bfd_vma) 0, (const char *) NULL, false, - get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h))) - return false; - h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF; - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - h->type = STT_SECTION; - - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - /* We need to create a .compact_rel section. */ - if (! mips_elf_create_compact_rel_section (abfd, info)) - return false; - - /* Change aligments of some sections. */ - s = bfd_get_section_by_name (abfd, ".hash"); - if (s != NULL) - bfd_set_section_alignment (abfd, s, 4); - s = bfd_get_section_by_name (abfd, ".dynsym"); - if (s != NULL) - bfd_set_section_alignment (abfd, s, 4); - s = bfd_get_section_by_name (abfd, ".dynstr"); - if (s != NULL) - bfd_set_section_alignment (abfd, s, 4); - s = bfd_get_section_by_name (abfd, ".reginfo"); - if (s != NULL) - bfd_set_section_alignment (abfd, s, 4); - s = bfd_get_section_by_name (abfd, ".dynamic"); - if (s != NULL) - bfd_set_section_alignment (abfd, s, 4); - } - - if (!info->shared) - { - h = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, "_DYNAMIC_LINK", BSF_GLOBAL, bfd_abs_section_ptr, - (bfd_vma) 0, (const char *) NULL, false, - get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h))) - return false; - h->elf_link_hash_flags ^=~ ELF_LINK_NON_ELF; - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - h->type = STT_SECTION; - - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - return true; -} - -/* Create the .compact_rel section. */ - -static boolean -mips_elf_create_compact_rel_section (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - flagword flags; - register asection *s; - - if (bfd_get_section_by_name (abfd, ".compact_rel") == NULL) - { - flags = SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY; - - s = bfd_make_section (abfd, ".compact_rel"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - s->_raw_size = sizeof (Elf32_External_compact_rel); - } - - return true; -} - -/* Create the .got section to hold the global offset table. */ - -static boolean -mips_elf_create_got_section (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - flagword flags; - register asection *s; - struct elf_link_hash_entry *h; - struct mips_got_info *g; - - /* This function may be called more than once. */ - if (bfd_get_section_by_name (abfd, ".got") != NULL) - return true; - - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - - s = bfd_make_section (abfd, ".got"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags) - || ! bfd_set_section_alignment (abfd, s, 4)) - return false; - - /* Define the symbol _GLOBAL_OFFSET_TABLE_. We don't do this in the - linker script because we don't want to define the symbol if we - are not creating a global offset table. */ - h = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s, - (bfd_vma) 0, (const char *) NULL, false, - get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h))) - return false; - h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF; - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - h->type = STT_OBJECT; - - if (info->shared - && ! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - - /* The first several global offset table entries are reserved. */ - s->_raw_size = MIPS_RESERVED_GOTNO * 4; - - g = (struct mips_got_info *) bfd_alloc (abfd, - sizeof (struct mips_got_info)); - if (g == NULL) - return false; - g->global_gotsym = 0; - g->local_gotno = MIPS_RESERVED_GOTNO; - if (elf_section_data (s) == NULL) - { - s->used_by_bfd = - (PTR) bfd_zalloc (abfd, sizeof (struct bfd_elf_section_data)); - if (elf_section_data (s) == NULL) - return false; - } - elf_section_data (s)->tdata = (PTR) g; - - return true; -} - -/* Look through the relocs for a section during the first phase, and - allocate space in the global offset table. */ - -static boolean -mips_elf_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; -{ - bfd *dynobj; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - struct mips_got_info *g; - size_t extsymoff; - const Elf_Internal_Rela *rel; - const Elf_Internal_Rela *rel_end; - asection *sgot; - asection *sreloc; - - if (info->relocateable) - return true; - - dynobj = elf_hash_table (info)->dynobj; - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (abfd); - extsymoff = (elf_bad_symtab (abfd)) ? 0 : symtab_hdr->sh_info; - - sgot = NULL; - sreloc = NULL; - - rel_end = relocs + sec->reloc_count; - for (rel = relocs; rel < rel_end; rel++) - { - unsigned long r_symndx; - struct elf_link_hash_entry *h; - - r_symndx = ELF32_R_SYM (rel->r_info); - - if (r_symndx < extsymoff) - h = NULL; - else - h = sym_hashes[r_symndx - extsymoff]; - - /* Some relocs require a global offset table. */ - if (dynobj == NULL) - { - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_MIPS_GOT16: - case R_MIPS_CALL16: - case R_MIPS_CALL_HI16: - case R_MIPS_CALL_LO16: - case R_MIPS_GOT_HI16: - case R_MIPS_GOT_LO16: - elf_hash_table (info)->dynobj = dynobj = abfd; - if (! mips_elf_create_got_section (dynobj, info)) - return false; - break; - - default: - break; - } - } - - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_MIPS_CALL16: - case R_MIPS_CALL_HI16: - case R_MIPS_CALL_LO16: - /* This symbol requires a global offset table entry. */ - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - BFD_ASSERT (elf_section_data (sgot) != NULL); - g = (struct mips_got_info *) elf_section_data (sgot)->tdata; - BFD_ASSERT (g != NULL); - } - - BFD_ASSERT (h != NULL); - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - if (h->got_offset != (bfd_vma) -1) - { - /* We have already allocated space in the .got. */ - break; - } - - /* Note the index of the first global got symbol in .dynsym. */ - if (g->global_gotsym == 0 - || g->global_gotsym > (unsigned long) h->dynindx) - g->global_gotsym = h->dynindx; - - /* Make this symbol to have the corresponding got entry. */ - h->got_offset = 0; - - /* We need a stub, not a plt entry for the undefined - function. But we record it as if it needs plt. See - elf_adjust_dynamic_symbol in elflink.h. */ - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; - h->type = STT_FUNC; - - break; - - case R_MIPS_GOT16: - case R_MIPS_GOT_HI16: - case R_MIPS_GOT_LO16: - /* This symbol requires a global offset table entry. */ - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - BFD_ASSERT (elf_section_data (sgot) != NULL); - g = (struct mips_got_info *) elf_section_data (sgot)->tdata; - BFD_ASSERT (g != NULL); - } - - if (h != NULL) - { - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - if (h->got_offset != (bfd_vma) -1) - { - /* We have already allocated space in the .got. */ - break; - } - /* Note the index of the first global got symbol in - .dynsym. */ - if (g->global_gotsym == 0 - || g->global_gotsym > (unsigned long) h->dynindx) - g->global_gotsym = h->dynindx; - - /* Make this symbol to be the global got symbol. */ - h->got_offset = 0; - } - - break; - - case R_MIPS_32: - case R_MIPS_REL32: - if (info->shared - && (sec->flags & SEC_ALLOC) != 0) - { - /* When creating a shared object, we must copy these - reloc types into the output file as R_MIPS_REL32 - relocs. We create the .rel.dyn reloc section in - dynobj and make room for this reloc. */ - if (sreloc == NULL) - { - const char *name = ".rel.dyn"; - - sreloc = bfd_get_section_by_name (dynobj, name); - if (sreloc == NULL) - { - sreloc = bfd_make_section (dynobj, name); - if (sreloc == NULL - || ! bfd_set_section_flags (dynobj, sreloc, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, sreloc, 4)) - return false; - - /* Add a null element. */ - sreloc->_raw_size += sizeof (Elf32_External_Rel); - ++sreloc->reloc_count; - } - } - - sreloc->_raw_size += sizeof (Elf32_External_Rel); - } - - if (SGI_COMPAT (abfd)) - mips_elf_hash_table (info)->compact_rel_size += - sizeof (Elf32_External_crinfo); - - break; - - case R_MIPS_26: - case R_MIPS_GPREL16: - case R_MIPS_LITERAL: - case R_MIPS_GPREL32: - if (SGI_COMPAT (abfd)) - mips_elf_hash_table (info)->compact_rel_size += - sizeof (Elf32_External_crinfo); - break; - - default: - break; - } - } - - return true; -} - -/* Adjust a symbol defined by a dynamic object and referenced by a - regular object. The current definition is in some section of the - dynamic object, but we're not including those sections. We have to - change the definition to something the rest of the link can - understand. */ - -static boolean -mips_elf_adjust_dynamic_symbol (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; -{ - bfd *dynobj; - asection *s; - - dynobj = elf_hash_table (info)->dynobj; - - /* Make sure we know what is going on here. */ - BFD_ASSERT (dynobj != NULL - && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) - || h->weakdef != NULL - || ((h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_REF_REGULAR) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0))); - - /* For a function, create a stub, if needed. */ - if (h->type == STT_FUNC - || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) - { - if (! elf_hash_table (info)->dynamic_sections_created) - return true; - - /* If this symbol is not defined in a regular file, then set - the symbol to the stub location. This is required to make - function pointers compare as equal between the normal - executable and the shared library. */ - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - /* We need .stub section. */ - s = bfd_get_section_by_name (dynobj, ".stub"); - BFD_ASSERT (s != NULL); - - h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; - - /* XXX Write this stub address somewhere. */ - h->plt_offset = s->_raw_size; - - /* Make room for this stub code. */ - s->_raw_size += MIPS_FUNCTION_STUB_SIZE; - - /* The last half word of the stub will be filled with the index - of this symbol in .dynsym section. */ - return true; - } - } - - /* If this is a weak symbol, and there is a real definition, the - processor independent code will have arranged for us to see the - real definition first, and we can just use the same value. */ - if (h->weakdef != NULL) - { - BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined - || h->weakdef->root.type == bfd_link_hash_defweak); - h->root.u.def.section = h->weakdef->root.u.def.section; - h->root.u.def.value = h->weakdef->root.u.def.value; - return true; - } - - /* This is a reference to a symbol defined by a dynamic object which - is not a function. */ - - return true; -} - -/* Set the sizes of the dynamic sections. */ - -static boolean -mips_elf_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *s; - boolean reltext; - asection *sgot; - struct mips_got_info *g; - - dynobj = elf_hash_table (info)->dynobj; - BFD_ASSERT (dynobj != NULL); - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Set the contents of the .interp section to the interpreter. */ - if (! info->shared) - { - s = bfd_get_section_by_name (dynobj, ".interp"); - BFD_ASSERT (s != NULL); - s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; - s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; - } - } - - /* Recompute the size of .got for local entires (reserved and - hipages) if needed. To estimate it, get the upper bound of total - size of loadable sections. */ - sgot = bfd_get_section_by_name (dynobj, ".got"); - - if (sgot != NULL) - { - bfd_size_type loadable_size = 0; - bfd_size_type local_gotno; - struct _bfd *sub; - - BFD_ASSERT (elf_section_data (sgot) != NULL); - g = (struct mips_got_info *) elf_section_data (sgot)->tdata; - BFD_ASSERT (g != NULL); - - for (sub = info->input_bfds; sub; sub = sub->link_next) - for (s = sub->sections; s != NULL; s = s->next) - { - if ((s->flags & SEC_ALLOC) == 0) - continue; - loadable_size += (s->_raw_size + 0xf) & ~0xf; - } - - loadable_size += MIPS_FUNCTION_STUB_SIZE; - - /* Assume there are two loadable segments consisting of - contiguous sections. Is 5 enough? */ - local_gotno = (loadable_size >> 16) + 5 + MIPS_RESERVED_GOTNO; - g->local_gotno = local_gotno; - sgot->_raw_size += local_gotno * 4; - } - - /* The check_relocs and adjust_dynamic_symbol entry points have - determined the sizes of the various dynamic sections. Allocate - memory for them. */ - reltext = false; - for (s = dynobj->sections; s != NULL; s = s->next) - { - const char *name; - boolean strip; - - /* It's OK to base decisions on the section name, because none - of the dynobj section names depend upon the input files. */ - name = bfd_get_section_name (dynobj, s); - - if ((s->flags & SEC_IN_MEMORY) == 0) - continue; - - strip = false; - - if (strncmp (name, ".rel", 4) == 0) - { - if (s->_raw_size == 0) - strip = true; - else - { - asection *target; - - /* If this relocation section applies to a read only - section, then we probably need a DT_TEXTREL entry. - If the relocation section is .rel.dyn, we always - assert a DT_TEXTREL entry rather than testing whether - there exists a relocation to a read only section or - not. */ - target = bfd_get_section_by_name (output_bfd, name + 4); - if ((target != NULL && (target->flags & SEC_READONLY) != 0) - || strcmp (name, ".rel.dyn") == 0) - reltext = true; - - /* We use the reloc_count field as a counter if we need - to copy relocs into the output file. */ - if (strcmp (name, ".rel.dyn") != 0) - s->reloc_count = 0; - } - } - else if (strncmp (name, ".got", 4) == 0) - { - int i; - - BFD_ASSERT (elf_section_data (s) != NULL); - g = (struct mips_got_info *) elf_section_data (s)->tdata; - BFD_ASSERT (g != NULL); - - /* Fix the size of .got section for the correspondence of - global symbols and got entries. This adds some useless - got entries. Is this required by ABI really? */ - i = elf_hash_table (info)->dynsymcount - g->global_gotsym; - s->_raw_size += i * 4; - } - else if (strncmp (name, ".stub", 5) == 0) - { - /* Irix rld assumes that the function stub isn't at the end - of .text section. So put a dummy. XXX */ - s->_raw_size += MIPS_FUNCTION_STUB_SIZE; - } - else if (SGI_COMPAT (output_bfd) - && strncmp (name, ".compact_rel", 12) == 0) - s->_raw_size += mips_elf_hash_table (info)->compact_rel_size; - else if (strncmp (name, ".init", 5) != 0) - { - /* It's not one of our sections, so don't allocate space. */ - continue; - } - - if (strip) - { - asection **spp; - - for (spp = &s->output_section->owner->sections; - *spp != s->output_section; - spp = &(*spp)->next) - ; - *spp = s->output_section->next; - --s->output_section->owner->section_count; - - continue; - } - - /* Allocate memory for the section contents. */ - s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - memset (s->contents, 0, s->_raw_size); - } - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in elf_mips_finish_dynamic_sections, but we - must add the entries now so that we get the correct size for - the .dynamic section. The DT_DEBUG entry is filled in by the - dynamic linker and used by the debugger. */ - if (! info->shared) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0)) - return false; - } - - if (reltext) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0)) - return false; - } - - if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)) - return false; - - if (bfd_get_section_by_name (dynobj, ".rel.dyn")) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_REL, 0)) - return false; - - if (! bfd_elf32_add_dynamic_entry (info, DT_RELSZ, 0)) - return false; - - if (! bfd_elf32_add_dynamic_entry (info, DT_RELENT, 0)) - return false; - } - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_CONFLICTNO, 0)) - return false; - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_LIBLISTNO, 0)) - return false; - - if (bfd_get_section_by_name (dynobj, ".conflict") != NULL) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_CONFLICT, 0)) - return false; - - s = bfd_get_section_by_name (dynobj, ".liblist"); - BFD_ASSERT (s != NULL); - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_LIBLIST, 0)) - return false; - } - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_RLD_VERSION, 0)) - return false; - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_FLAGS, 0)) - return false; - -#if 0 - /* Time stamps in executable files are a bad idea. */ - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_TIME_STAMP, 0)) - return false; -#endif - -#if 0 /* FIXME */ - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_ICHECKSUM, 0)) - return false; -#endif - -#if 0 /* FIXME */ - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_IVERSION, 0)) - return false; -#endif - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_BASE_ADDRESS, 0)) - return false; - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_LOCAL_GOTNO, 0)) - return false; - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_SYMTABNO, 0)) - return false; - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_UNREFEXTNO, 0)) - return false; - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_GOTSYM, 0)) - return false; - - if (! bfd_elf32_add_dynamic_entry (info, DT_MIPS_HIPAGENO, 0)) - return false; - -#if 0 /* (SGI_COMPAT) */ - if (! bfd_get_section_by_name (dynobj, ".init")) - if (! bfd_elf32_add_dynamic_entry (info, DT_INIT, 0)) - return false; - - if (! bfd_get_section_by_name (dynobj, ".fini")) - if (! bfd_elf32_add_dynamic_entry (info, DT_FINI, 0)) - return false; -#endif - } - - /* If we use dynamic linking, we generate a section symbol for each - output section. These are local symbols, which means that they - must come first in the dynamic symbol table. - That means we must increment the dynamic symbol index of every - other dynamic symbol. */ - { - const char * const *namep; - unsigned int c, i; - bfd_size_type strindex; - struct bfd_strtab_hash *dynstr; - struct mips_got_info *g; - - if (elf_hash_table (info)->dynamic_sections_created) - { - if (SGI_COMPAT (output_bfd)) - { - c = SIZEOF_MIPS_DYNSYM_SECNAMES - 1; - elf_link_hash_traverse (elf_hash_table (info), - mips_elf_adjust_dynindx, - (PTR) &c); - elf_hash_table (info)->dynsymcount += c; - - dynstr = elf_hash_table (info)->dynstr; - BFD_ASSERT (dynstr != NULL); - - for (i = 1, namep = mips_elf_dynsym_sec_names; - *namep != NULL; - i++, namep++) - { - s = bfd_get_section_by_name (output_bfd, *namep); - if (s != NULL) - elf_section_data (s)->dynindx = i; - - strindex = _bfd_stringtab_add (dynstr, *namep, true, false); - if (strindex == (bfd_size_type) -1) - return false; - - mips_elf_hash_table (info)->dynsym_sec_strindex[i] = strindex; - } - } - else - { - c = bfd_count_sections (output_bfd); - elf_link_hash_traverse (elf_hash_table (info), - mips_elf_adjust_dynindx, - (PTR) &c); - elf_hash_table (info)->dynsymcount += c; - - for (i = 1, s = output_bfd->sections; s != NULL; s = s->next, i++) - { - elf_section_data (s)->dynindx = i; - /* These symbols will have no names, so we don't need to - fiddle with dynstr_index. */ - } - } - } - - s = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (s != NULL); - BFD_ASSERT (elf_section_data (s) != NULL); - g = (struct mips_got_info *) elf_section_data (s)->tdata; - BFD_ASSERT (g != NULL); - - /* If there are no global got symbols, fake the last symbol so for - safety. */ - if (g->global_gotsym) - g->global_gotsym += c; - else - g->global_gotsym = elf_hash_table (info)->dynsymcount - 1; - } - - return true; -} - -/* Increment the index of a dynamic symbol by a given amount. Called - via elf_link_hash_traverse. */ - -static boolean -mips_elf_adjust_dynindx (h, cparg) - struct elf_link_hash_entry *h; - PTR cparg; -{ - unsigned int *cp = (unsigned int *) cparg; - - if (h->dynindx != -1) - h->dynindx += *cp; - return true; -} - -/* Finish up dynamic symbol handling. We set the contents of various - dynamic sections here. */ - -static boolean -mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym) - bfd *output_bfd; - struct bfd_link_info *info; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; -{ - bfd *dynobj; - bfd_vma gval; - asection *sgot; - struct mips_got_info *g; - const char *name; - - dynobj = elf_hash_table (info)->dynobj; - gval = sym->st_value; - - if (h->plt_offset != (bfd_vma) -1) - { - asection *s; - bfd_byte *p; - bfd_byte stub[MIPS_FUNCTION_STUB_SIZE]; - - /* This symbol has a stub. Set it up. */ - - BFD_ASSERT (h->dynindx != -1); - - s = bfd_get_section_by_name (dynobj, ".stub"); - BFD_ASSERT (s != NULL); - - /* Fill the stub. */ - p = stub; - bfd_put_32 (output_bfd, STUB_LW(output_bfd), p); - p += 4; - bfd_put_32 (output_bfd, STUB_MOVE, p); - p += 4; - - /* FIXME: Can h->dynindex be more than 64K? */ - if (h->dynindx & 0xffff0000) - return false; - - bfd_put_32 (output_bfd, STUB_JALR, p); - p += 4; - bfd_put_32 (output_bfd, STUB_LI16 + h->dynindx, p); - - BFD_ASSERT (h->plt_offset <= s->_raw_size); - memcpy (s->contents + h->plt_offset, stub, MIPS_FUNCTION_STUB_SIZE); - - /* Mark the symbol as undefined. plt_offset != -1 occurs - only for the referenced symbol. */ - sym->st_shndx = SHN_UNDEF; - - /* The run-time linker uses the st_value field of the symbol - to reset the global offset table entry for this external - to its stub address when unlinking a shared object. */ - gval = s->output_section->vma + s->output_offset + h->plt_offset; - sym->st_value = gval; - } - - BFD_ASSERT (h->dynindx != -1); - - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - BFD_ASSERT (elf_section_data (sgot) != NULL); - g = (struct mips_got_info *) elf_section_data (sgot)->tdata; - BFD_ASSERT (g != NULL); - - if ((unsigned long) h->dynindx >= g->global_gotsym) - { - bfd_size_type offset; - - /* This symbol has an entry in the global offset table. Set its - value to the corresponding got entry, if needed. */ - if (h->got_offset == (bfd_vma) -1) - { - offset = (h->dynindx - g->global_gotsym + g->local_gotno) * 4; - BFD_ASSERT (g->local_gotno * 4 <= offset - && offset < sgot->_raw_size); - bfd_put_32 (output_bfd, gval, sgot->contents + offset); - } - } - - /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ - name = h->root.root.string; - if (strcmp (name, "_DYNAMIC") == 0 - || strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) - sym->st_shndx = SHN_ABS; - else if (strcmp (name, "_DYNAMIC_LINK") == 0) - { - sym->st_shndx = SHN_ABS; - sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION); - sym->st_value = 1; - } - else if (SGI_COMPAT (output_bfd)) - { - if (strcmp (name, "_gp_disp") == 0) - { - sym->st_shndx = SHN_ABS; - sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION); - sym->st_value = elf_gp (output_bfd); - } - else if (strcmp (name, mips_elf_dynsym_rtproc_names[0]) == 0 - || strcmp (name, mips_elf_dynsym_rtproc_names[1]) == 0) - { - sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION); - sym->st_other = STO_PROTECTED; - sym->st_value = 0; - sym->st_shndx = SHN_MIPS_DATA; - } - else if (strcmp (name, mips_elf_dynsym_rtproc_names[2]) == 0) - { - sym->st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION); - sym->st_other = STO_PROTECTED; - sym->st_value = mips_elf_hash_table (info)->procedure_count; - sym->st_shndx = SHN_ABS; - } - else if (sym->st_shndx != SHN_UNDEF) - { - if (h->type == STT_FUNC) - sym->st_shndx = SHN_MIPS_TEXT; - else if (h->type == STT_OBJECT) - sym->st_shndx = SHN_MIPS_DATA; - } - } - - return true; -} - -/* Finish up the dynamic sections. */ - -static boolean -mips_elf_finish_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *sdyn; - asection *sgot; - struct mips_got_info *g; - - dynobj = elf_hash_table (info)->dynobj; - - sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); - - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - - BFD_ASSERT (elf_section_data (sgot) != NULL); - g = (struct mips_got_info *) elf_section_data (sgot)->tdata; - BFD_ASSERT (g != NULL); - - if (elf_hash_table (info)->dynamic_sections_created) - { - Elf32_External_Dyn *dyncon, *dynconend; - - BFD_ASSERT (sdyn != NULL); - - dyncon = (Elf32_External_Dyn *) sdyn->contents; - dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size); - for (; dyncon < dynconend; dyncon++) - { - Elf_Internal_Dyn dyn; - const char *name; - size_t elemsize; - asection *s; - - bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn); - - switch (dyn.d_tag) - { - default: - break; - - case DT_RELENT: - s = bfd_get_section_by_name (dynobj, ".rel.dyn"); - BFD_ASSERT (s != NULL); - dyn.d_un.d_val = sizeof (Elf32_External_Rel); - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_STRSZ: - /* Rewrite DT_STRSZ. */ - dyn.d_un.d_val = - _bfd_stringtab_size (elf_hash_table (info)->dynstr); - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_PLTGOT: - name = ".got"; - goto get_vma; - case DT_MIPS_CONFLICT: - name = ".conflict"; - goto get_vma; - case DT_MIPS_LIBLIST: - name = ".liblist"; - get_vma: - s = bfd_get_section_by_name (output_bfd, name); - BFD_ASSERT (s != NULL); - dyn.d_un.d_ptr = s->vma; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_RLD_VERSION: - dyn.d_un.d_val = 1; /* XXX */ - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_FLAGS: - dyn.d_un.d_val = RHF_NOTPOT; /* XXX */ - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_CONFLICTNO: - name = ".conflict"; - elemsize = sizeof (Elf32_Conflict); - goto set_elemno; - - case DT_MIPS_LIBLISTNO: - name = ".liblist"; - elemsize = sizeof (Elf32_Lib); - set_elemno: - s = bfd_get_section_by_name (output_bfd, name); - if (s != NULL) - { - if (s->_cooked_size != 0) - dyn.d_un.d_val = s->_cooked_size / elemsize; - else - dyn.d_un.d_val = s->_raw_size / elemsize; - } - else - dyn.d_un.d_val = 0; - - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_TIME_STAMP: - time ((time_t *) &dyn.d_un.d_val); - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_ICHECKSUM: - /* XXX FIXME: */ - break; - - case DT_MIPS_IVERSION: - /* XXX FIXME: */ - break; - - case DT_MIPS_BASE_ADDRESS: - s = output_bfd->sections; - BFD_ASSERT (s != NULL); - dyn.d_un.d_ptr = s->vma & ~(0xffff); - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_LOCAL_GOTNO: - dyn.d_un.d_val = g->local_gotno; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_SYMTABNO: - name = ".dynsym"; - elemsize = sizeof (Elf32_External_Sym); - s = bfd_get_section_by_name (output_bfd, name); - BFD_ASSERT (s != NULL); - - if (s->_cooked_size != 0) - dyn.d_un.d_val = s->_cooked_size / elemsize; - else - dyn.d_un.d_val = s->_raw_size / elemsize; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_UNREFEXTNO: - /* XXX FIXME: */ - dyn.d_un.d_val = SIZEOF_MIPS_DYNSYM_SECNAMES; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_GOTSYM: - dyn.d_un.d_val = g->global_gotsym; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - case DT_MIPS_HIPAGENO: - dyn.d_un.d_val = g->local_gotno - MIPS_RESERVED_GOTNO; - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - break; - - } - } - } - - /* The first entry of the global offset table will be filled at - runtime. The second entry will be used by some runtime loaders. - This isn't the case of Irix rld. */ - if (sgot->_raw_size > 0) - { - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents); - bfd_put_32 (output_bfd, (bfd_vma) 0x80000000, sgot->contents + 4); - } - - elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4; - - { - asection *sdynsym; - asection *s; - unsigned int i; - bfd_vma last; - Elf_Internal_Sym sym; - long dindx; - const char *name; - const char * const * namep = mips_elf_dynsym_sec_names; - Elf32_compact_rel cpt; - - /* Set up the section symbols for the output sections. SGI sets - the STT_NOTYPE attribute for these symbols. Should we do so? */ - - sdynsym = bfd_get_section_by_name (dynobj, ".dynsym"); - if (sdynsym != NULL) - { - if (SGI_COMPAT (output_bfd)) - { - sym.st_size = 0; - sym.st_name = 0; - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_NOTYPE); - sym.st_other = 0; - - i = 0; - while ((name = *namep++) != NULL) - { - s = bfd_get_section_by_name (output_bfd, name); - if (s != NULL) - { - sym.st_value = s->vma; - dindx = elf_section_data (s)->dynindx; - last = s->vma + s->_raw_size; - } - else - { - sym.st_value = last; - dindx++; - } - - sym.st_shndx = (i < MIPS_TEXT_DYNSYM_SECNO - ? SHN_MIPS_TEXT - : SHN_MIPS_DATA); - ++i; - sym.st_name = - mips_elf_hash_table (info)->dynsym_sec_strindex[dindx]; - - bfd_elf32_swap_symbol_out (output_bfd, &sym, - (((Elf32_External_Sym *) - sdynsym->contents) - + dindx)); - } - - /* Set the sh_info field of the output .dynsym section to - the index of the first global symbol. */ - elf_section_data (sdynsym->output_section)->this_hdr.sh_info = - SIZEOF_MIPS_DYNSYM_SECNAMES; - } - else - { - sym.st_size = 0; - sym.st_name = 0; - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); - sym.st_other = 0; - - for (s = output_bfd->sections; s != NULL; s = s->next) - { - int indx; - - sym.st_value = s->vma; - - indx = elf_section_data (s)->this_idx; - BFD_ASSERT (indx > 0); - sym.st_shndx = indx; - - bfd_elf32_swap_symbol_out (output_bfd, &sym, - (((Elf32_External_Sym *) - sdynsym->contents) - + elf_section_data (s)->dynindx)); - } - - /* Set the sh_info field of the output .dynsym section to - the index of the first global symbol. */ - elf_section_data (sdynsym->output_section)->this_hdr.sh_info = - bfd_count_sections (output_bfd) + 1; - } - } - - if (SGI_COMPAT (output_bfd)) - { - /* Write .compact_rel section out. */ - s = bfd_get_section_by_name (dynobj, ".compact_rel"); - if (s != NULL) - { - cpt.id1 = 1; - cpt.num = s->reloc_count; - cpt.id2 = 2; - cpt.offset = (s->output_section->filepos - + sizeof (Elf32_External_compact_rel)); - cpt.reserved0 = 0; - cpt.reserved1 = 0; - bfd_elf32_swap_compact_rel_out (output_bfd, &cpt, - ((Elf32_External_compact_rel *) - s->contents)); - - /* Clean up a dummy stub function entry in .text. */ - s = bfd_get_section_by_name (dynobj, ".stub"); - if (s != NULL) - { - file_ptr dummy_offset; - - BFD_ASSERT (s->_raw_size >= MIPS_FUNCTION_STUB_SIZE); - dummy_offset = s->_raw_size - MIPS_FUNCTION_STUB_SIZE; - memset (s->contents + dummy_offset, 0, - MIPS_FUNCTION_STUB_SIZE); - } - } - } - - /* Clean up a first relocation in .rel.dyn. */ - s = bfd_get_section_by_name (dynobj, ".rel.dyn"); - if (s != NULL) - memset (s->contents, 0, sizeof (Elf32_External_Rel)); - } - - return true; -} - -/* This is almost identical to bfd_generic_get_... except that some - MIPS relocations need to be handled specially. Sigh. */ - -static bfd_byte * -elf32_mips_get_relocated_section_contents (abfd, link_info, link_order, data, - relocateable, symbols) - bfd *abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - bfd_byte *data; - boolean relocateable; - asymbol **symbols; -{ - /* Get enough memory to hold the stuff */ - bfd *input_bfd = link_order->u.indirect.section->owner; - asection *input_section = link_order->u.indirect.section; - - long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); - arelent **reloc_vector = NULL; - long reloc_count; - - if (reloc_size < 0) - goto error_return; - - reloc_vector = (arelent **) bfd_malloc (reloc_size); - if (reloc_vector == NULL && reloc_size != 0) - goto error_return; - - /* read in the section */ - if (!bfd_get_section_contents (input_bfd, - input_section, - (PTR) data, - 0, - input_section->_raw_size)) - goto error_return; - - /* We're not relaxing the section, so just copy the size info */ - input_section->_cooked_size = input_section->_raw_size; - input_section->reloc_done = true; - - reloc_count = bfd_canonicalize_reloc (input_bfd, - input_section, - reloc_vector, - symbols); - if (reloc_count < 0) - goto error_return; - - if (reloc_count > 0) - { - arelent **parent; - /* for mips */ - int gp_found; - bfd_vma gp = 0x12345678; /* initialize just to shut gcc up */ - - { - struct bfd_hash_entry *h; - struct bfd_link_hash_entry *lh; - /* Skip all this stuff if we aren't mixing formats. */ - if (abfd && input_bfd - && abfd->xvec == input_bfd->xvec) - lh = 0; - else - { - h = bfd_hash_lookup (&link_info->hash->table, "_gp", false, false); - lh = (struct bfd_link_hash_entry *) h; - } - lookup: - if (lh) - { - switch (lh->type) - { - case bfd_link_hash_undefined: - case bfd_link_hash_undefweak: - case bfd_link_hash_common: - gp_found = 0; - break; - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - gp_found = 1; - gp = lh->u.def.value; - break; - case bfd_link_hash_indirect: - case bfd_link_hash_warning: - lh = lh->u.i.link; - /* @@FIXME ignoring warning for now */ - goto lookup; - case bfd_link_hash_new: - default: - abort (); - } - } - else - gp_found = 0; - } - /* end mips */ - for (parent = reloc_vector; *parent != (arelent *) NULL; - parent++) - { - char *error_message = (char *) NULL; - bfd_reloc_status_type r; - - /* Specific to MIPS: Deal with relocation types that require - knowing the gp of the output bfd. */ - asymbol *sym = *(*parent)->sym_ptr_ptr; - if (bfd_is_abs_section (sym->section) && abfd) - { - /* The special_function wouldn't get called anyways. */ - } - else if (!gp_found) - { - /* The gp isn't there; let the special function code - fall over on its own. */ - } - else if ((*parent)->howto->special_function - == mips_elf_gprel16_reloc) - { - /* bypass special_function call */ - r = gprel16_with_gp (input_bfd, sym, *parent, input_section, - relocateable, (PTR) data, gp); - goto skip_bfd_perform_relocation; - } - /* end mips specific stuff */ - - r = bfd_perform_relocation (input_bfd, - *parent, - (PTR) data, - input_section, - relocateable ? abfd : (bfd *) NULL, - &error_message); - skip_bfd_perform_relocation: - - if (relocateable) - { - asection *os = input_section->output_section; - - /* A partial link, so keep the relocs */ - os->orelocation[os->reloc_count] = *parent; - os->reloc_count++; - } - - if (r != bfd_reloc_ok) - { - switch (r) - { - case bfd_reloc_undefined: - if (!((*link_info->callbacks->undefined_symbol) - (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr), - input_bfd, input_section, (*parent)->address))) - goto error_return; - break; - case bfd_reloc_dangerous: - BFD_ASSERT (error_message != (char *) NULL); - if (!((*link_info->callbacks->reloc_dangerous) - (link_info, error_message, input_bfd, input_section, - (*parent)->address))) - goto error_return; - break; - case bfd_reloc_overflow: - if (!((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr), - (*parent)->howto->name, (*parent)->addend, - input_bfd, input_section, (*parent)->address))) - goto error_return; - break; - case bfd_reloc_outofrange: - default: - abort (); - break; - } - - } - } - } - if (reloc_vector != NULL) - free (reloc_vector); - return data; - -error_return: - if (reloc_vector != NULL) - free (reloc_vector); - return NULL; -} -#define bfd_elf32_bfd_get_relocated_section_contents \ - elf32_mips_get_relocated_section_contents - -/* 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_elf_ecoff_debug_swap = -{ - /* Symbol table magic number. */ - magicSym, - /* Alignment of debugging information. E.g., 4. */ - 4, - /* Sizes of external symbolic information. */ - sizeof (struct hdr_ext), - sizeof (struct dnr_ext), - sizeof (struct pdr_ext), - sizeof (struct sym_ext), - sizeof (struct opt_ext), - sizeof (struct fdr_ext), - sizeof (struct rfd_ext), - sizeof (struct ext_ext), - /* Functions to swap in external symbolic data. */ - ecoff_swap_hdr_in, - ecoff_swap_dnr_in, - ecoff_swap_pdr_in, - ecoff_swap_sym_in, - ecoff_swap_opt_in, - ecoff_swap_fdr_in, - ecoff_swap_rfd_in, - ecoff_swap_ext_in, - _bfd_ecoff_swap_tir_in, - _bfd_ecoff_swap_rndx_in, - /* Functions to swap out external symbolic data. */ - ecoff_swap_hdr_out, - ecoff_swap_dnr_out, - ecoff_swap_pdr_out, - ecoff_swap_sym_out, - ecoff_swap_opt_out, - ecoff_swap_fdr_out, - ecoff_swap_rfd_out, - ecoff_swap_ext_out, - _bfd_ecoff_swap_tir_out, - _bfd_ecoff_swap_rndx_out, - /* Function to read in symbolic data. */ - mips_elf_read_ecoff_info -}; - -#define TARGET_LITTLE_SYM bfd_elf32_littlemips_vec -#define TARGET_LITTLE_NAME "elf32-littlemips" -#define TARGET_BIG_SYM bfd_elf32_bigmips_vec -#define TARGET_BIG_NAME "elf32-bigmips" -#define ELF_ARCH bfd_arch_mips -#define ELF_MACHINE_CODE EM_MIPS -#define ELF_MAXPAGESIZE 0x10000 -#define elf_backend_collect true -#define elf_backend_type_change_ok true -#define elf_info_to_howto 0 -#define elf_info_to_howto_rel mips_info_to_howto_rel -#define elf_backend_sym_is_global mips_elf_sym_is_global -#define elf_backend_object_p mips_elf_object_p -#define elf_backend_section_from_shdr mips_elf_section_from_shdr -#define elf_backend_fake_sections mips_elf_fake_sections -#define elf_backend_section_from_bfd_section \ - mips_elf_section_from_bfd_section -#define elf_backend_section_processing mips_elf_section_processing -#define elf_backend_symbol_processing mips_elf_symbol_processing -#define elf_backend_additional_program_headers \ - mips_elf_additional_program_headers -#define elf_backend_modify_segment_map mips_elf_modify_segment_map -#define elf_backend_final_write_processing \ - mips_elf_final_write_processing -#define elf_backend_ecoff_debug_swap &mips_elf_ecoff_debug_swap - -#define bfd_elf32_bfd_is_local_label mips_elf_is_local_label -#define bfd_elf32_find_nearest_line mips_elf_find_nearest_line - -#define bfd_elf32_bfd_link_hash_table_create \ - mips_elf_link_hash_table_create -#define bfd_elf32_bfd_final_link mips_elf_final_link -#define bfd_elf32_bfd_copy_private_bfd_data \ - mips_elf_copy_private_bfd_data -#define bfd_elf32_bfd_merge_private_bfd_data \ - mips_elf_merge_private_bfd_data -#define bfd_elf32_bfd_set_private_flags mips_elf_set_private_flags -#define elf_backend_add_symbol_hook mips_elf_add_symbol_hook -#define elf_backend_create_dynamic_sections \ - mips_elf_create_dynamic_sections -#define elf_backend_check_relocs mips_elf_check_relocs -#define elf_backend_adjust_dynamic_symbol \ - mips_elf_adjust_dynamic_symbol -#define elf_backend_size_dynamic_sections \ - mips_elf_size_dynamic_sections -#define elf_backend_relocate_section mips_elf_relocate_section -#define elf_backend_finish_dynamic_symbol \ - mips_elf_finish_dynamic_symbol -#define elf_backend_finish_dynamic_sections \ - mips_elf_finish_dynamic_sections - -#include "elf32-target.h" diff --git a/contrib/gdb/bfd/elf32-ppc.c b/contrib/gdb/bfd/elf32-ppc.c deleted file mode 100644 index a8e5ad3..0000000 --- a/contrib/gdb/bfd/elf32-ppc.c +++ /dev/null @@ -1,2554 +0,0 @@ -/* PowerPC-specific support for 32-bit ELF - Copyright 1994, 1995, 1996 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Cygnus Support. - -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 is based on a preliminary PowerPC ELF ABI. The - information may not match the final PowerPC ELF ABI. It includes - suggestions from the in-progress Embedded PowerPC ABI, and that - information may also not match. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "elf-bfd.h" -#include "elf/ppc.h" - -#define USE_RELA /* we want RELA relocations, not REL */ - -/* PowerPC relocations defined by the ABIs */ -enum ppc_reloc_type -{ - R_PPC_NONE = 0, - R_PPC_ADDR32 = 1, - R_PPC_ADDR24 = 2, - R_PPC_ADDR16 = 3, - R_PPC_ADDR16_LO = 4, - R_PPC_ADDR16_HI = 5, - R_PPC_ADDR16_HA = 6, - R_PPC_ADDR14 = 7, - R_PPC_ADDR14_BRTAKEN = 8, - R_PPC_ADDR14_BRNTAKEN = 9, - R_PPC_REL24 = 10, - R_PPC_REL14 = 11, - R_PPC_REL14_BRTAKEN = 12, - R_PPC_REL14_BRNTAKEN = 13, - R_PPC_GOT16 = 14, - R_PPC_GOT16_LO = 15, - R_PPC_GOT16_HI = 16, - R_PPC_GOT16_HA = 17, - R_PPC_PLTREL24 = 18, - R_PPC_COPY = 19, - R_PPC_GLOB_DAT = 20, - R_PPC_JMP_SLOT = 21, - R_PPC_RELATIVE = 22, - R_PPC_LOCAL24PC = 23, - R_PPC_UADDR32 = 24, - R_PPC_UADDR16 = 25, - R_PPC_REL32 = 26, - R_PPC_PLT32 = 27, - R_PPC_PLTREL32 = 28, - R_PPC_PLT16_LO = 29, - R_PPC_PLT16_HI = 30, - R_PPC_PLT16_HA = 31, - R_PPC_SDAREL16 = 32, - R_PPC_SECTOFF = 33, - R_PPC_SECTOFF_LO = 34, - R_PPC_SECTOFF_HI = 35, - R_PPC_SECTOFF_HA = 36, - - /* The remaining relocs are from the Embedded ELF ABI, and are not - in the SVR4 ELF ABI. */ - R_PPC_EMB_NADDR32 = 101, - R_PPC_EMB_NADDR16 = 102, - R_PPC_EMB_NADDR16_LO = 103, - R_PPC_EMB_NADDR16_HI = 104, - R_PPC_EMB_NADDR16_HA = 105, - R_PPC_EMB_SDAI16 = 106, - R_PPC_EMB_SDA2I16 = 107, - R_PPC_EMB_SDA2REL = 108, - R_PPC_EMB_SDA21 = 109, - R_PPC_EMB_MRKREF = 110, - R_PPC_EMB_RELSEC16 = 111, - R_PPC_EMB_RELST_LO = 112, - R_PPC_EMB_RELST_HI = 113, - R_PPC_EMB_RELST_HA = 114, - R_PPC_EMB_BIT_FLD = 115, - R_PPC_EMB_RELSDA = 116, - - /* This is a phony reloc to handle any old fashioned TOC16 references - that may still be in object files. */ - R_PPC_TOC16 = 255, - - R_PPC_max -}; - -static reloc_howto_type *ppc_elf_reloc_type_lookup - PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); -static void ppc_elf_info_to_howto - PARAMS ((bfd *abfd, arelent *cache_ptr, Elf32_Internal_Rela *dst)); -static void ppc_elf_howto_init PARAMS ((void)); -static boolean ppc_elf_set_private_flags PARAMS ((bfd *, flagword)); -static boolean ppc_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *)); -static boolean ppc_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *)); - -static int ppc_elf_additional_program_headers PARAMS ((bfd *)); -static boolean ppc_elf_modify_segment_map PARAMS ((bfd *)); - -static boolean ppc_elf_section_from_shdr PARAMS ((bfd *, - Elf32_Internal_Shdr *, - char *)); - -static elf_linker_section_t *ppc_elf_create_linker_section - PARAMS ((bfd *abfd, - struct bfd_link_info *info, - enum elf_linker_section_enum)); - -static boolean ppc_elf_check_relocs PARAMS ((bfd *, - struct bfd_link_info *, - asection *, - const Elf_Internal_Rela *)); - -static boolean ppc_elf_adjust_dynamic_symbol PARAMS ((struct bfd_link_info *, - struct elf_link_hash_entry *)); - -static boolean ppc_elf_adjust_dynindx PARAMS ((struct elf_link_hash_entry *, PTR)); - -static boolean ppc_elf_size_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); - -static boolean ppc_elf_relocate_section PARAMS ((bfd *, - struct bfd_link_info *info, - bfd *, - asection *, - bfd_byte *, - Elf_Internal_Rela *relocs, - Elf_Internal_Sym *local_syms, - asection **)); - -static boolean ppc_elf_add_symbol_hook PARAMS ((bfd *, - struct bfd_link_info *, - const Elf_Internal_Sym *, - const char **, - flagword *, - asection **, - bfd_vma *)); - -static boolean ppc_elf_finish_dynamic_symbol PARAMS ((bfd *, - struct bfd_link_info *, - struct elf_link_hash_entry *, - Elf_Internal_Sym *)); - -static boolean ppc_elf_finish_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); - -#define BRANCH_PREDICT_BIT 0x200000 /* branch prediction bit for branch taken relocs */ -#define RA_REGISTER_MASK 0x001f0000 /* mask to set RA in memory instructions */ -#define RA_REGISTER_SHIFT 16 /* value to shift register by to insert RA */ - -/* The name of the dynamic interpreter. This is put in the .interp - section. */ - -#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" - - -static reloc_howto_type *ppc_elf_howto_table[ (int)R_PPC_max ]; - -static reloc_howto_type ppc_elf_howto_raw[] = -{ - /* This reloc does nothing. */ - HOWTO (R_PPC_NONE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_NONE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* A standard 32 bit relocation. */ - HOWTO (R_PPC_ADDR32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_ADDR32", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* An absolute 26 bit branch; the lower two bits must be zero. - FIXME: we don't check that, we just clear them. */ - HOWTO (R_PPC_ADDR24, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_ADDR24", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0x3fffffc, /* dst_mask */ - false), /* pcrel_offset */ - - /* A standard 16 bit relocation. */ - HOWTO (R_PPC_ADDR16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_ADDR16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 16 bit relocation without overflow. */ - HOWTO (R_PPC_ADDR16_LO, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont,/* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_ADDR16_LO", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* The high order 16 bits of an address. */ - HOWTO (R_PPC_ADDR16_HI, /* type */ - 16, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_ADDR16_HI", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* The high order 16 bits of an address, plus 1 if the contents of - the low 16 bits, treated as a signed number, is negative. */ - HOWTO (R_PPC_ADDR16_HA, /* type */ - 16, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_ADDR16_HA", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* An absolute 16 bit branch; the lower two bits must be zero. - FIXME: we don't check that, we just clear them. */ - HOWTO (R_PPC_ADDR14, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_ADDR14", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xfffc, /* dst_mask */ - false), /* pcrel_offset */ - - /* An absolute 16 bit branch, for which bit 10 should be set to - indicate that the branch is expected to be taken. The lower two - bits must be zero. */ - HOWTO (R_PPC_ADDR14_BRTAKEN, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_ADDR14_BRTAKEN",/* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xfffc, /* dst_mask */ - false), /* pcrel_offset */ - - /* An absolute 16 bit branch, for which bit 10 should be set to - indicate that the branch is not expected to be taken. The lower - two bits must be zero. */ - HOWTO (R_PPC_ADDR14_BRNTAKEN, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_ADDR14_BRNTAKEN",/* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xfffc, /* dst_mask */ - false), /* pcrel_offset */ - - /* A relative 26 bit branch; the lower two bits must be zero. */ - HOWTO (R_PPC_REL24, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_REL24", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0x3fffffc, /* dst_mask */ - true), /* pcrel_offset */ - - /* A relative 16 bit branch; the lower two bits must be zero. */ - HOWTO (R_PPC_REL14, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_REL14", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xfffc, /* dst_mask */ - true), /* pcrel_offset */ - - /* A relative 16 bit branch. Bit 10 should be set to indicate that - the branch is expected to be taken. The lower two bits must be - zero. */ - HOWTO (R_PPC_REL14_BRTAKEN, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_REL14_BRTAKEN", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xfffc, /* dst_mask */ - true), /* pcrel_offset */ - - /* A relative 16 bit branch. Bit 10 should be set to indicate that - the branch is not expected to be taken. The lower two bits must - be zero. */ - HOWTO (R_PPC_REL14_BRNTAKEN, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_REL14_BRNTAKEN",/* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xfffc, /* dst_mask */ - true), /* pcrel_offset */ - - /* Like R_PPC_ADDR16, but referring to the GOT table entry for the - symbol. */ - HOWTO (R_PPC_GOT16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_GOT16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Like R_PPC_ADDR16_LO, but referring to the GOT table entry for - the symbol. */ - HOWTO (R_PPC_GOT16_LO, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_GOT16_LO", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Like R_PPC_ADDR16_HI, but referring to the GOT table entry for - the symbol. */ - HOWTO (R_PPC_GOT16_HI, /* type */ - 16, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_GOT16_HI", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Like R_PPC_ADDR16_HA, but referring to the GOT table entry for - the symbol. */ - HOWTO (R_PPC_GOT16_HA, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_GOT16_HA", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Like R_PPC_REL24, but referring to the procedure linkage table - entry for the symbol. FIXME: Not supported. */ - HOWTO (R_PPC_PLTREL24, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_PLTREL24", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0x3fffffc, /* dst_mask */ - true), /* pcrel_offset */ - - /* This is used only by the dynamic linker. The symbol should exist - both in the object being run and in some shared library. The - dynamic linker copies the data addressed by the symbol from the - shared library into the object. I have no idea what the purpose - of this is. */ - HOWTO (R_PPC_COPY, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_COPY", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Like R_PPC_ADDR32, but used when setting global offset table - entries. */ - HOWTO (R_PPC_GLOB_DAT, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_GLOB_DAT", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Marks a procedure linkage table entry for a symbol. */ - HOWTO (R_PPC_JMP_SLOT, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_JMP_SLOT", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Used only by the dynamic linker. When the object is run, this - longword is set to the load address of the object, plus the - addend. */ - HOWTO (R_PPC_RELATIVE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_RELATIVE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Like R_PPC_REL24, but uses the value of the symbol within the - object rather than the final value. Normally used for - _GLOBAL_OFFSET_TABLE_. FIXME: Not supported. */ - HOWTO (R_PPC_LOCAL24PC, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_LOCAL24PC", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0x3fffffc, /* dst_mask */ - true), /* pcrel_offset */ - - /* Like R_PPC_ADDR32, but may be unaligned. */ - HOWTO (R_PPC_UADDR32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_UADDR32", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Like R_PPC_ADDR16, but may be unaligned. */ - HOWTO (R_PPC_UADDR16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_UADDR16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32-bit PC relative */ - HOWTO (R_PPC_REL32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_REL32", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffffffff, /* dst_mask */ - true), /* pcrel_offset */ - - /* 32-bit relocation to the symbol's procedure linkage table. - FIXEME: not supported. */ - HOWTO (R_PPC_PLT32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_PLT32", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32-bit PC relative relocation to the symbol's procedure linkage table. - FIXEME: not supported. */ - HOWTO (R_PPC_PLTREL32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_PLTREL32", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - true), /* pcrel_offset */ - - /* Like R_PPC_ADDR16_LO, but referring to the PLT table entry for - the symbol. */ - HOWTO (R_PPC_PLT16_LO, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_PLT16_LO", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Like R_PPC_ADDR16_HI, but referring to the PLT table entry for - the symbol. */ - HOWTO (R_PPC_PLT16_HI, /* type */ - 16, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_PLT16_HI", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Like R_PPC_ADDR16_HA, but referring to the PLT table entry for - the symbol. FIXME: Not supported. */ - HOWTO (R_PPC_PLT16_HA, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_PLT16_HA", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A sign-extended 16 bit value relative to _SDA_BASE_, for use with - small data items. */ - HOWTO (R_PPC_SDAREL16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_SDAREL16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32-bit section relative relocation. */ - HOWTO (R_PPC_SECTOFF, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_SECTOFF", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - true), /* pcrel_offset */ - - /* 16-bit lower half section relative relocation. */ - HOWTO (R_PPC_SECTOFF_LO, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_SECTOFF_LO", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16-bit upper half section relative relocation. */ - HOWTO (R_PPC_SECTOFF_HI, /* type */ - 16, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_SECTOFF_HI", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16-bit upper half adjusted section relative relocation. */ - HOWTO (R_PPC_SECTOFF_HA, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_SECTOFF_HA", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* The remaining relocs are from the Embedded ELF ABI, and are not - in the SVR4 ELF ABI. */ - - /* 32 bit value resulting from the addend minus the symbol */ - HOWTO (R_PPC_EMB_NADDR32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_NADDR32", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit value resulting from the addend minus the symbol */ - HOWTO (R_PPC_EMB_NADDR16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_NADDR16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit value resulting from the addend minus the symbol */ - HOWTO (R_PPC_EMB_NADDR16_LO, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont,/* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_ADDR16_LO", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* The high order 16 bits of the addend minus the symbol */ - HOWTO (R_PPC_EMB_NADDR16_HI, /* type */ - 16, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_NADDR16_HI", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* The high order 16 bits of the result of the addend minus the address, - plus 1 if the contents of the low 16 bits, treated as a signed number, - is negative. */ - HOWTO (R_PPC_EMB_NADDR16_HA, /* type */ - 16, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_NADDR16_HA", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit value resulting from allocating a 4 byte word to hold an - address in the .sdata section, and returning the offset from - _SDA_BASE_ for that relocation */ - HOWTO (R_PPC_EMB_SDAI16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_SDAI16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit value resulting from allocating a 4 byte word to hold an - address in the .sdata2 section, and returning the offset from - _SDA2_BASE_ for that relocation */ - HOWTO (R_PPC_EMB_SDA2I16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_SDA2I16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A sign-extended 16 bit value relative to _SDA2_BASE_, for use with - small data items. */ - HOWTO (R_PPC_EMB_SDA2REL, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_SDA2REL", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Relocate against either _SDA_BASE_ or _SDA2_BASE_, filling in the 16 bit - signed offset from the appropriate base, and filling in the register - field with the appropriate register (0, 2, or 13). */ - HOWTO (R_PPC_EMB_SDA21, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_SDA21", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Relocation not handled: R_PPC_EMB_MRKREF */ - /* Relocation not handled: R_PPC_EMB_RELSEC16 */ - /* Relocation not handled: R_PPC_EMB_RELST_LO */ - /* Relocation not handled: R_PPC_EMB_RELST_HI */ - /* Relocation not handled: R_PPC_EMB_RELST_HA */ - /* Relocation not handled: R_PPC_EMB_BIT_FLD */ - - /* PC relative relocation against either _SDA_BASE_ or _SDA2_BASE_, filling - in the 16 bit signed offset from the appropriate base, and filling in the - register field with the appropriate register (0, 2, or 13). */ - HOWTO (R_PPC_EMB_RELSDA, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_EMB_RELSDA", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Phony reloc to handle AIX style TOC entries */ - HOWTO (R_PPC_TOC16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_TOC16", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ -}; - - -/* Initialize the ppc_elf_howto_table, so that linear accesses can be done. */ - -static void -ppc_elf_howto_init () -{ - unsigned int i, type; - - for (i = 0; i < sizeof (ppc_elf_howto_raw) / sizeof (ppc_elf_howto_raw[0]); i++) - { - type = ppc_elf_howto_raw[i].type; - BFD_ASSERT (type < sizeof(ppc_elf_howto_table) / sizeof(ppc_elf_howto_table[0])); - ppc_elf_howto_table[type] = &ppc_elf_howto_raw[i]; - } -} - - -static reloc_howto_type * -ppc_elf_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - enum ppc_reloc_type ppc_reloc = R_PPC_NONE; - - if (!ppc_elf_howto_table[ R_PPC_ADDR32 ]) /* Initialize howto table if needed */ - ppc_elf_howto_init (); - - switch ((int)code) - { - default: - return (reloc_howto_type *)NULL; - - case BFD_RELOC_NONE: ppc_reloc = R_PPC_NONE; break; - case BFD_RELOC_32: ppc_reloc = R_PPC_ADDR32; break; - case BFD_RELOC_PPC_BA26: ppc_reloc = R_PPC_ADDR24; break; - case BFD_RELOC_16: ppc_reloc = R_PPC_ADDR16; break; - case BFD_RELOC_LO16: ppc_reloc = R_PPC_ADDR16_LO; break; - case BFD_RELOC_HI16: ppc_reloc = R_PPC_ADDR16_HI; break; - case BFD_RELOC_HI16_S: ppc_reloc = R_PPC_ADDR16_HA; break; - case BFD_RELOC_PPC_BA16: ppc_reloc = R_PPC_ADDR14; break; - case BFD_RELOC_PPC_BA16_BRTAKEN: ppc_reloc = R_PPC_ADDR14_BRTAKEN; break; - case BFD_RELOC_PPC_BA16_BRNTAKEN: ppc_reloc = R_PPC_ADDR14_BRNTAKEN; break; - case BFD_RELOC_PPC_B26: ppc_reloc = R_PPC_REL24; break; - case BFD_RELOC_PPC_B16: ppc_reloc = R_PPC_REL14; break; - case BFD_RELOC_PPC_B16_BRTAKEN: ppc_reloc = R_PPC_REL14_BRTAKEN; break; - case BFD_RELOC_PPC_B16_BRNTAKEN: ppc_reloc = R_PPC_REL14_BRNTAKEN; break; - case BFD_RELOC_16_GOTOFF: ppc_reloc = R_PPC_GOT16; break; - case BFD_RELOC_LO16_GOTOFF: ppc_reloc = R_PPC_GOT16_LO; break; - case BFD_RELOC_HI16_GOTOFF: ppc_reloc = R_PPC_GOT16_HI; break; - case BFD_RELOC_HI16_S_GOTOFF: ppc_reloc = R_PPC_GOT16_HA; break; - case BFD_RELOC_24_PLT_PCREL: ppc_reloc = R_PPC_PLTREL24; break; - case BFD_RELOC_PPC_COPY: ppc_reloc = R_PPC_COPY; break; - case BFD_RELOC_PPC_GLOB_DAT: ppc_reloc = R_PPC_GLOB_DAT; break; - case BFD_RELOC_PPC_LOCAL24PC: ppc_reloc = R_PPC_LOCAL24PC; break; - case BFD_RELOC_32_PCREL: ppc_reloc = R_PPC_REL32; break; - case BFD_RELOC_32_PLTOFF: ppc_reloc = R_PPC_PLT32; break; - case BFD_RELOC_32_PLT_PCREL: ppc_reloc = R_PPC_PLTREL32; break; - case BFD_RELOC_LO16_PLTOFF: ppc_reloc = R_PPC_PLT16_LO; break; - case BFD_RELOC_HI16_PLTOFF: ppc_reloc = R_PPC_PLT16_HI; break; - case BFD_RELOC_HI16_S_PLTOFF: ppc_reloc = R_PPC_PLT16_HA; break; - case BFD_RELOC_GPREL16: ppc_reloc = R_PPC_SDAREL16; break; - case BFD_RELOC_32_BASEREL: ppc_reloc = R_PPC_SECTOFF; break; - case BFD_RELOC_LO16_BASEREL: ppc_reloc = R_PPC_SECTOFF_LO; break; - case BFD_RELOC_HI16_BASEREL: ppc_reloc = R_PPC_SECTOFF_HI; break; - case BFD_RELOC_HI16_S_BASEREL: ppc_reloc = R_PPC_SECTOFF_HA; break; - case BFD_RELOC_CTOR: ppc_reloc = R_PPC_ADDR32; break; - case BFD_RELOC_PPC_TOC16: ppc_reloc = R_PPC_TOC16; break; - case BFD_RELOC_PPC_EMB_NADDR32: ppc_reloc = R_PPC_EMB_NADDR32; break; - case BFD_RELOC_PPC_EMB_NADDR16: ppc_reloc = R_PPC_EMB_NADDR16; break; - case BFD_RELOC_PPC_EMB_NADDR16_LO: ppc_reloc = R_PPC_EMB_NADDR16_LO; break; - case BFD_RELOC_PPC_EMB_NADDR16_HI: ppc_reloc = R_PPC_EMB_NADDR16_HI; break; - case BFD_RELOC_PPC_EMB_NADDR16_HA: ppc_reloc = R_PPC_EMB_NADDR16_HA; break; - case BFD_RELOC_PPC_EMB_SDAI16: ppc_reloc = R_PPC_EMB_SDAI16; break; - case BFD_RELOC_PPC_EMB_SDA2I16: ppc_reloc = R_PPC_EMB_SDA2I16; break; - case BFD_RELOC_PPC_EMB_SDA2REL: ppc_reloc = R_PPC_EMB_SDA2REL; break; - case BFD_RELOC_PPC_EMB_SDA21: ppc_reloc = R_PPC_EMB_SDA21; break; - case BFD_RELOC_PPC_EMB_MRKREF: ppc_reloc = R_PPC_EMB_MRKREF; break; - case BFD_RELOC_PPC_EMB_RELSEC16: ppc_reloc = R_PPC_EMB_RELSEC16; break; - case BFD_RELOC_PPC_EMB_RELST_LO: ppc_reloc = R_PPC_EMB_RELST_LO; break; - case BFD_RELOC_PPC_EMB_RELST_HI: ppc_reloc = R_PPC_EMB_RELST_HI; break; - case BFD_RELOC_PPC_EMB_RELST_HA: ppc_reloc = R_PPC_EMB_RELST_HA; break; - case BFD_RELOC_PPC_EMB_BIT_FLD: ppc_reloc = R_PPC_EMB_BIT_FLD; break; - case BFD_RELOC_PPC_EMB_RELSDA: ppc_reloc = R_PPC_EMB_RELSDA; break; - } - - return ppc_elf_howto_table[ (int)ppc_reloc ]; -}; - -/* Set the howto pointer for a PowerPC ELF reloc. */ - -static void -ppc_elf_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf32_Internal_Rela *dst; -{ - if (!ppc_elf_howto_table[ R_PPC_ADDR32 ]) /* Initialize howto table if needed */ - ppc_elf_howto_init (); - - BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_PPC_max); - cache_ptr->howto = ppc_elf_howto_table[ELF32_R_TYPE (dst->r_info)]; -} - -/* Function to set whether a module needs the -mrelocatable bit set. */ - -static boolean -ppc_elf_set_private_flags (abfd, flags) - bfd *abfd; - flagword flags; -{ - BFD_ASSERT (!elf_flags_init (abfd) - || elf_elfheader (abfd)->e_flags == flags); - - elf_elfheader (abfd)->e_flags = flags; - elf_flags_init (abfd) = true; - return true; -} - -/* Copy backend specific data from one object module to another */ -static boolean -ppc_elf_copy_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; -{ - /* This function is selected based on the input vector. We only - want to copy information over if the output BFD also uses Elf - format. */ - if (bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return true; - - BFD_ASSERT (!elf_flags_init (obfd) - || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags); - - elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; - elf_flags_init (obfd) = true; - return true; -} - -/* Merge backend specific data from an object file to the output - object file when linking */ -static boolean -ppc_elf_merge_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; -{ - flagword old_flags; - flagword new_flags; - boolean error; - - /* Check if we have the same endianess */ - if (ibfd->xvec->byteorder != obfd->xvec->byteorder - && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN) - { - (*_bfd_error_handler) - ("%s: compiled for a %s endian system and target is %s endian", - bfd_get_filename (ibfd), - bfd_big_endian (ibfd) ? "big" : "little", - bfd_big_endian (obfd) ? "big" : "little"); - - bfd_set_error (bfd_error_wrong_format); - return false; - } - - /* This function is selected based on the input vector. We only - want to copy information over if the output BFD also uses Elf - format. */ - if (bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return true; - - new_flags = elf_elfheader (ibfd)->e_flags; - old_flags = elf_elfheader (obfd)->e_flags; - if (!elf_flags_init (obfd)) /* First call, no flags set */ - { - elf_flags_init (obfd) = true; - elf_elfheader (obfd)->e_flags = new_flags; - } - - else if (new_flags == old_flags) /* Compatible flags are ok */ - ; - - else /* Incompatible flags */ - { - /* Warn about -mrelocatable mismatch. Allow -mrelocatable-lib to be linked - with either. */ - error = false; - if ((new_flags & EF_PPC_RELOCATABLE) != 0 - && (old_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0) - { - error = true; - (*_bfd_error_handler) - ("%s: compiled with -mrelocatable and linked with modules compiled normally", - bfd_get_filename (ibfd)); - } - else if ((new_flags & (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB)) == 0 - && (old_flags & EF_PPC_RELOCATABLE) != 0) - { - error = true; - (*_bfd_error_handler) - ("%s: compiled normally and linked with modules compiled with -mrelocatable", - bfd_get_filename (ibfd)); - } - else if ((new_flags & EF_PPC_RELOCATABLE_LIB) != 0) - elf_elfheader (obfd)->e_flags |= EF_PPC_RELOCATABLE_LIB; - - - /* Do not warn about eabi vs. V.4 mismatch, just or in the bit if any module uses it */ - elf_elfheader (obfd)->e_flags |= (new_flags & EF_PPC_EMB); - - new_flags &= ~ (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB | EF_PPC_EMB); - old_flags &= ~ (EF_PPC_RELOCATABLE | EF_PPC_RELOCATABLE_LIB | EF_PPC_EMB); - - /* Warn about any other mismatches */ - if (new_flags != old_flags) - { - error = true; - (*_bfd_error_handler) - ("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)", - bfd_get_filename (ibfd), (long)new_flags, (long)old_flags); - } - - if (error) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - } - - return true; -} - - -/* Handle a PowerPC specific section when reading an object file. This - is called when elfcode.h finds a section with an unknown type. */ - -static boolean -ppc_elf_section_from_shdr (abfd, hdr, name) - bfd *abfd; - Elf32_Internal_Shdr *hdr; - char *name; -{ - asection *newsect; - flagword flags; - - if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) - return false; - - newsect = hdr->bfd_section; - flags = bfd_get_section_flags (abfd, newsect); - if (hdr->sh_flags & SHF_EXCLUDE) - flags |= SEC_EXCLUDE; - - if (hdr->sh_type == SHT_ORDERED) - flags |= SEC_SORT_ENTRIES; - - bfd_set_section_flags (abfd, newsect, flags); - return true; -} - - -/* Set up any other section flags and such that may be necessary. */ - -boolean -ppc_elf_fake_sections (abfd, shdr, asect) - bfd *abfd; - Elf32_Internal_Shdr *shdr; - asection *asect; -{ - if ((asect->flags & SEC_EXCLUDE) != 0) - shdr->sh_flags |= SHF_EXCLUDE; - - if ((asect->flags & SEC_SORT_ENTRIES) != 0) - shdr->sh_type = SHT_ORDERED; -} - - -/* Create a special linker section */ -static elf_linker_section_t * -ppc_elf_create_linker_section (abfd, info, which) - bfd *abfd; - struct bfd_link_info *info; - enum elf_linker_section_enum which; -{ - bfd *dynobj = elf_hash_table (info)->dynobj; - elf_linker_section_t *lsect; - - /* Record the first bfd section that needs the special section */ - if (!dynobj) - dynobj = elf_hash_table (info)->dynobj = abfd; - - /* If this is the first time, create the section */ - lsect = elf_linker_section (dynobj, which); - if (!lsect) - { - elf_linker_section_t defaults; - static elf_linker_section_t zero_section; - - defaults = zero_section; - defaults.which = which; - defaults.hole_written_p = false; - defaults.alignment = 2; - defaults.flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - - switch (which) - { - default: - (*_bfd_error_handler) ("%s: Unknown special linker type %d", - bfd_get_filename (abfd), - (int)which); - - bfd_set_error (bfd_error_bad_value); - return (elf_linker_section_t *)0; - - case LINKER_SECTION_GOT: /* .got section */ - defaults.name = ".got"; - defaults.rel_name = ".rela.got"; - defaults.sym_name = "_GLOBAL_OFFSET_TABLE_"; - defaults.max_hole_offset = 32764; - defaults.hole_size = 16; - defaults.sym_offset = 4; - break; - - case LINKER_SECTION_SDATA: /* .sdata/.sbss section */ - defaults.name = ".sdata"; - defaults.rel_name = ".rela.sdata"; - defaults.bss_name = ".sbss"; - defaults.sym_name = "_SDA_BASE_"; - defaults.sym_offset = 32768; - break; - - case LINKER_SECTION_SDATA2: /* .sdata2/.sbss2 section */ - defaults.name = ".sdata2"; - defaults.rel_name = ".rela.sdata2"; - defaults.bss_name = ".sbss2"; - defaults.sym_name = "_SDA2_BASE_"; - defaults.sym_offset = 32768; - defaults.flags |= SEC_READONLY; - break; - } - - lsect = _bfd_elf_create_linker_section (abfd, info, which, &defaults); - } - - return lsect; -} - - -/* If we have a non-zero sized .sbss2 or .PPC.EMB.sbss0 sections, we need to bump up - the number of section headers. */ - -static int -ppc_elf_additional_program_headers (abfd) - bfd *abfd; -{ - asection *s; - int ret; - - ret = 0; - - s = bfd_get_section_by_name (abfd, ".sbss2"); - if (s != NULL && (s->flags & SEC_LOAD) != 0 && s->_raw_size > 0) - ++ret; - - s = bfd_get_section_by_name (abfd, ".PPC.EMB.sbss0"); - if (s != NULL && (s->flags & SEC_LOAD) != 0 && s->_raw_size > 0) - ++ret; - - return ret; -} - -/* Modify the segment map if needed */ - -static boolean -ppc_elf_modify_segment_map (abfd) - bfd *abfd; -{ - return true; -} - -/* Adjust a symbol defined by a dynamic object and referenced by a - regular object. The current definition is in some section of the - dynamic object, but we're not including those sections. We have to - change the definition to something the rest of the link can - understand. */ - -static boolean -ppc_elf_adjust_dynamic_symbol (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; -{ -#ifdef DEBUG - fprintf (stderr, "ppc_elf_adjust_dynamic_symbol called\n"); -#endif - return true; -} - - -/* Increment the index of a dynamic symbol by a given amount. Called - via elf_link_hash_traverse. */ - -static boolean -ppc_elf_adjust_dynindx (h, cparg) - struct elf_link_hash_entry *h; - PTR cparg; -{ - int *cp = (int *) cparg; - -#ifdef DEBUG - fprintf (stderr, "ppc_elf_adjust_dynindx called, h->dynindx = %d, *cp = %d\n", h->dynindx, *cp); -#endif - - if (h->dynindx != -1) - h->dynindx += *cp; - - return true; -} - - -/* Set the sizes of the dynamic sections. */ - -static boolean -ppc_elf_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *s; - boolean reltext; - boolean relplt; - -#ifdef DEBUG - fprintf (stderr, "ppc_elf_size_dynamic_sections called\n"); -#endif - - dynobj = elf_hash_table (info)->dynobj; - BFD_ASSERT (dynobj != NULL); - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Set the contents of the .interp section to the interpreter. */ - if (! info->shared) - { - s = bfd_get_section_by_name (dynobj, ".interp"); - BFD_ASSERT (s != NULL); - s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; - s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; - } - - /* Make space for the trailing nop in .plt. */ - s = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (s != NULL); - if (s->_raw_size > 0) - s->_raw_size += 4; - } - else - { - /* We may have created entries in the .rela.got, .rela.sdata, and - .rela.sdata2 section2. However, if we are not creating the - dynamic sections, we will not actually use these entries. Reset - the size of .rela.got, et al, which will cause it to get - stripped from the output file below. */ - static char *rela_sections[] = { ".rela.got", ".rela.sdata", ".rela.sdata", (char *)0 }; - char **p; - - for (p = rela_sections; *p != (char *)0; p++) - { - s = bfd_get_section_by_name (dynobj, *p); - if (s != NULL) - s->_raw_size = 0; - } - } - - /* The check_relocs and adjust_dynamic_symbol entry points have - determined the sizes of the various dynamic sections. Allocate - memory for them. */ - reltext = false; - relplt = false; - for (s = dynobj->sections; s != NULL; s = s->next) - { - const char *name; - boolean strip; - - if ((s->flags & SEC_IN_MEMORY) == 0) - continue; - - /* It's OK to base decisions on the section name, because none - of the dynobj section names depend upon the input files. */ - name = bfd_get_section_name (dynobj, s); - - strip = false; - -#if 0 - if (strncmp (name, ".rela", 5) == 0) - { - if (s->_raw_size == 0) - { - /* If we don't need this section, strip it from the - output file. This is to handle .rela.bss and - .rel.plt. We must create it in - create_dynamic_sections, because it must be created - before the linker maps input sections to output - sections. The linker does that before - adjust_dynamic_symbol is called, and it is that - function which decides whether anything needs to go - into these sections. */ - strip = true; - } - else - { - asection *target; - - /* If this relocation section applies to a read only - section, then we probably need a DT_TEXTREL entry. */ - target = bfd_get_section_by_name (output_bfd, name + 5); - if (target != NULL - && (target->flags & SEC_READONLY) != 0) - reltext = true; - - if (strcmp (name, ".rela.plt") == 0) - relplt = true; - - /* We use the reloc_count field as a counter if we need - to copy relocs into the output file. */ - s->reloc_count = 0; - } - } - else -#endif - if (strcmp (name, ".plt") != 0 - && strcmp (name, ".got") != 0 - && strcmp (name, ".sdata") != 0 - && strcmp (name, ".sdata2") != 0 - && strcmp (name, ".rela.sdata") != 0 - && strcmp (name, ".rela.sdata2") != 0) - { - /* It's not one of our sections, so don't allocate space. */ - continue; - } - - if (strip) - { - asection **spp; - - for (spp = &s->output_section->owner->sections; - *spp != s->output_section; - spp = &(*spp)->next) - ; - *spp = s->output_section->next; - --s->output_section->owner->section_count; - - continue; - } - - /* Allocate memory for the section contents. */ - s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) - return false; - } - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in ppc_elf_finish_dynamic_sections, but we - must add the entries now so that we get the correct size for - the .dynamic section. The DT_DEBUG entry is filled in by the - dynamic linker and used by the debugger. */ - if (! info->shared) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0)) - return false; - } - - if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)) - return false; - - if (relplt) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_RELA) - || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0)) - return false; - } - - if (! bfd_elf32_add_dynamic_entry (info, DT_RELA, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_RELASZ, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_RELAENT, - sizeof (Elf32_External_Rela))) - return false; - - if (reltext) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0)) - return false; - } - } - - /* If we are generating a shared library, we generate a section - symbol for each output section. These are local symbols, which - means that they must come first in the dynamic symbol table. - That means we must increment the dynamic symbol index of every - other dynamic symbol. */ - if (info->shared) - { - int c, i; - - c = bfd_count_sections (output_bfd); - elf_link_hash_traverse (elf_hash_table (info), - ppc_elf_adjust_dynindx, - (PTR) &c); - elf_hash_table (info)->dynsymcount += c; - - for (i = 1, s = output_bfd->sections; s != NULL; s = s->next, i++) - { - elf_section_data (s)->dynindx = i; - /* These symbols will have no names, so we don't need to - fiddle with dynstr_index. */ - } - } - - return true; -} - - -/* Look through the relocs for a section during the first phase, and - allocate space in the global offset table or procedure linkage - table. */ - -static boolean -ppc_elf_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; -{ - bfd *dynobj; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - const Elf_Internal_Rela *rel; - const Elf_Internal_Rela *rel_end; - elf_linker_section_t *got; - elf_linker_section_t *sdata; - elf_linker_section_t *sdata2; - asection *sreloc; - - if (info->relocateable) - return true; - -#ifdef DEBUG - fprintf (stderr, "ppc_elf_check_relocs called for section %s\n", - bfd_get_section_name (abfd, sec)); -#endif - - /* Create the linker generated sections all the time so that the special - symbols are created. */ - if ((got = elf_linker_section (abfd, LINKER_SECTION_GOT)) == NULL) - { - got = ppc_elf_create_linker_section (abfd, info, LINKER_SECTION_GOT); - if (!got) - return false; - } - - if ((sdata = elf_linker_section (abfd, LINKER_SECTION_SDATA)) == NULL) - { - sdata = ppc_elf_create_linker_section (abfd, info, LINKER_SECTION_SDATA); - if (!sdata) - return false; - } - - - if ((sdata2 = elf_linker_section (abfd, LINKER_SECTION_SDATA2)) == NULL) - { - sdata2 = ppc_elf_create_linker_section (abfd, info, LINKER_SECTION_SDATA2); - if (!sdata2) - return false; - } - - dynobj = elf_hash_table (info)->dynobj; - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (abfd); - - sreloc = NULL; - - rel_end = relocs + sec->reloc_count; - for (rel = relocs; rel < rel_end; rel++) - { - unsigned long r_symndx; - struct elf_link_hash_entry *h; - - r_symndx = ELF32_R_SYM (rel->r_info); - if (r_symndx < symtab_hdr->sh_info) - h = NULL; - else - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - - switch (ELF32_R_TYPE (rel->r_info)) - { - default: - break; - - /* GOT16 relocations */ - case R_PPC_GOT16: - case R_PPC_GOT16_LO: - case R_PPC_GOT16_HI: - case R_PPC_GOT16_HA: - if (got->rel_section == NULL - && (h != NULL || info->shared) - && !_bfd_elf_make_linker_section_rela (dynobj, got, 2)) - return false; - - if (!bfd_elf32_create_pointer_linker_section (abfd, info, got, h, rel)) - return false; - - break; - - /* Indirect .sdata relocation */ - case R_PPC_EMB_SDAI16: - if (got->rel_section == NULL - && (h != NULL || info->shared) - && !_bfd_elf_make_linker_section_rela (dynobj, got, 2)) - return false; - - if (!bfd_elf32_create_pointer_linker_section (abfd, info, sdata, h, rel)) - return false; - - break; - - /* Indirect .sdata2 relocation */ - case R_PPC_EMB_SDA2I16: - if (got->rel_section == NULL - && (h != NULL || info->shared) - && !_bfd_elf_make_linker_section_rela (dynobj, got, 2)) - return false; - - if (!bfd_elf32_create_pointer_linker_section (abfd, info, sdata2, h, rel)) - return false; - - break; - -#if 0 - case R_PPC_PLT32: - case R_PPC_PLTREL24: - case R_PPC_PLT16_LO: - case R_PPC_PLT16_HI: - case R_PPC_PLT16_HA: -#ifdef DEBUG - fprintf (stderr, "Reloc requires a PLT entry\n"); -#endif - /* This symbol requires a procedure linkage table entry. We - actually build the entry in adjust_dynamic_symbol, - because this might be a case of linking PIC code without - linking in any dynamic objects, in which case we don't - need to generate a procedure linkage table after all. */ - - if (h == NULL) - { - /* It does not make sense to have a procedure linkage - table entry for a local symbol. */ - bfd_set_error (bfd_error_bad_value); - return false; - } - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; - break; - - case R_SPARC_PC10: - case R_SPARC_PC22: - if (h != NULL - && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) - break; - /* Fall through. */ - case R_SPARC_DISP8: - case R_SPARC_DISP16: - case R_SPARC_DISP32: - case R_SPARC_WDISP30: - case R_SPARC_WDISP22: - if (h == NULL) - break; - /* Fall through. */ - case R_SPARC_8: - case R_SPARC_16: - case R_SPARC_32: - case R_SPARC_HI22: - case R_SPARC_22: - case R_SPARC_13: - case R_SPARC_LO10: - case R_SPARC_UA32: - if (info->shared - && (sec->flags & SEC_ALLOC) != 0) - { - /* When creating a shared object, we must copy these - relocs into the output file. We create a reloc - section in dynobj and make room for the reloc. */ - if (sreloc == NULL) - { - const char *name; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return false; - - BFD_ASSERT (strncmp (name, ".rela", 5) == 0 - && strcmp (bfd_get_section_name (abfd, sec), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - if (sreloc == NULL) - { - sreloc = bfd_make_section (dynobj, name); - if (sreloc == NULL - || ! bfd_set_section_flags (dynobj, sreloc, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, sreloc, 2)) - return false; - } - } - - sreloc->_raw_size += sizeof (Elf32_External_Rela); - } - - break; -#endif - } - } - - return true; -} - - -/* Hook called by the linker routine which adds symbols from an object - file. We use it to put .comm items in .sbss, and not .bss. */ - -/*ARGSUSED*/ -static boolean -ppc_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) - bfd *abfd; - struct bfd_link_info *info; - const Elf_Internal_Sym *sym; - const char **namep; - flagword *flagsp; - asection **secp; - bfd_vma *valp; -{ - if (sym->st_shndx == SHN_COMMON && sym->st_size <= bfd_get_gp_size (abfd)) - { - /* Common symbols less than or equal to -G nn bytes are automatically - put into .sdata. */ - elf_linker_section_t *sdata = ppc_elf_create_linker_section (abfd, info, LINKER_SECTION_SDATA); - if (!sdata->bss_section) - { - sdata->bss_section = bfd_make_section (elf_hash_table (info)->dynobj, sdata->bss_name); - sdata->bss_section->flags = (sdata->bss_section->flags & ~SEC_LOAD) | SEC_IS_COMMON; - } - - *secp = sdata->bss_section; - *valp = sym->st_size; - } - - return true; -} - - -/* Finish up dynamic symbol handling. We set the contents of various - dynamic sections here. */ - -static boolean -ppc_elf_finish_dynamic_symbol (output_bfd, info, h, sym) - bfd *output_bfd; - struct bfd_link_info *info; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; -{ - bfd *dynobj; - -#ifdef DEBUG - fprintf (stderr, "ppc_elf_finish_dynamic_symbol called for %s\n", h->root.root.string); -#endif - - dynobj = elf_hash_table (info)->dynobj; - BFD_ASSERT (dynobj != NULL); - - if (h->plt_offset != (bfd_vma) -1) - { - asection *splt; - asection *srela; - Elf_Internal_Rela rela; - - /* This symbol has an entry in the procedure linkage table. Set - it up. */ - - BFD_ASSERT (h->dynindx != -1); - - splt = bfd_get_section_by_name (dynobj, ".plt"); - srela = bfd_get_section_by_name (dynobj, ".rela.plt"); - BFD_ASSERT (splt != NULL && srela != NULL); - - /* Fill in the entry in the procedure linkage table. */ -#if 0 - bfd_put_32 (output_bfd, - PLT_ENTRY_WORD0 + h->plt_offset, - splt->contents + h->plt_offset); - bfd_put_32 (output_bfd, - (PLT_ENTRY_WORD1 - + (((- (h->plt_offset + 4)) >> 2) & 0x3fffff)), - splt->contents + h->plt_offset + 4); - bfd_put_32 (output_bfd, PLT_ENTRY_WORD2, - splt->contents + h->plt_offset + 8); - - /* Fill in the entry in the .rela.plt section. */ - rela.r_offset = (splt->output_section->vma - + splt->output_offset - + h->plt_offset); - rela.r_info = ELF32_R_INFO (h->dynindx, R_SPARC_JMP_SLOT); - rela.r_addend = 0; - bfd_elf32_swap_reloca_out (output_bfd, &rela, - ((Elf32_External_Rela *) srela->contents - + h->plt_offset / PLT_ENTRY_SIZE - 4)); -#endif - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - /* Mark the symbol as undefined, rather than as defined in - the .plt section. Leave the value alone. */ - sym->st_shndx = SHN_UNDEF; - } - } - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0) - { - asection *s; - Elf_Internal_Rela rela; - - /* This symbols needs a copy reloc. Set it up. */ - - BFD_ASSERT (h->dynindx != -1); - - s = bfd_get_section_by_name (h->root.u.def.section->owner, - ".rela.bss"); - BFD_ASSERT (s != NULL); - - rela.r_offset = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_COPY); - rela.r_addend = 0; - bfd_elf32_swap_reloca_out (output_bfd, &rela, - ((Elf32_External_Rela *) s->contents - + s->reloc_count)); - ++s->reloc_count; - } - - /* Mark some specially defined symbols as absolute. */ - if (strcmp (h->root.root.string, "_DYNAMIC") == 0 - || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0 - || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0) - sym->st_shndx = SHN_ABS; - - return true; -} - - -/* Finish up the dynamic sections. */ - -static boolean -ppc_elf_finish_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - asection *sdyn; - bfd *dynobj = elf_hash_table (info)->dynobj; - elf_linker_section_t *got = elf_linker_section (dynobj, LINKER_SECTION_GOT); - -#ifdef DEBUG - fprintf (stderr, "ppc_elf_finish_dynamic_sections called\n"); -#endif - - sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); - - if (elf_hash_table (info)->dynamic_sections_created) - { - asection *splt; - Elf32_External_Dyn *dyncon, *dynconend; - - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL && sdyn != NULL); - - dyncon = (Elf32_External_Dyn *) sdyn->contents; - dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size); - for (; dyncon < dynconend; dyncon++) - { - Elf_Internal_Dyn dyn; - const char *name; - boolean size; - - bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn); - - switch (dyn.d_tag) - { - case DT_PLTGOT: name = ".plt"; size = false; break; - case DT_PLTRELSZ: name = ".rela.plt"; size = true; break; - case DT_JMPREL: name = ".rela.plt"; size = false; break; - default: name = NULL; size = false; break; - } - - if (name != NULL) - { - asection *s; - - s = bfd_get_section_by_name (output_bfd, name); - if (s == NULL) - dyn.d_un.d_val = 0; - else - { - if (! size) - dyn.d_un.d_ptr = s->vma; - else - { - if (s->_cooked_size != 0) - dyn.d_un.d_val = s->_cooked_size; - else - dyn.d_un.d_val = s->_raw_size; - } - } - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - } - } - } - - /* Add a blrl instruction at _GLOBAL_OFFSET_TABLE_-4 so that a function can - easily find the address of the _GLOBAL_OFFSET_TABLE_. */ - if (got) - { - unsigned char *contents = got->section->contents + got->hole_offset; - bfd_put_32 (output_bfd, 0x4e800021 /* blrl */, contents); - - if (sdyn == NULL) - bfd_put_32 (output_bfd, (bfd_vma) 0, contents+4); - else - bfd_put_32 (output_bfd, - sdyn->output_section->vma + sdyn->output_offset, - contents+4); - - elf_section_data (got->section->output_section)->this_hdr.sh_entsize = 4; - } - - if (info->shared) - { - asection *sdynsym; - asection *s; - Elf_Internal_Sym sym; - - /* Set up the section symbols for the output sections. */ - - sdynsym = bfd_get_section_by_name (dynobj, ".dynsym"); - BFD_ASSERT (sdynsym != NULL); - - sym.st_size = 0; - sym.st_name = 0; - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); - sym.st_other = 0; - - for (s = output_bfd->sections; s != NULL; s = s->next) - { - int indx; - - sym.st_value = s->vma; - - indx = elf_section_data (s)->this_idx; - BFD_ASSERT (indx > 0); - sym.st_shndx = indx; - - bfd_elf32_swap_symbol_out (output_bfd, &sym, - (PTR) (((Elf32_External_Sym *) - sdynsym->contents) - + elf_section_data (s)->dynindx)); - } - - /* Set the sh_info field of the output .dynsym section to the - index of the first global symbol. */ - elf_section_data (sdynsym->output_section)->this_hdr.sh_info = - bfd_count_sections (output_bfd) + 1; - } - - return true; -} - - -/* The RELOCATE_SECTION function is called by the ELF backend linker - to handle the relocations for a section. - - The relocs are always passed as Rela structures; if the section - actually uses Rel structures, the r_addend field will always be - zero. - - This function is responsible for adjust the section contents as - necessary, and (if using Rela relocs and generating a - relocateable output file) adjusting the reloc addend as - necessary. - - This function does not have to worry about setting the reloc - address or the reloc symbol index. - - LOCAL_SYMS is a pointer to the swapped in local symbols. - - LOCAL_SECTIONS is an array giving the section in the input file - corresponding to the st_shndx field of each local symbol. - - The global hash table entry for the global symbols can be found - via elf_sym_hashes (input_bfd). - - When generating relocateable output, this function must handle - STB_LOCAL/STT_SECTION symbols specially. The output symbol is - going to be the section symbol corresponding to the output - section, which means that the addend must be adjusted - accordingly. */ - -static boolean -ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; -{ - Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd); - bfd *dynobj = elf_hash_table (info)->dynobj; - elf_linker_section_t *got = (dynobj) ? elf_linker_section (dynobj, LINKER_SECTION_GOT) : NULL; - elf_linker_section_t *sdata = (dynobj) ? elf_linker_section (dynobj, LINKER_SECTION_SDATA) : NULL; - elf_linker_section_t *sdata2 = (dynobj) ? elf_linker_section (dynobj, LINKER_SECTION_SDATA2) : NULL; - Elf_Internal_Rela *rel = relocs; - Elf_Internal_Rela *relend = relocs + input_section->reloc_count; - boolean ret = true; - long insn; - -#ifdef DEBUG - fprintf (stderr, "ppc_elf_relocate_section called for %s section %s, %ld relocations%s\n", - bfd_get_filename (input_bfd), - bfd_section_name(input_bfd, input_section), - (long)input_section->reloc_count, - (info->relocateable) ? " (relocatable)" : ""); -#endif - - if (!ppc_elf_howto_table[ R_PPC_ADDR32 ]) /* Initialize howto table if needed */ - ppc_elf_howto_init (); - - for (; rel < relend; rel++) - { - enum ppc_reloc_type r_type = (enum ppc_reloc_type)ELF32_R_TYPE (rel->r_info); - bfd_vma offset = rel->r_offset; - bfd_vma addend = rel->r_addend; - bfd_reloc_status_type r = bfd_reloc_other; - Elf_Internal_Sym *sym = (Elf_Internal_Sym *)0; - asection *sec = (asection *)0; - struct elf_link_hash_entry *h = (struct elf_link_hash_entry *)0; - const char *sym_name = (const char *)0; - reloc_howto_type *howto; - unsigned long r_symndx; - bfd_vma relocation; - - /* Unknown relocation handling */ - if ((unsigned)r_type >= (unsigned)R_PPC_max || !ppc_elf_howto_table[(int)r_type]) - { - (*_bfd_error_handler) ("%s: unknown relocation type %d", - bfd_get_filename (input_bfd), - (int)r_type); - - bfd_set_error (bfd_error_bad_value); - ret = false; - continue; - } - - howto = ppc_elf_howto_table[(int)r_type]; - r_symndx = ELF32_R_SYM (rel->r_info); - - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if ((unsigned)ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - sec = local_sections[r_symndx]; - addend = rel->r_addend += sec->output_offset + sym->st_value; - } - } - -#ifdef DEBUG - fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n", - howto->name, - (int)r_type, - r_symndx, - (long)offset, - (long)addend); -#endif - continue; - } - - /* This is a final link. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - sec = local_sections[r_symndx]; - sym_name = "<local symbol>"; - - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); - } - else - { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - sym_name = h->root.root.string; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else if (info->shared) - relocation = 0; - else - { - (*info->callbacks->undefined_symbol)(info, - h->root.root.string, - input_bfd, - input_section, - rel->r_offset); - ret = false; - continue; - } - } - - switch ((int)r_type) - { - default: - (*_bfd_error_handler) ("%s: unknown relocation type %d for symbol %s", - bfd_get_filename (input_bfd), - (int)r_type, sym_name); - - bfd_set_error (bfd_error_bad_value); - ret = false; - continue; - - /* relocations that need no special processing */ - case (int)R_PPC_NONE: - case (int)R_PPC_ADDR32: - case (int)R_PPC_ADDR24: - case (int)R_PPC_ADDR16: - case (int)R_PPC_ADDR16_LO: - case (int)R_PPC_ADDR16_HI: - case (int)R_PPC_ADDR14: - case (int)R_PPC_REL24: - case (int)R_PPC_REL14: - case (int)R_PPC_UADDR32: - case (int)R_PPC_UADDR16: - case (int)R_PPC_REL32: - break; - - /* branch taken prediction relocations */ - case (int)R_PPC_ADDR14_BRTAKEN: - case (int)R_PPC_REL14_BRTAKEN: - insn = bfd_get_32 (output_bfd, contents + offset); - if ((relocation - offset) & 0x8000) - insn &= ~BRANCH_PREDICT_BIT; - else - insn |= BRANCH_PREDICT_BIT; - bfd_put_32 (output_bfd, insn, contents + offset); - break; - - /* branch not taken predicition relocations */ - case (int)R_PPC_ADDR14_BRNTAKEN: - case (int)R_PPC_REL14_BRNTAKEN: - insn = bfd_get_32 (output_bfd, contents + offset); - if ((relocation - offset) & 0x8000) - insn |= BRANCH_PREDICT_BIT; - else - insn &= ~BRANCH_PREDICT_BIT; - bfd_put_32 (output_bfd, insn, contents + offset); - break; - - /* GOT16 relocations */ - case (int)R_PPC_GOT16: - case (int)R_PPC_GOT16_LO: - case (int)R_PPC_GOT16_HI: - case (int)R_PPC_GOT16_HA: - relocation = bfd_elf32_finish_pointer_linker_section (output_bfd, input_bfd, info, - got, h, relocation, rel, - R_PPC_RELATIVE); - break; - - /* Indirect .sdata relocation */ - case (int)R_PPC_EMB_SDAI16: - BFD_ASSERT (sdata != NULL); - relocation = bfd_elf32_finish_pointer_linker_section (output_bfd, input_bfd, info, - sdata, h, relocation, rel, - R_PPC_RELATIVE); - break; - - /* Indirect .sdata2 relocation */ - case (int)R_PPC_EMB_SDA2I16: - BFD_ASSERT (sdata2 != NULL); - relocation = bfd_elf32_finish_pointer_linker_section (output_bfd, input_bfd, info, - sdata2, h, relocation, rel, - R_PPC_RELATIVE); - break; - - /* Handle the TOC16 reloc. We want to use the offset within the .got - section, not the actual VMA. This is appropriate when generating - an embedded ELF object, for which the .got section acts like the - AIX .toc section. */ - case (int)R_PPC_TOC16: /* phony GOT16 relocations */ - BFD_ASSERT (sec != (asection *)0); - BFD_ASSERT (bfd_is_und_section (sec) - || strcmp (bfd_get_section_name (abfd, sec), ".got") == 0 - || strcmp (bfd_get_section_name (abfd, sec), ".cgot") == 0) - - addend -= sec->output_section->vma + sec->output_offset + 0x8000; - break; - - /* arithmetic adjust relocations */ - case (int)R_PPC_ADDR16_HA: - BFD_ASSERT (sec != (asection *)0); - addend += ((relocation + addend) & 0x8000) << 1; - break; - - /* relocate against _SDA_BASE_ */ - case (int)R_PPC_SDAREL16: - BFD_ASSERT (sec != (asection *)0); - if (strcmp (bfd_get_section_name (abfd, sec), ".sdata") != 0 - && strcmp (bfd_get_section_name (abfd, sec), ".sbss") != 0) - { - (*_bfd_error_handler) ("%s: The target (%s) of a %s relocation is in the wrong section (%s)", - bfd_get_filename (input_bfd), - sym_name, - ppc_elf_howto_table[ (int)r_type ]->name, - bfd_get_section_name (abfd, sec)); - - bfd_set_error (bfd_error_bad_value); - ret = false; - continue; - } - addend -= (sdata->sym_hash->root.u.def.value - + sdata->sym_hash->root.u.def.section->output_section->vma - + sdata->sym_hash->root.u.def.section->output_offset); - break; - - - /* relocate against _SDA2_BASE_ */ - case (int)R_PPC_EMB_SDA2REL: - BFD_ASSERT (sec != (asection *)0); - if (strcmp (bfd_get_section_name (abfd, sec), ".sdata2") != 0 - && strcmp (bfd_get_section_name (abfd, sec), ".sbss2") != 0) - { - (*_bfd_error_handler) ("%s: The target (%s) of a %s relocation is in the wrong section (%s)", - bfd_get_filename (input_bfd), - sym_name, - ppc_elf_howto_table[ (int)r_type ]->name, - bfd_get_section_name (abfd, sec)); - - bfd_set_error (bfd_error_bad_value); - ret = false; - continue; - } - addend -= (sdata2->sym_hash->root.u.def.value - + sdata2->sym_hash->root.u.def.section->output_section->vma - + sdata2->sym_hash->root.u.def.section->output_offset); - break; - - - /* relocate against either _SDA_BASE_, _SDA2_BASE_, or 0 */ - case (int)R_PPC_EMB_SDA21: - case (int)R_PPC_EMB_RELSDA: - { - const char *name = bfd_get_section_name (abfd, sec); - int reg; - - BFD_ASSERT (sec != (asection *)0); - if (strcmp (name, ".sdata") == 0 || strcmp (name, ".sbss") == 0) - { - reg = 13; - addend -= (sdata->sym_hash->root.u.def.value - + sdata->sym_hash->root.u.def.section->output_section->vma - + sdata->sym_hash->root.u.def.section->output_offset); - } - - else if (strcmp (name, ".sdata2") == 0 || strcmp (name, ".sbss2") == 0) - { - reg = 2; - addend -= (sdata2->sym_hash->root.u.def.value - + sdata2->sym_hash->root.u.def.section->output_section->vma - + sdata2->sym_hash->root.u.def.section->output_offset); - } - - else if (strcmp (name, ".PPC.EMB.sdata0") == 0 || strcmp (name, ".PPC.EMB.sbss0") == 0) - { - reg = 0; - } - - else - { - (*_bfd_error_handler) ("%s: The target (%s) of a %s relocation is in the wrong section (%s)", - bfd_get_filename (input_bfd), - sym_name, - ppc_elf_howto_table[ (int)r_type ]->name, - bfd_get_section_name (abfd, sec)); - - bfd_set_error (bfd_error_bad_value); - ret = false; - continue; - } - - if (r_type == R_PPC_EMB_SDA21) - { /* fill in register field */ - insn = bfd_get_32 (output_bfd, contents + offset); - insn = (insn & ~RA_REGISTER_MASK) | (reg << RA_REGISTER_SHIFT); - bfd_put_32 (output_bfd, insn, contents + offset); - } - } - break; - - /* Relocate against the beginning of the section */ - case (int)R_PPC_SECTOFF: - case (int)R_PPC_SECTOFF_LO: - case (int)R_PPC_SECTOFF_HI: - BFD_ASSERT (sec != (asection *)0); - addend -= sec->output_section->vma; - break; - - case (int)R_PPC_SECTOFF_HA: - BFD_ASSERT (sec != (asection *)0); - addend -= sec->output_section->vma; - addend += ((relocation + addend) & 0x8000) << 1; - break; - - /* Negative relocations */ - case (int)R_PPC_EMB_NADDR32: - case (int)R_PPC_EMB_NADDR16: - case (int)R_PPC_EMB_NADDR16_LO: - case (int)R_PPC_EMB_NADDR16_HI: - addend -= 2*relocation; - break; - - case (int)R_PPC_EMB_NADDR16_HA: - addend -= 2*relocation; - addend += ((relocation + addend) & 0x8000) << 1; - break; - - /* NOP relocation that prevents garbage collecting linkers from omitting a - reference. */ - case (int)R_PPC_EMB_MRKREF: - continue; - - case (int)R_PPC_PLTREL24: - case (int)R_PPC_COPY: - case (int)R_PPC_GLOB_DAT: - case (int)R_PPC_JMP_SLOT: - case (int)R_PPC_RELATIVE: - case (int)R_PPC_LOCAL24PC: - case (int)R_PPC_PLT32: - case (int)R_PPC_PLTREL32: - case (int)R_PPC_PLT16_LO: - case (int)R_PPC_PLT16_HI: - case (int)R_PPC_PLT16_HA: - case (int)R_PPC_EMB_RELSEC16: - case (int)R_PPC_EMB_RELST_LO: - case (int)R_PPC_EMB_RELST_HI: - case (int)R_PPC_EMB_RELST_HA: - case (int)R_PPC_EMB_BIT_FLD: - (*_bfd_error_handler) ("%s: Relocation %s is not yet supported for symbol %s.", - bfd_get_filename (input_bfd), - ppc_elf_howto_table[ (int)r_type ]->name, - sym_name); - - bfd_set_error (bfd_error_invalid_operation); - ret = false; - continue; - } - - -#ifdef DEBUG - fprintf (stderr, "\ttype = %s (%d), name = %s, symbol index = %ld, offset = %ld, addend = %ld\n", - howto->name, - (int)r_type, - sym_name, - r_symndx, - (long)offset, - (long)addend); -#endif - - r = _bfd_final_link_relocate (howto, - input_bfd, - input_section, - contents, - offset, - relocation, - addend); - - if (r != bfd_reloc_ok) - { - ret = false; - switch (r) - { - default: - break; - - case bfd_reloc_overflow: - { - const char *name; - - if (h != NULL) - name = h->root.root.string; - else - { - name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - if (name == NULL) - break; - - if (*name == '\0') - name = bfd_section_name (input_bfd, sec); - } - - (*info->callbacks->reloc_overflow)(info, - name, - howto->name, - (bfd_vma) 0, - input_bfd, - input_section, - offset); - } - break; - - } - } - } - - -#ifdef DEBUG - fprintf (stderr, "\n"); -#endif - - return ret; -} - - -#define TARGET_LITTLE_SYM bfd_elf32_powerpcle_vec -#define TARGET_LITTLE_NAME "elf32-powerpcle" -#define TARGET_BIG_SYM bfd_elf32_powerpc_vec -#define TARGET_BIG_NAME "elf32-powerpc" -#define ELF_ARCH bfd_arch_powerpc -#define ELF_MACHINE_CODE EM_PPC -#define ELF_MAXPAGESIZE 0x10000 -#define elf_info_to_howto ppc_elf_info_to_howto - -#ifdef EM_CYGNUS_POWERPC -#define ELF_MACHINE_ALT1 EM_CYGNUS_POWERPC -#endif - -#ifdef EM_PPC_OLD -#define ELF_MACHINE_ALT2 EM_PPC_OLD -#endif - -#define bfd_elf32_bfd_copy_private_bfd_data ppc_elf_copy_private_bfd_data -#define bfd_elf32_bfd_merge_private_bfd_data ppc_elf_merge_private_bfd_data -#define bfd_elf32_bfd_set_private_flags ppc_elf_set_private_flags -#define bfd_elf32_bfd_reloc_type_lookup ppc_elf_reloc_type_lookup -#define elf_backend_section_from_shdr ppc_elf_section_from_shdr -#define elf_backend_relocate_section ppc_elf_relocate_section -#define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections -#define elf_backend_check_relocs ppc_elf_check_relocs -#define elf_backend_adjust_dynamic_symbol ppc_elf_adjust_dynamic_symbol -#define elf_backend_add_symbol_hook ppc_elf_add_symbol_hook -#define elf_backend_size_dynamic_sections ppc_elf_size_dynamic_sections -#define elf_backend_finish_dynamic_symbol ppc_elf_finish_dynamic_symbol -#define elf_backend_finish_dynamic_sections ppc_elf_finish_dynamic_sections -#define elf_backend_fake_sections ppc_elf_fake_sections -#define elf_backend_additional_program_headers ppc_elf_additional_program_headers -#define elf_backend_modify_segment_map ppc_elf_modify_segment_map - -#include "elf32-target.h" diff --git a/contrib/gdb/bfd/elf32-sparc.c b/contrib/gdb/bfd/elf32-sparc.c deleted file mode 100644 index 918eb00..0000000 --- a/contrib/gdb/bfd/elf32-sparc.c +++ /dev/null @@ -1,1795 +0,0 @@ -/* SPARC-specific support for 32-bit ELF - Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "elf-bfd.h" -#include "elf/sparc.h" - -static reloc_howto_type *elf32_sparc_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static void elf_info_to_howto - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static boolean elf32_sparc_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static boolean elf32_sparc_adjust_dynamic_symbol - PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); -static boolean elf32_sparc_adjust_dynindx - PARAMS ((struct elf_link_hash_entry *, PTR)); -static boolean elf32_sparc_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf32_sparc_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static boolean elf32_sparc_finish_dynamic_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, - Elf_Internal_Sym *)); -static boolean elf32_sparc_finish_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf32_sparc_merge_private_bfd_data PARAMS ((bfd *, bfd *)); -static boolean elf32_sparc_object_p - PARAMS ((bfd *)); -static void elf32_sparc_final_write_processing - PARAMS ((bfd *, boolean)); - -/* The howto table and associated functions. - ??? elf64-sparc.c has its own copy for the moment to ease transition - since some of the relocation values have changed. At some point we'll - want elf64-sparc.c to switch over and use this table. - ??? Do we want to recognize (or flag as errors) some of the 64 bit entries - if the target is elf32-sparc. -*/ - -static bfd_reloc_status_type sparc_elf_notsupported_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_reloc_status_type sparc_elf_wdisp16_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); - -reloc_howto_type _bfd_sparc_elf_howto_table[] = -{ - HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", false,0,0x00000000,true), - HOWTO(R_SPARC_8, 0,0, 8,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_8", false,0,0x000000ff,true), - HOWTO(R_SPARC_16, 0,1,16,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_16", false,0,0x0000ffff,true), - HOWTO(R_SPARC_32, 0,2,32,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_32", false,0,0xffffffff,true), - HOWTO(R_SPARC_DISP8, 0,0, 8,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP8", false,0,0x000000ff,true), - HOWTO(R_SPARC_DISP16, 0,1,16,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP16", false,0,0x0000ffff,true), - HOWTO(R_SPARC_DISP32, 0,2,32,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP32", false,0,0x00ffffff,true), - HOWTO(R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP30", false,0,0x3fffffff,true), - HOWTO(R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP22", false,0,0x003fffff,true), - HOWTO(R_SPARC_HI22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HI22", false,0,0x003fffff,true), - HOWTO(R_SPARC_22, 0,2,22,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_22", false,0,0x003fffff,true), - HOWTO(R_SPARC_13, 0,2,13,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_13", false,0,0x00001fff,true), - HOWTO(R_SPARC_LO10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LO10", false,0,0x000003ff,true), - HOWTO(R_SPARC_GOT10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GOT10", false,0,0x000003ff,true), - HOWTO(R_SPARC_GOT13, 0,2,13,false,0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_GOT13", false,0,0x00001fff,true), - HOWTO(R_SPARC_GOT22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GOT22", false,0,0x003fffff,true), - HOWTO(R_SPARC_PC10, 0,2,10,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_PC10", false,0,0x000003ff,true), - HOWTO(R_SPARC_PC22, 10,2,22,true, 0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_PC22", false,0,0x003fffff,true), - HOWTO(R_SPARC_WPLT30, 2,2,30,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WPLT30", false,0,0x3fffffff,true), - HOWTO(R_SPARC_COPY, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_COPY", false,0,0x00000000,true), - HOWTO(R_SPARC_GLOB_DAT, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GLOB_DAT",false,0,0x00000000,true), - HOWTO(R_SPARC_JMP_SLOT, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_JMP_SLOT",false,0,0x00000000,true), - HOWTO(R_SPARC_RELATIVE, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_RELATIVE",false,0,0x00000000,true), - HOWTO(R_SPARC_UA32, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_UA32", false,0,0x00000000,true), - HOWTO(R_SPARC_PLT32, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PLT32", false,0,0x00000000,true), - HOWTO(R_SPARC_HIPLT22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_HIPLT22", false,0,0x00000000,true), - HOWTO(R_SPARC_LOPLT10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_LOPLT10", false,0,0x00000000,true), - HOWTO(R_SPARC_PCPLT32, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PCPLT32", false,0,0x00000000,true), - HOWTO(R_SPARC_PCPLT22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PCPLT22", false,0,0x00000000,true), - HOWTO(R_SPARC_PCPLT10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PCPLT10", false,0,0x00000000,true), - HOWTO(R_SPARC_10, 0,2,10,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_10", false,0,0x000003ff,true), - HOWTO(R_SPARC_11, 0,2,11,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_11", false,0,0x000007ff,true), - /* ??? If we need to handle R_SPARC_64 then we need (figuratively) - --enable-64-bit-bfd. That causes objdump to print address as 64 bits - which we really don't want on an elf32-sparc system. There may be other - consequences which we may not want (at least not until it's proven they're - necessary) so for now these are only enabled ifdef BFD64. */ -#ifdef BFD64 - HOWTO(R_SPARC_64, 0,4,00,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_64", false,0,~ (bfd_vma) 0, true), - /* ??? These don't make sense except in 64 bit systems so they're disabled - ifndef BFD64 too (for now). */ - HOWTO(R_SPARC_OLO10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_OLO10", false,0,0x000003ff,true), - HOWTO(R_SPARC_HH22, 42,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HH22", false,0,0x003fffff,true), - HOWTO(R_SPARC_HM10, 32,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HM10", false,0,0x000003ff,true), - HOWTO(R_SPARC_LM22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LM22", false,0,0x003fffff,true), - HOWTO(R_SPARC_PC_HH22, 42,2,22,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HH22", false,0,0x003fffff,true), - HOWTO(R_SPARC_PC_HM10, 32,2,10,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HM10", false,0,0x000003ff,true), - HOWTO(R_SPARC_PC_LM22, 10,2,22,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LM22", false,0,0x003fffff,true), -#else - HOWTO(R_SPARC_64, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_64", false,0,0x00000000,true), - HOWTO(R_SPARC_OLO10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_OLO10", false,0,0x00000000,true), - HOWTO(R_SPARC_HH22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_HH22", false,0,0x00000000,true), - HOWTO(R_SPARC_HM10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_HM10", false,0,0x00000000,true), - HOWTO(R_SPARC_LM22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_LM22", false,0,0x00000000,true), - HOWTO(R_SPARC_PC_HH22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PC_HH22", false,0,0x00000000,true), - HOWTO(R_SPARC_PC_HM10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PC_HM10", false,0,0x00000000,true), - HOWTO(R_SPARC_PC_LM22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PC_LM22", false,0,0x00000000,true), -#endif - HOWTO(R_SPARC_WDISP16, 2,2,16,true, 0,complain_overflow_signed, sparc_elf_wdisp16_reloc,"R_SPARC_WDISP16", false,0,0x00000000,true), - HOWTO(R_SPARC_WDISP19, 2,2,22,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP19", false,0,0x0007ffff,true), - HOWTO(R_SPARC_GLOB_JMP, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GLOB_DAT",false,0,0x00000000,true), - HOWTO(R_SPARC_7, 0,2, 7,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_7", false,0,0x0000007f,true), - HOWTO(R_SPARC_5, 0,2, 5,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_5", false,0,0x0000001f,true), - HOWTO(R_SPARC_6, 0,2, 6,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_6", false,0,0x0000003f,true), -}; - -struct elf_reloc_map { - unsigned char bfd_reloc_val; - unsigned char elf_reloc_val; -}; - -static CONST struct elf_reloc_map sparc_reloc_map[] = -{ - { BFD_RELOC_NONE, R_SPARC_NONE, }, - { BFD_RELOC_16, R_SPARC_16, }, - { BFD_RELOC_8, R_SPARC_8 }, - { BFD_RELOC_8_PCREL, R_SPARC_DISP8 }, - /* ??? This might cause us to need separate functions in elf{32,64}-sparc.c - (we could still have just one table), but is this reloc ever used? */ - { BFD_RELOC_CTOR, R_SPARC_32 }, /* @@ Assumes 32 bits. */ - { BFD_RELOC_32, R_SPARC_32 }, - { BFD_RELOC_32_PCREL, R_SPARC_DISP32 }, - { BFD_RELOC_HI22, R_SPARC_HI22 }, - { BFD_RELOC_LO10, R_SPARC_LO10, }, - { BFD_RELOC_32_PCREL_S2, R_SPARC_WDISP30 }, - { BFD_RELOC_SPARC22, R_SPARC_22 }, - { BFD_RELOC_SPARC13, R_SPARC_13 }, - { BFD_RELOC_SPARC_GOT10, R_SPARC_GOT10 }, - { BFD_RELOC_SPARC_GOT13, R_SPARC_GOT13 }, - { BFD_RELOC_SPARC_GOT22, R_SPARC_GOT22 }, - { BFD_RELOC_SPARC_PC10, R_SPARC_PC10 }, - { BFD_RELOC_SPARC_PC22, R_SPARC_PC22 }, - { BFD_RELOC_SPARC_WPLT30, R_SPARC_WPLT30 }, - { BFD_RELOC_SPARC_COPY, R_SPARC_COPY }, - { BFD_RELOC_SPARC_GLOB_DAT, R_SPARC_GLOB_DAT }, - { BFD_RELOC_SPARC_JMP_SLOT, R_SPARC_JMP_SLOT }, - { BFD_RELOC_SPARC_RELATIVE, R_SPARC_RELATIVE }, - { BFD_RELOC_SPARC_WDISP22, R_SPARC_WDISP22 }, - /* ??? Doesn't dwarf use this? */ -/*{ BFD_RELOC_SPARC_UA32, R_SPARC_UA32 }, not used?? */ - {BFD_RELOC_SPARC_10, R_SPARC_10}, - {BFD_RELOC_SPARC_11, R_SPARC_11}, - {BFD_RELOC_SPARC_64, R_SPARC_64}, - {BFD_RELOC_SPARC_OLO10, R_SPARC_OLO10}, - {BFD_RELOC_SPARC_HH22, R_SPARC_HH22}, - {BFD_RELOC_SPARC_HM10, R_SPARC_HM10}, - {BFD_RELOC_SPARC_LM22, R_SPARC_LM22}, - {BFD_RELOC_SPARC_PC_HH22, R_SPARC_PC_HH22}, - {BFD_RELOC_SPARC_PC_HM10, R_SPARC_PC_HM10}, - {BFD_RELOC_SPARC_PC_LM22, R_SPARC_PC_LM22}, - {BFD_RELOC_SPARC_WDISP16, R_SPARC_WDISP16}, - {BFD_RELOC_SPARC_WDISP19, R_SPARC_WDISP19}, - {BFD_RELOC_SPARC_GLOB_JMP, R_SPARC_GLOB_JMP}, - {BFD_RELOC_SPARC_7, R_SPARC_7}, - {BFD_RELOC_SPARC_5, R_SPARC_5}, - {BFD_RELOC_SPARC_6, R_SPARC_6}, -}; - -static reloc_howto_type * -elf32_sparc_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - unsigned int i; - for (i = 0; i < sizeof (sparc_reloc_map) / sizeof (struct elf_reloc_map); i++) - { - if (sparc_reloc_map[i].bfd_reloc_val == code) - return &_bfd_sparc_elf_howto_table[(int) sparc_reloc_map[i].elf_reloc_val]; - } - return 0; -} - -/* We need to use ELF32_R_TYPE so we have our own copy of this function, - and elf64-sparc.c has its own copy. */ - -static void -elf_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf_Internal_Rela *dst; -{ - BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_SPARC_max); - cache_ptr->howto = &_bfd_sparc_elf_howto_table[ELF32_R_TYPE(dst->r_info)]; -} - -/* For unsupported relocs. */ - -static bfd_reloc_status_type -sparc_elf_notsupported_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - return bfd_reloc_notsupported; -} - -/* Handle the WDISP16 reloc. */ - -static bfd_reloc_status_type -sparc_elf_wdisp16_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_vma relocation; - bfd_vma x; - - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && (! reloc_entry->howto->partial_inplace - || reloc_entry->addend == 0)) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - if (output_bfd != NULL) - return bfd_reloc_continue; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - relocation = (symbol->value - + symbol->section->output_section->vma - + symbol->section->output_offset); - relocation += reloc_entry->addend; - relocation -= (input_section->output_section->vma - + input_section->output_offset); - relocation -= reloc_entry->address; - - x = bfd_get_32 (abfd, (char *) data + reloc_entry->address); - x |= ((((relocation >> 2) & 0xc000) << 6) - | ((relocation >> 2) & 0x3fff)); - bfd_put_32 (abfd, x, (char *) data + reloc_entry->address); - - if ((bfd_signed_vma) relocation < - 0x40000 - || (bfd_signed_vma) relocation > 0x3ffff) - return bfd_reloc_overflow; - else - return bfd_reloc_ok; -} - -/* Functions for the SPARC ELF linker. */ - -/* The name of the dynamic interpreter. This is put in the .interp - section. */ - -#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" - -/* The nop opcode we use. */ - -#define SPARC_NOP 0x01000000 - -/* The size in bytes of an entry in the procedure linkage table. */ - -#define PLT_ENTRY_SIZE 12 - -/* The first four entries in a procedure linkage table are reserved, - and the initial contents are unimportant (we zero them out). - Subsequent entries look like this. See the SVR4 ABI SPARC - supplement to see how this works. */ - -/* sethi %hi(.-.plt0),%g1. We fill in the address later. */ -#define PLT_ENTRY_WORD0 0x03000000 -/* b,a .plt0. We fill in the offset later. */ -#define PLT_ENTRY_WORD1 0x30800000 -/* nop. */ -#define PLT_ENTRY_WORD2 SPARC_NOP - -/* Look through the relocs for a section during the first phase, and - allocate space in the global offset table or procedure linkage - table. */ - -static boolean -elf32_sparc_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; -{ - bfd *dynobj; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - bfd_vma *local_got_offsets; - const Elf_Internal_Rela *rel; - const Elf_Internal_Rela *rel_end; - asection *sgot; - asection *srelgot; - asection *sreloc; - - if (info->relocateable) - return true; - - dynobj = elf_hash_table (info)->dynobj; - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (abfd); - local_got_offsets = elf_local_got_offsets (abfd); - - sgot = NULL; - srelgot = NULL; - sreloc = NULL; - - rel_end = relocs + sec->reloc_count; - for (rel = relocs; rel < rel_end; rel++) - { - unsigned long r_symndx; - struct elf_link_hash_entry *h; - - r_symndx = ELF32_R_SYM (rel->r_info); - if (r_symndx < symtab_hdr->sh_info) - h = NULL; - else - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_SPARC_GOT10: - case R_SPARC_GOT13: - case R_SPARC_GOT22: - /* This symbol requires a global offset table entry. */ - - if (dynobj == NULL) - { - /* Create the .got section. */ - elf_hash_table (info)->dynobj = dynobj = abfd; - if (! _bfd_elf_create_got_section (dynobj, info)) - return false; - } - - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - } - - if (srelgot == NULL - && (h != NULL || info->shared)) - { - srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); - if (srelgot == NULL) - { - srelgot = bfd_make_section (dynobj, ".rela.got"); - if (srelgot == NULL - || ! bfd_set_section_flags (dynobj, srelgot, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, srelgot, 2)) - return false; - } - } - - if (h != NULL) - { - if (h->got_offset != (bfd_vma) -1) - { - /* We have already allocated space in the .got. */ - break; - } - h->got_offset = sgot->_raw_size; - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - srelgot->_raw_size += sizeof (Elf32_External_Rela); - } - else - { - /* This is a global offset table entry for a local - symbol. */ - if (local_got_offsets == NULL) - { - size_t size; - register unsigned int i; - - size = symtab_hdr->sh_info * sizeof (bfd_vma); - local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size); - if (local_got_offsets == NULL) - return false; - elf_local_got_offsets (abfd) = local_got_offsets; - for (i = 0; i < symtab_hdr->sh_info; i++) - local_got_offsets[i] = (bfd_vma) -1; - } - if (local_got_offsets[r_symndx] != (bfd_vma) -1) - { - /* We have already allocated space in the .got. */ - break; - } - local_got_offsets[r_symndx] = sgot->_raw_size; - - if (info->shared) - { - /* If we are generating a shared object, we need to - output a R_SPARC_RELATIVE reloc so that the - dynamic linker can adjust this GOT entry. */ - srelgot->_raw_size += sizeof (Elf32_External_Rela); - } - } - - sgot->_raw_size += 4; - - break; - - case R_SPARC_WPLT30: - /* This symbol requires a procedure linkage table entry. We - actually build the entry in adjust_dynamic_symbol, - because this might be a case of linking PIC code without - linking in any dynamic objects, in which case we don't - need to generate a procedure linkage table after all. */ - - if (h == NULL) - { - /* It does not make sense to have a procedure linkage - table entry for a local symbol. */ - bfd_set_error (bfd_error_bad_value); - return false; - } - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; - - break; - - case R_SPARC_PC10: - case R_SPARC_PC22: - if (h != NULL - && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) - break; - /* Fall through. */ - case R_SPARC_DISP8: - case R_SPARC_DISP16: - case R_SPARC_DISP32: - case R_SPARC_WDISP30: - case R_SPARC_WDISP22: - case R_SPARC_WDISP19: - case R_SPARC_WDISP16: - if (h == NULL) - break; - /* Fall through. */ - case R_SPARC_8: - case R_SPARC_16: - case R_SPARC_32: - case R_SPARC_HI22: - case R_SPARC_22: - case R_SPARC_13: - case R_SPARC_LO10: - case R_SPARC_UA32: - if (info->shared - && (sec->flags & SEC_ALLOC) != 0) - { - /* When creating a shared object, we must copy these - relocs into the output file. We create a reloc - section in dynobj and make room for the reloc. */ - if (sreloc == NULL) - { - const char *name; - - name = (bfd_elf_string_from_elf_section - (abfd, - elf_elfheader (abfd)->e_shstrndx, - elf_section_data (sec)->rel_hdr.sh_name)); - if (name == NULL) - return false; - - BFD_ASSERT (strncmp (name, ".rela", 5) == 0 - && strcmp (bfd_get_section_name (abfd, sec), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - if (sreloc == NULL) - { - sreloc = bfd_make_section (dynobj, name); - if (sreloc == NULL - || ! bfd_set_section_flags (dynobj, sreloc, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, sreloc, 2)) - return false; - } - } - - sreloc->_raw_size += sizeof (Elf32_External_Rela); - } - - break; - - default: - break; - } - } - - return true; -} - -/* Adjust a symbol defined by a dynamic object and referenced by a - regular object. The current definition is in some section of the - dynamic object, but we're not including those sections. We have to - change the definition to something the rest of the link can - understand. */ - -static boolean -elf32_sparc_adjust_dynamic_symbol (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; -{ - bfd *dynobj; - asection *s; - unsigned int power_of_two; - - dynobj = elf_hash_table (info)->dynobj; - - /* Make sure we know what is going on here. */ - BFD_ASSERT (dynobj != NULL - && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) - || h->weakdef != NULL - || ((h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_REF_REGULAR) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0))); - - /* If this is a function, put it in the procedure linkage table. We - will fill in the contents of the procedure linkage table later - (although we could actually do it here). */ - if (h->type == STT_FUNC - || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) - { - if (! elf_hash_table (info)->dynamic_sections_created) - { - /* This case can occur if we saw a WPLT30 reloc in an input - file, but none of the input files were dynamic objects. - In such a case, we don't actually need to build a - procedure linkage table, and we can just do a WDISP30 - reloc instead. */ - BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0); - return true; - } - - s = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (s != NULL); - - /* The first four entries in .plt are reserved. */ - if (s->_raw_size == 0) - s->_raw_size = 4 * PLT_ENTRY_SIZE; - - /* The procedure linkage table has a maximum size. */ - if (s->_raw_size >= 0x400000) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - /* If this symbol is not defined in a regular file, and we are - not generating a shared library, then set the symbol to this - location in the .plt. This is required to make function - pointers compare as equal between the normal executable and - the shared library. */ - if (! info->shared - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; - } - - h->plt_offset = s->_raw_size; - - /* Make room for this entry. */ - s->_raw_size += PLT_ENTRY_SIZE; - - /* We also need to make an entry in the .rela.plt section. */ - - s = bfd_get_section_by_name (dynobj, ".rela.plt"); - BFD_ASSERT (s != NULL); - s->_raw_size += sizeof (Elf32_External_Rela); - - return true; - } - - /* If this is a weak symbol, and there is a real definition, the - processor independent code will have arranged for us to see the - real definition first, and we can just use the same value. */ - if (h->weakdef != NULL) - { - BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined - || h->weakdef->root.type == bfd_link_hash_defweak); - h->root.u.def.section = h->weakdef->root.u.def.section; - h->root.u.def.value = h->weakdef->root.u.def.value; - return true; - } - - /* This is a reference to a symbol defined by a dynamic object which - is not a function. */ - - /* If we are creating a shared library, we must presume that the - only references to the symbol are via the global offset table. - For such cases we need not do anything here; the relocations will - be handled correctly by relocate_section. */ - if (info->shared) - return true; - - /* We must allocate the symbol in our .dynbss section, which will - become part of the .bss section of the executable. There will be - an entry for this symbol in the .dynsym section. The dynamic - object will contain position independent code, so all references - from the dynamic object to this symbol will go through the global - offset table. The dynamic linker will use the .dynsym entry to - determine the address it must put in the global offset table, so - both the dynamic object and the regular object will refer to the - same memory location for the variable. */ - - s = bfd_get_section_by_name (dynobj, ".dynbss"); - BFD_ASSERT (s != NULL); - - /* If the symbol is currently defined in the .bss section of the - dynamic object, then it is OK to simply initialize it to zero. - If the symbol is in some other section, we must generate a - R_SPARC_COPY reloc to tell the dynamic linker to copy the initial - value out of the dynamic object and into the runtime process - image. We need to remember the offset into the .rel.bss section - we are going to use. */ - if ((h->root.u.def.section->flags & SEC_LOAD) != 0) - { - asection *srel; - - srel = bfd_get_section_by_name (dynobj, ".rela.bss"); - BFD_ASSERT (srel != NULL); - srel->_raw_size += sizeof (Elf32_External_Rela); - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY; - } - - /* We need to figure out the alignment required for this symbol. I - have no idea how ELF linkers handle this. */ - power_of_two = bfd_log2 (h->size); - if (power_of_two > 3) - power_of_two = 3; - - /* Apply the required alignment. */ - s->_raw_size = BFD_ALIGN (s->_raw_size, - (bfd_size_type) (1 << power_of_two)); - if (power_of_two > bfd_get_section_alignment (dynobj, s)) - { - if (! bfd_set_section_alignment (dynobj, s, power_of_two)) - return false; - } - - /* Define the symbol as being at this point in the section. */ - h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; - - /* Increment the section size to make room for the symbol. */ - s->_raw_size += h->size; - - return true; -} - -/* Set the sizes of the dynamic sections. */ - -static boolean -elf32_sparc_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *s; - boolean reltext; - boolean relplt; - - dynobj = elf_hash_table (info)->dynobj; - BFD_ASSERT (dynobj != NULL); - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Set the contents of the .interp section to the interpreter. */ - if (! info->shared) - { - s = bfd_get_section_by_name (dynobj, ".interp"); - BFD_ASSERT (s != NULL); - s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; - s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; - } - - /* Make space for the trailing nop in .plt. */ - s = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (s != NULL); - if (s->_raw_size > 0) - s->_raw_size += 4; - } - else - { - /* We may have created entries in the .rela.got section. - However, if we are not creating the dynamic sections, we will - not actually use these entries. Reset the size of .rela.got, - which will cause it to get stripped from the output file - below. */ - s = bfd_get_section_by_name (dynobj, ".rela.got"); - if (s != NULL) - s->_raw_size = 0; - } - - /* The check_relocs and adjust_dynamic_symbol entry points have - determined the sizes of the various dynamic sections. Allocate - memory for them. */ - reltext = false; - relplt = false; - for (s = dynobj->sections; s != NULL; s = s->next) - { - const char *name; - boolean strip; - - if ((s->flags & SEC_IN_MEMORY) == 0) - continue; - - /* It's OK to base decisions on the section name, because none - of the dynobj section names depend upon the input files. */ - name = bfd_get_section_name (dynobj, s); - - strip = false; - - if (strncmp (name, ".rela", 5) == 0) - { - if (s->_raw_size == 0) - { - /* If we don't need this section, strip it from the - output file. This is to handle .rela.bss and - .rel.plt. We must create it in - create_dynamic_sections, because it must be created - before the linker maps input sections to output - sections. The linker does that before - adjust_dynamic_symbol is called, and it is that - function which decides whether anything needs to go - into these sections. */ - strip = true; - } - else - { - asection *target; - - /* If this relocation section applies to a read only - section, then we probably need a DT_TEXTREL entry. */ - target = bfd_get_section_by_name (output_bfd, name + 5); - if (target != NULL - && (target->flags & SEC_READONLY) != 0) - reltext = true; - - if (strcmp (name, ".rela.plt") == 0) - relplt = true; - - /* We use the reloc_count field as a counter if we need - to copy relocs into the output file. */ - s->reloc_count = 0; - } - } - else if (strcmp (name, ".plt") != 0 - && strcmp (name, ".got") != 0) - { - /* It's not one of our sections, so don't allocate space. */ - continue; - } - - if (strip) - { - asection **spp; - - for (spp = &s->output_section->owner->sections; - *spp != s->output_section; - spp = &(*spp)->next) - ; - *spp = s->output_section->next; - --s->output_section->owner->section_count; - - continue; - } - - /* Allocate memory for the section contents. */ - s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) - return false; - } - - if (elf_hash_table (info)->dynamic_sections_created) - { - /* Add some entries to the .dynamic section. We fill in the - values later, in elf32_sparc_finish_dynamic_sections, but we - must add the entries now so that we get the correct size for - the .dynamic section. The DT_DEBUG entry is filled in by the - dynamic linker and used by the debugger. */ - if (! info->shared) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0)) - return false; - } - - if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)) - return false; - - if (relplt) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_RELA) - || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0)) - return false; - } - - if (! bfd_elf32_add_dynamic_entry (info, DT_RELA, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_RELASZ, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_RELAENT, - sizeof (Elf32_External_Rela))) - return false; - - if (reltext) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0)) - return false; - } - } - - /* If we are generating a shared library, we generate a section - symbol for each output section. These are local symbols, which - means that they must come first in the dynamic symbol table. - That means we must increment the dynamic symbol index of every - other dynamic symbol. */ - if (info->shared) - { - int c, i; - - c = bfd_count_sections (output_bfd); - elf_link_hash_traverse (elf_hash_table (info), - elf32_sparc_adjust_dynindx, - (PTR) &c); - elf_hash_table (info)->dynsymcount += c; - - for (i = 1, s = output_bfd->sections; s != NULL; s = s->next, i++) - { - elf_section_data (s)->dynindx = i; - /* These symbols will have no names, so we don't need to - fiddle with dynstr_index. */ - } - } - - return true; -} - -/* Increment the index of a dynamic symbol by a given amount. Called - via elf_link_hash_traverse. */ - -static boolean -elf32_sparc_adjust_dynindx (h, cparg) - struct elf_link_hash_entry *h; - PTR cparg; -{ - int *cp = (int *) cparg; - - if (h->dynindx != -1) - h->dynindx += *cp; - return true; -} - -/* Relocate a SPARC ELF section. */ - -static boolean -elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; -{ - bfd *dynobj; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - bfd_vma *local_got_offsets; - asection *sgot; - asection *splt; - asection *sreloc; - Elf_Internal_Rela *rel; - Elf_Internal_Rela *relend; - - dynobj = elf_hash_table (info)->dynobj; - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (input_bfd); - local_got_offsets = elf_local_got_offsets (input_bfd); - - sgot = NULL; - splt = NULL; - sreloc = NULL; - - rel = relocs; - relend = relocs + input_section->reloc_count; - for (; rel < relend; rel++) - { - int r_type; - reloc_howto_type *howto; - unsigned long r_symndx; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; - asection *sec; - bfd_vma relocation; - bfd_reloc_status_type r; - - r_type = ELF32_R_TYPE (rel->r_info); - if (r_type < 0 || r_type >= (int) R_SPARC_max) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - howto = _bfd_sparc_elf_howto_table + r_type; - - r_symndx = ELF32_R_SYM (rel->r_info); - - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - sec = local_sections[r_symndx]; - rel->r_addend += sec->output_offset + sym->st_value; - } - } - - continue; - } - - /* This is a final link. */ - h = NULL; - sym = NULL; - sec = NULL; - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); - } - else - { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - if ((r_type == R_SPARC_WPLT30 - && h->plt_offset != (bfd_vma) -1) - || ((r_type == R_SPARC_GOT10 - || r_type == R_SPARC_GOT13 - || r_type == R_SPARC_GOT22) - && elf_hash_table (info)->dynamic_sections_created - && (! info->shared - || ! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)) - || (info->shared - && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0) - && (input_section->flags & SEC_ALLOC) != 0 - && (r_type == R_SPARC_8 - || r_type == R_SPARC_16 - || r_type == R_SPARC_32 - || r_type == R_SPARC_DISP8 - || r_type == R_SPARC_DISP16 - || r_type == R_SPARC_DISP32 - || r_type == R_SPARC_WDISP30 - || r_type == R_SPARC_WDISP22 - || r_type == R_SPARC_WDISP19 - || r_type == R_SPARC_WDISP16 - || r_type == R_SPARC_HI22 - || r_type == R_SPARC_22 - || r_type == R_SPARC_13 - || r_type == R_SPARC_LO10 - || r_type == R_SPARC_UA32 - || ((r_type == R_SPARC_PC10 - || r_type == R_SPARC_PC22) - && strcmp (h->root.root.string, - "_GLOBAL_OFFSET_TABLE_") != 0)))) - { - /* In these cases, we don't need the relocation - value. We check specially because in some - obscure cases sec->output_section will be NULL. */ - relocation = 0; - } - else - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else if (info->shared && !info->symbolic) - relocation = 0; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset))) - return false; - relocation = 0; - } - } - - switch (r_type) - { - case R_SPARC_GOT10: - case R_SPARC_GOT13: - case R_SPARC_GOT22: - /* Relocation is to the entry for this symbol in the global - offset table. */ - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - } - - if (h != NULL) - { - bfd_vma off; - - off = h->got_offset; - BFD_ASSERT (off != (bfd_vma) -1); - - if (! elf_hash_table (info)->dynamic_sections_created - || (info->shared - && info->symbolic - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) - { - /* This is actually a static link, or it is a - -Bsymbolic link and the symbol is defined - locally. We must initialize this entry in the - global offset table. Since the offset must - always be a multiple of 4, we use the least - significant bit to record whether we have - initialized it already. - - When doing a dynamic link, we create a .rela.got - relocation entry to initialize the value. This - is done in the finish_dynamic_symbol routine. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_32 (output_bfd, relocation, - sgot->contents + off); - h->got_offset |= 1; - } - } - - relocation = sgot->output_offset + off; - } - else - { - bfd_vma off; - - BFD_ASSERT (local_got_offsets != NULL - && local_got_offsets[r_symndx] != (bfd_vma) -1); - - off = local_got_offsets[r_symndx]; - - /* The offset must always be a multiple of 4. We use - the least significant bit to record whether we have - already processed this entry. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_32 (output_bfd, relocation, sgot->contents + off); - - if (info->shared) - { - asection *srelgot; - Elf_Internal_Rela outrel; - - /* We need to generate a R_SPARC_RELATIVE reloc - for the dynamic linker. */ - srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); - BFD_ASSERT (srelgot != NULL); - - outrel.r_offset = (sgot->output_section->vma - + sgot->output_offset - + off); - outrel.r_info = ELF32_R_INFO (0, R_SPARC_RELATIVE); - outrel.r_addend = 0; - bfd_elf32_swap_reloca_out (output_bfd, &outrel, - (((Elf32_External_Rela *) - srelgot->contents) - + srelgot->reloc_count)); - ++srelgot->reloc_count; - } - - local_got_offsets[r_symndx] |= 1; - } - - relocation = sgot->output_offset + off; - } - - break; - - case R_SPARC_WPLT30: - /* Relocation is to the entry for this symbol in the - procedure linkage table. */ - BFD_ASSERT (h != NULL); - - if (h->plt_offset == (bfd_vma) -1) - { - /* We didn't make a PLT entry for this symbol. This - happens when statically linking PIC code, or when - using -Bsymbolic. */ - break; - } - - if (splt == NULL) - { - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL); - } - - relocation = (splt->output_section->vma - + splt->output_offset - + h->plt_offset); - break; - - case R_SPARC_PC10: - case R_SPARC_PC22: - if (h != NULL - && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) - break; - /* Fall through. */ - case R_SPARC_DISP8: - case R_SPARC_DISP16: - case R_SPARC_DISP32: - case R_SPARC_WDISP30: - case R_SPARC_WDISP22: - case R_SPARC_WDISP19: - case R_SPARC_WDISP16: - if (h == NULL) - break; - /* Fall through. */ - case R_SPARC_8: - case R_SPARC_16: - case R_SPARC_32: - case R_SPARC_HI22: - case R_SPARC_22: - case R_SPARC_13: - case R_SPARC_LO10: - case R_SPARC_UA32: - if (info->shared - && (input_section->flags & SEC_ALLOC) != 0) - { - Elf_Internal_Rela outrel; - - /* When generating a shared object, these relocations - are copied into the output file to be resolved at run - time. */ - - if (sreloc == NULL) - { - const char *name; - - name = (bfd_elf_string_from_elf_section - (input_bfd, - elf_elfheader (input_bfd)->e_shstrndx, - elf_section_data (input_section)->rel_hdr.sh_name)); - if (name == NULL) - return false; - - BFD_ASSERT (strncmp (name, ".rela", 5) == 0 - && strcmp (bfd_get_section_name (input_bfd, - input_section), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - BFD_ASSERT (sreloc != NULL); - } - - outrel.r_offset = (rel->r_offset - + input_section->output_section->vma - + input_section->output_offset); - if (h != NULL - && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)) - { - BFD_ASSERT (h->dynindx != -1); - outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); - outrel.r_addend = rel->r_addend; - } - else - { - if (r_type == R_SPARC_32) - { - outrel.r_info = ELF32_R_INFO (0, R_SPARC_RELATIVE); - outrel.r_addend = relocation + rel->r_addend; - } - else - { - long indx; - - if (h == NULL) - sec = local_sections[r_symndx]; - else - { - BFD_ASSERT (h->root.type == bfd_link_hash_defined - || (h->root.type - == bfd_link_hash_defweak)); - sec = h->root.u.def.section; - } - if (sec != NULL && bfd_is_abs_section (sec)) - indx = 0; - else if (sec == NULL || sec->owner == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - else - { - asection *osec; - - osec = sec->output_section; - indx = elf_section_data (osec)->dynindx; - if (indx == 0) - abort (); - } - - outrel.r_info = ELF32_R_INFO (indx, r_type); - outrel.r_addend = relocation + rel->r_addend; - } - } - - bfd_elf32_swap_reloca_out (output_bfd, &outrel, - (((Elf32_External_Rela *) - sreloc->contents) - + sreloc->reloc_count)); - ++sreloc->reloc_count; - - /* This reloc will be computed at runtime, so there's no - need to do anything now. */ - continue; - } - - default: - break; - } - - if (r_type != R_SPARC_WDISP16) - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, - relocation, rel->r_addend); - else - { - bfd_vma x; - - relocation += rel->r_addend; - relocation -= (input_section->output_section->vma - + input_section->output_offset); - relocation -= rel->r_offset; - - x = bfd_get_32 (input_bfd, contents + rel->r_offset); - x |= ((((relocation >> 2) & 0xc000) << 6) - | ((relocation >> 2) & 0x3fff)); - bfd_put_32 (input_bfd, x, contents + rel->r_offset); - - if ((bfd_signed_vma) relocation < - 0x40000 - || (bfd_signed_vma) relocation > 0x3ffff) - r = bfd_reloc_overflow; - else - r = bfd_reloc_ok; - } - - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (h != NULL) - name = h->root.root.string; - else - { - name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - if (name == NULL) - return false; - if (*name == '\0') - name = bfd_section_name (input_bfd, sec); - } - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, - input_bfd, input_section, rel->r_offset))) - return false; - } - break; - } - } - } - - return true; -} - -/* Finish up dynamic symbol handling. We set the contents of various - dynamic sections here. */ - -static boolean -elf32_sparc_finish_dynamic_symbol (output_bfd, info, h, sym) - bfd *output_bfd; - struct bfd_link_info *info; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; -{ - bfd *dynobj; - - dynobj = elf_hash_table (info)->dynobj; - - if (h->plt_offset != (bfd_vma) -1) - { - asection *splt; - asection *srela; - Elf_Internal_Rela rela; - - /* This symbol has an entry in the procedure linkage table. Set - it up. */ - - BFD_ASSERT (h->dynindx != -1); - - splt = bfd_get_section_by_name (dynobj, ".plt"); - srela = bfd_get_section_by_name (dynobj, ".rela.plt"); - BFD_ASSERT (splt != NULL && srela != NULL); - - /* Fill in the entry in the procedure linkage table. */ - bfd_put_32 (output_bfd, - PLT_ENTRY_WORD0 + h->plt_offset, - splt->contents + h->plt_offset); - bfd_put_32 (output_bfd, - (PLT_ENTRY_WORD1 - + (((- (h->plt_offset + 4)) >> 2) & 0x3fffff)), - splt->contents + h->plt_offset + 4); - bfd_put_32 (output_bfd, PLT_ENTRY_WORD2, - splt->contents + h->plt_offset + 8); - - /* Fill in the entry in the .rela.plt section. */ - rela.r_offset = (splt->output_section->vma - + splt->output_offset - + h->plt_offset); - rela.r_info = ELF32_R_INFO (h->dynindx, R_SPARC_JMP_SLOT); - rela.r_addend = 0; - bfd_elf32_swap_reloca_out (output_bfd, &rela, - ((Elf32_External_Rela *) srela->contents - + h->plt_offset / PLT_ENTRY_SIZE - 4)); - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - /* Mark the symbol as undefined, rather than as defined in - the .plt section. Leave the value alone. */ - sym->st_shndx = SHN_UNDEF; - } - } - - if (h->got_offset != (bfd_vma) -1) - { - asection *sgot; - asection *srela; - Elf_Internal_Rela rela; - - /* This symbol has an entry in the global offset table. Set it - up. */ - - BFD_ASSERT (h->dynindx != -1); - - sgot = bfd_get_section_by_name (dynobj, ".got"); - srela = bfd_get_section_by_name (dynobj, ".rela.got"); - BFD_ASSERT (sgot != NULL && srela != NULL); - - rela.r_offset = (sgot->output_section->vma - + sgot->output_offset - + (h->got_offset &~ 1)); - - /* If this is a -Bsymbolic link, and the symbol is defined - locally, we just want to emit a RELATIVE reloc. The entry in - the global offset table will already have been initialized in - the relocate_section function. */ - if (info->shared - && info->symbolic - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) - rela.r_info = ELF32_R_INFO (0, R_SPARC_RELATIVE); - else - { - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got_offset); - rela.r_info = ELF32_R_INFO (h->dynindx, R_SPARC_GLOB_DAT); - } - - rela.r_addend = 0; - bfd_elf32_swap_reloca_out (output_bfd, &rela, - ((Elf32_External_Rela *) srela->contents - + srela->reloc_count)); - ++srela->reloc_count; - } - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0) - { - asection *s; - Elf_Internal_Rela rela; - - /* This symbols needs a copy reloc. Set it up. */ - - BFD_ASSERT (h->dynindx != -1); - - s = bfd_get_section_by_name (h->root.u.def.section->owner, - ".rela.bss"); - BFD_ASSERT (s != NULL); - - rela.r_offset = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - rela.r_info = ELF32_R_INFO (h->dynindx, R_SPARC_COPY); - rela.r_addend = 0; - bfd_elf32_swap_reloca_out (output_bfd, &rela, - ((Elf32_External_Rela *) s->contents - + s->reloc_count)); - ++s->reloc_count; - } - - /* Mark some specially defined symbols as absolute. */ - if (strcmp (h->root.root.string, "_DYNAMIC") == 0 - || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0 - || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0) - sym->st_shndx = SHN_ABS; - - return true; -} - -/* Finish up the dynamic sections. */ - -static boolean -elf32_sparc_finish_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *sdyn; - asection *sgot; - - dynobj = elf_hash_table (info)->dynobj; - - sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); - - if (elf_hash_table (info)->dynamic_sections_created) - { - asection *splt; - Elf32_External_Dyn *dyncon, *dynconend; - - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL && sdyn != NULL); - - dyncon = (Elf32_External_Dyn *) sdyn->contents; - dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size); - for (; dyncon < dynconend; dyncon++) - { - Elf_Internal_Dyn dyn; - const char *name; - boolean size; - - bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn); - - switch (dyn.d_tag) - { - case DT_PLTGOT: name = ".plt"; size = false; break; - case DT_PLTRELSZ: name = ".rela.plt"; size = true; break; - case DT_JMPREL: name = ".rela.plt"; size = false; break; - default: name = NULL; size = false; break; - } - - if (name != NULL) - { - asection *s; - - s = bfd_get_section_by_name (output_bfd, name); - if (s == NULL) - dyn.d_un.d_val = 0; - else - { - if (! size) - dyn.d_un.d_ptr = s->vma; - else - { - if (s->_cooked_size != 0) - dyn.d_un.d_val = s->_cooked_size; - else - dyn.d_un.d_val = s->_raw_size; - } - } - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - } - } - - /* Clear the first four entries in the procedure linkage table, - and put a nop in the last four bytes. */ - if (splt->_raw_size > 0) - { - memset (splt->contents, 0, 4 * PLT_ENTRY_SIZE); - bfd_put_32 (output_bfd, SPARC_NOP, - splt->contents + splt->_raw_size - 4); - } - - elf_section_data (splt->output_section)->this_hdr.sh_entsize = - PLT_ENTRY_SIZE; - } - - /* Set the first entry in the global offset table to the address of - the dynamic section. */ - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - if (sgot->_raw_size > 0) - { - if (sdyn == NULL) - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents); - else - bfd_put_32 (output_bfd, - sdyn->output_section->vma + sdyn->output_offset, - sgot->contents); - } - - elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4; - - if (info->shared) - { - asection *sdynsym; - asection *s; - Elf_Internal_Sym sym; - - /* Set up the section symbols for the output sections. */ - - sdynsym = bfd_get_section_by_name (dynobj, ".dynsym"); - BFD_ASSERT (sdynsym != NULL); - - sym.st_size = 0; - sym.st_name = 0; - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); - sym.st_other = 0; - - for (s = output_bfd->sections; s != NULL; s = s->next) - { - int indx; - - sym.st_value = s->vma; - - indx = elf_section_data (s)->this_idx; - BFD_ASSERT (indx > 0); - sym.st_shndx = indx; - - bfd_elf32_swap_symbol_out (output_bfd, &sym, - (PTR) (((Elf32_External_Sym *) - sdynsym->contents) - + elf_section_data (s)->dynindx)); - } - - /* Set the sh_info field of the output .dynsym section to the - index of the first global symbol. */ - elf_section_data (sdynsym->output_section)->this_hdr.sh_info = - bfd_count_sections (output_bfd) + 1; - } - - return true; -} - -/* Functions for dealing with the e_flags field. - - We don't define set_private_flags or copy_private_bfd_data because - the only currently defined values are based on the bfd mach number, - so we use the latter instead and defer setting e_flags until the - file is written out. */ - -/* Merge backend specific data from an object file to the output - object file when linking. */ - -static boolean -elf32_sparc_merge_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; -{ - boolean error; - - /* This function is selected based on the input vector. We only - want to copy information over if the output BFD also uses Elf - format. */ - if (bfd_get_flavour (obfd) != bfd_target_elf_flavour) - return true; - - error = false; - -#if 0 - /* ??? The native linker doesn't do this so we can't (otherwise gcc would - have to know which linker is being used). Instead, the native linker - bumps up the architecture level when it has to. However, I still think - warnings like these are good, so it would be nice to have them turned on - by some option. */ - - /* If the output machine is normal sparc, we can't allow v9 input files. */ - if (bfd_get_mach (obfd) == bfd_mach_sparc - && (bfd_get_mach (ibfd) == bfd_mach_sparc_v8plus - || bfd_get_mach (ibfd) == bfd_mach_sparc_v8plusa)) - { - error = true; - (*_bfd_error_handler) - ("%s: compiled for a v8plus system and target is v8", - bfd_get_filename (ibfd)); - } - /* If the output machine is v9, we can't allow v9+vis input files. */ - if (bfd_get_mach (obfd) == bfd_mach_sparc_v8plus - && bfd_get_mach (ibfd) == bfd_mach_sparc_v8plusa) - { - error = true; - (*_bfd_error_handler) - ("%s: compiled for a v8plusa system and target is v8plus", - bfd_get_filename (ibfd)); - } -#else - if (bfd_get_mach (ibfd) >= bfd_mach_sparc_v9) - { - error = true; - (*_bfd_error_handler) - ("%s: compiled for a 64 bit system and target is 32 bit", - bfd_get_filename (ibfd)); - } - else if (bfd_get_mach (obfd) < bfd_get_mach (ibfd)) - bfd_set_arch_mach (obfd, bfd_arch_sparc, bfd_get_mach (ibfd)); -#endif - - if (error) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - return true; -} - -/* Set the right machine number. */ - -static boolean -elf32_sparc_object_p (abfd) - bfd *abfd; -{ - if (elf_elfheader (abfd)->e_machine == EM_SPARC32PLUS) - { - if (elf_elfheader (abfd)->e_flags & EF_SPARC_SUN_US1) - return bfd_default_set_arch_mach (abfd, bfd_arch_sparc, - bfd_mach_sparc_v8plusa); - else if (elf_elfheader (abfd)->e_flags & EF_SPARC_32PLUS) - return bfd_default_set_arch_mach (abfd, bfd_arch_sparc, - bfd_mach_sparc_v8plus); - else - return false; - } - else - return bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc); -} - -/* The final processing done just before writing out the object file. - We need to set the e_machine field appropriately. */ - -static void -elf32_sparc_final_write_processing (abfd, linker) - bfd *abfd; - boolean linker; -{ - switch (bfd_get_mach (abfd)) - { - case bfd_mach_sparc : - break; /* nothing to do */ - case bfd_mach_sparc_v8plus : - elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS; - elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK; - elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS; - break; - case bfd_mach_sparc_v8plusa : - elf_elfheader (abfd)->e_machine = EM_SPARC32PLUS; - elf_elfheader (abfd)->e_flags &=~ EF_SPARC_32PLUS_MASK; - elf_elfheader (abfd)->e_flags |= EF_SPARC_32PLUS | EF_SPARC_SUN_US1; - break; - default : - abort (); - } -} - -#define TARGET_BIG_SYM bfd_elf32_sparc_vec -#define TARGET_BIG_NAME "elf32-sparc" -#define ELF_ARCH bfd_arch_sparc -#define ELF_MACHINE_CODE EM_SPARC -#define ELF_MACHINE_ALT1 EM_SPARC32PLUS -#define ELF_MAXPAGESIZE 0x10000 - -#define bfd_elf32_bfd_reloc_type_lookup elf32_sparc_reloc_type_lookup -#define elf_backend_create_dynamic_sections \ - _bfd_elf_create_dynamic_sections -#define elf_backend_check_relocs elf32_sparc_check_relocs -#define elf_backend_adjust_dynamic_symbol \ - elf32_sparc_adjust_dynamic_symbol -#define elf_backend_size_dynamic_sections \ - elf32_sparc_size_dynamic_sections -#define elf_backend_relocate_section elf32_sparc_relocate_section -#define elf_backend_finish_dynamic_symbol \ - elf32_sparc_finish_dynamic_symbol -#define elf_backend_finish_dynamic_sections \ - elf32_sparc_finish_dynamic_sections -#define bfd_elf32_bfd_merge_private_bfd_data \ - elf32_sparc_merge_private_bfd_data -#define elf_backend_object_p elf32_sparc_object_p -#define elf_backend_final_write_processing \ - elf32_sparc_final_write_processing -#define elf_backend_want_got_plt 0 -#define elf_backend_plt_readonly 0 -#define elf_backend_want_plt_sym 1 - -#include "elf32-target.h" diff --git a/contrib/gdb/bfd/elf32.c b/contrib/gdb/bfd/elf32.c deleted file mode 100644 index f222969..0000000 --- a/contrib/gdb/bfd/elf32.c +++ /dev/null @@ -1,23 +0,0 @@ -/* ELF 32-bit executable support for BFD. - Copyright 1993 Free Software Foundation, Inc. - -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. */ - -#define ARCH_SIZE 32 - - -#include "elfcode.h" diff --git a/contrib/gdb/bfd/elf64-gen.c b/contrib/gdb/bfd/elf64-gen.c deleted file mode 100644 index 5daf4ee..0000000 --- a/contrib/gdb/bfd/elf64-gen.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Generic support for 64-bit ELF - Copyright 1993 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "elf-bfd.h" - -/* This does not include any relocations, but should be good enough - for GDB to read the file. */ - -#define TARGET_LITTLE_SYM bfd_elf64_little_generic_vec -#define TARGET_LITTLE_NAME "elf64-little" -#define TARGET_BIG_SYM bfd_elf64_big_generic_vec -#define TARGET_BIG_NAME "elf64-big" -#define ELF_ARCH bfd_arch_unknown -#define ELF_MACHINE_CODE EM_NONE -#define bfd_elf64_bfd_reloc_type_lookup bfd_default_reloc_type_lookup -#define elf_info_to_howto _bfd_elf_no_info_to_howto - -#include "elf64-target.h" diff --git a/contrib/gdb/bfd/elf64-sparc.c b/contrib/gdb/bfd/elf64-sparc.c deleted file mode 100644 index 5059b80..0000000 --- a/contrib/gdb/bfd/elf64-sparc.c +++ /dev/null @@ -1,421 +0,0 @@ -/* SPARC-specific support for 64-bit ELF - Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. - -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. */ - -/* We need a published ABI spec for this. Until one comes out, don't - assume this'll remain unchanged forever. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "elf-bfd.h" - -#define SPARC64_OLD_RELOCS -#include "elf/sparc.h" - -static reloc_howto_type *sparc64_elf_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static void elf_info_to_howto - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); - -static boolean sparc64_elf_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static boolean sparc64_elf_object_p PARAMS ((bfd *)); - -/* The howto table and associated functions. - ??? Some of the relocation values have changed. Until we're ready - to upgrade, we have our own copy. At some point a non upward compatible - change will be made at which point this table can be deleted and we'll - use the one in elf32-sparc.c. */ - -static bfd_reloc_status_type sparc_elf_wdisp16_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); - -static reloc_howto_type sparc64_elf_howto_table[] = -{ - HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_NONE", false,0,0x00000000,true), - HOWTO(R_SPARC_8, 0,0, 8,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_8", false,0,0x000000ff,true), - HOWTO(R_SPARC_16, 0,1,16,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_16", false,0,0x0000ffff,true), - HOWTO(R_SPARC_32, 0,2,32,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_32", false,0,0xffffffff,true), - HOWTO(R_SPARC_DISP8, 0,0, 8,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP8", false,0,0x000000ff,true), - HOWTO(R_SPARC_DISP16, 0,1,16,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP16", false,0,0x0000ffff,true), - HOWTO(R_SPARC_DISP32, 0,2,32,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_DISP32", false,0,0x00ffffff,true), - HOWTO(R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP30", false,0,0x3fffffff,true), - HOWTO(R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP22", false,0,0x003fffff,true), - HOWTO(R_SPARC_HI22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HI22", false,0,0x003fffff,true), - HOWTO(R_SPARC_22, 0,2,22,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_22", false,0,0x003fffff,true), - HOWTO(R_SPARC_13, 0,2,13,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_13", false,0,0x00001fff,true), - HOWTO(R_SPARC_LO10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LO10", false,0,0x000003ff,true), - HOWTO(R_SPARC_GOT10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GOT10", false,0,0x000003ff,true), - HOWTO(R_SPARC_GOT13, 0,2,13,false,0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_GOT13", false,0,0x00001fff,true), - HOWTO(R_SPARC_GOT22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GOT22", false,0,0x003fffff,true), - HOWTO(R_SPARC_PC10, 0,2,10,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_PC10", false,0,0x000003ff,true), - HOWTO(R_SPARC_PC22, 10,2,22,true, 0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_PC22", false,0,0x003fffff,true), - HOWTO(R_SPARC_WPLT30, 2,2,30,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WPLT30", false,0,0x3fffffff,true), - HOWTO(R_SPARC_COPY, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_COPY", false,0,0x00000000,true), - HOWTO(R_SPARC_GLOB_DAT, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GLOB_DAT",false,0,0x00000000,true), - HOWTO(R_SPARC_JMP_SLOT, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_JMP_SLOT",false,0,0x00000000,true), - HOWTO(R_SPARC_RELATIVE, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_RELATIVE",false,0,0x00000000,true), - HOWTO(R_SPARC_UA32, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_UA32", false,0,0x00000000,true), -#if 0 /* not used yet */ - HOWTO(R_SPARC_PLT32, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PLT32", false,0,0x00000000,true), - HOWTO(R_SPARC_HIPLT22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_HIPLT22", false,0,0x00000000,true), - HOWTO(R_SPARC_LOPLT10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_LOPLT10", false,0,0x00000000,true), - HOWTO(R_SPARC_PCPLT32, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PCPLT32", false,0,0x00000000,true), - HOWTO(R_SPARC_PCPLT22, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PCPLT22", false,0,0x00000000,true), - HOWTO(R_SPARC_PCPLT10, 0,0,00,false,0,complain_overflow_dont, sparc_elf_notsupported_reloc, "R_SPARC_PCPLT10", false,0,0x00000000,true), -#endif - HOWTO(R_SPARC_10, 0,2,10,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_10", false,0,0x000003ff,true), - HOWTO(R_SPARC_11, 0,2,11,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_11", false,0,0x000007ff,true), - HOWTO(R_SPARC_64, 0,4,00,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_64", false,0,~ (bfd_vma) 0, true), - HOWTO(R_SPARC_OLO10, 0,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_OLO10", false,0,0x000003ff,true), - HOWTO(R_SPARC_HH22, 42,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HH22", false,0,0x003fffff,true), - HOWTO(R_SPARC_HM10, 32,2,10,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HM10", false,0,0x000003ff,true), - HOWTO(R_SPARC_LM22, 10,2,22,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LM22", false,0,0x003fffff,true), - HOWTO(R_SPARC_PC_HH22, 42,2,22,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HH22", false,0,0x003fffff,true), - HOWTO(R_SPARC_PC_HM10, 32,2,10,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_HM10", false,0,0x000003ff,true), - HOWTO(R_SPARC_PC_LM22, 10,2,22,true, 0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_LM22", false,0,0x003fffff,true), - HOWTO(R_SPARC_WDISP16, 2,2,16,true, 0,complain_overflow_signed, sparc_elf_wdisp16_reloc,"R_SPARC_WDISP16", false,0,0x00000000,true), - HOWTO(R_SPARC_WDISP19, 2,2,22,true, 0,complain_overflow_signed, bfd_elf_generic_reloc, "R_SPARC_WDISP19", false,0,0x0007ffff,true), - HOWTO(R_SPARC_GLOB_JMP, 0,0,00,false,0,complain_overflow_dont, bfd_elf_generic_reloc, "R_SPARC_GLOB_DAT",false,0,0x00000000,true), - HOWTO(R_SPARC_7, 0,2, 7,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_7", false,0,0x0000007f,true), -#if 0 /* not used yet */ - HOWTO(R_SPARC_5, 0,2, 5,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_5", false,0,0x0000001f,true), - HOWTO(R_SPARC_6, 0,2, 6,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc, "R_SPARC_6", false,0,0x0000003f,true), -#endif -}; - -struct elf_reloc_map { - unsigned char bfd_reloc_val; - unsigned char elf_reloc_val; -}; - -static CONST struct elf_reloc_map sparc_reloc_map[] = -{ - { BFD_RELOC_NONE, R_SPARC_NONE, }, - { BFD_RELOC_16, R_SPARC_16, }, - { BFD_RELOC_8, R_SPARC_8 }, - { BFD_RELOC_8_PCREL, R_SPARC_DISP8 }, - /* ??? This might cause us to need separate functions in elf{32,64}-sparc.c - (we could still have just one table), but is this reloc ever used? */ - { BFD_RELOC_CTOR, R_SPARC_32 }, /* @@ Assumes 32 bits. */ - { BFD_RELOC_32, R_SPARC_32 }, - { BFD_RELOC_32_PCREL, R_SPARC_DISP32 }, - { BFD_RELOC_HI22, R_SPARC_HI22 }, - { BFD_RELOC_LO10, R_SPARC_LO10, }, - { BFD_RELOC_32_PCREL_S2, R_SPARC_WDISP30 }, - { BFD_RELOC_SPARC22, R_SPARC_22 }, - { BFD_RELOC_SPARC13, R_SPARC_13 }, - { BFD_RELOC_SPARC_GOT10, R_SPARC_GOT10 }, - { BFD_RELOC_SPARC_GOT13, R_SPARC_GOT13 }, - { BFD_RELOC_SPARC_GOT22, R_SPARC_GOT22 }, - { BFD_RELOC_SPARC_PC10, R_SPARC_PC10 }, - { BFD_RELOC_SPARC_PC22, R_SPARC_PC22 }, - { BFD_RELOC_SPARC_WPLT30, R_SPARC_WPLT30 }, - { BFD_RELOC_SPARC_COPY, R_SPARC_COPY }, - { BFD_RELOC_SPARC_GLOB_DAT, R_SPARC_GLOB_DAT }, - { BFD_RELOC_SPARC_JMP_SLOT, R_SPARC_JMP_SLOT }, - { BFD_RELOC_SPARC_RELATIVE, R_SPARC_RELATIVE }, - { BFD_RELOC_SPARC_WDISP22, R_SPARC_WDISP22 }, - /* ??? Doesn't dwarf use this? */ -/*{ BFD_RELOC_SPARC_UA32, R_SPARC_UA32 }, not used?? */ - {BFD_RELOC_SPARC_10, R_SPARC_10}, - {BFD_RELOC_SPARC_11, R_SPARC_11}, - {BFD_RELOC_SPARC_64, R_SPARC_64}, - {BFD_RELOC_SPARC_OLO10, R_SPARC_OLO10}, - {BFD_RELOC_SPARC_HH22, R_SPARC_HH22}, - {BFD_RELOC_SPARC_HM10, R_SPARC_HM10}, - {BFD_RELOC_SPARC_LM22, R_SPARC_LM22}, - {BFD_RELOC_SPARC_PC_HH22, R_SPARC_PC_HH22}, - {BFD_RELOC_SPARC_PC_HM10, R_SPARC_PC_HM10}, - {BFD_RELOC_SPARC_PC_LM22, R_SPARC_PC_LM22}, - {BFD_RELOC_SPARC_WDISP16, R_SPARC_WDISP16}, - {BFD_RELOC_SPARC_WDISP19, R_SPARC_WDISP19}, - {BFD_RELOC_SPARC_GLOB_JMP, R_SPARC_GLOB_JMP}, - {BFD_RELOC_SPARC_7, R_SPARC_7}, -#if 0 /* unused */ - {BFD_RELOC_SPARC_5, R_SPARC_5}, - {BFD_RELOC_SPARC_6, R_SPARC_6}, -#endif -}; - -static reloc_howto_type * -sparc64_elf_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - unsigned int i; - for (i = 0; i < sizeof (sparc_reloc_map) / sizeof (struct elf_reloc_map); i++) - { - if (sparc_reloc_map[i].bfd_reloc_val == code) - return &sparc64_elf_howto_table[(int) sparc_reloc_map[i].elf_reloc_val]; - } - return 0; -} - -static void -elf_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf64_Internal_Rela *dst; -{ - BFD_ASSERT (ELF64_R_TYPE (dst->r_info) < (unsigned int) R_SPARC_max); - cache_ptr->howto = &sparc64_elf_howto_table[ELF64_R_TYPE (dst->r_info)]; -} - -/* Handle the WDISP16 reloc. */ - -static bfd_reloc_status_type -sparc_elf_wdisp16_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_vma relocation; - bfd_vma x; - - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && (! reloc_entry->howto->partial_inplace - || reloc_entry->addend == 0)) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - if (output_bfd != NULL) - return bfd_reloc_continue; - - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - relocation = (symbol->value - + symbol->section->output_section->vma - + symbol->section->output_offset); - relocation += reloc_entry->addend; - relocation -= (input_section->output_section->vma - + input_section->output_offset); - relocation -= reloc_entry->address; - - x = bfd_get_32 (abfd, (char *) data + reloc_entry->address); - x |= ((((relocation >> 2) & 0xc000) << 6) - | ((relocation >> 2) & 0x3fff)); - bfd_put_32 (abfd, x, (char *) data + reloc_entry->address); - - if ((bfd_signed_vma) relocation < - 0x40000 - || (bfd_signed_vma) relocation > 0x3ffff) - return bfd_reloc_overflow; - else - return bfd_reloc_ok; -} - -/* Relocate a SPARC64 ELF section. */ - -static boolean -sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; -{ - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - Elf_Internal_Rela *rel; - Elf_Internal_Rela *relend; - - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (input_bfd); - - rel = relocs; - relend = relocs + input_section->reloc_count; - for (; rel < relend; rel++) - { - int r_type; - reloc_howto_type *howto; - long r_symndx; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; - asection *sec; - bfd_vma relocation; - bfd_reloc_status_type r; - - r_type = ELF64_R_TYPE (rel->r_info); - if (r_type < 0 || r_type >= (int) R_SPARC_max) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - howto = sparc64_elf_howto_table + r_type; - - r_symndx = ELF64_R_SYM (rel->r_info); - - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - sec = local_sections[r_symndx]; - rel->r_addend += sec->output_offset + sym->st_value; - } - } - - continue; - } - - /* This is a final link. */ - h = NULL; - sym = NULL; - sec = NULL; - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); - } - else - { - h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - sec = h->root.u.def.section; - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_undefweak) - relocation = 0; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset))) - return false; - relocation = 0; - } - } - - if (r_type != R_SPARC_WDISP16) - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, - relocation, rel->r_addend); - else - { - bfd_vma x; - - relocation += rel->r_addend; - relocation -= (input_section->output_section->vma - + input_section->output_offset); - relocation -= rel->r_offset; - - x = bfd_get_32 (input_bfd, contents + rel->r_offset); - x |= ((((relocation >> 2) & 0xc000) << 6) - | ((relocation >> 2) & 0x3fff)); - bfd_put_32 (input_bfd, x, contents + rel->r_offset); - - if ((bfd_signed_vma) relocation < - 0x40000 - || (bfd_signed_vma) relocation > 0x3ffff) - r = bfd_reloc_overflow; - else - r = bfd_reloc_ok; - } - - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (h != NULL) - name = h->root.root.string; - else - { - name = (bfd_elf_string_from_elf_section - (input_bfd, - symtab_hdr->sh_link, - sym->st_name)); - if (name == NULL) - return false; - if (*name == '\0') - name = bfd_section_name (input_bfd, sec); - } - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, - input_bfd, input_section, rel->r_offset))) - return false; - } - break; - } - } - } - - return true; -} - -/* Set the right machine number for a SPARC64 ELF file. */ - -static boolean -sparc64_elf_object_p (abfd) - bfd *abfd; -{ - return bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc_v9); -} - -#define TARGET_BIG_SYM bfd_elf64_sparc_vec -#define TARGET_BIG_NAME "elf64-sparc" -#define ELF_ARCH bfd_arch_sparc -#define ELF_MACHINE_CODE EM_SPARC64 -#define ELF_MAXPAGESIZE 0x100000 - -#define bfd_elf64_bfd_reloc_type_lookup sparc64_elf_reloc_type_lookup -#define elf_backend_relocate_section sparc64_elf_relocate_section -#define elf_backend_object_p sparc64_elf_object_p - -#include "elf64-target.h" diff --git a/contrib/gdb/bfd/elf64.c b/contrib/gdb/bfd/elf64.c deleted file mode 100644 index 69fb5b5..0000000 --- a/contrib/gdb/bfd/elf64.c +++ /dev/null @@ -1,22 +0,0 @@ -/* ELF 64-bit executable support for BFD. - Copyright 1993 Free Software Foundation, Inc. - -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. */ - -#define ARCH_SIZE 64 - -#include "elfcode.h" diff --git a/contrib/gdb/bfd/elfcode.h b/contrib/gdb/bfd/elfcode.h deleted file mode 100644 index a6199f0..0000000 --- a/contrib/gdb/bfd/elfcode.h +++ /dev/null @@ -1,1406 +0,0 @@ -/* ELF executable support for BFD. - Copyright 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - - Written by Fred Fish @ Cygnus Support, from information published - in "UNIX System V Release 4, Programmers Guide: ANSI C and - Programming Support Tools". Sufficient support for gdb. - - Rewritten by Mark Eichin @ Cygnus Support, from information - published in "System V Application Binary Interface", chapters 4 - and 5, as well as the various "Processor Supplement" documents - derived from it. Added support for assembler and other object file - utilities. Further work done by Ken Raeburn (Cygnus Support), Michael - Meissner (Open Software Foundation), and Peter Hoogenboom (University - of Utah) to finish and extend this. - -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. */ - -/* Problems and other issues to resolve. - - (1) BFD expects there to be some fixed number of "sections" in - the object file. I.E. there is a "section_count" variable in the - bfd structure which contains the number of sections. However, ELF - supports multiple "views" of a file. In particular, with current - implementations, executable files typically have two tables, a - program header table and a section header table, both of which - partition the executable. - - In ELF-speak, the "linking view" of the file uses the section header - table to access "sections" within the file, and the "execution view" - uses the program header table to access "segments" within the file. - "Segments" typically may contain all the data from one or more - "sections". - - Note that the section header table is optional in ELF executables, - but it is this information that is most useful to gdb. If the - section header table is missing, then gdb should probably try - to make do with the program header table. (FIXME) - - (2) The code in this file is compiled twice, once in 32-bit mode and - once in 64-bit mode. More of it should be made size-independent - and moved into elf.c. - - (3) ELF section symbols are handled rather sloppily now. This should - be cleaned up, and ELF section symbols reconciled with BFD section - symbols. - - (4) We need a published spec for 64-bit ELF. We've got some stuff here - that we're using for SPARC V9 64-bit chips, but don't assume that - it's cast in stone. - */ - -#include <string.h> /* For strrchr and friends */ -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "elf-bfd.h" - -/* Renaming structures, typedefs, macros and functions to be size-specific. */ -#define Elf_External_Ehdr NAME(Elf,External_Ehdr) -#define Elf_External_Sym NAME(Elf,External_Sym) -#define Elf_External_Shdr NAME(Elf,External_Shdr) -#define Elf_External_Phdr NAME(Elf,External_Phdr) -#define Elf_External_Rel NAME(Elf,External_Rel) -#define Elf_External_Rela NAME(Elf,External_Rela) -#define Elf_External_Dyn NAME(Elf,External_Dyn) - -#define elf_core_file_failing_command NAME(bfd_elf,core_file_failing_command) -#define elf_core_file_failing_signal NAME(bfd_elf,core_file_failing_signal) -#define elf_core_file_matches_executable_p \ - NAME(bfd_elf,core_file_matches_executable_p) -#define elf_object_p NAME(bfd_elf,object_p) -#define elf_core_file_p NAME(bfd_elf,core_file_p) -#define elf_get_symtab_upper_bound NAME(bfd_elf,get_symtab_upper_bound) -#define elf_get_dynamic_symtab_upper_bound \ - NAME(bfd_elf,get_dynamic_symtab_upper_bound) -#define elf_swap_reloc_in NAME(bfd_elf,swap_reloc_in) -#define elf_swap_reloca_in NAME(bfd_elf,swap_reloca_in) -#define elf_swap_reloc_out NAME(bfd_elf,swap_reloc_out) -#define elf_swap_reloca_out NAME(bfd_elf,swap_reloca_out) -#define elf_swap_symbol_in NAME(bfd_elf,swap_symbol_in) -#define elf_swap_symbol_out NAME(bfd_elf,swap_symbol_out) -#define elf_swap_phdr_in NAME(bfd_elf,swap_phdr_in) -#define elf_swap_phdr_out NAME(bfd_elf,swap_phdr_out) -#define elf_swap_dyn_in NAME(bfd_elf,swap_dyn_in) -#define elf_swap_dyn_out NAME(bfd_elf,swap_dyn_out) -#define elf_get_reloc_upper_bound NAME(bfd_elf,get_reloc_upper_bound) -#define elf_canonicalize_reloc NAME(bfd_elf,canonicalize_reloc) -#define elf_get_symtab NAME(bfd_elf,get_symtab) -#define elf_canonicalize_dynamic_symtab \ - NAME(bfd_elf,canonicalize_dynamic_symtab) -#define elf_make_empty_symbol NAME(bfd_elf,make_empty_symbol) -#define elf_get_symbol_info NAME(bfd_elf,get_symbol_info) -#define elf_get_lineno NAME(bfd_elf,get_lineno) -#define elf_set_arch_mach NAME(bfd_elf,set_arch_mach) -#define elf_find_nearest_line NAME(bfd_elf,find_nearest_line) -#define elf_sizeof_headers NAME(bfd_elf,sizeof_headers) -#define elf_set_section_contents NAME(bfd_elf,set_section_contents) -#define elf_no_info_to_howto NAME(bfd_elf,no_info_to_howto) -#define elf_no_info_to_howto_rel NAME(bfd_elf,no_info_to_howto_rel) -#define elf_find_section NAME(bfd_elf,find_section) -#define elf_bfd_link_add_symbols NAME(bfd_elf,bfd_link_add_symbols) -#define elf_add_dynamic_entry NAME(bfd_elf,add_dynamic_entry) -#define elf_link_create_dynamic_sections \ - NAME(bfd_elf,link_create_dynamic_sections) -#define elf_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol -#define elf_bfd_final_link NAME(bfd_elf,bfd_final_link) -#define elf_create_pointer_linker_section NAME(bfd_elf,create_pointer_linker_section) -#define elf_finish_pointer_linker_section NAME(bfd_elf,finish_pointer_linker_section) - -#if ARCH_SIZE == 64 -#define ELF_R_INFO(X,Y) ELF64_R_INFO(X,Y) -#define ELF_R_SYM(X) ELF64_R_SYM(X) -#define ELF_R_TYPE(X) ELF64_R_TYPE(X) -#define ELFCLASS ELFCLASS64 -#define FILE_ALIGN 8 -#define LOG_FILE_ALIGN 3 -#endif -#if ARCH_SIZE == 32 -#define ELF_R_INFO(X,Y) ELF32_R_INFO(X,Y) -#define ELF_R_SYM(X) ELF32_R_SYM(X) -#define ELF_R_TYPE(X) ELF32_R_TYPE(X) -#define ELFCLASS ELFCLASS32 -#define FILE_ALIGN 4 -#define LOG_FILE_ALIGN 2 -#endif - -/* Forward declarations of static functions */ - -#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 long elf_slurp_symbol_table PARAMS ((bfd *, asymbol **, boolean)); - -static boolean elf_slurp_reloc_table PARAMS ((bfd *, asection *, asymbol **)); - - 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 *)); -static char *elf_symbol_flags PARAMS ((flagword)); -#endif - -/* Structure swapping routines */ - -/* Should perhaps use put_offset, put_word, etc. For now, the two versions - can be handled by explicitly specifying 32 bits or "the long type". */ -#if ARCH_SIZE == 64 -#define put_word bfd_h_put_64 -#define get_word bfd_h_get_64 -#endif -#if ARCH_SIZE == 32 -#define put_word bfd_h_put_32 -#define get_word bfd_h_get_32 -#endif - -/* Translate an ELF symbol in external format into an ELF symbol in internal - format. */ - -void -elf_swap_symbol_in (abfd, src, dst) - bfd *abfd; - Elf_External_Sym *src; - Elf_Internal_Sym *dst; -{ - dst->st_name = bfd_h_get_32 (abfd, (bfd_byte *) src->st_name); - dst->st_value = get_word (abfd, (bfd_byte *) src->st_value); - dst->st_size = get_word (abfd, (bfd_byte *) src->st_size); - dst->st_info = bfd_h_get_8 (abfd, (bfd_byte *) src->st_info); - dst->st_other = bfd_h_get_8 (abfd, (bfd_byte *) src->st_other); - dst->st_shndx = bfd_h_get_16 (abfd, (bfd_byte *) src->st_shndx); -} - -/* Translate an ELF symbol in internal format into an ELF symbol in external - format. */ - -void -elf_swap_symbol_out (abfd, src, cdst) - bfd *abfd; - Elf_Internal_Sym *src; - PTR cdst; -{ - Elf_External_Sym *dst = (Elf_External_Sym *) cdst; - bfd_h_put_32 (abfd, src->st_name, dst->st_name); - put_word (abfd, src->st_value, dst->st_value); - put_word (abfd, src->st_size, dst->st_size); - bfd_h_put_8 (abfd, src->st_info, dst->st_info); - bfd_h_put_8 (abfd, src->st_other, dst->st_other); - bfd_h_put_16 (abfd, src->st_shndx, dst->st_shndx); -} - - -/* Translate an ELF file header in external format into an ELF file header in - internal format. */ - -static void -elf_swap_ehdr_in (abfd, src, dst) - bfd *abfd; - Elf_External_Ehdr *src; - Elf_Internal_Ehdr *dst; -{ - memcpy (dst->e_ident, src->e_ident, EI_NIDENT); - dst->e_type = bfd_h_get_16 (abfd, (bfd_byte *) src->e_type); - dst->e_machine = bfd_h_get_16 (abfd, (bfd_byte *) src->e_machine); - dst->e_version = bfd_h_get_32 (abfd, (bfd_byte *) src->e_version); - dst->e_entry = get_word (abfd, (bfd_byte *) src->e_entry); - dst->e_phoff = get_word (abfd, (bfd_byte *) src->e_phoff); - dst->e_shoff = get_word (abfd, (bfd_byte *) src->e_shoff); - dst->e_flags = bfd_h_get_32 (abfd, (bfd_byte *) src->e_flags); - dst->e_ehsize = bfd_h_get_16 (abfd, (bfd_byte *) src->e_ehsize); - dst->e_phentsize = bfd_h_get_16 (abfd, (bfd_byte *) src->e_phentsize); - dst->e_phnum = bfd_h_get_16 (abfd, (bfd_byte *) src->e_phnum); - dst->e_shentsize = bfd_h_get_16 (abfd, (bfd_byte *) src->e_shentsize); - dst->e_shnum = bfd_h_get_16 (abfd, (bfd_byte *) src->e_shnum); - dst->e_shstrndx = bfd_h_get_16 (abfd, (bfd_byte *) src->e_shstrndx); -} - -/* Translate an ELF file header in internal format into an ELF file header in - external format. */ - -static void -elf_swap_ehdr_out (abfd, src, dst) - bfd *abfd; - Elf_Internal_Ehdr *src; - Elf_External_Ehdr *dst; -{ - memcpy (dst->e_ident, src->e_ident, EI_NIDENT); - /* note that all elements of dst are *arrays of unsigned char* already... */ - bfd_h_put_16 (abfd, src->e_type, dst->e_type); - bfd_h_put_16 (abfd, src->e_machine, dst->e_machine); - bfd_h_put_32 (abfd, src->e_version, dst->e_version); - put_word (abfd, src->e_entry, dst->e_entry); - put_word (abfd, src->e_phoff, dst->e_phoff); - put_word (abfd, src->e_shoff, dst->e_shoff); - bfd_h_put_32 (abfd, src->e_flags, dst->e_flags); - bfd_h_put_16 (abfd, src->e_ehsize, dst->e_ehsize); - bfd_h_put_16 (abfd, src->e_phentsize, dst->e_phentsize); - bfd_h_put_16 (abfd, src->e_phnum, dst->e_phnum); - bfd_h_put_16 (abfd, src->e_shentsize, dst->e_shentsize); - bfd_h_put_16 (abfd, src->e_shnum, dst->e_shnum); - bfd_h_put_16 (abfd, src->e_shstrndx, dst->e_shstrndx); -} - - -/* Translate an ELF section header table entry in external format into an - ELF section header table entry in internal format. */ - -static void -elf_swap_shdr_in (abfd, src, dst) - bfd *abfd; - Elf_External_Shdr *src; - Elf_Internal_Shdr *dst; -{ - dst->sh_name = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_name); - dst->sh_type = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_type); - dst->sh_flags = get_word (abfd, (bfd_byte *) src->sh_flags); - dst->sh_addr = get_word (abfd, (bfd_byte *) src->sh_addr); - dst->sh_offset = get_word (abfd, (bfd_byte *) src->sh_offset); - dst->sh_size = get_word (abfd, (bfd_byte *) src->sh_size); - dst->sh_link = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_link); - dst->sh_info = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_info); - dst->sh_addralign = get_word (abfd, (bfd_byte *) src->sh_addralign); - dst->sh_entsize = get_word (abfd, (bfd_byte *) src->sh_entsize); - dst->bfd_section = NULL; - dst->contents = NULL; -} - -/* Translate an ELF section header table entry in internal format into an - ELF section header table entry in external format. */ - -static void -elf_swap_shdr_out (abfd, src, dst) - bfd *abfd; - Elf_Internal_Shdr *src; - Elf_External_Shdr *dst; -{ - /* note that all elements of dst are *arrays of unsigned char* already... */ - bfd_h_put_32 (abfd, src->sh_name, dst->sh_name); - bfd_h_put_32 (abfd, src->sh_type, dst->sh_type); - put_word (abfd, src->sh_flags, dst->sh_flags); - put_word (abfd, src->sh_addr, dst->sh_addr); - put_word (abfd, src->sh_offset, dst->sh_offset); - put_word (abfd, src->sh_size, dst->sh_size); - bfd_h_put_32 (abfd, src->sh_link, dst->sh_link); - bfd_h_put_32 (abfd, src->sh_info, dst->sh_info); - put_word (abfd, src->sh_addralign, dst->sh_addralign); - put_word (abfd, src->sh_entsize, dst->sh_entsize); -} - - -/* Translate an ELF program header table entry in external format into an - ELF program header table entry in internal format. */ - -void -elf_swap_phdr_in (abfd, src, dst) - bfd *abfd; - Elf_External_Phdr *src; - Elf_Internal_Phdr *dst; -{ - dst->p_type = bfd_h_get_32 (abfd, (bfd_byte *) src->p_type); - dst->p_flags = bfd_h_get_32 (abfd, (bfd_byte *) src->p_flags); - dst->p_offset = get_word (abfd, (bfd_byte *) src->p_offset); - dst->p_vaddr = get_word (abfd, (bfd_byte *) src->p_vaddr); - dst->p_paddr = get_word (abfd, (bfd_byte *) src->p_paddr); - dst->p_filesz = get_word (abfd, (bfd_byte *) src->p_filesz); - dst->p_memsz = get_word (abfd, (bfd_byte *) src->p_memsz); - dst->p_align = get_word (abfd, (bfd_byte *) src->p_align); -} - -void -elf_swap_phdr_out (abfd, src, dst) - bfd *abfd; - Elf_Internal_Phdr *src; - Elf_External_Phdr *dst; -{ - /* note that all elements of dst are *arrays of unsigned char* already... */ - bfd_h_put_32 (abfd, src->p_type, dst->p_type); - put_word (abfd, src->p_offset, dst->p_offset); - put_word (abfd, src->p_vaddr, dst->p_vaddr); - put_word (abfd, src->p_paddr, dst->p_paddr); - put_word (abfd, src->p_filesz, dst->p_filesz); - put_word (abfd, src->p_memsz, dst->p_memsz); - bfd_h_put_32 (abfd, src->p_flags, dst->p_flags); - put_word (abfd, src->p_align, dst->p_align); -} - -/* Translate an ELF reloc from external format to internal format. */ -INLINE void -elf_swap_reloc_in (abfd, src, dst) - bfd *abfd; - Elf_External_Rel *src; - Elf_Internal_Rel *dst; -{ - dst->r_offset = get_word (abfd, (bfd_byte *) src->r_offset); - dst->r_info = get_word (abfd, (bfd_byte *) src->r_info); -} - -INLINE void -elf_swap_reloca_in (abfd, src, dst) - bfd *abfd; - Elf_External_Rela *src; - Elf_Internal_Rela *dst; -{ - dst->r_offset = get_word (abfd, (bfd_byte *) src->r_offset); - dst->r_info = get_word (abfd, (bfd_byte *) src->r_info); - dst->r_addend = get_word (abfd, (bfd_byte *) src->r_addend); -} - -/* Translate an ELF reloc from internal format to external format. */ -INLINE void -elf_swap_reloc_out (abfd, src, dst) - bfd *abfd; - Elf_Internal_Rel *src; - Elf_External_Rel *dst; -{ - put_word (abfd, src->r_offset, dst->r_offset); - put_word (abfd, src->r_info, dst->r_info); -} - -INLINE void -elf_swap_reloca_out (abfd, src, dst) - bfd *abfd; - Elf_Internal_Rela *src; - Elf_External_Rela *dst; -{ - put_word (abfd, src->r_offset, dst->r_offset); - put_word (abfd, src->r_info, dst->r_info); - put_word (abfd, src->r_addend, dst->r_addend); -} - -INLINE void -elf_swap_dyn_in (abfd, p, dst) - bfd *abfd; - const PTR p; - Elf_Internal_Dyn *dst; -{ - const Elf_External_Dyn *src = (const Elf_External_Dyn *) p; - - dst->d_tag = get_word (abfd, src->d_tag); - dst->d_un.d_val = get_word (abfd, src->d_un.d_val); -} - -INLINE void -elf_swap_dyn_out (abfd, src, dst) - bfd *abfd; - const Elf_Internal_Dyn *src; - Elf_External_Dyn *dst; -{ - put_word (abfd, src->d_tag, dst->d_tag); - put_word (abfd, src->d_un.d_val, dst->d_un.d_val); -} - -/* ELF .o/exec file reading */ - - -/* Begin processing a given object. - - First we validate the file by reading in the ELF header and checking - the magic number. */ - -static INLINE boolean -elf_file_p (x_ehdrp) - Elf_External_Ehdr *x_ehdrp; -{ - return ((x_ehdrp->e_ident[EI_MAG0] == ELFMAG0) - && (x_ehdrp->e_ident[EI_MAG1] == ELFMAG1) - && (x_ehdrp->e_ident[EI_MAG2] == ELFMAG2) - && (x_ehdrp->e_ident[EI_MAG3] == ELFMAG3)); -} - -/* Check to see if the file associated with ABFD matches the target vector - that ABFD points to. - - Note that we may be called several times with the same ABFD, but different - target vectors, most of which will not match. We have to avoid leaving - any side effects in ABFD, or any data it points to (like tdata), if the - file does not match the target vector. */ - -const bfd_target * -elf_object_p (abfd) - bfd *abfd; -{ - Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ - Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ - Elf_External_Shdr x_shdr; /* Section header table entry, external form */ - Elf_Internal_Shdr *i_shdrp = NULL; /* Section header table, internal form */ - unsigned int shindex; - char *shstrtab; /* Internal copy of section header stringtab */ - struct elf_backend_data *ebd; - struct elf_obj_tdata *preserved_tdata = elf_tdata (abfd); - struct elf_obj_tdata *new_tdata = NULL; - - /* Read in the ELF header in external format. */ - - if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr)) - { - if (bfd_get_error () != bfd_error_system_call) - goto got_wrong_format_error; - else - goto got_no_match; - } - - /* Now check to see if we have a valid ELF file, and one that BFD can - make use of. The magic number must match, the address size ('class') - and byte-swapping must match our XVEC entry, and it must have a - section header table (FIXME: See comments re sections at top of this - file). */ - - if ((elf_file_p (&x_ehdr) == false) || - (x_ehdr.e_ident[EI_VERSION] != EV_CURRENT) || - (x_ehdr.e_ident[EI_CLASS] != ELFCLASS)) - goto got_wrong_format_error; - - /* Check that file's byte order matches xvec's */ - switch (x_ehdr.e_ident[EI_DATA]) - { - case ELFDATA2MSB: /* Big-endian */ - if (! bfd_header_big_endian (abfd)) - goto got_wrong_format_error; - break; - case ELFDATA2LSB: /* Little-endian */ - if (! bfd_header_little_endian (abfd)) - goto got_wrong_format_error; - break; - case ELFDATANONE: /* No data encoding specified */ - default: /* Unknown data encoding specified */ - goto got_wrong_format_error; - } - - /* Allocate an instance of the elf_obj_tdata structure and hook it up to - the tdata pointer in the bfd. */ - - new_tdata = ((struct elf_obj_tdata *) - bfd_zalloc (abfd, sizeof (struct elf_obj_tdata))); - if (new_tdata == NULL) - goto got_no_match; - elf_tdata (abfd) = new_tdata; - - /* Now that we know the byte order, swap in the rest of the header */ - i_ehdrp = elf_elfheader (abfd); - elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp); -#if DEBUG & 1 - elf_debug_file (i_ehdrp); -#endif - - /* If there is no section header table, we're hosed. */ - if (i_ehdrp->e_shoff == 0) - goto got_wrong_format_error; - - /* As a simple sanity check, verify that the what BFD thinks is the - size of each section header table entry actually matches the size - recorded in the file. */ - if (i_ehdrp->e_shentsize != sizeof (x_shdr)) - goto got_wrong_format_error; - - ebd = get_elf_backend_data (abfd); - - /* Check that the ELF e_machine field matches what this particular - BFD format expects. */ - if (ebd->elf_machine_code != i_ehdrp->e_machine - && (ebd->elf_machine_alt1 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt1) - && (ebd->elf_machine_alt2 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt2)) - { - const bfd_target * const *target_ptr; - - if (ebd->elf_machine_code != EM_NONE) - goto got_wrong_format_error; - - /* This is the generic ELF target. Let it match any ELF target - for which we do not have a specific backend. */ - for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++) - { - struct elf_backend_data *back; - - if ((*target_ptr)->flavour != bfd_target_elf_flavour) - continue; - back = (struct elf_backend_data *) (*target_ptr)->backend_data; - if (back->elf_machine_code == i_ehdrp->e_machine) - { - /* target_ptr is an ELF backend which matches this - object file, so reject the generic ELF target. */ - goto got_wrong_format_error; - } - } - } - - if (i_ehdrp->e_type == ET_EXEC) - abfd->flags |= EXEC_P; - else if (i_ehdrp->e_type == ET_DYN) - abfd->flags |= DYNAMIC; - - if (i_ehdrp->e_phnum > 0) - abfd->flags |= D_PAGED; - - if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0)) - goto got_no_match; - - /* Remember the entry point specified in the ELF file header. */ - bfd_get_start_address (abfd) = i_ehdrp->e_entry; - - /* Allocate space for a copy of the section header table in - internal form, seek to the section header table in the file, - read it in, and convert it to internal form. */ - i_shdrp = ((Elf_Internal_Shdr *) - bfd_alloc (abfd, sizeof (*i_shdrp) * i_ehdrp->e_shnum)); - elf_elfsections (abfd) = ((Elf_Internal_Shdr **) - bfd_alloc (abfd, - sizeof (i_shdrp) * i_ehdrp->e_shnum)); - if (!i_shdrp || !elf_elfsections (abfd)) - goto got_no_match; - if (bfd_seek (abfd, i_ehdrp->e_shoff, SEEK_SET) != 0) - goto got_no_match; - for (shindex = 0; shindex < i_ehdrp->e_shnum; shindex++) - { - if (bfd_read ((PTR) & x_shdr, sizeof x_shdr, 1, abfd) != sizeof (x_shdr)) - goto got_no_match; - elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex); - elf_elfsections (abfd)[shindex] = i_shdrp + shindex; - } - if (i_ehdrp->e_shstrndx) - { - if (! bfd_section_from_shdr (abfd, i_ehdrp->e_shstrndx)) - goto got_no_match; - } - - /* Read in the program headers. */ - if (i_ehdrp->e_phnum == 0) - elf_tdata (abfd)->phdr = NULL; - else - { - Elf_Internal_Phdr *i_phdr; - unsigned int i; - - elf_tdata (abfd)->phdr = ((Elf_Internal_Phdr *) - bfd_alloc (abfd, - (i_ehdrp->e_phnum - * sizeof (Elf_Internal_Phdr)))); - if (elf_tdata (abfd)->phdr == NULL) - goto got_no_match; - if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) != 0) - goto got_no_match; - i_phdr = elf_tdata (abfd)->phdr; - for (i = 0; i < i_ehdrp->e_phnum; i++, i_phdr++) - { - Elf_External_Phdr x_phdr; - - if (bfd_read ((PTR) &x_phdr, sizeof x_phdr, 1, abfd) - != sizeof x_phdr) - goto got_no_match; - elf_swap_phdr_in (abfd, &x_phdr, i_phdr); - } - } - - /* Read in the string table containing the names of the sections. We - will need the base pointer to this table later. */ - /* We read this inline now, so that we don't have to go through - bfd_section_from_shdr with it (since this particular strtab is - used to find all of the ELF section names.) */ - - shstrtab = bfd_elf_get_str_section (abfd, i_ehdrp->e_shstrndx); - if (!shstrtab) - goto got_no_match; - - /* Once all of the section headers have been read and converted, we - can start processing them. Note that the first section header is - a dummy placeholder entry, so we ignore it. */ - - for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++) - { - if (! bfd_section_from_shdr (abfd, shindex)) - goto got_no_match; - } - - /* Let the backend double check the format and override global - information. */ - if (ebd->elf_backend_object_p) - { - if ((*ebd->elf_backend_object_p) (abfd) == false) - goto got_wrong_format_error; - } - - return (abfd->xvec); - -got_wrong_format_error: - bfd_set_error (bfd_error_wrong_format); - goto got_no_match; -got_no_match: - if (new_tdata != NULL - && new_tdata->elf_sect_ptr != NULL) - bfd_release (abfd, new_tdata->elf_sect_ptr); - if (i_shdrp != NULL) - bfd_release (abfd, i_shdrp); - if (new_tdata != NULL) - bfd_release (abfd, new_tdata); - elf_tdata (abfd) = preserved_tdata; - return (NULL); -} - -/* 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 -write_relocs (abfd, sec, data) - bfd *abfd; - asection *sec; - PTR data; -{ - boolean *failedp = (boolean *) data; - Elf_Internal_Shdr *rela_hdr; - Elf_External_Rela *outbound_relocas; - Elf_External_Rel *outbound_relocs; - unsigned int idx; - int use_rela_p = get_elf_backend_data (abfd)->use_rela_p; - asymbol *last_sym = 0; - int last_sym_idx = 0; - - /* If we have already failed, don't do anything. */ - if (*failedp) - return; - - if ((sec->flags & SEC_RELOC) == 0) - return; - - /* The linker backend writes the relocs out itself, and sets the - reloc_count field to zero to inhibit writing them here. Also, - sometimes the SEC_RELOC flag gets set even when there aren't any - relocs. */ - if (sec->reloc_count == 0) - return; - - rela_hdr = &elf_section_data (sec)->rel_hdr; - - rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count; - rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size); - if (rela_hdr->contents == NULL) - { - *failedp = true; - return; - } - - /* orelocation has the data, reloc_count has the count... */ - if (use_rela_p) - { - outbound_relocas = (Elf_External_Rela *) rela_hdr->contents; - - for (idx = 0; idx < sec->reloc_count; idx++) - { - Elf_Internal_Rela dst_rela; - Elf_External_Rela *src_rela; - arelent *ptr; - asymbol *sym; - int n; - - ptr = sec->orelocation[idx]; - src_rela = outbound_relocas + idx; - - /* 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) - dst_rela.r_offset = ptr->address; - else - dst_rela.r_offset = ptr->address + sec->vma; - - sym = *ptr->sym_ptr_ptr; - if (sym == last_sym) - n = last_sym_idx; - else - { - last_sym = sym; - n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym); - if (n < 0) - { - *failedp = true; - return; - } - last_sym_idx = n; - } - - if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec - && ! validate_reloc (abfd, ptr)) - { - *failedp = true; - return; - } - - dst_rela.r_info = ELF_R_INFO (n, ptr->howto->type); - - dst_rela.r_addend = ptr->addend; - elf_swap_reloca_out (abfd, &dst_rela, src_rela); - } - } - else - /* REL relocations */ - { - outbound_relocs = (Elf_External_Rel *) rela_hdr->contents; - - for (idx = 0; idx < sec->reloc_count; idx++) - { - Elf_Internal_Rel dst_rel; - Elf_External_Rel *src_rel; - arelent *ptr; - int n; - asymbol *sym; - - ptr = sec->orelocation[idx]; - sym = *ptr->sym_ptr_ptr; - src_rel = outbound_relocs + idx; - - /* 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) - dst_rel.r_offset = ptr->address; - else - dst_rel.r_offset = ptr->address + sec->vma; - - if (sym == last_sym) - n = last_sym_idx; - else - { - last_sym = sym; - n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym); - if (n < 0) - { - *failedp = true; - return; - } - last_sym_idx = n; - } - - if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec - && ! validate_reloc (abfd, ptr)) - { - *failedp = true; - return; - } - - dst_rel.r_info = ELF_R_INFO (n, ptr->howto->type); - - elf_swap_reloc_out (abfd, &dst_rel, src_rel); - } - } -} - -static int -write_out_phdrs (abfd, phdr, count) - bfd *abfd; - Elf_Internal_Phdr *phdr; - int count; -{ - while (count--) - { - Elf_External_Phdr extphdr; - elf_swap_phdr_out (abfd, phdr, &extphdr); - if (bfd_write (&extphdr, sizeof (Elf_External_Phdr), 1, abfd) - != sizeof (Elf_External_Phdr)) - return -1; - phdr++; - } - return 0; -} - -static boolean -write_shdrs_and_ehdr (abfd) - bfd *abfd; -{ - Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ - Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ - Elf_External_Shdr *x_shdrp; /* Section header table, external form */ - Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */ - unsigned int count; - - i_ehdrp = elf_elfheader (abfd); - i_shdrp = elf_elfsections (abfd); - - /* swap the header before spitting it out... */ - -#if DEBUG & 1 - elf_debug_file (i_ehdrp); -#endif - elf_swap_ehdr_out (abfd, i_ehdrp, &x_ehdr); - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || (bfd_write ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) - != sizeof (x_ehdr))) - return false; - - /* at this point we've concocted all the ELF sections... */ - x_shdrp = (Elf_External_Shdr *) - bfd_alloc (abfd, sizeof (*x_shdrp) * (i_ehdrp->e_shnum)); - if (!x_shdrp) - return false; - - for (count = 0; count < i_ehdrp->e_shnum; count++) - { -#if DEBUG & 2 - elf_debug_section (count, i_shdrp[count]); -#endif - elf_swap_shdr_out (abfd, i_shdrp[count], x_shdrp + count); - } - if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0 - || (bfd_write ((PTR) x_shdrp, sizeof (*x_shdrp), i_ehdrp->e_shnum, abfd) - != sizeof (*x_shdrp) * i_ehdrp->e_shnum)) - return false; - - /* need to dump the string table too... */ - - return true; -} - -static long -elf_slurp_symbol_table (abfd, symptrs, dynamic) - bfd *abfd; - asymbol **symptrs; /* Buffer for generated bfd symbols */ - boolean dynamic; -{ - Elf_Internal_Shdr *hdr; - long symcount; /* Number of external ELF symbols */ - elf_symbol_type *sym; /* Pointer to current bfd symbol */ - elf_symbol_type *symbase; /* Buffer for generated bfd symbols */ - Elf_Internal_Sym i_sym; - Elf_External_Sym *x_symp = NULL; - - /* Read each raw ELF symbol, converting from external ELF form to - internal ELF form, and then using the information to create a - canonical bfd symbol table entry. - - Note that we allocate the initial bfd canonical symbol buffer - based on a one-to-one mapping of the ELF symbols to canonical - symbols. We actually use all the ELF symbols, so there will be no - space left over at the end. When we have all the symbols, we - build the caller's pointer vector. */ - - if (dynamic) - hdr = &elf_tdata (abfd)->dynsymtab_hdr; - else - hdr = &elf_tdata (abfd)->symtab_hdr; - if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1) - return -1; - - symcount = hdr->sh_size / sizeof (Elf_External_Sym); - - if (symcount == 0) - sym = symbase = NULL; - else - { - long i; - - if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1) - return -1; - - symbase = ((elf_symbol_type *) - bfd_zalloc (abfd, symcount * sizeof (elf_symbol_type))); - if (symbase == (elf_symbol_type *) NULL) - return -1; - sym = symbase; - - /* Temporarily allocate room for the raw ELF symbols. */ - x_symp = ((Elf_External_Sym *) - bfd_malloc (symcount * sizeof (Elf_External_Sym))); - if (x_symp == NULL && symcount != 0) - goto error_return; - - if (bfd_read ((PTR) x_symp, sizeof (Elf_External_Sym), symcount, abfd) - != symcount * sizeof (Elf_External_Sym)) - goto error_return; - /* Skip first symbol, which is a null dummy. */ - for (i = 1; i < symcount; i++) - { - elf_swap_symbol_in (abfd, x_symp + i, &i_sym); - memcpy (&sym->internal_elf_sym, &i_sym, sizeof (Elf_Internal_Sym)); -#ifdef ELF_KEEP_EXTSYM - memcpy (&sym->native_elf_sym, x_symp + i, sizeof (Elf_External_Sym)); -#endif - sym->symbol.the_bfd = abfd; - - sym->symbol.name = bfd_elf_string_from_elf_section (abfd, - hdr->sh_link, - i_sym.st_name); - - sym->symbol.value = i_sym.st_value; - - if (i_sym.st_shndx > 0 && i_sym.st_shndx < SHN_LORESERVE) - { - sym->symbol.section = section_from_elf_index (abfd, - i_sym.st_shndx); - if (sym->symbol.section == NULL) - { - /* This symbol is in a section for which we did not - create a BFD section. Just use bfd_abs_section, - although it is wrong. FIXME. */ - sym->symbol.section = bfd_abs_section_ptr; - } - } - else if (i_sym.st_shndx == SHN_ABS) - { - sym->symbol.section = bfd_abs_section_ptr; - } - else if (i_sym.st_shndx == SHN_COMMON) - { - sym->symbol.section = bfd_com_section_ptr; - /* Elf puts the alignment into the `value' field, and - the size into the `size' field. BFD wants to see the - size in the value field, and doesn't care (at the - moment) about the alignment. */ - sym->symbol.value = i_sym.st_size; - } - else if (i_sym.st_shndx == SHN_UNDEF) - { - sym->symbol.section = bfd_und_section_ptr; - } - else - sym->symbol.section = bfd_abs_section_ptr; - - sym->symbol.value -= sym->symbol.section->vma; - - switch (ELF_ST_BIND (i_sym.st_info)) - { - case STB_LOCAL: - sym->symbol.flags |= BSF_LOCAL; - break; - case STB_GLOBAL: - if (i_sym.st_shndx != SHN_UNDEF - && i_sym.st_shndx != SHN_COMMON) - sym->symbol.flags |= BSF_GLOBAL; - break; - case STB_WEAK: - sym->symbol.flags |= BSF_WEAK; - break; - } - - switch (ELF_ST_TYPE (i_sym.st_info)) - { - case STT_SECTION: - sym->symbol.flags |= BSF_SECTION_SYM | BSF_DEBUGGING; - break; - case STT_FILE: - sym->symbol.flags |= BSF_FILE | BSF_DEBUGGING; - break; - case STT_FUNC: - sym->symbol.flags |= BSF_FUNCTION; - break; - case STT_OBJECT: - sym->symbol.flags |= BSF_OBJECT; - break; - } - - if (dynamic) - sym->symbol.flags |= BSF_DYNAMIC; - - /* Do some backend-specific processing on this symbol. */ - { - struct elf_backend_data *ebd = get_elf_backend_data (abfd); - if (ebd->elf_backend_symbol_processing) - (*ebd->elf_backend_symbol_processing) (abfd, &sym->symbol); - } - - sym++; - } - } - - /* Do some backend-specific processing on this symbol table. */ - { - struct elf_backend_data *ebd = get_elf_backend_data (abfd); - if (ebd->elf_backend_symbol_table_processing) - (*ebd->elf_backend_symbol_table_processing) (abfd, symbase, symcount); - } - - /* We rely on the zalloc to clear out the final symbol entry. */ - - symcount = sym - symbase; - - /* Fill in the user's symbol pointer vector if needed. */ - if (symptrs) - { - long l = symcount; - - sym = symbase; - while (l-- > 0) - { - *symptrs++ = &sym->symbol; - sym++; - } - *symptrs = 0; /* Final null pointer */ - } - - if (x_symp != NULL) - free (x_symp); - return symcount; -error_return: - if (x_symp != NULL) - free (x_symp); - return -1; -} - -/* Read in and swap the external relocs. */ - -static boolean -elf_slurp_reloc_table (abfd, asect, symbols) - bfd *abfd; - asection *asect; - asymbol **symbols; -{ - struct elf_backend_data * const ebd = get_elf_backend_data (abfd); - struct bfd_elf_section_data * const d = elf_section_data (asect); - PTR allocated = NULL; - bfd_byte *native_relocs; - arelent *relents; - arelent *relent; - unsigned int i; - int entsize; - - if (asect->relocation != NULL - || (asect->flags & SEC_RELOC) == 0 - || asect->reloc_count == 0) - 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)); - - allocated = (PTR) bfd_malloc ((size_t) d->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)) - goto error_return; - - native_relocs = (bfd_byte *) allocated; - - relents = ((arelent *) - bfd_alloc (abfd, asect->reloc_count * sizeof (arelent))); - if (relents == NULL) - goto error_return; - - entsize = d->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++, relent++, native_relocs += entsize) - { - Elf_Internal_Rela rela; - Elf_Internal_Rel rel; - - if (entsize == sizeof (Elf_External_Rela)) - elf_swap_reloca_in (abfd, (Elf_External_Rela *) native_relocs, &rela); - else - { - elf_swap_reloc_in (abfd, (Elf_External_Rel *) native_relocs, &rel); - rela.r_offset = rel.r_offset; - rela.r_info = rel.r_info; - rela.r_addend = 0; - } - - /* 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) - relent->address = rela.r_offset; - else - relent->address = rela.r_offset - asect->vma; - - if (ELF_R_SYM (rela.r_info) == 0) - relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - else - { - asymbol **ps, *s; - - ps = symbols + ELF_R_SYM (rela.r_info) - 1; - s = *ps; - - /* Canonicalize ELF section symbols. FIXME: Why? */ - if ((s->flags & BSF_SECTION_SYM) == 0) - relent->sym_ptr_ptr = ps; - else - relent->sym_ptr_ptr = s->section->symbol_ptr_ptr; - } - - relent->addend = rela.r_addend; - - if (entsize == sizeof (Elf_External_Rela)) - (*ebd->elf_info_to_howto) (abfd, relent, &rela); - else - (*ebd->elf_info_to_howto_rel) (abfd, relent, &rel); - } - - asect->relocation = relents; - - if (allocated != NULL) - free (allocated); - - return true; - - error_return: - if (allocated != NULL) - free (allocated); - return false; -} - -#ifdef DEBUG -static void -elf_debug_section (num, hdr) - int num; - Elf_Internal_Shdr *hdr; -{ - fprintf (stderr, "\nSection#%d '%s' 0x%.8lx\n", num, - hdr->bfd_section != NULL ? hdr->bfd_section->name : "", - (long) hdr); - fprintf (stderr, - "sh_name = %ld\tsh_type = %ld\tsh_flags = %ld\n", - (long) hdr->sh_name, - (long) hdr->sh_type, - (long) hdr->sh_flags); - fprintf (stderr, - "sh_addr = %ld\tsh_offset = %ld\tsh_size = %ld\n", - (long) hdr->sh_addr, - (long) hdr->sh_offset, - (long) hdr->sh_size); - fprintf (stderr, - "sh_link = %ld\tsh_info = %ld\tsh_addralign = %ld\n", - (long) hdr->sh_link, - (long) hdr->sh_info, - (long) hdr->sh_addralign); - fprintf (stderr, "sh_entsize = %ld\n", - (long) hdr->sh_entsize); - fflush (stderr); -} - -static void -elf_debug_file (ehdrp) - Elf_Internal_Ehdr *ehdrp; -{ - fprintf (stderr, "e_entry = 0x%.8lx\n", (long) ehdrp->e_entry); - fprintf (stderr, "e_phoff = %ld\n", (long) ehdrp->e_phoff); - fprintf (stderr, "e_phnum = %ld\n", (long) ehdrp->e_phnum); - fprintf (stderr, "e_phentsize = %ld\n", (long) ehdrp->e_phentsize); - fprintf (stderr, "e_shoff = %ld\n", (long) ehdrp->e_shoff); - fprintf (stderr, "e_shnum = %ld\n", (long) ehdrp->e_shnum); - fprintf (stderr, "e_shentsize = %ld\n", (long) ehdrp->e_shentsize); -} - -static char * -elf_symbol_flags (flags) - flagword flags; -{ - static char buffer[1024]; - - buffer[0] = '\0'; - if (flags & BSF_LOCAL) - strcat (buffer, " local"); - - if (flags & BSF_GLOBAL) - strcat (buffer, " global"); - - if (flags & BSF_DEBUGGING) - strcat (buffer, " debug"); - - if (flags & BSF_FUNCTION) - strcat (buffer, " function"); - - if (flags & BSF_KEEP) - strcat (buffer, " keep"); - - if (flags & BSF_KEEP_G) - strcat (buffer, " keep_g"); - - if (flags & BSF_WEAK) - strcat (buffer, " weak"); - - if (flags & BSF_SECTION_SYM) - strcat (buffer, " section-sym"); - - if (flags & BSF_OLD_COMMON) - strcat (buffer, " old-common"); - - if (flags & BSF_NOT_AT_END) - strcat (buffer, " not-at-end"); - - if (flags & BSF_CONSTRUCTOR) - strcat (buffer, " constructor"); - - if (flags & BSF_WARNING) - strcat (buffer, " warning"); - - if (flags & BSF_INDIRECT) - strcat (buffer, " indirect"); - - if (flags & BSF_FILE) - strcat (buffer, " file"); - - if (flags & DYNAMIC) - strcat (buffer, " dynamic"); - - if (flags & ~(BSF_LOCAL - | BSF_GLOBAL - | BSF_DEBUGGING - | BSF_FUNCTION - | BSF_KEEP - | BSF_KEEP_G - | BSF_WEAK - | BSF_SECTION_SYM - | BSF_OLD_COMMON - | BSF_NOT_AT_END - | BSF_CONSTRUCTOR - | BSF_WARNING - | BSF_INDIRECT - | BSF_FILE - | BSF_DYNAMIC)) - strcat (buffer, " unknown-bits"); - - return buffer; -} -#endif - -#include "elfcore.h" -#include "elflink.h" - -/* Size-dependent data and functions. */ -const struct elf_size_info NAME(_bfd_elf,size_info) = { - sizeof (Elf_External_Ehdr), - sizeof (Elf_External_Phdr), - sizeof (Elf_External_Shdr), - sizeof (Elf_External_Rel), - sizeof (Elf_External_Rela), - sizeof (Elf_External_Sym), - sizeof (Elf_External_Dyn), - sizeof (Elf_External_Note), - - ARCH_SIZE, FILE_ALIGN, - ELFCLASS, EV_CURRENT, - write_out_phdrs, - write_shdrs_and_ehdr, - write_relocs, - elf_swap_symbol_out, - elf_slurp_reloc_table, - elf_slurp_symbol_table, - elf_swap_dyn_in -}; diff --git a/contrib/gdb/bfd/elfcore.h b/contrib/gdb/bfd/elfcore.h deleted file mode 100644 index 8100627..0000000 --- a/contrib/gdb/bfd/elfcore.h +++ /dev/null @@ -1,475 +0,0 @@ -/* ELF core file support for BFD. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - -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. */ -/* Core file support */ - -#ifdef HAVE_SYS_PROCFS_H /* Some core file support requires host /proc files */ -#include <signal.h> -#include <sys/procfs.h> -#else -#define bfd_prstatus(abfd, descdata, descsz, filepos) true -#define bfd_fpregset(abfd, descdata, descsz, filepos) true -#define bfd_prpsinfo(abfd, descdata, descsz, filepos) true -#endif - -#ifdef HAVE_SYS_PROCFS_H - -static boolean -bfd_prstatus (abfd, descdata, descsz, filepos) - bfd *abfd; - char *descdata; - int descsz; - long filepos; -{ - asection *newsect; - prstatus_t *status = (prstatus_t *) 0; - - if (descsz == sizeof (prstatus_t)) - { - newsect = bfd_make_section (abfd, ".reg"); - if (newsect == NULL) - return false; - newsect->_raw_size = sizeof (status->pr_reg); - newsect->filepos = filepos + (long) &status->pr_reg; - newsect->flags = SEC_HAS_CONTENTS; - newsect->alignment_power = 2; - if ((core_prstatus (abfd) = bfd_alloc (abfd, descsz)) != NULL) - { - memcpy (core_prstatus (abfd), descdata, descsz); - } - } - return true; -} - -/* Stash a copy of the prpsinfo structure away for future use. */ - -static boolean -bfd_prpsinfo (abfd, descdata, descsz, filepos) - bfd *abfd; - char *descdata; - int descsz; - long filepos; -{ - if (descsz == sizeof (prpsinfo_t)) - { - if ((core_prpsinfo (abfd) = bfd_alloc (abfd, descsz)) == NULL) - return false; - memcpy (core_prpsinfo (abfd), descdata, descsz); - } - return true; -} - -static boolean -bfd_fpregset (abfd, descdata, descsz, filepos) - bfd *abfd; - char *descdata; - int descsz; - long filepos; -{ - asection *newsect; - - newsect = bfd_make_section (abfd, ".reg2"); - if (newsect == NULL) - return false; - newsect->_raw_size = descsz; - newsect->filepos = filepos; - newsect->flags = SEC_HAS_CONTENTS; - newsect->alignment_power = 2; - return true; -} - -#endif /* HAVE_SYS_PROCFS_H */ - -/* Return a pointer to the args (including the command name) that were - seen by the program that generated the core dump. Note that for - some reason, a spurious space is tacked onto the end of the args - in some (at least one anyway) implementations, so strip it off if - it exists. */ - -char * -elf_core_file_failing_command (abfd) - bfd *abfd; -{ -#ifdef HAVE_SYS_PROCFS_H - if (core_prpsinfo (abfd)) - { - prpsinfo_t *p = core_prpsinfo (abfd); - char *scan = p->pr_psargs; - while (*scan++) - {; - } - scan -= 2; - if ((scan > p->pr_psargs) && (*scan == ' ')) - { - *scan = '\000'; - } - return p->pr_psargs; - } -#endif - return NULL; -} - -/* Return the number of the signal that caused the core dump. Presumably, - since we have a core file, we got a signal of some kind, so don't bother - checking the other process status fields, just return the signal number. - */ - -int -elf_core_file_failing_signal (abfd) - bfd *abfd; -{ -#ifdef HAVE_SYS_PROCFS_H - if (core_prstatus (abfd)) - { - return ((prstatus_t *) (core_prstatus (abfd)))->pr_cursig; - } -#endif - return -1; -} - -/* Check to see if the core file could reasonably be expected to have - come for the current executable file. Note that by default we return - true unless we find something that indicates that there might be a - problem. - */ - -boolean -elf_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd; - bfd *exec_bfd; -{ -#ifdef HAVE_SYS_PROCFS_H - char *corename; - char *execname; -#endif - - /* First, xvecs must match since both are ELF files for the same target. */ - - if (core_bfd->xvec != exec_bfd->xvec) - { - bfd_set_error (bfd_error_system_call); - return false; - } - -#ifdef HAVE_SYS_PROCFS_H - - /* If no prpsinfo, just return true. Otherwise, grab the last component - of the exec'd pathname from the prpsinfo. */ - - if (core_prpsinfo (core_bfd)) - { - corename = (((prpsinfo_t *) core_prpsinfo (core_bfd))->pr_fname); - } - else - { - return true; - } - - /* Find the last component of the executable pathname. */ - - if ((execname = strrchr (exec_bfd->filename, '/')) != NULL) - { - execname++; - } - else - { - execname = (char *) exec_bfd->filename; - } - - /* See if they match */ - - return strcmp (execname, corename) ? false : true; - -#else - - return true; - -#endif /* HAVE_SYS_PROCFS_H */ -} - -/* ELF core files contain a segment of type PT_NOTE, that holds much of - the information that would normally be available from the /proc interface - for the process, at the time the process dumped core. Currently this - includes copies of the prstatus, prpsinfo, and fpregset structures. - - Since these structures are potentially machine dependent in size and - ordering, bfd provides two levels of support for them. The first level, - available on all machines since it does not require that the host - have /proc support or the relevant include files, is to create a bfd - section for each of the prstatus, prpsinfo, and fpregset structures, - without any interpretation of their contents. With just this support, - the bfd client will have to interpret the structures itself. Even with - /proc support, it might want these full structures for it's own reasons. - - In the second level of support, where HAVE_SYS_PROCFS_H is defined, - bfd will pick apart the structures to gather some additional - information that clients may want, such as the general register - set, the name of the exec'ed file and its arguments, the signal (if - any) that caused the core dump, etc. - - */ - -static boolean -elf_corefile_note (abfd, hdr) - bfd *abfd; - Elf_Internal_Phdr *hdr; -{ - Elf_External_Note *x_note_p; /* Elf note, external form */ - Elf_Internal_Note i_note; /* Elf note, internal form */ - char *buf = NULL; /* Entire note segment contents */ - char *namedata; /* Name portion of the note */ - char *descdata; /* Descriptor portion of the note */ - char *sectname; /* Name to use for new section */ - long filepos; /* File offset to descriptor data */ - asection *newsect; - - if (hdr->p_filesz > 0 - && (buf = (char *) bfd_malloc ((size_t) hdr->p_filesz)) != NULL - && bfd_seek (abfd, hdr->p_offset, SEEK_SET) != -1 - && bfd_read ((PTR) buf, hdr->p_filesz, 1, abfd) == hdr->p_filesz) - { - x_note_p = (Elf_External_Note *) buf; - while ((char *) x_note_p < (buf + hdr->p_filesz)) - { - i_note.namesz = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p->namesz); - i_note.descsz = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p->descsz); - i_note.type = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p->type); - namedata = x_note_p->name; - descdata = namedata + BFD_ALIGN (i_note.namesz, 4); - filepos = hdr->p_offset + (descdata - buf); - switch (i_note.type) - { - case NT_PRSTATUS: - /* process descdata as prstatus info */ - if (! bfd_prstatus (abfd, descdata, i_note.descsz, filepos)) - return false; - sectname = ".prstatus"; - break; - case NT_FPREGSET: - /* process descdata as fpregset info */ - if (! bfd_fpregset (abfd, descdata, i_note.descsz, filepos)) - return false; - sectname = ".fpregset"; - break; - case NT_PRPSINFO: - /* process descdata as prpsinfo */ - if (! bfd_prpsinfo (abfd, descdata, i_note.descsz, filepos)) - return false; - sectname = ".prpsinfo"; - break; - default: - /* Unknown descriptor, just ignore it. */ - sectname = NULL; - break; - } - if (sectname != NULL) - { - newsect = bfd_make_section (abfd, sectname); - if (newsect == NULL) - return false; - newsect->_raw_size = i_note.descsz; - newsect->filepos = filepos; - newsect->flags = SEC_ALLOC | SEC_HAS_CONTENTS; - newsect->alignment_power = 2; - } - x_note_p = (Elf_External_Note *) - (descdata + BFD_ALIGN (i_note.descsz, 4)); - } - } - if (buf != NULL) - { - free (buf); - } - else if (hdr->p_filesz > 0) - { - return false; - } - return true; - -} - -/* Core files are simply standard ELF formatted files that partition - the file using the execution view of the file (program header table) - rather than the linking view. In fact, there is no section header - table in a core file. - - The process status information (including the contents of the general - register set) and the floating point register set are stored in a - segment of type PT_NOTE. We handcraft a couple of extra bfd sections - that allow standard bfd access to the general registers (.reg) and the - floating point registers (.reg2). - - */ - -const bfd_target * -elf_core_file_p (abfd) - bfd *abfd; -{ - Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ - Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ - Elf_External_Phdr x_phdr; /* Program header table entry, external form */ - Elf_Internal_Phdr *i_phdrp; /* Program header table, internal form */ - unsigned int phindex; - struct elf_backend_data *ebd; - - /* Read in the ELF header in external format. */ - - if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr)) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* Now check to see if we have a valid ELF file, and one that BFD can - make use of. The magic number must match, the address size ('class') - and byte-swapping must match our XVEC entry, and it must have a - program header table (FIXME: See comments re segments at top of this - file). */ - - if (elf_file_p (&x_ehdr) == false) - { - wrong: - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* FIXME, Check EI_VERSION here ! */ - - { -#if ARCH_SIZE == 32 - int desired_address_size = ELFCLASS32; -#endif -#if ARCH_SIZE == 64 - int desired_address_size = ELFCLASS64; -#endif - - if (x_ehdr.e_ident[EI_CLASS] != desired_address_size) - goto wrong; - } - - /* Switch xvec to match the specified byte order. */ - switch (x_ehdr.e_ident[EI_DATA]) - { - case ELFDATA2MSB: /* Big-endian */ - if (! bfd_big_endian (abfd)) - goto wrong; - break; - case ELFDATA2LSB: /* Little-endian */ - if (! bfd_little_endian (abfd)) - goto wrong; - break; - case ELFDATANONE: /* No data encoding specified */ - default: /* Unknown data encoding specified */ - goto wrong; - } - - /* Allocate an instance of the elf_obj_tdata structure and hook it up to - the tdata pointer in the bfd. */ - - elf_tdata (abfd) = - (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata)); - if (elf_tdata (abfd) == NULL) - return NULL; - - /* FIXME, `wrong' returns from this point onward, leak memory. */ - - /* Now that we know the byte order, swap in the rest of the header */ - i_ehdrp = elf_elfheader (abfd); - elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp); -#if DEBUG & 1 - elf_debug_file (i_ehdrp); -#endif - - ebd = get_elf_backend_data (abfd); - - /* Check that the ELF e_machine field matches what this particular - BFD format expects. */ - if (ebd->elf_machine_code != i_ehdrp->e_machine - && (ebd->elf_machine_alt1 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt1) - && (ebd->elf_machine_alt2 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt2)) - { - const bfd_target * const *target_ptr; - - if (ebd->elf_machine_code != EM_NONE) - goto wrong; - - /* This is the generic ELF target. Let it match any ELF target - for which we do not have a specific backend. */ - for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++) - { - struct elf_backend_data *back; - - if ((*target_ptr)->flavour != bfd_target_elf_flavour) - continue; - back = (struct elf_backend_data *) (*target_ptr)->backend_data; - if (back->elf_machine_code == i_ehdrp->e_machine) - { - /* target_ptr is an ELF backend which matches this - object file, so reject the generic ELF target. */ - goto wrong; - } - } - } - - /* If there is no program header, or the type is not a core file, then - we are hosed. */ - if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE) - goto wrong; - - /* Allocate space for a copy of the program header table in - internal form, seek to the program header table in the file, - read it in, and convert it to internal form. As a simple sanity - check, verify that the what BFD thinks is the size of each program - header table entry actually matches the size recorded in the file. */ - - if (i_ehdrp->e_phentsize != sizeof (x_phdr)) - goto wrong; - i_phdrp = (Elf_Internal_Phdr *) - bfd_alloc (abfd, sizeof (*i_phdrp) * i_ehdrp->e_phnum); - if (!i_phdrp) - return NULL; - if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) == -1) - return NULL; - for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++) - { - if (bfd_read ((PTR) & x_phdr, sizeof (x_phdr), 1, abfd) - != sizeof (x_phdr)) - return NULL; - elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex); - } - - /* Once all of the program headers have been read and converted, we - can start processing them. */ - - for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++) - { - bfd_section_from_phdr (abfd, i_phdrp + phindex, phindex); - if ((i_phdrp + phindex)->p_type == PT_NOTE) - { - if (! elf_corefile_note (abfd, i_phdrp + phindex)) - return NULL; - } - } - - /* Remember the entry point specified in the ELF file header. */ - - bfd_get_start_address (abfd) = i_ehdrp->e_entry; - - return abfd->xvec; -} diff --git a/contrib/gdb/bfd/elflink.c b/contrib/gdb/bfd/elflink.c deleted file mode 100644 index 7b204f7..0000000 --- a/contrib/gdb/bfd/elflink.c +++ /dev/null @@ -1,372 +0,0 @@ -/* ELF linking support for BFD. - Copyright 1995 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#define ARCH_SIZE 0 -#include "elf-bfd.h" - -boolean -_bfd_elf_create_got_section (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - flagword flags; - register asection *s; - struct elf_link_hash_entry *h; - struct elf_backend_data *bed = get_elf_backend_data (abfd); - - /* This function may be called more than once. */ - if (bfd_get_section_by_name (abfd, ".got") != NULL) - return true; - - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - - s = bfd_make_section (abfd, ".got"); - if (s == NULL - || !bfd_set_section_flags (abfd, s, flags) - || !bfd_set_section_alignment (abfd, s, 2)) - return false; - - if (bed->want_got_plt) - { - s = bfd_make_section (abfd, ".got.plt"); - if (s == NULL - || !bfd_set_section_flags (abfd, s, flags) - || !bfd_set_section_alignment (abfd, s, 2)) - return false; - } - - /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got - (or .got.plt) section. We don't do this in the linker script - because we don't want to define the symbol if we are not creating - a global offset table. */ - h = NULL; - if (!(_bfd_generic_link_add_one_symbol - (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s, (bfd_vma) 0, - (const char *) NULL, false, get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h))) - return false; - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - h->type = STT_OBJECT; - - if (info->shared - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) - return false; - - /* The first three global offset table entries are reserved. */ - s->_raw_size += 3 * 4; - - return true; -} - - -/* Create dynamic sections when linking against a dynamic object. */ - -boolean -_bfd_elf_create_dynamic_sections (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - flagword flags; - register asection *s; - struct elf_backend_data *bed = get_elf_backend_data (abfd); - - /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and - .rel[a].bss sections. */ - - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - - s = bfd_make_section (abfd, ".plt"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, - (flags | SEC_CODE - | (bed->plt_readonly ? SEC_READONLY : 0))) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - if (bed->want_plt_sym) - { - /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the - .plt section. */ - struct elf_link_hash_entry *h = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s, - (bfd_vma) 0, (const char *) NULL, false, - get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h))) - return false; - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - h->type = STT_OBJECT; - - if (info->shared - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) - return false; - } - - s = bfd_make_section (abfd, bed->use_rela_p ? ".rela.plt" : ".rel.plt"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - if (! _bfd_elf_create_got_section (abfd, info)) - return false; - - /* The .dynbss section is a place to put symbols which are defined - by dynamic objects, are referenced by regular objects, and are - not functions. We must allocate space for them in the process - image and use a R_*_COPY reloc to tell the dynamic linker to - initialize them at run time. The linker script puts the .dynbss - section into the .bss section of the final image. */ - s = bfd_make_section (abfd, ".dynbss"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, SEC_ALLOC)) - return false; - - /* The .rel[a].bss section holds copy relocs. This section is not - normally needed. We need to create it here, though, so that the - linker will map it to an output section. We can't just create it - only if we need it, because we will not know whether we need it - until we have seen all the input files, and the first time the - main linker code calls BFD after examining all the input files - (size_dynamic_sections) the input sections have already been - mapped to the output sections. If the section turns out not to - be needed, we can discard it later. We will never need this - section when generating a shared object, since they do not use - copy relocs. */ - if (! info->shared) - { - s = bfd_make_section (abfd, bed->use_rela_p ? ".rela.bss" : ".rel.bss"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - } - - return true; -} - - -/* Record a new dynamic symbol. We record the dynamic symbols as we - read the input files, since we need to have a list of all of them - before we can determine the final sizes of the output sections. - Note that we may actually call this function even though we are not - going to output any dynamic symbols; in some cases we know that a - symbol should be in the dynamic symbol table, but only if there is - one. */ - -boolean -_bfd_elf_link_record_dynamic_symbol (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; -{ - if (h->dynindx == -1) - { - struct bfd_strtab_hash *dynstr; - - h->dynindx = elf_hash_table (info)->dynsymcount; - ++elf_hash_table (info)->dynsymcount; - - dynstr = elf_hash_table (info)->dynstr; - if (dynstr == NULL) - { - /* Create a strtab to hold the dynamic symbol names. */ - elf_hash_table (info)->dynstr = dynstr = _bfd_elf_stringtab_init (); - if (dynstr == NULL) - return false; - } - - h->dynstr_index = ((unsigned long) - _bfd_stringtab_add (dynstr, h->root.root.string, - true, false)); - if (h->dynstr_index == (unsigned long) -1) - return false; - } - - return true; -} - -/* Create a special linker section, or return a pointer to a linker section already created */ - -elf_linker_section_t * -_bfd_elf_create_linker_section (abfd, info, which, defaults) - bfd *abfd; - struct bfd_link_info *info; - enum elf_linker_section_enum which; - elf_linker_section_t *defaults; -{ - bfd *dynobj = elf_hash_table (info)->dynobj; - elf_linker_section_t *lsect; - - /* Record the first bfd section that needs the special section */ - if (!dynobj) - dynobj = elf_hash_table (info)->dynobj = abfd; - - /* If this is the first time, create the section */ - lsect = elf_linker_section (dynobj, which); - if (!lsect) - { - asection *s; - - lsect = (elf_linker_section_t *) - bfd_alloc (dynobj, sizeof (elf_linker_section_t)); - - *lsect = *defaults; - elf_linker_section (dynobj, which) = lsect; - lsect->which = which; - lsect->hole_written_p = false; - - /* See if the sections already exist */ - lsect->section = s = bfd_get_section_by_name (dynobj, lsect->name); - if (!s) - { - lsect->section = s = bfd_make_section (dynobj, lsect->name); - - if (s == NULL) - return (elf_linker_section_t *)0; - - bfd_set_section_flags (dynobj, s, defaults->flags); - bfd_set_section_alignment (dynobj, s, lsect->alignment); - } - else if (bfd_get_section_alignment (dynobj, s) < lsect->alignment) - bfd_set_section_alignment (dynobj, s, lsect->alignment); - - s->_raw_size = align_power (s->_raw_size, lsect->alignment); - - /* Is there a hole we have to provide? If so check whether the segment is - too big already */ - if (lsect->hole_size) - { - lsect->hole_offset = s->_raw_size; - s->_raw_size += lsect->hole_size; - if (lsect->hole_offset > lsect->max_hole_offset) - { - (*_bfd_error_handler) ("%s: Section %s is already to large to put hole of %ld bytes in", - bfd_get_filename (abfd), - lsect->name, - (long)lsect->hole_size); - - bfd_set_error (bfd_error_bad_value); - return (elf_linker_section_t *)0; - } - } - -#ifdef DEBUG - fprintf (stderr, "Creating section %s, current size = %ld\n", - lsect->name, (long)s->_raw_size); -#endif - - if (lsect->sym_name) - { - struct elf_link_hash_entry *h = NULL; -#ifdef DEBUG - fprintf (stderr, "Adding %s to section %s\n", - lsect->sym_name, - lsect->name); -#endif - h = (struct elf_link_hash_entry *) - bfd_link_hash_lookup (info->hash, lsect->sym_name, false, false, false); - - if ((h == NULL || h->root.type == bfd_link_hash_undefined) - && !(_bfd_generic_link_add_one_symbol (info, - abfd, - lsect->sym_name, - BSF_GLOBAL, - s, - ((lsect->hole_size) - ? s->_raw_size - lsect->hole_size + lsect->sym_offset - : lsect->sym_offset), - (const char *) NULL, - false, - get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h))) - return (elf_linker_section_t *)0; - - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_DYNAMIC; - h->type = STT_OBJECT; - lsect->sym_hash = h; - - if (info->shared - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) - return (elf_linker_section_t *)0; - } - } - - /* Find the related sections if they have been created */ - if (lsect->bss_name && !lsect->bss_section) - lsect->bss_section = bfd_get_section_by_name (dynobj, lsect->bss_name); - - if (lsect->rel_name && !lsect->rel_section) - lsect->rel_section = bfd_get_section_by_name (dynobj, lsect->rel_name); - - return lsect; -} - - -/* Find a linker generated pointer with a given addend and type. */ - -elf_linker_section_pointers_t * -_bfd_elf_find_pointer_linker_section (linker_pointers, addend, which) - elf_linker_section_pointers_t *linker_pointers; - bfd_signed_vma addend; - elf_linker_section_enum_t which; -{ - for ( ; linker_pointers != NULL; linker_pointers = linker_pointers->next) - { - if (which == linker_pointers->which && addend == linker_pointers->addend) - return linker_pointers; - } - - return (elf_linker_section_pointers_t *)0; -} - - -/* Make the .rela section corresponding to the generated linker section. */ - -boolean -_bfd_elf_make_linker_section_rela (dynobj, lsect, alignment) - bfd *dynobj; - elf_linker_section_t *lsect; - int alignment; -{ - if (lsect->rel_section) - return true; - - lsect->rel_section = bfd_get_section_by_name (dynobj, lsect->rel_name); - if (lsect->rel_section == NULL) - { - lsect->rel_section = bfd_make_section (dynobj, lsect->rel_name); - if (lsect->rel_section == NULL - || ! bfd_set_section_flags (dynobj, - lsect->rel_section, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, lsect->rel_section, alignment)) - return false; - } - - return true; -} - diff --git a/contrib/gdb/bfd/elflink.h b/contrib/gdb/bfd/elflink.h deleted file mode 100644 index 4ef3c8b..0000000 --- a/contrib/gdb/bfd/elflink.h +++ /dev/null @@ -1,3424 +0,0 @@ -/* ELF linker support. - Copyright 1995, 1996 Free Software Foundation, Inc. - -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. */ - -/* ELF linker code. */ - -static boolean elf_link_add_object_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf_link_add_archive_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static Elf_Internal_Rela *elf_link_read_relocs - PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, boolean)); -static boolean elf_export_symbol - PARAMS ((struct elf_link_hash_entry *, PTR)); -static boolean elf_adjust_dynamic_symbol - PARAMS ((struct elf_link_hash_entry *, PTR)); - -/* This struct is used to pass information to routines called via - elf_link_hash_traverse which must return failure. */ - -struct elf_info_failed -{ - boolean failed; - struct bfd_link_info *info; -}; - -/* Given an ELF BFD, add symbols to the global hash table as - appropriate. */ - -boolean -elf_bfd_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - switch (bfd_get_format (abfd)) - { - case bfd_object: - return elf_link_add_object_symbols (abfd, info); - case bfd_archive: - return elf_link_add_archive_symbols (abfd, info); - default: - bfd_set_error (bfd_error_wrong_format); - return false; - } -} - - -/* Add symbols from an ELF archive file to the linker hash table. We - don't use _bfd_generic_link_add_archive_symbols because of a - problem which arises on UnixWare. The UnixWare libc.so is an - archive which includes an entry libc.so.1 which defines a bunch of - symbols. The libc.so archive also includes a number of other - object files, which also define symbols, some of which are the same - as those defined in libc.so.1. Correct linking requires that we - consider each object file in turn, and include it if it defines any - symbols we need. _bfd_generic_link_add_archive_symbols does not do - this; it looks through the list of undefined symbols, and includes - any object file which defines them. When this algorithm is used on - UnixWare, it winds up pulling in libc.so.1 early and defining a - bunch of symbols. This means that some of the other objects in the - archive are not included in the link, which is incorrect since they - precede libc.so.1 in the archive. - - Fortunately, ELF archive handling is simpler than that done by - _bfd_generic_link_add_archive_symbols, which has to allow for a.out - oddities. In ELF, if we find a symbol in the archive map, and the - symbol is currently undefined, we know that we must pull in that - object file. - - Unfortunately, we do have to make multiple passes over the symbol - table until nothing further is resolved. */ - -static boolean -elf_link_add_archive_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - symindex c; - boolean *defined = NULL; - boolean *included = NULL; - carsym *symdefs; - boolean loop; - - if (! bfd_has_map (abfd)) - { - /* An empty archive is a special case. */ - if (bfd_openr_next_archived_file (abfd, (bfd *) NULL) == NULL) - return true; - bfd_set_error (bfd_error_no_armap); - return false; - } - - /* Keep track of all symbols we know to be already defined, and all - files we know to be already included. This is to speed up the - second and subsequent passes. */ - c = bfd_ardata (abfd)->symdef_count; - if (c == 0) - return true; - defined = (boolean *) bfd_malloc (c * sizeof (boolean)); - included = (boolean *) bfd_malloc (c * sizeof (boolean)); - if (defined == (boolean *) NULL || included == (boolean *) NULL) - goto error_return; - memset (defined, 0, c * sizeof (boolean)); - memset (included, 0, c * sizeof (boolean)); - - symdefs = bfd_ardata (abfd)->symdefs; - - do - { - file_ptr last; - symindex i; - carsym *symdef; - carsym *symdefend; - - loop = false; - last = -1; - - symdef = symdefs; - symdefend = symdef + c; - for (i = 0; symdef < symdefend; symdef++, i++) - { - struct elf_link_hash_entry *h; - bfd *element; - struct bfd_link_hash_entry *undefs_tail; - symindex mark; - - if (defined[i] || included[i]) - continue; - if (symdef->file_offset == last) - { - included[i] = true; - continue; - } - - h = elf_link_hash_lookup (elf_hash_table (info), symdef->name, - false, false, false); - if (h == (struct elf_link_hash_entry *) NULL) - continue; - if (h->root.type != bfd_link_hash_undefined) - { - if (h->root.type != bfd_link_hash_undefweak) - defined[i] = true; - continue; - } - - /* We need to include this archive member. */ - - element = _bfd_get_elt_at_filepos (abfd, symdef->file_offset); - if (element == (bfd *) NULL) - goto error_return; - - if (! bfd_check_format (element, bfd_object)) - goto error_return; - - /* Doublecheck that we have not included this object - already--it should be impossible, but there may be - something wrong with the archive. */ - if (element->archive_pass != 0) - { - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - element->archive_pass = 1; - - undefs_tail = info->hash->undefs_tail; - - if (! (*info->callbacks->add_archive_element) (info, element, - symdef->name)) - goto error_return; - if (! elf_link_add_object_symbols (element, info)) - goto error_return; - - /* If there are any new undefined symbols, we need to make - another pass through the archive in order to see whether - they can be defined. FIXME: This isn't perfect, because - common symbols wind up on undefs_tail and because an - undefined symbol which is defined later on in this pass - does not require another pass. This isn't a bug, but it - does make the code less efficient than it could be. */ - if (undefs_tail != info->hash->undefs_tail) - loop = true; - - /* Look backward to mark all symbols from this object file - which we have already seen in this pass. */ - mark = i; - do - { - included[mark] = true; - if (mark == 0) - break; - --mark; - } - while (symdefs[mark].file_offset == symdef->file_offset); - - /* We mark subsequent symbols from this object file as we go - on through the loop. */ - last = symdef->file_offset; - } - } - while (loop); - - free (defined); - free (included); - - return true; - - error_return: - if (defined != (boolean *) NULL) - free (defined); - if (included != (boolean *) NULL) - free (included); - return false; -} - -/* Add symbols from an ELF object file to the linker hash table. */ - -static boolean -elf_link_add_object_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - boolean (*add_symbol_hook) PARAMS ((bfd *, struct bfd_link_info *, - const Elf_Internal_Sym *, - const char **, flagword *, - asection **, bfd_vma *)); - boolean (*check_relocs) PARAMS ((bfd *, struct bfd_link_info *, - asection *, const Elf_Internal_Rela *)); - boolean collect; - Elf_Internal_Shdr *hdr; - size_t symcount; - size_t extsymcount; - size_t extsymoff; - Elf_External_Sym *buf = NULL; - struct elf_link_hash_entry **sym_hash; - boolean dynamic; - Elf_External_Dyn *dynbuf = NULL; - struct elf_link_hash_entry *weaks; - Elf_External_Sym *esym; - Elf_External_Sym *esymend; - - add_symbol_hook = get_elf_backend_data (abfd)->elf_add_symbol_hook; - collect = get_elf_backend_data (abfd)->collect; - - /* As a GNU extension, any input sections which are named - .gnu.warning.SYMBOL are treated as warning symbols for the given - symbol. This differs from .gnu.warning sections, which generate - warnings when they are included in an output file. */ - if (! info->shared) - { - asection *s; - - for (s = abfd->sections; s != NULL; s = s->next) - { - const char *name; - - name = bfd_get_section_name (abfd, s); - if (strncmp (name, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0) - { - char *msg; - bfd_size_type sz; - - sz = bfd_section_size (abfd, s); - msg = (char *) bfd_alloc (abfd, sz); - if (msg == NULL) - goto error_return; - - if (! bfd_get_section_contents (abfd, s, msg, (file_ptr) 0, sz)) - goto error_return; - - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, - name + sizeof ".gnu.warning." - 1, - BSF_WARNING, s, (bfd_vma) 0, msg, false, collect, - (struct bfd_link_hash_entry **) NULL))) - goto error_return; - - if (! info->relocateable) - { - /* Clobber the section size so that the warning does - not get copied into the output file. */ - s->_raw_size = 0; - } - } - } - } - - /* A stripped shared library might only have a dynamic symbol table, - not a regular symbol table. In that case we can still go ahead - and link using the dynamic symbol table. */ - if (elf_onesymtab (abfd) == 0 - && elf_dynsymtab (abfd) != 0) - { - elf_onesymtab (abfd) = elf_dynsymtab (abfd); - elf_tdata (abfd)->symtab_hdr = elf_tdata (abfd)->dynsymtab_hdr; - } - - hdr = &elf_tdata (abfd)->symtab_hdr; - symcount = hdr->sh_size / sizeof (Elf_External_Sym); - - /* The sh_info field of the symtab header tells us where the - external symbols start. We don't care about the local symbols at - this point. */ - if (elf_bad_symtab (abfd)) - { - extsymcount = symcount; - extsymoff = 0; - } - else - { - extsymcount = symcount - hdr->sh_info; - extsymoff = hdr->sh_info; - } - - buf = ((Elf_External_Sym *) - bfd_malloc (extsymcount * sizeof (Elf_External_Sym))); - if (buf == NULL && extsymcount != 0) - goto error_return; - - /* We store a pointer to the hash table entry for each external - symbol. */ - sym_hash = ((struct elf_link_hash_entry **) - bfd_alloc (abfd, - extsymcount * sizeof (struct elf_link_hash_entry *))); - if (sym_hash == NULL) - goto error_return; - elf_sym_hashes (abfd) = sym_hash; - - if (elf_elfheader (abfd)->e_type != ET_DYN) - { - dynamic = false; - - /* If we are creating a shared library, create all the dynamic - sections immediately. We need to attach them to something, - so we attach them to this BFD, provided it is the right - format. FIXME: If there are no input BFD's of the same - format as the output, we can't make a shared library. */ - if (info->shared - && ! elf_hash_table (info)->dynamic_sections_created - && abfd->xvec == info->hash->creator) - { - if (! elf_link_create_dynamic_sections (abfd, info)) - goto error_return; - } - } - else - { - asection *s; - boolean add_needed; - const char *name; - bfd_size_type oldsize; - bfd_size_type strindex; - - dynamic = true; - - /* You can't use -r against a dynamic object. Also, there's no - hope of using a dynamic object which does not exactly match - the format of the output file. */ - if (info->relocateable - || info->hash->creator != abfd->xvec) - { - bfd_set_error (bfd_error_invalid_operation); - goto error_return; - } - - /* Find the name to use in a DT_NEEDED entry that refers to this - object. If the object has a DT_SONAME entry, we use it. - Otherwise, if the generic linker stuck something in - elf_dt_name, we use that. Otherwise, we just use the file - name. If the generic linker put a null string into - elf_dt_name, we don't make a DT_NEEDED entry at all, even if - there is a DT_SONAME entry. */ - add_needed = true; - name = bfd_get_filename (abfd); - if (elf_dt_name (abfd) != NULL) - { - name = elf_dt_name (abfd); - if (*name == '\0') - add_needed = false; - } - s = bfd_get_section_by_name (abfd, ".dynamic"); - if (s != NULL) - { - Elf_External_Dyn *extdyn; - Elf_External_Dyn *extdynend; - int elfsec; - unsigned long link; - - dynbuf = (Elf_External_Dyn *) bfd_malloc ((size_t) s->_raw_size); - if (dynbuf == NULL) - goto error_return; - - if (! bfd_get_section_contents (abfd, s, (PTR) dynbuf, - (file_ptr) 0, s->_raw_size)) - goto error_return; - - elfsec = _bfd_elf_section_from_bfd_section (abfd, s); - if (elfsec == -1) - goto error_return; - link = elf_elfsections (abfd)[elfsec]->sh_link; - - extdyn = dynbuf; - extdynend = extdyn + s->_raw_size / sizeof (Elf_External_Dyn); - for (; extdyn < extdynend; extdyn++) - { - Elf_Internal_Dyn dyn; - - elf_swap_dyn_in (abfd, extdyn, &dyn); - if (dyn.d_tag == DT_SONAME) - { - name = bfd_elf_string_from_elf_section (abfd, link, - dyn.d_un.d_val); - if (name == NULL) - goto error_return; - } - if (dyn.d_tag == DT_NEEDED) - { - struct bfd_link_needed_list *n, **pn; - char *fnm, *anm; - - n = ((struct bfd_link_needed_list *) - bfd_alloc (abfd, sizeof (struct bfd_link_needed_list))); - fnm = bfd_elf_string_from_elf_section (abfd, link, - dyn.d_un.d_val); - if (n == NULL || fnm == NULL) - goto error_return; - anm = bfd_alloc (abfd, strlen (fnm) + 1); - if (anm == NULL) - goto error_return; - strcpy (anm, fnm); - n->name = anm; - n->by = abfd; - n->next = NULL; - for (pn = &elf_hash_table (info)->needed; - *pn != NULL; - pn = &(*pn)->next) - ; - *pn = n; - } - } - - free (dynbuf); - dynbuf = NULL; - } - - /* We do not want to include any of the sections in a dynamic - object in the output file. We hack by simply clobbering the - list of sections in the BFD. This could be handled more - cleanly by, say, a new section flag; the existing - SEC_NEVER_LOAD flag is not the one we want, because that one - still implies that the section takes up space in the output - file. */ - abfd->sections = NULL; - abfd->section_count = 0; - - /* If this is the first dynamic object found in the link, create - the special sections required for dynamic linking. */ - if (! elf_hash_table (info)->dynamic_sections_created) - { - if (! elf_link_create_dynamic_sections (abfd, info)) - goto error_return; - } - - if (add_needed) - { - /* Add a DT_NEEDED entry for this dynamic object. */ - oldsize = _bfd_stringtab_size (elf_hash_table (info)->dynstr); - strindex = _bfd_stringtab_add (elf_hash_table (info)->dynstr, name, - true, false); - if (strindex == (bfd_size_type) -1) - goto error_return; - - if (oldsize == _bfd_stringtab_size (elf_hash_table (info)->dynstr)) - { - asection *sdyn; - Elf_External_Dyn *dyncon, *dynconend; - - /* The hash table size did not change, which means that - the dynamic object name was already entered. If we - have already included this dynamic object in the - link, just ignore it. There is no reason to include - a particular dynamic object more than once. */ - sdyn = bfd_get_section_by_name (elf_hash_table (info)->dynobj, - ".dynamic"); - BFD_ASSERT (sdyn != NULL); - - dyncon = (Elf_External_Dyn *) sdyn->contents; - dynconend = (Elf_External_Dyn *) (sdyn->contents + - sdyn->_raw_size); - for (; dyncon < dynconend; dyncon++) - { - Elf_Internal_Dyn dyn; - - elf_swap_dyn_in (elf_hash_table (info)->dynobj, dyncon, - &dyn); - if (dyn.d_tag == DT_NEEDED - && dyn.d_un.d_val == strindex) - { - if (buf != NULL) - free (buf); - return true; - } - } - } - - if (! elf_add_dynamic_entry (info, DT_NEEDED, strindex)) - goto error_return; - } - - /* Save the SONAME, if there is one, because sometimes the - linker emulation code will need to know it. */ - if (*name == '\0') - name = bfd_get_filename (abfd); - elf_dt_name (abfd) = name; - } - - if (bfd_seek (abfd, - hdr->sh_offset + extsymoff * sizeof (Elf_External_Sym), - SEEK_SET) != 0 - || (bfd_read ((PTR) buf, sizeof (Elf_External_Sym), extsymcount, abfd) - != extsymcount * sizeof (Elf_External_Sym))) - goto error_return; - - weaks = NULL; - - esymend = buf + extsymcount; - for (esym = buf; esym < esymend; esym++, sym_hash++) - { - Elf_Internal_Sym sym; - int bind; - bfd_vma value; - asection *sec; - flagword flags; - const char *name; - struct elf_link_hash_entry *h; - boolean definition; - boolean size_change_ok, type_change_ok; - boolean new_weakdef; - - elf_swap_symbol_in (abfd, esym, &sym); - - flags = BSF_NO_FLAGS; - sec = NULL; - value = sym.st_value; - *sym_hash = NULL; - - bind = ELF_ST_BIND (sym.st_info); - if (bind == STB_LOCAL) - { - /* This should be impossible, since ELF requires that all - global symbols follow all local symbols, and that sh_info - point to the first global symbol. Unfortunatealy, Irix 5 - screws this up. */ - continue; - } - else if (bind == STB_GLOBAL) - { - if (sym.st_shndx != SHN_UNDEF - && sym.st_shndx != SHN_COMMON) - flags = BSF_GLOBAL; - else - flags = 0; - } - else if (bind == STB_WEAK) - flags = BSF_WEAK; - else - { - /* Leave it up to the processor backend. */ - } - - if (sym.st_shndx == SHN_UNDEF) - sec = bfd_und_section_ptr; - else if (sym.st_shndx > 0 && sym.st_shndx < SHN_LORESERVE) - { - sec = section_from_elf_index (abfd, sym.st_shndx); - if (sec != NULL) - value -= sec->vma; - else - sec = bfd_abs_section_ptr; - } - else if (sym.st_shndx == SHN_ABS) - sec = bfd_abs_section_ptr; - else if (sym.st_shndx == SHN_COMMON) - { - sec = bfd_com_section_ptr; - /* What ELF calls the size we call the value. What ELF - calls the value we call the alignment. */ - value = sym.st_size; - } - else - { - /* Leave it up to the processor backend. */ - } - - name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link, sym.st_name); - if (name == (const char *) NULL) - goto error_return; - - if (add_symbol_hook) - { - if (! (*add_symbol_hook) (abfd, info, &sym, &name, &flags, &sec, - &value)) - goto error_return; - - /* The hook function sets the name to NULL if this symbol - should be skipped for some reason. */ - if (name == (const char *) NULL) - continue; - } - - /* Sanity check that all possibilities were handled. */ - if (sec == (asection *) NULL) - { - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - if (bfd_is_und_section (sec) - || bfd_is_com_section (sec)) - definition = false; - else - definition = true; - - size_change_ok = false; - type_change_ok = get_elf_backend_data (abfd)->type_change_ok; - if (info->hash->creator->flavour == bfd_target_elf_flavour) - { - /* We need to look up the symbol now in order to get some of - the dynamic object handling right. We pass the hash - table entry in to _bfd_generic_link_add_one_symbol so - that it does not have to look it up again. */ - if (! bfd_is_und_section (sec)) - h = elf_link_hash_lookup (elf_hash_table (info), name, - true, false, false); - else - h = ((struct elf_link_hash_entry *) - bfd_wrapped_link_hash_lookup (abfd, info, name, true, - false, false)); - if (h == NULL) - goto error_return; - *sym_hash = h; - - if (h->root.type == bfd_link_hash_new) - h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF; - - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - /* It's OK to change the type if it used to be a weak - definition. */ - if (h->root.type == bfd_link_hash_defweak - || h->root.type == bfd_link_hash_undefweak) - type_change_ok = true; - - /* It's OK to change the size if it used to be a weak - definition, or if it used to be undefined, or if we will - be overriding an old definition. */ - if (type_change_ok - || h->root.type == bfd_link_hash_undefined) - size_change_ok = true; - - /* If we are looking at a dynamic object, and this is a - definition, we need to see if it has already been defined - by some other object. If it has, we want to use the - existing definition, and we do not want to report a - multiple symbol definition error; we do this by - clobbering sec to be bfd_und_section_ptr. */ - if (dynamic && definition) - { - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak - || (h->root.type == bfd_link_hash_common - && bind == STB_WEAK)) - { - sec = bfd_und_section_ptr; - definition = false; - size_change_ok = true; - } - } - - /* Similarly, if we are not looking at a dynamic object, and - we have a definition, we want to override any definition - we may have from a dynamic object. Symbols from regular - files always take precedence over symbols from dynamic - objects, even if they are defined after the dynamic - object in the link. */ - if (! dynamic - && definition - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - && (bfd_get_flavour (h->root.u.def.section->owner) - == bfd_target_elf_flavour) - && (elf_elfheader (h->root.u.def.section->owner)->e_type - == ET_DYN)) - { - /* Change the hash table entry to undefined, and let - _bfd_generic_link_add_one_symbol do the right thing - with the new definition. */ - h->root.type = bfd_link_hash_undefined; - h->root.u.undef.abfd = h->root.u.def.section->owner; - size_change_ok = true; - } - } - - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, name, flags, sec, value, (const char *) NULL, - false, collect, (struct bfd_link_hash_entry **) sym_hash))) - goto error_return; - - h = *sym_hash; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - *sym_hash = h; - - new_weakdef = false; - if (dynamic - && definition - && (flags & BSF_WEAK) != 0 - && ELF_ST_TYPE (sym.st_info) != STT_FUNC - && info->hash->creator->flavour == bfd_target_elf_flavour - && h->weakdef == NULL) - { - /* Keep a list of all weak defined non function symbols from - a dynamic object, using the weakdef field. Later in this - function we will set the weakdef field to the correct - value. We only put non-function symbols from dynamic - objects on this list, because that happens to be the only - time we need to know the normal symbol corresponding to a - weak symbol, and the information is time consuming to - figure out. If the weakdef field is not already NULL, - then this symbol was already defined by some previous - dynamic object, and we will be using that previous - definition anyhow. */ - - h->weakdef = weaks; - weaks = h; - new_weakdef = true; - } - - /* Get the alignment of a common symbol. */ - if (sym.st_shndx == SHN_COMMON - && h->root.type == bfd_link_hash_common) - h->root.u.c.p->alignment_power = bfd_log2 (sym.st_value); - - if (info->hash->creator->flavour == bfd_target_elf_flavour) - { - int old_flags; - boolean dynsym; - int new_flag; - - /* Remember the symbol size and type. */ - if (sym.st_size != 0 - && (definition || h->size == 0)) - { - if (h->size != 0 && h->size != sym.st_size && ! size_change_ok) - (*_bfd_error_handler) - ("Warning: size of symbol `%s' changed from %lu to %lu in %s", - name, (unsigned long) h->size, (unsigned long) sym.st_size, - bfd_get_filename (abfd)); - - h->size = sym.st_size; - } - if (ELF_ST_TYPE (sym.st_info) != STT_NOTYPE - && (definition || h->type == STT_NOTYPE)) - { - if (h->type != STT_NOTYPE - && h->type != ELF_ST_TYPE (sym.st_info) - && ! type_change_ok) - (*_bfd_error_handler) - ("Warning: type of symbol `%s' changed from %d to %d in %s", - name, h->type, ELF_ST_TYPE (sym.st_info), - bfd_get_filename (abfd)); - - h->type = ELF_ST_TYPE (sym.st_info); - } - - /* Set a flag in the hash table entry indicating the type of - reference or definition we just found. Keep a count of - the number of dynamic symbols we find. A dynamic symbol - is one which is referenced or defined by both a regular - object and a shared object, or one which is referenced or - defined by more than one shared object. */ - old_flags = h->elf_link_hash_flags; - dynsym = false; - if (! dynamic) - { - if (! definition) - new_flag = ELF_LINK_HASH_REF_REGULAR; - else - new_flag = ELF_LINK_HASH_DEF_REGULAR; - if (info->shared - || (old_flags & (ELF_LINK_HASH_DEF_DYNAMIC - | ELF_LINK_HASH_REF_DYNAMIC)) != 0) - dynsym = true; - } - else - { - if (! definition) - new_flag = ELF_LINK_HASH_REF_DYNAMIC; - else - new_flag = ELF_LINK_HASH_DEF_DYNAMIC; - if ((old_flags & new_flag) != 0 - || (old_flags & (ELF_LINK_HASH_DEF_REGULAR - | ELF_LINK_HASH_REF_REGULAR)) != 0 - || (h->weakdef != NULL - && (old_flags & (ELF_LINK_HASH_DEF_DYNAMIC - | ELF_LINK_HASH_REF_DYNAMIC)) != 0)) - dynsym = true; - } - - h->elf_link_hash_flags |= new_flag; - if (dynsym && h->dynindx == -1) - { - if (! _bfd_elf_link_record_dynamic_symbol (info, h)) - goto error_return; - if (h->weakdef != NULL - && ! new_weakdef - && h->weakdef->dynindx == -1) - { - if (! _bfd_elf_link_record_dynamic_symbol (info, - h->weakdef)) - goto error_return; - } - } - } - } - - /* Now set the weakdefs field correctly for all the weak defined - symbols we found. The only way to do this is to search all the - symbols. Since we only need the information for non functions in - dynamic objects, that's the only time we actually put anything on - the list WEAKS. We need this information so that if a regular - object refers to a symbol defined weakly in a dynamic object, the - real symbol in the dynamic object is also put in the dynamic - symbols; we also must arrange for both symbols to point to the - same memory location. We could handle the general case of symbol - aliasing, but a general symbol alias can only be generated in - assembler code, handling it correctly would be very time - consuming, and other ELF linkers don't handle general aliasing - either. */ - while (weaks != NULL) - { - struct elf_link_hash_entry *hlook; - asection *slook; - bfd_vma vlook; - struct elf_link_hash_entry **hpp; - struct elf_link_hash_entry **hppend; - - hlook = weaks; - weaks = hlook->weakdef; - hlook->weakdef = NULL; - - BFD_ASSERT (hlook->root.type == bfd_link_hash_defined - || hlook->root.type == bfd_link_hash_defweak - || hlook->root.type == bfd_link_hash_common - || hlook->root.type == bfd_link_hash_indirect); - slook = hlook->root.u.def.section; - vlook = hlook->root.u.def.value; - - hpp = elf_sym_hashes (abfd); - hppend = hpp + extsymcount; - for (; hpp < hppend; hpp++) - { - struct elf_link_hash_entry *h; - - h = *hpp; - if (h != NULL && h != hlook - && h->root.type == bfd_link_hash_defined - && h->root.u.def.section == slook - && h->root.u.def.value == vlook) - { - hlook->weakdef = h; - - /* If the weak definition is in the list of dynamic - symbols, make sure the real definition is put there - as well. */ - if (hlook->dynindx != -1 - && h->dynindx == -1) - { - if (! _bfd_elf_link_record_dynamic_symbol (info, h)) - goto error_return; - } - - break; - } - } - } - - if (buf != NULL) - { - free (buf); - buf = NULL; - } - - /* If this object is the same format as the output object, and it is - not a shared library, then let the backend look through the - relocs. - - This is required to build global offset table entries and to - arrange for dynamic relocs. It is not required for the - particular common case of linking non PIC code, even when linking - against shared libraries, but unfortunately there is no way of - knowing whether an object file has been compiled PIC or not. - Looking through the relocs is not particularly time consuming. - The problem is that we must either (1) keep the relocs in memory, - which causes the linker to require additional runtime memory or - (2) read the relocs twice from the input file, which wastes time. - This would be a good case for using mmap. - - I have no idea how to handle linking PIC code into a file of a - different format. It probably can't be done. */ - check_relocs = get_elf_backend_data (abfd)->check_relocs; - if (! dynamic - && abfd->xvec == info->hash->creator - && check_relocs != NULL) - { - asection *o; - - for (o = abfd->sections; o != NULL; o = o->next) - { - Elf_Internal_Rela *internal_relocs; - boolean ok; - - if ((o->flags & SEC_RELOC) == 0 - || o->reloc_count == 0) - continue; - - /* I believe we can ignore the relocs for any section which - does not form part of the final process image, such as a - debugging section. */ - if ((o->flags & SEC_ALLOC) == 0) - continue; - - internal_relocs = elf_link_read_relocs (abfd, o, (PTR) NULL, - (Elf_Internal_Rela *) NULL, - info->keep_memory); - if (internal_relocs == NULL) - goto error_return; - - ok = (*check_relocs) (abfd, info, o, internal_relocs); - - if (! info->keep_memory) - free (internal_relocs); - - if (! ok) - goto error_return; - } - } - - return true; - - error_return: - if (buf != NULL) - free (buf); - if (dynbuf != NULL) - free (dynbuf); - return false; -} - -/* Create some sections which will be filled in with dynamic linking - information. ABFD is an input file which requires dynamic sections - to be created. The dynamic sections take up virtual memory space - when the final executable is run, so we need to create them before - addresses are assigned to the output sections. We work out the - actual contents and size of these sections later. */ - -boolean -elf_link_create_dynamic_sections (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - flagword flags; - register asection *s; - struct elf_link_hash_entry *h; - struct elf_backend_data *bed; - - if (elf_hash_table (info)->dynamic_sections_created) - return true; - - /* Make sure that all dynamic sections use the same input BFD. */ - if (elf_hash_table (info)->dynobj == NULL) - elf_hash_table (info)->dynobj = abfd; - else - abfd = elf_hash_table (info)->dynobj; - - /* Note that we set the SEC_IN_MEMORY flag for all of these - sections. */ - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - - /* A dynamically linked executable has a .interp section, but a - shared library does not. */ - if (! info->shared) - { - s = bfd_make_section (abfd, ".interp"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)) - return false; - } - - s = bfd_make_section (abfd, ".dynsym"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, LOG_FILE_ALIGN)) - return false; - - s = bfd_make_section (abfd, ".dynstr"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)) - return false; - - /* Create a strtab to hold the dynamic symbol names. */ - if (elf_hash_table (info)->dynstr == NULL) - { - elf_hash_table (info)->dynstr = elf_stringtab_init (); - if (elf_hash_table (info)->dynstr == NULL) - return false; - } - - s = bfd_make_section (abfd, ".dynamic"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags) - || ! bfd_set_section_alignment (abfd, s, LOG_FILE_ALIGN)) - return false; - - /* The special symbol _DYNAMIC is always set to the start of the - .dynamic section. This call occurs before we have processed the - symbols for any dynamic object, so we don't have to worry about - overriding a dynamic definition. We could set _DYNAMIC in a - linker script, but we only want to define it if we are, in fact, - creating a .dynamic section. We don't want to define it if there - is no .dynamic section, since on some ELF platforms the start up - code examines it to decide how to initialize the process. */ - h = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, "_DYNAMIC", BSF_GLOBAL, s, (bfd_vma) 0, - (const char *) NULL, false, get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h))) - return false; - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - h->type = STT_OBJECT; - - if (info->shared - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) - return false; - - s = bfd_make_section (abfd, ".hash"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, LOG_FILE_ALIGN)) - return false; - - /* Let the backend create the rest of the sections. This lets the - backend set the right flags. The backend will normally create - the .got and .plt sections. */ - bed = get_elf_backend_data (abfd); - if (! (*bed->elf_backend_create_dynamic_sections) (abfd, info)) - return false; - - elf_hash_table (info)->dynamic_sections_created = true; - - return true; -} - -/* Add an entry to the .dynamic table. */ - -boolean -elf_add_dynamic_entry (info, tag, val) - struct bfd_link_info *info; - bfd_vma tag; - bfd_vma val; -{ - Elf_Internal_Dyn dyn; - bfd *dynobj; - asection *s; - size_t newsize; - bfd_byte *newcontents; - - dynobj = elf_hash_table (info)->dynobj; - - s = bfd_get_section_by_name (dynobj, ".dynamic"); - BFD_ASSERT (s != NULL); - - newsize = s->_raw_size + sizeof (Elf_External_Dyn); - newcontents = (bfd_byte *) bfd_realloc (s->contents, newsize); - if (newcontents == NULL) - return false; - - dyn.d_tag = tag; - dyn.d_un.d_val = val; - elf_swap_dyn_out (dynobj, &dyn, - (Elf_External_Dyn *) (newcontents + s->_raw_size)); - - s->_raw_size = newsize; - s->contents = newcontents; - - return true; -} - - -/* Read and swap the relocs for a section. They may have been cached. - If the EXTERNAL_RELOCS and INTERNAL_RELOCS arguments are not NULL, - they are used as buffers to read into. They are known to be large - enough. If the INTERNAL_RELOCS relocs argument is NULL, the return - value is allocated using either malloc or bfd_alloc, according to - the KEEP_MEMORY argument. */ - -static Elf_Internal_Rela * -elf_link_read_relocs (abfd, o, external_relocs, internal_relocs, keep_memory) - bfd *abfd; - asection *o; - PTR external_relocs; - Elf_Internal_Rela *internal_relocs; - boolean keep_memory; -{ - Elf_Internal_Shdr *rel_hdr; - PTR alloc1 = NULL; - Elf_Internal_Rela *alloc2 = NULL; - - if (elf_section_data (o)->relocs != NULL) - return elf_section_data (o)->relocs; - - if (o->reloc_count == 0) - return NULL; - - rel_hdr = &elf_section_data (o)->rel_hdr; - - if (internal_relocs == NULL) - { - size_t size; - - size = o->reloc_count * sizeof (Elf_Internal_Rela); - if (keep_memory) - internal_relocs = (Elf_Internal_Rela *) bfd_alloc (abfd, size); - else - internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_malloc (size); - if (internal_relocs == NULL) - goto error_return; - } - - if (external_relocs == NULL) - { - alloc1 = (PTR) bfd_malloc ((size_t) rel_hdr->sh_size); - if (alloc1 == NULL) - goto error_return; - external_relocs = alloc1; - } - - if ((bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0) - || (bfd_read (external_relocs, 1, rel_hdr->sh_size, abfd) - != rel_hdr->sh_size)) - goto error_return; - - /* Swap in the relocs. For convenience, we always produce an - Elf_Internal_Rela array; if the relocs are Rel, we set the addend - to 0. */ - if (rel_hdr->sh_entsize == sizeof (Elf_External_Rel)) - { - Elf_External_Rel *erel; - Elf_External_Rel *erelend; - Elf_Internal_Rela *irela; - - erel = (Elf_External_Rel *) external_relocs; - erelend = erel + o->reloc_count; - irela = internal_relocs; - for (; erel < erelend; erel++, irela++) - { - Elf_Internal_Rel irel; - - elf_swap_reloc_in (abfd, erel, &irel); - irela->r_offset = irel.r_offset; - irela->r_info = irel.r_info; - irela->r_addend = 0; - } - } - else - { - Elf_External_Rela *erela; - Elf_External_Rela *erelaend; - Elf_Internal_Rela *irela; - - BFD_ASSERT (rel_hdr->sh_entsize == sizeof (Elf_External_Rela)); - - erela = (Elf_External_Rela *) external_relocs; - erelaend = erela + o->reloc_count; - irela = internal_relocs; - for (; erela < erelaend; erela++, irela++) - elf_swap_reloca_in (abfd, erela, irela); - } - - /* Cache the results for next time, if we can. */ - if (keep_memory) - elf_section_data (o)->relocs = internal_relocs; - - if (alloc1 != NULL) - free (alloc1); - - /* Don't free alloc2, since if it was allocated we are passing it - back (under the name of internal_relocs). */ - - return internal_relocs; - - error_return: - if (alloc1 != NULL) - free (alloc1); - if (alloc2 != NULL) - free (alloc2); - return NULL; -} - - -/* Record an assignment to a symbol made by a linker script. We need - this in case some dynamic object refers to this symbol. */ - -/*ARGSUSED*/ -boolean -NAME(bfd_elf,record_link_assignment) (output_bfd, info, name, provide) - bfd *output_bfd; - struct bfd_link_info *info; - const char *name; - boolean provide; -{ - struct elf_link_hash_entry *h; - - if (info->hash->creator->flavour != bfd_target_elf_flavour) - return true; - - h = elf_link_hash_lookup (elf_hash_table (info), name, true, true, false); - if (h == NULL) - return false; - - if (h->root.type == bfd_link_hash_new) - h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF; - - /* If this symbol is being provided by the linker script, and it is - currently defined by a dynamic object, but not by a regular - object, then mark it as undefined so that the generic linker will - force the correct value. */ - if (provide - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - h->root.type = bfd_link_hash_undefined; - - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - h->type = STT_OBJECT; - - if (((h->elf_link_hash_flags & (ELF_LINK_HASH_DEF_DYNAMIC - | ELF_LINK_HASH_REF_DYNAMIC)) != 0 - || info->shared) - && h->dynindx == -1) - { - if (! _bfd_elf_link_record_dynamic_symbol (info, h)) - return false; - - /* If this is a weak defined symbol, and we know a corresponding - real symbol from the same dynamic object, make sure the real - symbol is also made into a dynamic symbol. */ - if (h->weakdef != NULL - && h->weakdef->dynindx == -1) - { - if (! _bfd_elf_link_record_dynamic_symbol (info, h->weakdef)) - return false; - } - } - - return true; -} - - -/* Array used to determine the number of hash table buckets to use - based on the number of symbols there are. If there are fewer than - 3 symbols we use 1 bucket, fewer than 17 symbols we use 3 buckets, - fewer than 37 we use 17 buckets, and so forth. We never use more - than 521 buckets. */ - -static const size_t elf_buckets[] = -{ - 1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 0 -}; - -/* Set up the sizes and contents of the ELF dynamic sections. This is - called by the ELF linker emulation before_allocation routine. We - must set the sizes of the sections before the linker sets the - addresses of the various sections. */ - -boolean -NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath, - export_dynamic, info, sinterpptr) - bfd *output_bfd; - const char *soname; - const char *rpath; - boolean export_dynamic; - struct bfd_link_info *info; - asection **sinterpptr; -{ - bfd *dynobj; - struct elf_backend_data *bed; - - *sinterpptr = NULL; - - if (info->hash->creator->flavour != bfd_target_elf_flavour) - return true; - - dynobj = elf_hash_table (info)->dynobj; - - /* If there were no dynamic objects in the link, there is nothing to - do here. */ - if (dynobj == NULL) - return true; - - /* If we are supposed to export all symbols into the dynamic symbol - table (this is not the normal case), then do so. */ - if (export_dynamic) - { - struct elf_info_failed eif; - - eif.failed = false; - eif.info = info; - elf_link_hash_traverse (elf_hash_table (info), elf_export_symbol, - (PTR) &eif); - if (eif.failed) - return false; - } - - if (elf_hash_table (info)->dynamic_sections_created) - { - struct elf_info_failed eif; - struct elf_link_hash_entry *h; - bfd_size_type strsize; - - *sinterpptr = bfd_get_section_by_name (dynobj, ".interp"); - BFD_ASSERT (*sinterpptr != NULL || info->shared); - - if (soname != NULL) - { - bfd_size_type indx; - - indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr, soname, - true, true); - if (indx == (bfd_size_type) -1 - || ! elf_add_dynamic_entry (info, DT_SONAME, indx)) - return false; - } - - if (info->symbolic) - { - if (! elf_add_dynamic_entry (info, DT_SYMBOLIC, 0)) - return false; - } - - if (rpath != NULL) - { - bfd_size_type indx; - - indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr, rpath, - true, true); - if (indx == (bfd_size_type) -1 - || ! elf_add_dynamic_entry (info, DT_RPATH, indx)) - return false; - } - - /* Find all symbols which were defined in a dynamic object and make - the backend pick a reasonable value for them. */ - eif.failed = false; - eif.info = info; - elf_link_hash_traverse (elf_hash_table (info), - elf_adjust_dynamic_symbol, - (PTR) &eif); - if (eif.failed) - return false; - - /* Add some entries to the .dynamic section. We fill in some of the - values later, in elf_bfd_final_link, but we must add the entries - now so that we know the final size of the .dynamic section. */ - h = elf_link_hash_lookup (elf_hash_table (info), "_init", false, - false, false); - if (h != NULL - && (h->elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR - | ELF_LINK_HASH_DEF_REGULAR)) != 0) - { - if (! elf_add_dynamic_entry (info, DT_INIT, 0)) - return false; - } - h = elf_link_hash_lookup (elf_hash_table (info), "_fini", false, - false, false); - if (h != NULL - && (h->elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR - | ELF_LINK_HASH_DEF_REGULAR)) != 0) - { - if (! elf_add_dynamic_entry (info, DT_FINI, 0)) - return false; - } - strsize = _bfd_stringtab_size (elf_hash_table (info)->dynstr); - if (! elf_add_dynamic_entry (info, DT_HASH, 0) - || ! elf_add_dynamic_entry (info, DT_STRTAB, 0) - || ! elf_add_dynamic_entry (info, DT_SYMTAB, 0) - || ! elf_add_dynamic_entry (info, DT_STRSZ, strsize) - || ! elf_add_dynamic_entry (info, DT_SYMENT, - sizeof (Elf_External_Sym))) - return false; - } - - /* The backend must work out the sizes of all the other dynamic - sections. */ - bed = get_elf_backend_data (output_bfd); - if (! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info)) - return false; - - if (elf_hash_table (info)->dynamic_sections_created) - { - size_t dynsymcount; - asection *s; - size_t i; - size_t bucketcount = 0; - Elf_Internal_Sym isym; - - /* Set the size of the .dynsym and .hash sections. We counted - the number of dynamic symbols in elf_link_add_object_symbols. - We will build the contents of .dynsym and .hash when we build - the final symbol table, because until then we do not know the - correct value to give the symbols. We built the .dynstr - section as we went along in elf_link_add_object_symbols. */ - dynsymcount = elf_hash_table (info)->dynsymcount; - s = bfd_get_section_by_name (dynobj, ".dynsym"); - BFD_ASSERT (s != NULL); - s->_raw_size = dynsymcount * sizeof (Elf_External_Sym); - s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) - return false; - - /* The first entry in .dynsym is a dummy symbol. */ - isym.st_value = 0; - isym.st_size = 0; - isym.st_name = 0; - isym.st_info = 0; - isym.st_other = 0; - isym.st_shndx = 0; - elf_swap_symbol_out (output_bfd, &isym, - (PTR) (Elf_External_Sym *) s->contents); - - for (i = 0; elf_buckets[i] != 0; i++) - { - bucketcount = elf_buckets[i]; - if (dynsymcount < elf_buckets[i + 1]) - break; - } - - s = bfd_get_section_by_name (dynobj, ".hash"); - BFD_ASSERT (s != NULL); - s->_raw_size = (2 + bucketcount + dynsymcount) * (ARCH_SIZE / 8); - s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); - if (s->contents == NULL) - return false; - memset (s->contents, 0, (size_t) s->_raw_size); - - put_word (output_bfd, bucketcount, s->contents); - put_word (output_bfd, dynsymcount, s->contents + (ARCH_SIZE / 8)); - - elf_hash_table (info)->bucketcount = bucketcount; - - s = bfd_get_section_by_name (dynobj, ".dynstr"); - BFD_ASSERT (s != NULL); - s->_raw_size = _bfd_stringtab_size (elf_hash_table (info)->dynstr); - - if (! elf_add_dynamic_entry (info, DT_NULL, 0)) - return false; - } - - return true; -} - - -/* This routine is used to export all defined symbols into the dynamic - symbol table. It is called via elf_link_hash_traverse. */ - -static boolean -elf_export_symbol (h, data) - struct elf_link_hash_entry *h; - PTR data; -{ - struct elf_info_failed *eif = (struct elf_info_failed *) data; - - if (h->dynindx == -1 - && (h->elf_link_hash_flags - & (ELF_LINK_HASH_DEF_REGULAR | ELF_LINK_HASH_REF_REGULAR)) != 0) - { - if (! _bfd_elf_link_record_dynamic_symbol (eif->info, h)) - { - eif->failed = true; - return false; - } - } - - return true; -} - - -/* Make the backend pick a good value for a dynamic symbol. This is - called via elf_link_hash_traverse, and also calls itself - recursively. */ - -static boolean -elf_adjust_dynamic_symbol (h, data) - struct elf_link_hash_entry *h; - PTR data; -{ - struct elf_info_failed *eif = (struct elf_info_failed *) data; - bfd *dynobj; - struct elf_backend_data *bed; - - /* If this symbol was mentioned in a non-ELF file, try to set - DEF_REGULAR and REF_REGULAR correctly. This is the only way to - permit a non-ELF file to correctly refer to a symbol defined in - an ELF dynamic object. */ - if ((h->elf_link_hash_flags & ELF_LINK_NON_ELF) != 0) - { - if (h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak) - h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR; - else - { - if (h->root.u.def.section->owner != NULL - && (bfd_get_flavour (h->root.u.def.section->owner) - == bfd_target_elf_flavour)) - h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR; - else - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - } - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - || (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0) - { - if (! _bfd_elf_link_record_dynamic_symbol (eif->info, h)) - { - eif->failed = true; - return false; - } - } - } - - /* If -Bsymbolic was used (which means to bind references to global - symbols to the definition within the shared object), and this - symbol was defined in a regular object, then it actually doesn't - need a PLT entry. */ - if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0 - && eif->info->shared - && eif->info->symbolic - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0) - h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT; - - /* If this symbol does not require a PLT entry, and it is not - defined by a dynamic object, or is not referenced by a regular - object, ignore it. We do have to handle a weak defined symbol, - even if no regular object refers to it, if we decided to add it - to the dynamic symbol table. FIXME: Do we normally need to worry - about symbols which are defined by one dynamic object and - referenced by another one? */ - if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) == 0 - && ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0 - || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 - || ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0 - && (h->weakdef == NULL || h->weakdef->dynindx == -1)))) - return true; - - /* If we've already adjusted this symbol, don't do it again. This - can happen via a recursive call. */ - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DYNAMIC_ADJUSTED) != 0) - return true; - - /* Don't look at this symbol again. Note that we must set this - after checking the above conditions, because we may look at a - symbol once, decide not to do anything, and then get called - recursively later after REF_REGULAR is set below. */ - h->elf_link_hash_flags |= ELF_LINK_HASH_DYNAMIC_ADJUSTED; - - /* If this is a weak definition, and we know a real definition, and - the real symbol is not itself defined by a regular object file, - then get a good value for the real definition. We handle the - real symbol first, for the convenience of the backend routine. - - Note that there is a confusing case here. If the real definition - is defined by a regular object file, we don't get the real symbol - from the dynamic object, but we do get the weak symbol. If the - processor backend uses a COPY reloc, then if some routine in the - dynamic object changes the real symbol, we will not see that - change in the corresponding weak symbol. This is the way other - ELF linkers work as well, and seems to be a result of the shared - library model. - - I will clarify this issue. Most SVR4 shared libraries define the - variable _timezone and define timezone as a weak synonym. The - tzset call changes _timezone. If you write - extern int timezone; - int _timezone = 5; - int main () { tzset (); printf ("%d %d\n", timezone, _timezone); } - you might expect that, since timezone is a synonym for _timezone, - the same number will print both times. However, if the processor - backend uses a COPY reloc, then actually timezone will be copied - into your process image, and, since you define _timezone - yourself, _timezone will not. Thus timezone and _timezone will - wind up at different memory locations. The tzset call will set - _timezone, leaving timezone unchanged. */ - - if (h->weakdef != NULL) - { - struct elf_link_hash_entry *weakdef; - - BFD_ASSERT (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak); - weakdef = h->weakdef; - BFD_ASSERT (weakdef->root.type == bfd_link_hash_defined - || weakdef->root.type == bfd_link_hash_defweak); - BFD_ASSERT (weakdef->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC); - if ((weakdef->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0) - { - /* This symbol is defined by a regular object file, so we - will not do anything special. Clear weakdef for the - convenience of the processor backend. */ - h->weakdef = NULL; - } - else - { - /* There is an implicit reference by a regular object file - via the weak symbol. */ - weakdef->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR; - if (! elf_adjust_dynamic_symbol (weakdef, (PTR) eif)) - return false; - } - } - - dynobj = elf_hash_table (eif->info)->dynobj; - bed = get_elf_backend_data (dynobj); - if (! (*bed->elf_backend_adjust_dynamic_symbol) (eif->info, h)) - { - eif->failed = true; - return false; - } - - return true; -} - -/* Final phase of ELF linker. */ - -/* A structure we use to avoid passing large numbers of arguments. */ - -struct elf_final_link_info -{ - /* General link information. */ - struct bfd_link_info *info; - /* Output BFD. */ - bfd *output_bfd; - /* Symbol string table. */ - struct bfd_strtab_hash *symstrtab; - /* .dynsym section. */ - asection *dynsym_sec; - /* .hash section. */ - asection *hash_sec; - /* Buffer large enough to hold contents of any section. */ - bfd_byte *contents; - /* Buffer large enough to hold external relocs of any section. */ - PTR external_relocs; - /* Buffer large enough to hold internal relocs of any section. */ - Elf_Internal_Rela *internal_relocs; - /* Buffer large enough to hold external local symbols of any input - BFD. */ - Elf_External_Sym *external_syms; - /* Buffer large enough to hold internal local symbols of any input - BFD. */ - Elf_Internal_Sym *internal_syms; - /* Array large enough to hold a symbol index for each local symbol - of any input BFD. */ - long *indices; - /* Array large enough to hold a section pointer for each local - symbol of any input BFD. */ - asection **sections; - /* Buffer to hold swapped out symbols. */ - Elf_External_Sym *symbuf; - /* Number of swapped out symbols in buffer. */ - size_t symbuf_count; - /* Number of symbols which fit in symbuf. */ - size_t symbuf_size; -}; - -static boolean elf_link_output_sym - PARAMS ((struct elf_final_link_info *, const char *, - Elf_Internal_Sym *, asection *)); -static boolean elf_link_flush_output_syms - PARAMS ((struct elf_final_link_info *)); -static boolean elf_link_output_extsym - PARAMS ((struct elf_link_hash_entry *, PTR)); -static boolean elf_link_input_bfd - PARAMS ((struct elf_final_link_info *, bfd *)); -static boolean elf_reloc_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *)); - -/* This struct is used to pass information to routines called via - elf_link_hash_traverse which must return failure. */ - -struct elf_finfo_failed -{ - boolean failed; - struct elf_final_link_info *finfo; -}; - -/* Do the final step of an ELF link. */ - -boolean -elf_bfd_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - boolean dynamic; - bfd *dynobj; - struct elf_final_link_info finfo; - register asection *o; - register struct bfd_link_order *p; - register bfd *sub; - size_t max_contents_size; - size_t max_external_reloc_size; - size_t max_internal_reloc_count; - size_t max_sym_count; - file_ptr off; - Elf_Internal_Sym elfsym; - unsigned int i; - Elf_Internal_Shdr *symtab_hdr; - Elf_Internal_Shdr *symstrtab_hdr; - struct elf_backend_data *bed = get_elf_backend_data (abfd); - struct elf_finfo_failed eif; - - if (info->shared) - abfd->flags |= DYNAMIC; - - dynamic = elf_hash_table (info)->dynamic_sections_created; - dynobj = elf_hash_table (info)->dynobj; - - finfo.info = info; - finfo.output_bfd = abfd; - finfo.symstrtab = elf_stringtab_init (); - if (finfo.symstrtab == NULL) - return false; - if (! dynamic) - { - finfo.dynsym_sec = NULL; - finfo.hash_sec = NULL; - } - else - { - finfo.dynsym_sec = bfd_get_section_by_name (dynobj, ".dynsym"); - finfo.hash_sec = bfd_get_section_by_name (dynobj, ".hash"); - BFD_ASSERT (finfo.dynsym_sec != NULL && finfo.hash_sec != NULL); - } - finfo.contents = NULL; - finfo.external_relocs = NULL; - finfo.internal_relocs = NULL; - finfo.external_syms = NULL; - finfo.internal_syms = NULL; - finfo.indices = NULL; - finfo.sections = NULL; - finfo.symbuf = NULL; - finfo.symbuf_count = 0; - - /* Count up the number of relocations we will output for each output - section, so that we know the sizes of the reloc sections. We - also figure out some maximum sizes. */ - max_contents_size = 0; - max_external_reloc_size = 0; - max_internal_reloc_count = 0; - max_sym_count = 0; - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - o->reloc_count = 0; - - for (p = o->link_order_head; p != NULL; p = p->next) - { - if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - ++o->reloc_count; - else if (p->type == bfd_indirect_link_order) - { - asection *sec; - - sec = p->u.indirect.section; - - if (info->relocateable) - o->reloc_count += sec->reloc_count; - - if (sec->_raw_size > max_contents_size) - max_contents_size = sec->_raw_size; - if (sec->_cooked_size > max_contents_size) - max_contents_size = sec->_cooked_size; - - /* We are interested in just local symbols, not all - symbols. */ - if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour) - { - size_t sym_count; - - if (elf_bad_symtab (sec->owner)) - sym_count = (elf_tdata (sec->owner)->symtab_hdr.sh_size - / sizeof (Elf_External_Sym)); - else - sym_count = elf_tdata (sec->owner)->symtab_hdr.sh_info; - - if (sym_count > max_sym_count) - max_sym_count = sym_count; - - if ((sec->flags & SEC_RELOC) != 0) - { - size_t ext_size; - - ext_size = elf_section_data (sec)->rel_hdr.sh_size; - if (ext_size > max_external_reloc_size) - max_external_reloc_size = ext_size; - if (sec->reloc_count > max_internal_reloc_count) - max_internal_reloc_count = sec->reloc_count; - } - } - } - } - - if (o->reloc_count > 0) - o->flags |= SEC_RELOC; - else - { - /* Explicitly clear the SEC_RELOC flag. The linker tends to - set it (this is probably a bug) and if it is set - assign_section_numbers will create a reloc section. */ - o->flags &=~ SEC_RELOC; - } - - /* If the SEC_ALLOC flag is not set, force the section VMA to - zero. This is done in elf_fake_sections as well, but forcing - the VMA to 0 here will ensure that relocs against these - sections are handled correctly. */ - if ((o->flags & SEC_ALLOC) == 0) - o->vma = 0; - } - - /* Figure out the file positions for everything but the symbol table - and the relocs. We set symcount to force assign_section_numbers - to create a symbol table. */ - abfd->symcount = info->strip == strip_all ? 0 : 1; - BFD_ASSERT (! abfd->output_has_begun); - if (! _bfd_elf_compute_section_file_positions (abfd, info)) - goto error_return; - - /* That created the reloc sections. Set their sizes, and assign - them file positions, and allocate some buffers. */ - for (o = abfd->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_RELOC) != 0) - { - Elf_Internal_Shdr *rel_hdr; - register struct elf_link_hash_entry **p, **pend; - - rel_hdr = &elf_section_data (o)->rel_hdr; - - rel_hdr->sh_size = rel_hdr->sh_entsize * o->reloc_count; - - /* The contents field must last into write_object_contents, - so we allocate it with bfd_alloc rather than malloc. */ - rel_hdr->contents = (PTR) bfd_alloc (abfd, rel_hdr->sh_size); - if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0) - goto error_return; - - p = ((struct elf_link_hash_entry **) - bfd_malloc (o->reloc_count - * sizeof (struct elf_link_hash_entry *))); - if (p == NULL && o->reloc_count != 0) - goto error_return; - elf_section_data (o)->rel_hashes = p; - pend = p + o->reloc_count; - for (; p < pend; p++) - *p = NULL; - - /* Use the reloc_count field as an index when outputting the - relocs. */ - o->reloc_count = 0; - } - } - - _bfd_elf_assign_file_positions_for_relocs (abfd); - - /* We have now assigned file positions for all the sections except - .symtab and .strtab. We start the .symtab section at the current - file position, and write directly to it. We build the .strtab - section in memory. */ - abfd->symcount = 0; - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - /* sh_name is set in prep_headers. */ - symtab_hdr->sh_type = SHT_SYMTAB; - symtab_hdr->sh_flags = 0; - symtab_hdr->sh_addr = 0; - symtab_hdr->sh_size = 0; - symtab_hdr->sh_entsize = sizeof (Elf_External_Sym); - /* sh_link is set in assign_section_numbers. */ - /* sh_info is set below. */ - /* sh_offset is set just below. */ - symtab_hdr->sh_addralign = 4; /* FIXME: system dependent? */ - - off = elf_tdata (abfd)->next_file_pos; - off = _bfd_elf_assign_file_position_for_section (symtab_hdr, off, true); - - /* Note that at this point elf_tdata (abfd)->next_file_pos is - incorrect. We do not yet know the size of the .symtab section. - We correct next_file_pos below, after we do know the size. */ - - /* Allocate a buffer to hold swapped out symbols. This is to avoid - continuously seeking to the right position in the file. */ - if (! info->keep_memory || max_sym_count < 20) - finfo.symbuf_size = 20; - else - finfo.symbuf_size = max_sym_count; - finfo.symbuf = ((Elf_External_Sym *) - bfd_malloc (finfo.symbuf_size * sizeof (Elf_External_Sym))); - if (finfo.symbuf == NULL) - goto error_return; - - /* Start writing out the symbol table. The first symbol is always a - dummy symbol. */ - if (info->strip != strip_all || info->relocateable) - { - elfsym.st_value = 0; - elfsym.st_size = 0; - elfsym.st_info = 0; - elfsym.st_other = 0; - elfsym.st_shndx = SHN_UNDEF; - if (! elf_link_output_sym (&finfo, (const char *) NULL, - &elfsym, bfd_und_section_ptr)) - goto error_return; - } - -#if 0 - /* Some standard ELF linkers do this, but we don't because it causes - bootstrap comparison failures. */ - /* Output a file symbol for the output file as the second symbol. - We output this even if we are discarding local symbols, although - I'm not sure if this is correct. */ - elfsym.st_value = 0; - elfsym.st_size = 0; - elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE); - elfsym.st_other = 0; - elfsym.st_shndx = SHN_ABS; - if (! elf_link_output_sym (&finfo, bfd_get_filename (abfd), - &elfsym, bfd_abs_section_ptr)) - goto error_return; -#endif - - /* Output a symbol for each section. We output these even if we are - discarding local symbols, since they are used for relocs. These - symbols have no names. We store the index of each one in the - index field of the section, so that we can find it again when - outputting relocs. */ - if (info->strip != strip_all || info->relocateable) - { - elfsym.st_value = 0; - elfsym.st_size = 0; - elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); - elfsym.st_other = 0; - for (i = 1; i < elf_elfheader (abfd)->e_shnum; i++) - { - o = section_from_elf_index (abfd, i); - if (o != NULL) - o->target_index = abfd->symcount; - elfsym.st_shndx = i; - if (! elf_link_output_sym (&finfo, (const char *) NULL, - &elfsym, o)) - goto error_return; - } - } - - /* Allocate some memory to hold information read in from the input - files. */ - finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size); - finfo.external_relocs = (PTR) bfd_malloc (max_external_reloc_size); - finfo.internal_relocs = ((Elf_Internal_Rela *) - bfd_malloc (max_internal_reloc_count - * sizeof (Elf_Internal_Rela))); - finfo.external_syms = ((Elf_External_Sym *) - bfd_malloc (max_sym_count - * sizeof (Elf_External_Sym))); - finfo.internal_syms = ((Elf_Internal_Sym *) - bfd_malloc (max_sym_count - * sizeof (Elf_Internal_Sym))); - finfo.indices = (long *) bfd_malloc (max_sym_count * sizeof (long)); - finfo.sections = ((asection **) - bfd_malloc (max_sym_count * sizeof (asection *))); - if ((finfo.contents == NULL && max_contents_size != 0) - || (finfo.external_relocs == NULL && max_external_reloc_size != 0) - || (finfo.internal_relocs == NULL && max_internal_reloc_count != 0) - || (finfo.external_syms == NULL && max_sym_count != 0) - || (finfo.internal_syms == NULL && max_sym_count != 0) - || (finfo.indices == NULL && max_sym_count != 0) - || (finfo.sections == NULL && max_sym_count != 0)) - goto error_return; - - /* Since ELF permits relocations to be against local symbols, we - must have the local symbols available when we do the relocations. - Since we would rather only read the local symbols once, and we - would rather not keep them in memory, we handle all the - relocations for a single input file at the same time. - - Unfortunately, there is no way to know the total number of local - symbols until we have seen all of them, and the local symbol - indices precede the global symbol indices. This means that when - we are generating relocateable output, and we see a reloc against - a global symbol, we can not know the symbol index until we have - finished examining all the local symbols to see which ones we are - going to output. To deal with this, we keep the relocations in - memory, and don't output them until the end of the link. This is - an unfortunate waste of memory, but I don't see a good way around - it. Fortunately, it only happens when performing a relocateable - link, which is not the common case. FIXME: If keep_memory is set - we could write the relocs out and then read them again; I don't - know how bad the memory loss will be. */ - - for (sub = info->input_bfds; sub != NULL; sub = sub->next) - sub->output_has_begun = false; - for (o = abfd->sections; o != NULL; o = o->next) - { - for (p = o->link_order_head; p != NULL; p = p->next) - { - if (p->type == bfd_indirect_link_order - && (bfd_get_flavour (p->u.indirect.section->owner) - == bfd_target_elf_flavour)) - { - sub = p->u.indirect.section->owner; - if (! sub->output_has_begun) - { - if (! elf_link_input_bfd (&finfo, sub)) - goto error_return; - sub->output_has_begun = true; - } - } - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - { - if (! elf_reloc_link_order (abfd, info, o, p)) - goto error_return; - } - else - { - if (! _bfd_default_link_order (abfd, info, o, p)) - goto error_return; - } - } - } - - /* That wrote out all the local symbols. Finish up the symbol table - with the global symbols. */ - - /* The sh_info field records the index of the first non local - symbol. */ - symtab_hdr->sh_info = abfd->symcount; - if (dynamic) - elf_section_data (finfo.dynsym_sec->output_section)->this_hdr.sh_info = 1; - - /* We get the global symbols from the hash table. */ - eif.failed = false; - eif.finfo = &finfo; - elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym, - (PTR) &eif); - if (eif.failed) - return false; - - /* Flush all symbols to the file. */ - if (! elf_link_flush_output_syms (&finfo)) - return false; - - /* Now we know the size of the symtab section. */ - off += symtab_hdr->sh_size; - - /* Finish up and write out the symbol string table (.strtab) - section. */ - symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; - /* sh_name was set in prep_headers. */ - symstrtab_hdr->sh_type = SHT_STRTAB; - symstrtab_hdr->sh_flags = 0; - symstrtab_hdr->sh_addr = 0; - symstrtab_hdr->sh_size = _bfd_stringtab_size (finfo.symstrtab); - symstrtab_hdr->sh_entsize = 0; - symstrtab_hdr->sh_link = 0; - symstrtab_hdr->sh_info = 0; - /* sh_offset is set just below. */ - symstrtab_hdr->sh_addralign = 1; - - off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr, off, true); - elf_tdata (abfd)->next_file_pos = off; - - if (abfd->symcount > 0) - { - if (bfd_seek (abfd, symstrtab_hdr->sh_offset, SEEK_SET) != 0 - || ! _bfd_stringtab_emit (abfd, finfo.symstrtab)) - return false; - } - - /* Adjust the relocs to have the correct symbol indices. */ - for (o = abfd->sections; o != NULL; o = o->next) - { - struct elf_link_hash_entry **rel_hash; - Elf_Internal_Shdr *rel_hdr; - - if ((o->flags & SEC_RELOC) == 0) - continue; - - rel_hash = elf_section_data (o)->rel_hashes; - rel_hdr = &elf_section_data (o)->rel_hdr; - for (i = 0; i < o->reloc_count; i++, rel_hash++) - { - if (*rel_hash == NULL) - continue; - - BFD_ASSERT ((*rel_hash)->indx >= 0); - - if (rel_hdr->sh_entsize == sizeof (Elf_External_Rel)) - { - Elf_External_Rel *erel; - Elf_Internal_Rel irel; - - erel = (Elf_External_Rel *) rel_hdr->contents + i; - elf_swap_reloc_in (abfd, erel, &irel); - irel.r_info = ELF_R_INFO ((*rel_hash)->indx, - ELF_R_TYPE (irel.r_info)); - elf_swap_reloc_out (abfd, &irel, erel); - } - else - { - Elf_External_Rela *erela; - Elf_Internal_Rela irela; - - BFD_ASSERT (rel_hdr->sh_entsize - == sizeof (Elf_External_Rela)); - - erela = (Elf_External_Rela *) rel_hdr->contents + i; - elf_swap_reloca_in (abfd, erela, &irela); - irela.r_info = ELF_R_INFO ((*rel_hash)->indx, - ELF_R_TYPE (irela.r_info)); - elf_swap_reloca_out (abfd, &irela, erela); - } - } - - /* Set the reloc_count field to 0 to prevent write_relocs from - trying to swap the relocs out itself. */ - o->reloc_count = 0; - } - - /* If we are linking against a dynamic object, or generating a - shared library, finish up the dynamic linking information. */ - if (dynamic) - { - Elf_External_Dyn *dyncon, *dynconend; - - /* Fix up .dynamic entries. */ - o = bfd_get_section_by_name (dynobj, ".dynamic"); - BFD_ASSERT (o != NULL); - - dyncon = (Elf_External_Dyn *) o->contents; - dynconend = (Elf_External_Dyn *) (o->contents + o->_raw_size); - for (; dyncon < dynconend; dyncon++) - { - Elf_Internal_Dyn dyn; - const char *name; - unsigned int type; - - elf_swap_dyn_in (dynobj, dyncon, &dyn); - - switch (dyn.d_tag) - { - default: - break; - - /* SVR4 linkers seem to set DT_INIT and DT_FINI based on - magic _init and _fini symbols. This is pretty ugly, - but we are compatible. */ - case DT_INIT: - name = "_init"; - goto get_sym; - case DT_FINI: - name = "_fini"; - get_sym: - { - struct elf_link_hash_entry *h; - - h = elf_link_hash_lookup (elf_hash_table (info), name, - false, false, true); - if (h != NULL - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)) - { - dyn.d_un.d_val = h->root.u.def.value; - o = h->root.u.def.section; - if (o->output_section != NULL) - dyn.d_un.d_val += (o->output_section->vma - + o->output_offset); - else - { - /* The symbol is imported from another shared - library and does not apply to this one. */ - dyn.d_un.d_val = 0; - } - - elf_swap_dyn_out (dynobj, &dyn, dyncon); - } - } - break; - - case DT_HASH: - name = ".hash"; - goto get_vma; - case DT_STRTAB: - name = ".dynstr"; - goto get_vma; - case DT_SYMTAB: - name = ".dynsym"; - get_vma: - o = bfd_get_section_by_name (abfd, name); - BFD_ASSERT (o != NULL); - dyn.d_un.d_ptr = o->vma; - elf_swap_dyn_out (dynobj, &dyn, dyncon); - break; - - case DT_REL: - case DT_RELA: - case DT_RELSZ: - case DT_RELASZ: - if (dyn.d_tag == DT_REL || dyn.d_tag == DT_RELSZ) - type = SHT_REL; - else - type = SHT_RELA; - dyn.d_un.d_val = 0; - for (i = 1; i < elf_elfheader (abfd)->e_shnum; i++) - { - Elf_Internal_Shdr *hdr; - - hdr = elf_elfsections (abfd)[i]; - if (hdr->sh_type == type - && (hdr->sh_flags & SHF_ALLOC) != 0) - { - if (dyn.d_tag == DT_RELSZ || dyn.d_tag == DT_RELASZ) - dyn.d_un.d_val += hdr->sh_size; - else - { - if (dyn.d_un.d_val == 0 - || hdr->sh_addr < dyn.d_un.d_val) - dyn.d_un.d_val = hdr->sh_addr; - } - } - } - elf_swap_dyn_out (dynobj, &dyn, dyncon); - break; - } - } - } - - /* If we have created any dynamic sections, then output them. */ - if (dynobj != NULL) - { - if (! (*bed->elf_backend_finish_dynamic_sections) (abfd, info)) - goto error_return; - - for (o = dynobj->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_HAS_CONTENTS) == 0 - || o->_raw_size == 0) - continue; - if ((o->flags & SEC_IN_MEMORY) == 0) - { - /* At this point, we are only interested in sections - created by elf_link_create_dynamic_sections. FIXME: - This test is fragile. */ - continue; - } - if ((elf_section_data (o->output_section)->this_hdr.sh_type - != SHT_STRTAB) - || strcmp (bfd_get_section_name (abfd, o), ".dynstr") != 0) - { - if (! bfd_set_section_contents (abfd, o->output_section, - o->contents, o->output_offset, - o->_raw_size)) - goto error_return; - } - else - { - file_ptr off; - - /* The contents of the .dynstr section are actually in a - stringtab. */ - off = elf_section_data (o->output_section)->this_hdr.sh_offset; - if (bfd_seek (abfd, off, SEEK_SET) != 0 - || ! _bfd_stringtab_emit (abfd, - elf_hash_table (info)->dynstr)) - goto error_return; - } - } - } - - if (finfo.symstrtab != NULL) - _bfd_stringtab_free (finfo.symstrtab); - if (finfo.contents != NULL) - free (finfo.contents); - if (finfo.external_relocs != NULL) - free (finfo.external_relocs); - if (finfo.internal_relocs != NULL) - free (finfo.internal_relocs); - if (finfo.external_syms != NULL) - free (finfo.external_syms); - if (finfo.internal_syms != NULL) - free (finfo.internal_syms); - if (finfo.indices != NULL) - free (finfo.indices); - if (finfo.sections != NULL) - free (finfo.sections); - if (finfo.symbuf != NULL) - free (finfo.symbuf); - for (o = abfd->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_RELOC) != 0 - && elf_section_data (o)->rel_hashes != NULL) - free (elf_section_data (o)->rel_hashes); - } - - elf_tdata (abfd)->linker = true; - - return true; - - error_return: - if (finfo.symstrtab != NULL) - _bfd_stringtab_free (finfo.symstrtab); - if (finfo.contents != NULL) - free (finfo.contents); - if (finfo.external_relocs != NULL) - free (finfo.external_relocs); - if (finfo.internal_relocs != NULL) - free (finfo.internal_relocs); - if (finfo.external_syms != NULL) - free (finfo.external_syms); - if (finfo.internal_syms != NULL) - free (finfo.internal_syms); - if (finfo.indices != NULL) - free (finfo.indices); - if (finfo.sections != NULL) - free (finfo.sections); - if (finfo.symbuf != NULL) - free (finfo.symbuf); - for (o = abfd->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_RELOC) != 0 - && elf_section_data (o)->rel_hashes != NULL) - free (elf_section_data (o)->rel_hashes); - } - - return false; -} - -/* Add a symbol to the output symbol table. */ - -static boolean -elf_link_output_sym (finfo, name, elfsym, input_sec) - struct elf_final_link_info *finfo; - const char *name; - Elf_Internal_Sym *elfsym; - asection *input_sec; -{ - boolean (*output_symbol_hook) PARAMS ((bfd *, - struct bfd_link_info *info, - const char *, - Elf_Internal_Sym *, - asection *)); - - output_symbol_hook = get_elf_backend_data (finfo->output_bfd)-> - elf_backend_link_output_symbol_hook; - if (output_symbol_hook != NULL) - { - if (! ((*output_symbol_hook) - (finfo->output_bfd, finfo->info, name, elfsym, input_sec))) - return false; - } - - if (name == (const char *) NULL || *name == '\0') - elfsym->st_name = 0; - else - { - elfsym->st_name = (unsigned long) _bfd_stringtab_add (finfo->symstrtab, - name, true, - false); - if (elfsym->st_name == (unsigned long) -1) - return false; - } - - if (finfo->symbuf_count >= finfo->symbuf_size) - { - if (! elf_link_flush_output_syms (finfo)) - return false; - } - - elf_swap_symbol_out (finfo->output_bfd, elfsym, - (PTR) (finfo->symbuf + finfo->symbuf_count)); - ++finfo->symbuf_count; - - ++finfo->output_bfd->symcount; - - return true; -} - -/* Flush the output symbols to the file. */ - -static boolean -elf_link_flush_output_syms (finfo) - struct elf_final_link_info *finfo; -{ - if (finfo->symbuf_count > 0) - { - Elf_Internal_Shdr *symtab; - - symtab = &elf_tdata (finfo->output_bfd)->symtab_hdr; - - if (bfd_seek (finfo->output_bfd, symtab->sh_offset + symtab->sh_size, - SEEK_SET) != 0 - || (bfd_write ((PTR) finfo->symbuf, finfo->symbuf_count, - sizeof (Elf_External_Sym), finfo->output_bfd) - != finfo->symbuf_count * sizeof (Elf_External_Sym))) - return false; - - symtab->sh_size += finfo->symbuf_count * sizeof (Elf_External_Sym); - - finfo->symbuf_count = 0; - } - - return true; -} - -/* Add an external symbol to the symbol table. This is called from - the hash table traversal routine. */ - -static boolean -elf_link_output_extsym (h, data) - struct elf_link_hash_entry *h; - PTR data; -{ - struct elf_finfo_failed *eif = (struct elf_finfo_failed *) data; - struct elf_final_link_info *finfo = eif->finfo; - boolean strip; - Elf_Internal_Sym sym; - asection *input_sec; - - /* If we are not creating a shared library, and this symbol is - referenced by a shared library but is not defined anywhere, then - warn that it is undefined. If we do not do this, the runtime - linker will complain that the symbol is undefined when the - program is run. We don't have to worry about symbols that are - referenced by regular files, because we will already have issued - warnings for them. */ - if (! finfo->info->relocateable - && ! finfo->info->shared - && h->root.type == bfd_link_hash_undefined - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0 - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) - { - if (! ((*finfo->info->callbacks->undefined_symbol) - (finfo->info, h->root.root.string, h->root.u.undef.abfd, - (asection *) NULL, 0))) - { - eif->failed = true; - return false; - } - } - - /* We don't want to output symbols that have never been mentioned by - a regular file, or that we have been told to strip. However, if - h->indx is set to -2, the symbol is used by a reloc and we must - output it. */ - if (h->indx == -2) - strip = false; - else if (((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - || (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0) - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) - strip = true; - else if (finfo->info->strip == strip_all - || (finfo->info->strip == strip_some - && bfd_hash_lookup (finfo->info->keep_hash, - h->root.root.string, - false, false) == NULL)) - strip = true; - else - strip = false; - - /* If we're stripping it, and it's not a dynamic symbol, there's - nothing else to do. */ - if (strip && h->dynindx == -1) - return true; - - sym.st_value = 0; - sym.st_size = h->size; - sym.st_other = 0; - if (h->root.type == bfd_link_hash_undefweak - || h->root.type == bfd_link_hash_defweak) - sym.st_info = ELF_ST_INFO (STB_WEAK, h->type); - else - sym.st_info = ELF_ST_INFO (STB_GLOBAL, h->type); - - switch (h->root.type) - { - default: - case bfd_link_hash_new: - abort (); - return false; - - case bfd_link_hash_undefined: - input_sec = bfd_und_section_ptr; - sym.st_shndx = SHN_UNDEF; - break; - - case bfd_link_hash_undefweak: - input_sec = bfd_und_section_ptr; - sym.st_shndx = SHN_UNDEF; - break; - - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - { - input_sec = h->root.u.def.section; - if (input_sec->output_section != NULL) - { - sym.st_shndx = - _bfd_elf_section_from_bfd_section (finfo->output_bfd, - input_sec->output_section); - if (sym.st_shndx == (unsigned short) -1) - { - eif->failed = true; - return false; - } - - /* ELF symbols in relocateable files are section relative, - but in nonrelocateable files they are virtual - addresses. */ - sym.st_value = h->root.u.def.value + input_sec->output_offset; - if (! finfo->info->relocateable) - sym.st_value += input_sec->output_section->vma; - } - else - { - BFD_ASSERT ((bfd_get_flavour (input_sec->owner) - == bfd_target_elf_flavour) - && elf_elfheader (input_sec->owner)->e_type == ET_DYN); - sym.st_shndx = SHN_UNDEF; - input_sec = bfd_und_section_ptr; - } - } - break; - - case bfd_link_hash_common: - input_sec = bfd_com_section_ptr; - sym.st_shndx = SHN_COMMON; - sym.st_value = 1 << h->root.u.c.p->alignment_power; - break; - - case bfd_link_hash_indirect: - case bfd_link_hash_warning: - /* We can't represent these symbols in ELF. A warning symbol - may have come from a .gnu.warning.SYMBOL section anyhow. We - just put the target symbol in the hash table. If the target - symbol does not really exist, don't do anything. */ - if (h->root.u.i.link->type == bfd_link_hash_new) - return true; - return (elf_link_output_extsym - ((struct elf_link_hash_entry *) h->root.u.i.link, data)); - } - - /* If this symbol should be put in the .dynsym section, then put it - there now. We have already know the symbol index. We also fill - in the entry in the .hash section. */ - if (h->dynindx != -1 - && elf_hash_table (finfo->info)->dynamic_sections_created) - { - struct elf_backend_data *bed; - size_t bucketcount; - size_t bucket; - bfd_byte *bucketpos; - bfd_vma chain; - - sym.st_name = h->dynstr_index; - - /* Give the processor backend a chance to tweak the symbol - value, and also to finish up anything that needs to be done - for this symbol. */ - bed = get_elf_backend_data (finfo->output_bfd); - if (! ((*bed->elf_backend_finish_dynamic_symbol) - (finfo->output_bfd, finfo->info, h, &sym))) - { - eif->failed = true; - return false; - } - - elf_swap_symbol_out (finfo->output_bfd, &sym, - (PTR) (((Elf_External_Sym *) - finfo->dynsym_sec->contents) - + h->dynindx)); - - bucketcount = elf_hash_table (finfo->info)->bucketcount; - bucket = (bfd_elf_hash ((const unsigned char *) h->root.root.string) - % bucketcount); - bucketpos = ((bfd_byte *) finfo->hash_sec->contents - + (bucket + 2) * (ARCH_SIZE / 8)); - chain = get_word (finfo->output_bfd, bucketpos); - put_word (finfo->output_bfd, h->dynindx, bucketpos); - put_word (finfo->output_bfd, chain, - ((bfd_byte *) finfo->hash_sec->contents - + (bucketcount + 2 + h->dynindx) * (ARCH_SIZE / 8))); - } - - /* If we're stripping it, then it was just a dynamic symbol, and - there's nothing else to do. */ - if (strip) - return true; - - h->indx = finfo->output_bfd->symcount; - - if (! elf_link_output_sym (finfo, h->root.root.string, &sym, input_sec)) - { - eif->failed = true; - return false; - } - - return true; -} - -/* Link an input file into the linker output file. This function - handles all the sections and relocations of the input file at once. - This is so that we only have to read the local symbols once, and - don't have to keep them in memory. */ - -static boolean -elf_link_input_bfd (finfo, input_bfd) - struct elf_final_link_info *finfo; - bfd *input_bfd; -{ - boolean (*relocate_section) PARAMS ((bfd *, struct bfd_link_info *, - bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, - Elf_Internal_Sym *, asection **)); - bfd *output_bfd; - Elf_Internal_Shdr *symtab_hdr; - size_t locsymcount; - size_t extsymoff; - Elf_External_Sym *esym; - Elf_External_Sym *esymend; - Elf_Internal_Sym *isym; - long *pindex; - asection **ppsection; - asection *o; - - output_bfd = finfo->output_bfd; - relocate_section = - get_elf_backend_data (output_bfd)->elf_backend_relocate_section; - - /* If this is a dynamic object, we don't want to do anything here: - we don't want the local symbols, and we don't want the section - contents. */ - if (elf_elfheader (input_bfd)->e_type == ET_DYN) - return true; - - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - if (elf_bad_symtab (input_bfd)) - { - locsymcount = symtab_hdr->sh_size / sizeof (Elf_External_Sym); - extsymoff = 0; - } - else - { - locsymcount = symtab_hdr->sh_info; - extsymoff = symtab_hdr->sh_info; - } - - /* Read the local symbols. */ - if (locsymcount > 0 - && (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0 - || (bfd_read (finfo->external_syms, sizeof (Elf_External_Sym), - locsymcount, input_bfd) - != locsymcount * sizeof (Elf_External_Sym)))) - return false; - - /* Swap in the local symbols and write out the ones which we know - are going into the output file. */ - esym = finfo->external_syms; - esymend = esym + locsymcount; - isym = finfo->internal_syms; - pindex = finfo->indices; - ppsection = finfo->sections; - for (; esym < esymend; esym++, isym++, pindex++, ppsection++) - { - asection *isec; - const char *name; - Elf_Internal_Sym osym; - - elf_swap_symbol_in (input_bfd, esym, isym); - *pindex = -1; - - if (elf_bad_symtab (input_bfd)) - { - if (ELF_ST_BIND (isym->st_info) != STB_LOCAL) - { - *ppsection = NULL; - continue; - } - } - - if (isym->st_shndx == SHN_UNDEF) - isec = bfd_und_section_ptr; - else if (isym->st_shndx > 0 && isym->st_shndx < SHN_LORESERVE) - isec = section_from_elf_index (input_bfd, isym->st_shndx); - else if (isym->st_shndx == SHN_ABS) - isec = bfd_abs_section_ptr; - else if (isym->st_shndx == SHN_COMMON) - isec = bfd_com_section_ptr; - else - { - /* Who knows? */ - isec = NULL; - } - - *ppsection = isec; - - /* Don't output the first, undefined, symbol. */ - if (esym == finfo->external_syms) - continue; - - /* If we are stripping all symbols, we don't want to output this - one. */ - if (finfo->info->strip == strip_all) - continue; - - /* We never output section symbols. Instead, we use the section - symbol of the corresponding section in the output file. */ - if (ELF_ST_TYPE (isym->st_info) == STT_SECTION) - continue; - - /* If we are discarding all local symbols, we don't want to - output this one. If we are generating a relocateable output - file, then some of the local symbols may be required by - relocs; we output them below as we discover that they are - needed. */ - if (finfo->info->discard == discard_all) - continue; - - /* Get the name of the symbol. */ - name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, - isym->st_name); - if (name == NULL) - return false; - - /* See if we are discarding symbols with this name. */ - if ((finfo->info->strip == strip_some - && (bfd_hash_lookup (finfo->info->keep_hash, name, false, false) - == NULL)) - || (finfo->info->discard == discard_l - && strncmp (name, finfo->info->lprefix, - finfo->info->lprefix_len) == 0)) - continue; - - /* If we get here, we are going to output this symbol. */ - - osym = *isym; - - /* Adjust the section index for the output file. */ - osym.st_shndx = _bfd_elf_section_from_bfd_section (output_bfd, - isec->output_section); - if (osym.st_shndx == (unsigned short) -1) - return false; - - *pindex = output_bfd->symcount; - - /* ELF symbols in relocateable files are section relative, but - in executable files they are virtual addresses. Note that - this code assumes that all ELF sections have an associated - BFD section with a reasonable value for output_offset; below - we assume that they also have a reasonable value for - output_section. Any special sections must be set up to meet - these requirements. */ - osym.st_value += isec->output_offset; - if (! finfo->info->relocateable) - osym.st_value += isec->output_section->vma; - - if (! elf_link_output_sym (finfo, name, &osym, isec)) - return false; - } - - /* Relocate the contents of each section. */ - for (o = input_bfd->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_HAS_CONTENTS) == 0) - continue; - - if ((o->flags & SEC_IN_MEMORY) != 0 - && input_bfd == elf_hash_table (finfo->info)->dynobj) - { - /* Section was created by elf_link_create_dynamic_sections. - FIXME: This test is fragile. */ - continue; - } - - /* Read the contents of the section. */ - if (! bfd_get_section_contents (input_bfd, o, finfo->contents, - (file_ptr) 0, o->_raw_size)) - return false; - - if ((o->flags & SEC_RELOC) != 0) - { - Elf_Internal_Rela *internal_relocs; - - /* Get the swapped relocs. */ - internal_relocs = elf_link_read_relocs (input_bfd, o, - finfo->external_relocs, - finfo->internal_relocs, - false); - if (internal_relocs == NULL - && o->reloc_count > 0) - return false; - - /* Relocate the section by invoking a back end routine. - - The back end routine is responsible for adjusting the - section contents as necessary, and (if using Rela relocs - and generating a relocateable output file) adjusting the - reloc addend as necessary. - - The back end routine does not have to worry about setting - the reloc address or the reloc symbol index. - - The back end routine is given a pointer to the swapped in - internal symbols, and can access the hash table entries - for the external symbols via elf_sym_hashes (input_bfd). - - When generating relocateable output, the back end routine - must handle STB_LOCAL/STT_SECTION symbols specially. The - output symbol is going to be a section symbol - corresponding to the output section, which will require - the addend to be adjusted. */ - - if (! (*relocate_section) (output_bfd, finfo->info, - input_bfd, o, - finfo->contents, - internal_relocs, - finfo->internal_syms, - finfo->sections)) - return false; - - if (finfo->info->relocateable) - { - Elf_Internal_Rela *irela; - Elf_Internal_Rela *irelaend; - struct elf_link_hash_entry **rel_hash; - Elf_Internal_Shdr *input_rel_hdr; - Elf_Internal_Shdr *output_rel_hdr; - - /* Adjust the reloc addresses and symbol indices. */ - - irela = internal_relocs; - irelaend = irela + o->reloc_count; - rel_hash = (elf_section_data (o->output_section)->rel_hashes - + o->output_section->reloc_count); - for (; irela < irelaend; irela++, rel_hash++) - { - unsigned long r_symndx; - Elf_Internal_Sym *isym; - asection *sec; - - irela->r_offset += o->output_offset; - - r_symndx = ELF_R_SYM (irela->r_info); - - if (r_symndx == 0) - continue; - - if (r_symndx >= locsymcount - || (elf_bad_symtab (input_bfd) - && finfo->sections[r_symndx] == NULL)) - { - long indx; - - /* This is a reloc against a global symbol. We - have not yet output all the local symbols, so - we do not know the symbol index of any global - symbol. We set the rel_hash entry for this - reloc to point to the global hash table entry - for this symbol. The symbol index is then - set at the end of elf_bfd_final_link. */ - indx = r_symndx - extsymoff; - *rel_hash = elf_sym_hashes (input_bfd)[indx]; - - /* Setting the index to -2 tells - elf_link_output_extsym that this symbol is - used by a reloc. */ - BFD_ASSERT ((*rel_hash)->indx < 0); - (*rel_hash)->indx = -2; - - continue; - } - - /* This is a reloc against a local symbol. */ - - *rel_hash = NULL; - isym = finfo->internal_syms + r_symndx; - sec = finfo->sections[r_symndx]; - if (ELF_ST_TYPE (isym->st_info) == STT_SECTION) - { - /* I suppose the backend ought to fill in the - section of any STT_SECTION symbol against a - processor specific section. */ - if (sec != NULL && bfd_is_abs_section (sec)) - r_symndx = 0; - else if (sec == NULL || sec->owner == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - else - { - r_symndx = sec->output_section->target_index; - BFD_ASSERT (r_symndx != 0); - } - } - else - { - if (finfo->indices[r_symndx] == -1) - { - unsigned long link; - const char *name; - asection *osec; - - if (finfo->info->strip == strip_all) - { - /* You can't do ld -r -s. */ - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - /* This symbol was skipped earlier, but - since it is needed by a reloc, we - must output it now. */ - link = symtab_hdr->sh_link; - name = bfd_elf_string_from_elf_section (input_bfd, - link, - isym->st_name); - if (name == NULL) - return false; - - osec = sec->output_section; - isym->st_shndx = - _bfd_elf_section_from_bfd_section (output_bfd, - osec); - if (isym->st_shndx == (unsigned short) -1) - return false; - - isym->st_value += sec->output_offset; - if (! finfo->info->relocateable) - isym->st_value += osec->vma; - - finfo->indices[r_symndx] = output_bfd->symcount; - - if (! elf_link_output_sym (finfo, name, isym, sec)) - return false; - } - - r_symndx = finfo->indices[r_symndx]; - } - - irela->r_info = ELF_R_INFO (r_symndx, - ELF_R_TYPE (irela->r_info)); - } - - /* Swap out the relocs. */ - input_rel_hdr = &elf_section_data (o)->rel_hdr; - output_rel_hdr = &elf_section_data (o->output_section)->rel_hdr; - BFD_ASSERT (output_rel_hdr->sh_entsize - == input_rel_hdr->sh_entsize); - irela = internal_relocs; - irelaend = irela + o->reloc_count; - if (input_rel_hdr->sh_entsize == sizeof (Elf_External_Rel)) - { - Elf_External_Rel *erel; - - erel = ((Elf_External_Rel *) output_rel_hdr->contents - + o->output_section->reloc_count); - for (; irela < irelaend; irela++, erel++) - { - Elf_Internal_Rel irel; - - irel.r_offset = irela->r_offset; - irel.r_info = irela->r_info; - BFD_ASSERT (irela->r_addend == 0); - elf_swap_reloc_out (output_bfd, &irel, erel); - } - } - else - { - Elf_External_Rela *erela; - - BFD_ASSERT (input_rel_hdr->sh_entsize - == sizeof (Elf_External_Rela)); - erela = ((Elf_External_Rela *) output_rel_hdr->contents - + o->output_section->reloc_count); - for (; irela < irelaend; irela++, erela++) - elf_swap_reloca_out (output_bfd, irela, erela); - } - - o->output_section->reloc_count += o->reloc_count; - } - } - - /* Write out the modified section contents. */ - if (! bfd_set_section_contents (output_bfd, o->output_section, - finfo->contents, o->output_offset, - (o->_cooked_size != 0 - ? o->_cooked_size - : o->_raw_size))) - return false; - } - - return true; -} - -/* Generate a reloc when linking an ELF file. This is a reloc - requested by the linker, and does come from any input file. This - is used to build constructor and destructor tables when linking - with -Ur. */ - -static boolean -elf_reloc_link_order (output_bfd, info, output_section, link_order) - bfd *output_bfd; - struct bfd_link_info *info; - asection *output_section; - struct bfd_link_order *link_order; -{ - reloc_howto_type *howto; - long indx; - bfd_vma offset; - bfd_vma addend; - struct elf_link_hash_entry **rel_hash_ptr; - Elf_Internal_Shdr *rel_hdr; - - howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); - if (howto == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - addend = link_order->u.reloc.p->addend; - - /* Figure out the symbol index. */ - rel_hash_ptr = (elf_section_data (output_section)->rel_hashes - + output_section->reloc_count); - if (link_order->type == bfd_section_reloc_link_order) - { - indx = link_order->u.reloc.p->u.section->target_index; - BFD_ASSERT (indx != 0); - *rel_hash_ptr = NULL; - } - else - { - struct elf_link_hash_entry *h; - - /* Treat a reloc against a defined symbol as though it were - actually against the section. */ - h = ((struct elf_link_hash_entry *) - bfd_wrapped_link_hash_lookup (output_bfd, info, - link_order->u.reloc.p->u.name, - false, false, true)); - if (h != NULL - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)) - { - asection *section; - - section = h->root.u.def.section; - indx = section->output_section->target_index; - *rel_hash_ptr = NULL; - /* It seems that we ought to add the symbol value to the - addend here, but in practice it has already been added - because it was passed to constructor_callback. */ - addend += section->output_section->vma + section->output_offset; - } - else if (h != NULL) - { - /* Setting the index to -2 tells elf_link_output_extsym that - this symbol is used by a reloc. */ - h->indx = -2; - *rel_hash_ptr = h; - indx = 0; - } - else - { - if (! ((*info->callbacks->unattached_reloc) - (info, link_order->u.reloc.p->u.name, (bfd *) NULL, - (asection *) NULL, (bfd_vma) 0))) - return false; - indx = 0; - } - } - - /* If this is an inplace reloc, we must write the addend into the - object file. */ - if (howto->partial_inplace && addend != 0) - { - bfd_size_type size; - bfd_reloc_status_type rstat; - bfd_byte *buf; - boolean ok; - - size = bfd_get_reloc_size (howto); - buf = (bfd_byte *) bfd_zmalloc (size); - if (buf == (bfd_byte *) NULL) - return false; - rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf); - switch (rstat) - { - case bfd_reloc_ok: - break; - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - if (! ((*info->callbacks->reloc_overflow) - (info, - (link_order->type == bfd_section_reloc_link_order - ? bfd_section_name (output_bfd, - link_order->u.reloc.p->u.section) - : link_order->u.reloc.p->u.name), - howto->name, addend, (bfd *) NULL, (asection *) NULL, - (bfd_vma) 0))) - { - free (buf); - return false; - } - break; - } - ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf, - (file_ptr) link_order->offset, size); - free (buf); - if (! ok) - return false; - } - - /* The address of a reloc is relative to the section in a - relocateable file, and is a virtual address in an executable - file. */ - offset = link_order->offset; - if (! info->relocateable) - offset += output_section->vma; - - rel_hdr = &elf_section_data (output_section)->rel_hdr; - - if (rel_hdr->sh_type == SHT_REL) - { - Elf_Internal_Rel irel; - Elf_External_Rel *erel; - - irel.r_offset = offset; - irel.r_info = ELF_R_INFO (indx, howto->type); - erel = ((Elf_External_Rel *) rel_hdr->contents - + output_section->reloc_count); - elf_swap_reloc_out (output_bfd, &irel, erel); - } - else - { - Elf_Internal_Rela irela; - Elf_External_Rela *erela; - - irela.r_offset = offset; - irela.r_info = ELF_R_INFO (indx, howto->type); - irela.r_addend = addend; - erela = ((Elf_External_Rela *) rel_hdr->contents - + output_section->reloc_count); - elf_swap_reloca_out (output_bfd, &irela, erela); - } - - ++output_section->reloc_count; - - return true; -} - - -/* Allocate a pointer to live in a linker created section. */ - -boolean -elf_create_pointer_linker_section (abfd, info, lsect, h, rel) - bfd *abfd; - struct bfd_link_info *info; - elf_linker_section_t *lsect; - struct elf_link_hash_entry *h; - const Elf_Internal_Rela *rel; -{ - elf_linker_section_pointers_t **ptr_linker_section_ptr = NULL; - elf_linker_section_pointers_t *linker_section_ptr; - unsigned long r_symndx = ELF_R_SYM (rel->r_info);; - - BFD_ASSERT (lsect != NULL); - - /* Is this a global symbol? */ - if (h != NULL) - { - /* Has this symbol already been allocated, if so, our work is done */ - if (_bfd_elf_find_pointer_linker_section (h->linker_section_pointer, - rel->r_addend, - lsect->which)) - return true; - - ptr_linker_section_ptr = &h->linker_section_pointer; - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! elf_link_record_dynamic_symbol (info, h)) - return false; - } - - if (lsect->rel_section) - lsect->rel_section->_raw_size += sizeof (Elf_External_Rela); - } - - else /* Allocation of a pointer to a local symbol */ - { - elf_linker_section_pointers_t **ptr = elf_local_ptr_offsets (abfd); - - /* Allocate a table to hold the local symbols if first time */ - if (!ptr) - { - int num_symbols = elf_tdata (abfd)->symtab_hdr.sh_info; - register unsigned int i; - - ptr = (elf_linker_section_pointers_t **) - bfd_alloc (abfd, num_symbols * sizeof (elf_linker_section_pointers_t *)); - - if (!ptr) - return false; - - elf_local_ptr_offsets (abfd) = ptr; - for (i = 0; i < num_symbols; i++) - ptr[i] = (elf_linker_section_pointers_t *)0; - } - - /* Has this symbol already been allocated, if so, our work is done */ - if (_bfd_elf_find_pointer_linker_section (ptr[r_symndx], - rel->r_addend, - lsect->which)) - return true; - - ptr_linker_section_ptr = &ptr[r_symndx]; - - if (info->shared) - { - /* If we are generating a shared object, we need to - output a R_<xxx>_RELATIVE reloc so that the - dynamic linker can adjust this GOT entry. */ - BFD_ASSERT (lsect->rel_section != NULL); - lsect->rel_section->_raw_size += sizeof (Elf_External_Rela); - } - } - - /* Allocate space for a pointer in the linker section, and allocate a new pointer record - from internal memory. */ - BFD_ASSERT (ptr_linker_section_ptr != NULL); - linker_section_ptr = (elf_linker_section_pointers_t *) - bfd_alloc (abfd, sizeof (elf_linker_section_pointers_t)); - - if (!linker_section_ptr) - return false; - - linker_section_ptr->next = *ptr_linker_section_ptr; - linker_section_ptr->addend = rel->r_addend; - linker_section_ptr->which = lsect->which; - linker_section_ptr->written_address_p = false; - *ptr_linker_section_ptr = linker_section_ptr; - - if (lsect->hole_size && lsect->hole_offset < lsect->max_hole_offset) - { - linker_section_ptr->offset = lsect->section->_raw_size - lsect->hole_size; - lsect->hole_offset += ARCH_SIZE / 8; - lsect->sym_offset += ARCH_SIZE / 8; - if (lsect->sym_hash) /* Bump up symbol value if needed */ - lsect->sym_hash->root.u.def.value += ARCH_SIZE / 8; - } - else - linker_section_ptr->offset = lsect->section->_raw_size; - - lsect->section->_raw_size += ARCH_SIZE / 8; - -#ifdef DEBUG - fprintf (stderr, "Create pointer in linker section %s, offset = %ld, section size = %ld\n", - lsect->name, (long)linker_section_ptr->offset, (long)lsect->section->_raw_size); -#endif - - return true; -} - - -#if ARCH_SIZE==64 -#define bfd_put_ptr(BFD,VAL,ADDR) bfd_put_64 (BFD, VAL, ADDR) -#endif -#if ARCH_SIZE==32 -#define bfd_put_ptr(BFD,VAL,ADDR) bfd_put_32 (BFD, VAL, ADDR) -#endif - -/* Fill in the address for a pointer generated in alinker section. */ - -bfd_vma -elf_finish_pointer_linker_section (output_bfd, input_bfd, info, lsect, h, relocation, rel, relative_reloc) - bfd *output_bfd; - bfd *input_bfd; - struct bfd_link_info *info; - elf_linker_section_t *lsect; - struct elf_link_hash_entry *h; - bfd_vma relocation; - const Elf_Internal_Rela *rel; - int relative_reloc; -{ - elf_linker_section_pointers_t *linker_section_ptr; - - BFD_ASSERT (lsect != NULL); - - if (h != NULL) /* global symbol */ - { - linker_section_ptr = _bfd_elf_find_pointer_linker_section (h->linker_section_pointer, - rel->r_addend, - lsect->which); - - BFD_ASSERT (linker_section_ptr != NULL); - - if (! elf_hash_table (info)->dynamic_sections_created - || (info->shared - && info->symbolic - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) - { - /* This is actually a static link, or it is a - -Bsymbolic link and the symbol is defined - locally. We must initialize this entry in the - global section. - - When doing a dynamic link, we create a .rela.<xxx> - relocation entry to initialize the value. This - is done in the finish_dynamic_symbol routine. */ - if (!linker_section_ptr->written_address_p) - { - linker_section_ptr->written_address_p = true; - bfd_put_ptr (output_bfd, relocation + linker_section_ptr->addend, - lsect->section->contents + linker_section_ptr->offset); - } - } - } - else /* local symbol */ - { - unsigned long r_symndx = ELF_R_SYM (rel->r_info); - BFD_ASSERT (elf_local_ptr_offsets (input_bfd) != NULL); - BFD_ASSERT (elf_local_ptr_offsets (input_bfd)[r_symndx] != NULL); - linker_section_ptr = _bfd_elf_find_pointer_linker_section (elf_local_ptr_offsets (input_bfd)[r_symndx], - rel->r_addend, - lsect->which); - - BFD_ASSERT (linker_section_ptr != NULL); - - /* Write out pointer if it hasn't been rewritten out before */ - if (!linker_section_ptr->written_address_p) - { - linker_section_ptr->written_address_p = true; - bfd_put_ptr (output_bfd, relocation + linker_section_ptr->addend, - lsect->section->contents + linker_section_ptr->offset); - - if (info->shared) - { - asection *srel = lsect->rel_section; - Elf_Internal_Rela outrel; - - /* We need to generate a relative reloc for the dynamic linker. */ - if (!srel) - lsect->rel_section = srel = bfd_get_section_by_name (elf_hash_table (info)->dynobj, - lsect->rel_name); - - BFD_ASSERT (srel != NULL); - - outrel.r_offset = (lsect->section->output_section->vma - + lsect->section->output_offset - + linker_section_ptr->offset); - outrel.r_info = ELF_R_INFO (0, relative_reloc); - outrel.r_addend = 0; - elf_swap_reloca_out (output_bfd, &outrel, - (((Elf_External_Rela *) - lsect->section->contents) - + lsect->section->reloc_count)); - ++lsect->section->reloc_count; - } - } - } - - relocation = (lsect->section->output_offset - + linker_section_ptr->offset - - lsect->hole_offset - - lsect->sym_offset); - -#ifdef DEBUG - fprintf (stderr, "Finish pointer in linker section %s, offset = %ld (0x%lx)\n", - lsect->name, (long)relocation, (long)relocation); -#endif - - /* Subtract out the addend, because it will get added back in by the normal - processing. */ - return relocation - linker_section_ptr->addend; -} diff --git a/contrib/gdb/bfd/elfxx-target.h b/contrib/gdb/bfd/elfxx-target.h deleted file mode 100644 index f2c0c32..0000000 --- a/contrib/gdb/bfd/elfxx-target.h +++ /dev/null @@ -1,450 +0,0 @@ -/* Target definitions for NN-bit ELF - Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - -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 structure contains everything that BFD knows about a target. - It includes things like its byte order, name, what routines to call - to do various operations, etc. Every BFD points to a target structure - with its "xvec" member. - - There are two such structures here: one for big-endian machines and - one for little-endian machines. */ - -#define bfd_elfNN_close_and_cleanup _bfd_generic_close_and_cleanup -#define bfd_elfNN_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#ifndef bfd_elfNN_get_section_contents -#define bfd_elfNN_get_section_contents _bfd_generic_get_section_contents -#endif - -#define bfd_elfNN_canonicalize_dynamic_symtab _bfd_elf_canonicalize_dynamic_symtab -#define bfd_elfNN_canonicalize_reloc _bfd_elf_canonicalize_reloc -#ifndef bfd_elfNN_find_nearest_line -#define bfd_elfNN_find_nearest_line _bfd_elf_find_nearest_line -#endif -#define bfd_elfNN_read_minisymbols _bfd_elf_read_minisymbols -#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 -#define bfd_elfNN_get_reloc_upper_bound _bfd_elf_get_reloc_upper_bound -#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 -#if 0 /* done in elf-bfd.h */ -#define bfd_elfNN_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol -#endif -#define bfd_elfNN_make_empty_symbol _bfd_elf_make_empty_symbol -#define bfd_elfNN_new_section_hook _bfd_elf_new_section_hook -#define bfd_elfNN_set_arch_mach _bfd_elf_set_arch_mach -#ifndef bfd_elfNN_set_section_contents -#define bfd_elfNN_set_section_contents _bfd_elf_set_section_contents -#endif -#define bfd_elfNN_sizeof_headers _bfd_elf_sizeof_headers -#define bfd_elfNN_write_object_contents _bfd_elf_write_object_contents - -#define bfd_elfNN_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -#ifndef elf_backend_want_got_plt -#define elf_backend_want_got_plt 0 -#endif -#ifndef elf_backend_plt_readonly -#define elf_backend_plt_readonly 0 -#endif -#ifndef elf_backend_want_plt_sym -#define elf_backend_want_plt_sym 0 -#endif - -#define bfd_elfNN_bfd_debug_info_start bfd_void -#define bfd_elfNN_bfd_debug_info_end bfd_void -#define bfd_elfNN_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void - -#ifndef bfd_elfNN_bfd_get_relocated_section_contents -#define bfd_elfNN_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#endif - -#define bfd_elfNN_bfd_relax_section bfd_generic_relax_section -#define bfd_elfNN_bfd_make_debug_symbol \ - ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr) - -#ifndef bfd_elfNN_bfd_copy_private_symbol_data -#define bfd_elfNN_bfd_copy_private_symbol_data \ - _bfd_elf_copy_private_symbol_data -#endif - -#ifndef bfd_elfNN_bfd_copy_private_section_data -#define bfd_elfNN_bfd_copy_private_section_data \ - _bfd_elf_copy_private_section_data -#endif -#ifndef bfd_elfNN_bfd_copy_private_bfd_data -#define bfd_elfNN_bfd_copy_private_bfd_data \ - ((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true) -#endif -#ifndef bfd_elfNN_bfd_print_private_bfd_data -#define bfd_elfNN_bfd_print_private_bfd_data \ - _bfd_elf_print_private_bfd_data -#endif -#ifndef bfd_elfNN_bfd_merge_private_bfd_data -#define bfd_elfNN_bfd_merge_private_bfd_data \ - ((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true) -#endif -#ifndef bfd_elfNN_bfd_set_private_flags -#define bfd_elfNN_bfd_set_private_flags \ - ((boolean (*) PARAMS ((bfd *, flagword))) bfd_true) -#endif -#ifndef bfd_elfNN_bfd_is_local_label -#define bfd_elfNN_bfd_is_local_label bfd_generic_is_local_label -#endif - -#ifndef bfd_elfNN_get_dynamic_reloc_upper_bound -#define bfd_elfNN_get_dynamic_reloc_upper_bound \ - _bfd_nodynamic_get_dynamic_reloc_upper_bound -#endif -#ifndef bfd_elfNN_canonicalize_dynamic_reloc -#define bfd_elfNN_canonicalize_dynamic_reloc \ - _bfd_nodynamic_canonicalize_dynamic_reloc -#endif - -#ifdef elf_backend_relocate_section -#ifndef bfd_elfNN_bfd_link_hash_table_create -#define bfd_elfNN_bfd_link_hash_table_create _bfd_elf_link_hash_table_create -#endif -#else /* ! defined (elf_backend_relocate_section) */ -/* If no backend relocate_section routine, use the generic linker. */ -#ifndef bfd_elfNN_bfd_link_hash_table_create -#define bfd_elfNN_bfd_link_hash_table_create \ - _bfd_generic_link_hash_table_create -#endif -#ifndef bfd_elfNN_bfd_link_add_symbols -#define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols -#endif -#ifndef bfd_elfNN_bfd_final_link -#define bfd_elfNN_bfd_final_link _bfd_generic_final_link -#endif -#endif /* ! defined (elf_backend_relocate_section) */ -#ifndef bfd_elfNN_bfd_link_split_section -#define bfd_elfNN_bfd_link_split_section _bfd_generic_link_split_section -#endif - -#ifndef elf_symbol_leading_char -#define elf_symbol_leading_char 0 -#endif - -#ifndef elf_info_to_howto_rel -#define elf_info_to_howto_rel 0 -#endif - -#ifndef ELF_MAXPAGESIZE -#define ELF_MAXPAGESIZE 1 -#endif - -#ifndef elf_backend_collect -#define elf_backend_collect false -#endif -#ifndef elf_backend_type_change_ok -#define elf_backend_type_change_ok false -#endif - -#ifndef elf_backend_sym_is_global -#define elf_backend_sym_is_global 0 -#endif -#ifndef elf_backend_object_p -#define elf_backend_object_p 0 -#endif -#ifndef elf_backend_symbol_processing -#define elf_backend_symbol_processing 0 -#endif -#ifndef elf_backend_symbol_table_processing -#define elf_backend_symbol_table_processing 0 -#endif -#ifndef elf_backend_section_processing -#define elf_backend_section_processing 0 -#endif -#ifndef elf_backend_section_from_shdr -#define elf_backend_section_from_shdr 0 -#endif -#ifndef elf_backend_fake_sections -#define elf_backend_fake_sections 0 -#endif -#ifndef elf_backend_section_from_bfd_section -#define elf_backend_section_from_bfd_section 0 -#endif -#ifndef elf_backend_add_symbol_hook -#define elf_backend_add_symbol_hook 0 -#endif -#ifndef elf_backend_link_output_symbol_hook -#define elf_backend_link_output_symbol_hook 0 -#endif -#ifndef elf_backend_create_dynamic_sections -#define elf_backend_create_dynamic_sections 0 -#endif -#ifndef elf_backend_check_relocs -#define elf_backend_check_relocs 0 -#endif -#ifndef elf_backend_adjust_dynamic_symbol -#define elf_backend_adjust_dynamic_symbol 0 -#endif -#ifndef elf_backend_size_dynamic_sections -#define elf_backend_size_dynamic_sections 0 -#endif -#ifndef elf_backend_relocate_section -#define elf_backend_relocate_section 0 -#endif -#ifndef elf_backend_finish_dynamic_symbol -#define elf_backend_finish_dynamic_symbol 0 -#endif -#ifndef elf_backend_finish_dynamic_sections -#define elf_backend_finish_dynamic_sections 0 -#endif -#ifndef elf_backend_begin_write_processing -#define elf_backend_begin_write_processing 0 -#endif -#ifndef elf_backend_final_write_processing -#define elf_backend_final_write_processing 0 -#endif -#ifndef elf_backend_additional_program_headers -#define elf_backend_additional_program_headers 0 -#endif -#ifndef elf_backend_modify_segment_map -#define elf_backend_modify_segment_map 0 -#endif -#ifndef elf_backend_ecoff_debug_swap -#define elf_backend_ecoff_debug_swap 0 -#endif - -#ifndef ELF_MACHINE_ALT1 -#define ELF_MACHINE_ALT1 0 -#endif - -#ifndef ELF_MACHINE_ALT2 -#define ELF_MACHINE_ALT2 0 -#endif - -extern const struct elf_size_info _bfd_elfNN_size_info; - -static CONST struct elf_backend_data elfNN_bed = -{ -#ifdef USE_REL - 0, /* use_rela_p */ -#else - 1, /* use_rela_p */ -#endif - ELF_ARCH, /* arch */ - ELF_MACHINE_CODE, /* elf_machine_code */ - ELF_MAXPAGESIZE, /* maxpagesize */ - elf_backend_collect, - elf_backend_type_change_ok, - elf_info_to_howto, - elf_info_to_howto_rel, - elf_backend_sym_is_global, - elf_backend_object_p, - elf_backend_symbol_processing, - elf_backend_symbol_table_processing, - elf_backend_section_processing, - elf_backend_section_from_shdr, - elf_backend_fake_sections, - elf_backend_section_from_bfd_section, - elf_backend_add_symbol_hook, - elf_backend_link_output_symbol_hook, - elf_backend_create_dynamic_sections, - elf_backend_check_relocs, - elf_backend_adjust_dynamic_symbol, - elf_backend_size_dynamic_sections, - elf_backend_relocate_section, - elf_backend_finish_dynamic_symbol, - elf_backend_finish_dynamic_sections, - elf_backend_begin_write_processing, - elf_backend_final_write_processing, - elf_backend_additional_program_headers, - elf_backend_modify_segment_map, - elf_backend_ecoff_debug_swap, - ELF_MACHINE_ALT1, - ELF_MACHINE_ALT2, - &_bfd_elfNN_size_info, - elf_backend_want_got_plt, - elf_backend_plt_readonly, - elf_backend_want_plt_sym -}; - -#ifdef TARGET_BIG_SYM -const bfd_target TARGET_BIG_SYM = -{ - /* name: identify kind of target */ - TARGET_BIG_NAME, - - /* flavour: general indication about file */ - bfd_target_elf_flavour, - - /* byteorder: data is big endian */ - BFD_ENDIAN_BIG, - - /* header_byteorder: header is also big endian */ - BFD_ENDIAN_BIG, - - /* object_flags: mask of all file flags */ - (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | - DYNAMIC | WP_TEXT | D_PAGED), - - /* section_flags: mask of all section flags */ - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | - SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_EXCLUDE | SEC_SORT_ENTRIES), - - /* leading_symbol_char: is the first char of a user symbol - predictable, and if so what is it */ - elf_symbol_leading_char, - - /* ar_pad_char: pad character for filenames within an archive header - FIXME: this really has nothing to do with ELF, this is a characteristic - of the archiver and/or os and should be independently tunable */ - '/', - - /* ar_max_namelen: maximum number of characters in an archive header - FIXME: this really has nothing to do with ELF, this is a characteristic - of the archiver and should be independently tunable. This value is - a WAG (wild a** guess) */ - 14, - - /* Routines to byte-swap various sized integers from the data sections */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - - /* Routines to byte-swap various sized integers from the file headers */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - - /* 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_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_false - }, - - /* bfd_write_contents: write cached information into a file being written */ - { bfd_false, - bfd_elfNN_write_object_contents, - _bfd_write_archive_contents, - bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (bfd_elfNN), - BFD_JUMP_TABLE_COPY (bfd_elfNN), - BFD_JUMP_TABLE_CORE (bfd_elfNN), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (bfd_elfNN), - BFD_JUMP_TABLE_RELOCS (bfd_elfNN), - BFD_JUMP_TABLE_WRITE (bfd_elfNN), - BFD_JUMP_TABLE_LINK (bfd_elfNN), - BFD_JUMP_TABLE_DYNAMIC (bfd_elfNN), - - /* backend_data: */ - (PTR) &elfNN_bed, -}; -#endif - -#ifdef TARGET_LITTLE_SYM -const bfd_target TARGET_LITTLE_SYM = -{ - /* name: identify kind of target */ - TARGET_LITTLE_NAME, - - /* flavour: general indication about file */ - bfd_target_elf_flavour, - - /* byteorder: data is little endian */ - BFD_ENDIAN_LITTLE, - - /* header_byteorder: header is also little endian */ - BFD_ENDIAN_LITTLE, - - /* object_flags: mask of all file flags */ - (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | - DYNAMIC | WP_TEXT | D_PAGED), - - /* section_flags: mask of all section flags */ - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | - SEC_CODE | SEC_DATA | SEC_DEBUGGING | SEC_EXCLUDE | SEC_SORT_ENTRIES), - - /* leading_symbol_char: is the first char of a user symbol - predictable, and if so what is it */ - elf_symbol_leading_char, - - /* ar_pad_char: pad character for filenames within an archive header - FIXME: this really has nothing to do with ELF, this is a characteristic - of the archiver and/or os and should be independently tunable */ - '/', - - /* ar_max_namelen: maximum number of characters in an archive header - FIXME: this really has nothing to do with ELF, this is a characteristic - of the archiver and should be independently tunable. This value is - a WAG (wild a** guess) */ - 14, - - /* Routines to byte-swap various sized integers from the data sections */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, - - /* Routines to byte-swap various sized integers from the file headers */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, - - /* 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_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_false - }, - - /* bfd_write_contents: write cached information into a file being written */ - { bfd_false, - bfd_elfNN_write_object_contents, - _bfd_write_archive_contents, - bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (bfd_elfNN), - BFD_JUMP_TABLE_COPY (bfd_elfNN), - BFD_JUMP_TABLE_CORE (bfd_elfNN), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (bfd_elfNN), - BFD_JUMP_TABLE_RELOCS (bfd_elfNN), - BFD_JUMP_TABLE_WRITE (bfd_elfNN), - BFD_JUMP_TABLE_LINK (bfd_elfNN), - BFD_JUMP_TABLE_DYNAMIC (bfd_elfNN), - - /* backend_data: */ - (PTR) &elfNN_bed, -}; -#endif diff --git a/contrib/gdb/bfd/filemode.c b/contrib/gdb/bfd/filemode.c deleted file mode 100644 index fd790b3..0000000 --- a/contrib/gdb/bfd/filemode.c +++ /dev/null @@ -1,193 +0,0 @@ -/* filemode.c -- make a string describing file modes - Copyright (C) 1985, 1990 Free Software Foundation, Inc. - -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. */ - -#include <sys/types.h> -#include <sys/stat.h> - -void mode_string (); -static char ftypelet (); -static void rwx (); -static void setst (); - -/* filemodestring - fill in string STR with an ls-style ASCII - representation of the st_mode field of file stats block STATP. - 10 characters are stored in STR; no terminating null is added. - The characters stored in STR are: - - 0 File type. 'd' for directory, 'c' for character - special, 'b' for block special, 'm' for multiplex, - 'l' for symbolic link, 's' for socket, 'p' for fifo, - '-' for any other file type - - 1 'r' if the owner may read, '-' otherwise. - - 2 'w' if the owner may write, '-' otherwise. - - 3 'x' if the owner may execute, 's' if the file is - set-user-id, '-' otherwise. - 'S' if the file is set-user-id, but the execute - bit isn't set. - - 4 'r' if group members may read, '-' otherwise. - - 5 'w' if group members may write, '-' otherwise. - - 6 'x' if group members may execute, 's' if the file is - set-group-id, '-' otherwise. - 'S' if it is set-group-id but not executable. - - 7 'r' if any user may read, '-' otherwise. - - 8 'w' if any user may write, '-' otherwise. - - 9 'x' if any user may execute, 't' if the file is "sticky" - (will be retained in swap space after execution), '-' - otherwise. - 'T' if the file is sticky but not executable. */ - -void -filemodestring (statp, str) - struct stat *statp; - char *str; -{ - mode_string (statp->st_mode, str); -} - -/* Like filemodestring, but only the relevant part of the `struct stat' - is given as an argument. */ - -void -mode_string (mode, str) - unsigned short mode; - char *str; -{ - str[0] = ftypelet (mode); - rwx ((mode & 0700) << 0, &str[1]); - rwx ((mode & 0070) << 3, &str[4]); - rwx ((mode & 0007) << 6, &str[7]); - setst (mode, str); -} - -/* Return a character indicating the type of file described by - file mode BITS: - 'd' for directories - 'b' for block special files - 'c' for character special files - 'm' for multiplexor files - 'l' for symbolic links - 's' for sockets - 'p' for fifos - '-' for any other file type. */ - -static char -ftypelet (bits) - unsigned short bits; -{ - switch (bits & S_IFMT) - { - default: - return '-'; - case S_IFDIR: - return 'd'; -#ifdef S_IFLNK - case S_IFLNK: - return 'l'; -#endif -#ifdef S_IFCHR - case S_IFCHR: - return 'c'; -#endif -#ifdef S_IFBLK - case S_IFBLK: - return 'b'; -#endif -#ifdef S_IFMPC - case S_IFMPC: - case S_IFMPB: - return 'm'; -#endif -#ifdef S_IFSOCK - case S_IFSOCK: - return 's'; -#endif -#ifdef S_IFIFO -#if S_IFIFO != S_IFSOCK - case S_IFIFO: - return 'p'; -#endif -#endif -#ifdef S_IFNWK /* HP-UX */ - case S_IFNWK: - return 'n'; -#endif - } -} - -/* Look at read, write, and execute bits in BITS and set - flags in CHARS accordingly. */ - -static void -rwx (bits, chars) - unsigned short bits; - char *chars; -{ - chars[0] = (bits & S_IREAD) ? 'r' : '-'; - chars[1] = (bits & S_IWRITE) ? 'w' : '-'; - chars[2] = (bits & S_IEXEC) ? 'x' : '-'; -} - -/* Set the 's' and 't' flags in file attributes string CHARS, - according to the file mode BITS. */ - -static void -setst (bits, chars) - unsigned short bits; - char *chars; -{ -#ifdef S_ISUID - if (bits & S_ISUID) - { - if (chars[3] != 'x') - /* Set-uid, but not executable by owner. */ - chars[3] = 'S'; - else - chars[3] = 's'; - } -#endif -#ifdef S_ISGID - if (bits & S_ISGID) - { - if (chars[6] != 'x') - /* Set-gid, but not executable by group. */ - chars[6] = 'S'; - else - chars[6] = 's'; - } -#endif -#ifdef S_ISVTX - if (bits & S_ISVTX) - { - if (chars[9] != 'x') - /* Sticky, but not executable by others. */ - chars[9] = 'T'; - else - chars[9] = 't'; - } -#endif -} - - diff --git a/contrib/gdb/bfd/gen-aout.c b/contrib/gdb/bfd/gen-aout.c deleted file mode 100644 index d2224f7..0000000 --- a/contrib/gdb/bfd/gen-aout.c +++ /dev/null @@ -1,101 +0,0 @@ -/* Generate parameters for an a.out system. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - -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. */ - -#include "/usr/include/a.out.h" -#include <stdio.h> - -int -main (argc, argv) - int argc; char** argv; -{ - struct exec my_exec; - int page_size; - char *target = "unknown", *arch = "unknown"; - FILE *file = fopen("gen-aout", "r"); - - if (file == NULL) { - fprintf(stderr, "Cannot open gen-aout!\n"); - return -1; - } - if (fread(&my_exec, sizeof(struct exec), 1, file) != 1) { - fprintf(stderr, "Cannot read gen-aout!\n"); - return -1; - } - - target = argv[1]; - if (target == NULL) { - fprintf(stderr, "Usage: gen-aout target_name\n"); - exit (1); - } - -#ifdef N_TXTOFF - page_size = N_TXTOFF(my_exec); - if (page_size == 0) - printf("#define N_HEADER_IN_TEXT(x) 1\n"); - else - printf("#define N_HEADER_IN_TEXT(x) 0\n"); -#endif - - printf("#define BYTES_IN_WORD %d\n", sizeof (int)); - if (my_exec.a_entry == 0) { - printf("#define ENTRY_CAN_BE_ZERO\n"); - printf("#define N_SHARED_LIB(x) 0 /* Avoids warning */\n"); - } - else { - printf("/*#define ENTRY_CAN_BE_ZERO*/\n"); - printf("/*#define N_SHARED_LIB(x) 0*/\n"); - } - - printf("#define TEXT_START_ADDR %d\n", my_exec.a_entry); - -#ifdef PAGSIZ - if (page_size == 0) - page_size = PAGSIZ; -#endif - if (page_size != 0) - printf("#define TARGET_PAGE_SIZE %d\n", page_size); - else - printf("/* #define TARGET_PAGE_SIZE ??? */\n"); - printf("#define SEGMENT_SIZE TARGET_PAGE_SIZE\n"); - -#ifdef vax - arch = "vax"; -#endif -#ifdef m68k - arch = "m68k"; -#endif - if (arch[0] == '1') - { - fprintf (stderr, "warning: preprocessor substituted architecture name inside string;"); - fprintf (stderr, " fix DEFAULT_ARCH in the output file yourself\n"); - arch = "unknown"; - } - printf("#define DEFAULT_ARCH bfd_arch_%s\n", arch); - - printf("\n#define MY(OP) CAT(%s_,OP)\n", target); - printf("#define TARGETNAME \"a.out-%s\"\n\n", target); - - printf("#include \"bfd.h\"\n"); - printf("#include \"sysdep.h\"\n"); - printf("#include \"libbfd.h\"\n"); - printf("#include \"libaout.h\"\n"); - printf("\n#include \"aout-target.h\"\n"); - - return 0; -} diff --git a/contrib/gdb/bfd/host-aout.c b/contrib/gdb/bfd/host-aout.c deleted file mode 100644 index 99643dc..0000000 --- a/contrib/gdb/bfd/host-aout.c +++ /dev/null @@ -1,83 +0,0 @@ -/* BFD backend for local host's a.out binaries - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Cygnus Support. Probably John Gilmore's fault. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#define ARCH_SIZE 32 - -/* When porting to a new system, you must supply: - - HOST_PAGE_SIZE (optional) - HOST_SEGMENT_SIZE (optional -- defaults to page size) - HOST_MACHINE_ARCH (optional) - HOST_MACHINE_MACHINE (optional) - HOST_TEXT_START_ADDR (optional) - HOST_STACK_END_ADDR (not used, except by trad-core ???) - HOST_BIG_ENDIAN_P (required -- define if big-endian) - - in the ./hosts/h-systemname.h file. */ - -#ifdef TRAD_HEADER -#include TRAD_HEADER -#endif - -#ifdef HOST_PAGE_SIZE -#define TARGET_PAGE_SIZE HOST_PAGE_SIZE -#endif - -#ifdef HOST_SEGMENT_SIZE -#define SEGMENT_SIZE HOST_SEGMENT_SIZE -#else -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#endif - -#ifdef HOST_TEXT_START_ADDR -#define TEXT_START_ADDR HOST_TEXT_START_ADDR -#endif - -#ifdef HOST_STACK_END_ADDR -#define STACK_END_ADDR HOST_STACK_END_ADDR -#endif - -#ifdef HOST_BIG_ENDIAN_P -#define TARGET_IS_BIG_ENDIAN_P -#else -#undef TARGET_IS_BIG_ENDIAN_P -#endif - -#include "libaout.h" /* BFD a.out internal data structures */ -#include "aout/aout64.h" - -#ifdef HOST_MACHINE_ARCH -#ifdef HOST_MACHINE_MACHINE -#define SET_ARCH_MACH(abfd, execp) \ - bfd_default_set_arch_mach(abfd, HOST_MACHINE_ARCH, HOST_MACHINE_MACHINE) -#else -#define SET_ARCH_MACH(abfd, execp) \ - bfd_default_set_arch_mach(abfd, HOST_MACHINE_ARCH, 0) -#endif -#endif /* HOST_MACHINE_ARCH */ - -#define MY(OP) CAT(host_aout_,OP) -#define TARGETNAME "a.out" - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/hp300bsd.c b/contrib/gdb/bfd/hp300bsd.c deleted file mode 100644 index 5767b18..0000000 --- a/contrib/gdb/bfd/hp300bsd.c +++ /dev/null @@ -1,38 +0,0 @@ -/* BFD back-end for HP 9000/300 (68000-based) machines running BSD Unix. - Copyright 1992 Free Software Foundation, Inc. - -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. */ - -#define TARGET_IS_BIG_ENDIAN_P -#define N_HEADER_IN_TEXT(x) 0 -#define BYTES_IN_WORD 4 -#define ENTRY_CAN_BE_ZERO -#define N_SHARED_LIB(x) 0 /* Avoids warning */ -#define TEXT_START_ADDR 0 -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define DEFAULT_ARCH bfd_arch_m68k - -#define MY(OP) CAT(hp300bsd_,OP) -#define TARGETNAME "a.out-hp300bsd" - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/hp300hpux.c b/contrib/gdb/bfd/hp300hpux.c deleted file mode 100644 index 1d1acab..0000000 --- a/contrib/gdb/bfd/hp300hpux.c +++ /dev/null @@ -1,865 +0,0 @@ -/* BFD backend for hp-ux 9000/300 - Copyright (C) 1990, 1991, 1994, 1995 Free Software Foundation, Inc. - Written by Glenn Engel. - -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. */ - -/* - - hpux native ------------> | | - | hp300hpux bfd | ----------> hpux w/gnu ext - hpux w/gnu extension ----> | | - - - Support for the 9000/[34]00 has several limitations. - 1. Shared libraries are not supported. - 2. The output format from this bfd is not usable by native tools. - - The primary motivation for writing this bfd was to allow use of - gdb and gcc for host based debugging and not to mimic the hp-ux tools - in every detail. This leads to a significant simplification of the - code and a leap in performance. The decision to not output hp native - compatible objects was further strengthened by the fact that the richness - of the gcc compiled objects could not be represented without loss of - information. For example, while the hp format supports the concept of - secondary symbols, it does not support indirect symbols. Another - reason is to maintain backwards compatibility with older implementations - of gcc on hpux which used 'hpxt' to translate .a and .o files into a - format which could be readily understood by the gnu linker and gdb. - This allows reading hp secondary symbols and converting them into - indirect symbols but the reverse it not always possible. - - Another example of differences is that the hp format stores symbol offsets - in the object code while the gnu utilities use a field in the - relocation record for this. To support the hp native format, the object - code would need to be patched with the offsets when producing .o files. - - The basic technique taken in this implementation is to #include the code - from aoutx.h and aout-target.h with appropriate #defines to override - code where a unique implementation is needed: - - { - #define a bunch of stuff - #include <aoutx.h> - - implement a bunch of functions - - #include "aout-target.h" - } - - The hp symbol table is a bit different than other a.out targets. Instead - of having an array of nlist items and an array of strings, hp's format - has them mixed together in one structure. In addition, the strings are - not null terminated. It looks something like this: - - nlist element 1 - string1 - nlist element 2 - string2 - ... - - The whole symbol table is read as one chunk and then we march thru it - and convert it to canonical form. As we march thru the table, we copy - the nlist data into the internal form and we compact the strings and null - terminate them, using storage from the already allocated symbol table: - - string1 - null - string2 - null - */ - -/* @@ Is this really so different from normal a.out that it needs to include - aoutx.h? We should go through this file sometime and see what can be made - more dependent on aout32.o and what might need to be broken off and accessed - through the backend_data field. Or, maybe we really do need such a - completely separate implementation. I don't have time to investigate this - much further right now. [raeburn:19930428.2124EST] */ -/* @@ Also, note that there wind up being two versions of some routines, with - different names, only one of which actually gets used. For example: - slurp_symbol_table - swap_std_reloc_in - slurp_reloc_table - get_symtab - get_symtab_upper_bound - canonicalize_reloc - mkobject - This should also be fixed. */ - -#define TARGETNAME "a.out-hp300hpux" -#define MY(OP) CAT(hp300hpux_,OP) - -#define external_exec hp300hpux_exec_bytes -#define external_nlist hp300hpux_nlist_bytes - -#include "aout/hp300hpux.h" - -/* define these so we can compile unused routines in aoutx.h */ -#define e_strx e_shlib -#define e_other e_length -#define e_desc e_almod - -#define AR_PAD_CHAR '/' -#define TARGET_IS_BIG_ENDIAN_P -#define DEFAULT_ARCH bfd_arch_m68k - -#define MY_get_section_contents aout_32_get_section_contents -#define MY_slurp_armap bfd_slurp_bsd_armap_f2 - -/***********************************************/ -/* provide overrides for routines in this file */ -/***********************************************/ -/* these don't use MY because that causes problems within JUMP_TABLE - (CAT winds up being expanded recursively, which ANSI C compilers - will not do). */ -#define MY_get_symtab hp300hpux_get_symtab -#define MY_get_symtab_upper_bound hp300hpux_get_symtab_upper_bound -#define MY_canonicalize_reloc hp300hpux_canonicalize_reloc -#define MY_write_object_contents hp300hpux_write_object_contents - -#define MY_read_minisymbols _bfd_generic_read_minisymbols -#define MY_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol - -#define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define MY_final_link_callback unused -#define MY_bfd_final_link _bfd_generic_final_link - -/* Until and unless we convert the slurp_reloc and slurp_symtab - routines in this file, we can not use the default aout - free_cached_info routine which assumes that the relocs and symtabs - were allocated using malloc. */ -#define MY_bfd_free_cached_info bfd_true - -#define hp300hpux_write_syms aout_32_write_syms - -#define MY_callback MY(callback) - -#define MY_exec_hdr_flags 0x2 - -#define NAME_swap_exec_header_in NAME(hp300hpux_32_,swap_exec_header_in) - -#define HP_SYMTYPE_UNDEFINED 0x00 -#define HP_SYMTYPE_ABSOLUTE 0x01 -#define HP_SYMTYPE_TEXT 0x02 -#define HP_SYMTYPE_DATA 0x03 -#define HP_SYMTYPE_BSS 0x04 -#define HP_SYMTYPE_COMMON 0x05 - -#define HP_SYMTYPE_TYPE 0x0F -#define HP_SYMTYPE_FILENAME 0x1F - -#define HP_SYMTYPE_ALIGN 0x10 -#define HP_SYMTYPE_EXTERNAL 0x20 -#define HP_SECONDARY_SYMBOL 0x40 - -/* RELOCATION DEFINITIONS */ -#define HP_RSEGMENT_TEXT 0x00 -#define HP_RSEGMENT_DATA 0x01 -#define HP_RSEGMENT_BSS 0x02 -#define HP_RSEGMENT_EXTERNAL 0x03 -#define HP_RSEGMENT_PCREL 0x04 -#define HP_RSEGMENT_RDLT 0x05 -#define HP_RSEGMENT_RPLT 0x06 -#define HP_RSEGMENT_NOOP 0x3F - -#define HP_RLENGTH_BYTE 0x00 -#define HP_RLENGTH_WORD 0x01 -#define HP_RLENGTH_LONG 0x02 -#define HP_RLENGTH_ALIGN 0x03 - -#define NAME(x,y) CAT3(hp300hpux,_32_,y) -#define ARCH_SIZE 32 - -/* aoutx.h requires definitions for BMAGIC and QMAGIC. */ -#define BMAGIC HPUX_DOT_O_MAGIC -#define QMAGIC 0314 - -#include "aoutx.h" - -/* Since the hpux symbol table has nlist elements interspersed with - strings and we need to insert som strings for secondary symbols, we - give ourselves a little extra padding up front to account for - this. Note that for each non-secondary symbol we process, we gain - 9 bytes of space for the discarded nlist element (one byte used for - null). SYM_EXTRA_BYTES is the extra space. */ -#define SYM_EXTRA_BYTES 1024 - -/* Set parameters about this a.out file that are machine-dependent. - This routine is called from some_aout_object_p just before it returns. */ -static const bfd_target * -MY (callback) (abfd) - bfd *abfd; -{ - struct internal_exec *execp = exec_hdr (abfd); - - /* Calculate the file positions of the parts of a newly read aout header */ - obj_textsec (abfd)->_raw_size = N_TXTSIZE (*execp); - - /* The virtual memory addresses of the sections */ - obj_textsec (abfd)->vma = N_TXTADDR (*execp); - obj_datasec (abfd)->vma = N_DATADDR (*execp); - obj_bsssec (abfd)->vma = N_BSSADDR (*execp); - - obj_textsec (abfd)->lma = obj_textsec (abfd)->vma; - obj_datasec (abfd)->lma = obj_datasec (abfd)->vma; - obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma; - - /* The file offsets of the sections */ - obj_textsec (abfd)->filepos = N_TXTOFF (*execp); - obj_datasec (abfd)->filepos = N_DATOFF (*execp); - - /* The file offsets of the relocation info */ - obj_textsec (abfd)->rel_filepos = N_TRELOFF (*execp); - obj_datasec (abfd)->rel_filepos = N_DRELOFF (*execp); - - /* The file offsets of the string table and symbol table. */ - obj_sym_filepos (abfd) = N_SYMOFF (*execp); - obj_str_filepos (abfd) = N_STROFF (*execp); - - /* Determine the architecture and machine type of the object file. */ -#ifdef SET_ARCH_MACH - SET_ARCH_MACH (abfd, *execp); -#else - bfd_default_set_arch_mach (abfd, DEFAULT_ARCH, 0); -#endif - - - if (obj_aout_subformat (abfd) == gnu_encap_format) - { - /* The file offsets of the relocation info */ - obj_textsec (abfd)->rel_filepos = N_GNU_TRELOFF (*execp); - obj_datasec (abfd)->rel_filepos = N_GNU_DRELOFF (*execp); - - /* The file offsets of the string table and symbol table. */ - obj_sym_filepos (abfd) = N_GNU_SYMOFF (*execp); - obj_str_filepos (abfd) = (obj_sym_filepos (abfd) + execp->a_syms); - - abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS; - bfd_get_symcount (abfd) = execp->a_syms / 12; - obj_symbol_entry_size (abfd) = 12; - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - } - - return abfd->xvec; -} - -extern boolean aout_32_write_syms PARAMS ((bfd * abfd)); - -static boolean -MY (write_object_contents) (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - bfd_size_type text_size; /* dummy vars */ - file_ptr text_end; - - memset (&exec_bytes, 0, sizeof (exec_bytes)); -#if CHOOSE_RELOC_SIZE - CHOOSE_RELOC_SIZE (abfd); -#else - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; -#endif - - if (adata (abfd).magic == undecided_magic) - NAME (aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); - execp->a_syms = 0; - - execp->a_entry = bfd_get_start_address (abfd); - - execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * - obj_reloc_entry_size (abfd)); - execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * - obj_reloc_entry_size (abfd)); - - N_SET_MACHTYPE (*execp, 0xc); - N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags); - - NAME (aout,swap_exec_header_out) (abfd, execp, &exec_bytes); - - /* update fields not covered by default swap_exec_header_out */ - - /* this is really the sym table size but we store it in drelocs */ - bfd_h_put_32 (abfd, bfd_get_symcount (abfd) * 12, exec_bytes.e_drelocs); - - if (bfd_seek (abfd, 0L, false) != 0 - || (bfd_write ((PTR) & exec_bytes, 1, EXEC_BYTES_SIZE, abfd) - != EXEC_BYTES_SIZE)) - return false; - - /* Write out the symbols, and then the relocs. We must write out - the symbols first so that we know the symbol indices. */ - - if (bfd_get_symcount (abfd) != 0) - { - /* Skip the relocs to where we want to put the symbols. */ - if (bfd_seek (abfd, (file_ptr) N_DRELOFF (*execp) + execp->a_drsize, - SEEK_SET) != 0) - return false; - } - - if (!MY (write_syms) (abfd)) - return false; - - if (bfd_get_symcount (abfd) != 0) - { - if (bfd_seek (abfd, (long) (N_TRELOFF (*execp)), false) != 0) - return false; - if (!NAME (aout,squirt_out_relocs) (abfd, obj_textsec (abfd))) - return false; - if (bfd_seek (abfd, (long) (N_DRELOFF (*execp)), false) != 0) - return false; - if (!NAME (aout,squirt_out_relocs) (abfd, obj_datasec (abfd))) - return false; - } - - return true; -} - -/* convert the hp symbol type to be the same as aout64.h usage so we */ -/* can piggyback routines in aoutx.h. */ - -static void -convert_sym_type (sym_pointer, cache_ptr, abfd) - struct external_nlist *sym_pointer; - aout_symbol_type *cache_ptr; - bfd *abfd; -{ - int name_type; - int new_type; - - name_type = (cache_ptr->type); - new_type = 0; - - if ((name_type & HP_SYMTYPE_ALIGN) != 0) - { - /* iou_error ("aligned symbol encountered: %s", name);*/ - name_type = 0; - } - - if (name_type == HP_SYMTYPE_FILENAME) - new_type = N_FN; - else - { - switch (name_type & HP_SYMTYPE_TYPE) - { - case HP_SYMTYPE_UNDEFINED: - new_type = N_UNDF; - break; - - case HP_SYMTYPE_ABSOLUTE: - new_type = N_ABS; - break; - - case HP_SYMTYPE_TEXT: - new_type = N_TEXT; - break; - - case HP_SYMTYPE_DATA: - new_type = N_DATA; - break; - - case HP_SYMTYPE_BSS: - new_type = N_BSS; - break; - - case HP_SYMTYPE_COMMON: - new_type = N_COMM; - break; - - default: - abort (); - break; - } - if (name_type & HP_SYMTYPE_EXTERNAL) - new_type |= N_EXT; - - if (name_type & HP_SECONDARY_SYMBOL) - { - switch (new_type) - { - default: - abort (); - case N_UNDF | N_EXT: - new_type = N_WEAKU; - break; - case N_ABS | N_EXT: - new_type = N_WEAKA; - break; - case N_TEXT | N_EXT: - new_type = N_WEAKT; - break; - case N_DATA | N_EXT: - new_type = N_WEAKD; - break; - case N_BSS | N_EXT: - new_type = N_WEAKB; - break; - } - } - } - cache_ptr->type = new_type; - -} - - -/* -DESCRIPTION - Swaps the information in an executable header taken from a raw - byte stream memory image, into the internal exec_header - structure. -*/ - -void -NAME (aout,swap_exec_header_in) (abfd, raw_bytes, execp) - bfd *abfd; - struct external_exec *raw_bytes; - struct internal_exec *execp; -{ - struct external_exec *bytes = (struct external_exec *) raw_bytes; - - /* The internal_exec structure has some fields that are unused in this - configuration (IE for i960), so ensure that all such uninitialized - fields are zero'd out. There are places where two of these structs - are memcmp'd, and thus the contents do matter. */ - memset (execp, 0, sizeof (struct internal_exec)); - /* Now fill in fields in the execp, from the bytes in the raw data. */ - execp->a_info = bfd_h_get_32 (abfd, bytes->e_info); - execp->a_text = GET_WORD (abfd, bytes->e_text); - execp->a_data = GET_WORD (abfd, bytes->e_data); - execp->a_bss = GET_WORD (abfd, bytes->e_bss); - execp->a_syms = GET_WORD (abfd, bytes->e_syms); - execp->a_entry = GET_WORD (abfd, bytes->e_entry); - execp->a_trsize = GET_WORD (abfd, bytes->e_trsize); - execp->a_drsize = GET_WORD (abfd, bytes->e_drsize); - - /***************************************************************/ - /* check the header to see if it was generated by a bfd output */ - /* this is detected rather bizarely by requiring a bunch of */ - /* header fields to be zero and an old unused field (now used) */ - /* to be set. */ - /***************************************************************/ - do - { - long syms; - struct aout_data_struct *rawptr; - if (bfd_h_get_32 (abfd, bytes->e_passize) != 0) - break; - if (bfd_h_get_32 (abfd, bytes->e_syms) != 0) - break; - if (bfd_h_get_32 (abfd, bytes->e_supsize) != 0) - break; - - syms = bfd_h_get_32 (abfd, bytes->e_drelocs); - if (syms == 0) - break; - - /* OK, we've passed the test as best as we can determine */ - execp->a_syms = syms; - - /* allocate storage for where we will store this result */ - rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, sizeof (*rawptr)); - - if (rawptr == NULL) - return; - abfd->tdata.aout_data = rawptr; - obj_aout_subformat (abfd) = gnu_encap_format; - } - while (0); -} - - -/* The hp symbol table is a bit different than other a.out targets. Instead - of having an array of nlist items and an array of strings, hp's format - has them mixed together in one structure. In addition, the strings are - not null terminated. It looks something like this: - - nlist element 1 - string1 - nlist element 2 - string2 - ... - - The whole symbol table is read as one chunk and then we march thru it - and convert it to canonical form. As we march thru the table, we copy - the nlist data into the internal form and we compact the strings and null - terminate them, using storage from the already allocated symbol table: - - string1 - null - string2 - null - ... -*/ - -boolean -MY (slurp_symbol_table) (abfd) - bfd *abfd; -{ - bfd_size_type symbol_bytes; - struct external_nlist *syms; - struct external_nlist *sym_pointer; - struct external_nlist *sym_end; - char *strings; - aout_symbol_type *cached; - unsigned num_syms = 0; - - /* If there's no work to be done, don't do any */ - if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL) - return true; - symbol_bytes = exec_hdr (abfd)->a_syms; - - strings = (char *) bfd_alloc (abfd, - symbol_bytes + SYM_EXTRA_BYTES); - if (!strings) - return false; - syms = (struct external_nlist *) (strings + SYM_EXTRA_BYTES); - if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0 - || bfd_read ((PTR) syms, symbol_bytes, 1, abfd) != symbol_bytes) - { - bfd_release (abfd, syms); - return false; - } - - - sym_end = (struct external_nlist *) (((char *) syms) + symbol_bytes); - - /* first, march thru the table and figure out how many symbols there are */ - for (sym_pointer = syms; sym_pointer < sym_end; sym_pointer++, num_syms++) - { - /* skip over the embedded symbol. */ - sym_pointer = (struct external_nlist *) (((char *) sym_pointer) + - sym_pointer->e_length[0]); - } - - /* now that we know the symbol count, update the bfd header */ - bfd_get_symcount (abfd) = num_syms; - - cached = ((aout_symbol_type *) - bfd_zalloc (abfd, - bfd_get_symcount (abfd) * sizeof (aout_symbol_type))); - if (cached == NULL && bfd_get_symcount (abfd) != 0) - return false; - - /* as we march thru the hp symbol table, convert it into a list of - null terminated strings to hold the symbol names. Make sure any - assignment to the strings pointer is done after we're thru using - the nlist so we don't overwrite anything important. */ - - /* OK, now walk the new symtable, cacheing symbol properties */ - { - aout_symbol_type *cache_ptr = cached; - aout_symbol_type cache_save; - /* Run through table and copy values */ - for (sym_pointer = syms, cache_ptr = cached; - sym_pointer < sym_end; sym_pointer++, cache_ptr++) - { - unsigned int length; - cache_ptr->symbol.the_bfd = abfd; - cache_ptr->symbol.value = GET_SWORD (abfd, sym_pointer->e_value); - cache_ptr->desc = bfd_get_16 (abfd, sym_pointer->e_almod); - cache_ptr->type = bfd_get_8 (abfd, sym_pointer->e_type); - cache_ptr->symbol.udata.p = NULL; - length = bfd_get_8 (abfd, sym_pointer->e_length); - cache_ptr->other = length; /* other not used, save length here */ - - cache_save = *cache_ptr; - convert_sym_type (sym_pointer, cache_ptr, abfd); - if (!translate_from_native_sym_flags (abfd, cache_ptr)) - return false; - - /********************************************************/ - /* for hpux, the 'lenght' value indicates the length of */ - /* the symbol name which follows the nlist entry. */ - /********************************************************/ - if (length) - { - /**************************************************************/ - /* the hp string is not null terminated so we create a new one*/ - /* by copying the string to overlap the just vacated nlist */ - /* structure before it in memory. */ - /**************************************************************/ - cache_ptr->symbol.name = strings; - memcpy (strings, sym_pointer + 1, length); - strings[length] = '\0'; - strings += length + 1; - } - else - cache_ptr->symbol.name = (char *) NULL; - - /* skip over the embedded symbol. */ - sym_pointer = (struct external_nlist *) (((char *) sym_pointer) + - length); - } - } - - obj_aout_symbols (abfd) = cached; - - return true; -} - - - -void -MY (swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount) - bfd *abfd; - struct hp300hpux_reloc *bytes; - arelent *cache_ptr; - asymbol **symbols; - bfd_size_type symcount; -{ - int r_index; - int r_extern = 0; - unsigned int r_length; - int r_pcrel = 0; - struct aoutdata *su = &(abfd->tdata.aout_data->a); - - cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address); - r_index = bfd_h_get_16 (abfd, bytes->r_index); - - switch (bytes->r_type[0]) - { - case HP_RSEGMENT_TEXT: - r_index = N_TEXT; - break; - case HP_RSEGMENT_DATA: - r_index = N_DATA; - break; - case HP_RSEGMENT_BSS: - r_index = N_BSS; - break; - case HP_RSEGMENT_EXTERNAL: - r_extern = 1; - break; - case HP_RSEGMENT_PCREL: - r_extern = 1; - r_pcrel = 1; - break; - case HP_RSEGMENT_RDLT: - break; - case HP_RSEGMENT_RPLT: - break; - case HP_RSEGMENT_NOOP: - break; - default: - abort (); - break; - } - - switch (bytes->r_length[0]) - { - case HP_RLENGTH_BYTE: - r_length = 0; - break; - case HP_RLENGTH_WORD: - r_length = 1; - break; - case HP_RLENGTH_LONG: - r_length = 2; - break; - default: - abort (); - break; - } - - cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel; - /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */ - - /* This macro uses the r_index value computed above */ - if (r_pcrel && r_extern) - { - /* The GNU linker assumes any offset from beginning of section */ - /* is already incorporated into the image while the HP linker */ - /* adds this in later. Add it in now... */ - MOVE_ADDRESS (-cache_ptr->address); - } - else - { - MOVE_ADDRESS (0); - } -} - -boolean -MY (slurp_reloc_table) (abfd, asect, symbols) - bfd *abfd; - sec_ptr asect; - asymbol **symbols; -{ - unsigned int count; - bfd_size_type reloc_size; - PTR relocs; - arelent *reloc_cache; - size_t each_size; - struct hp300hpux_reloc *rptr; - unsigned int counter; - arelent *cache_ptr; - - if (asect->relocation) - return true; - - if (asect->flags & SEC_CONSTRUCTOR) - return true; - - if (asect == obj_datasec (abfd)) - { - reloc_size = exec_hdr (abfd)->a_drsize; - goto doit; - } - - if (asect == obj_textsec (abfd)) - { - reloc_size = exec_hdr (abfd)->a_trsize; - goto doit; - } - - bfd_set_error (bfd_error_invalid_operation); - return false; - -doit: - if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0) - return false; - each_size = obj_reloc_entry_size (abfd); - - count = reloc_size / each_size; - - - reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t) (count * sizeof - (arelent))); - if (!reloc_cache && count != 0) - return false; - - relocs = (PTR) bfd_alloc (abfd, reloc_size); - if (!relocs && reloc_size != 0) - { - bfd_release (abfd, reloc_cache); - return false; - } - - if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) - { - bfd_release (abfd, relocs); - bfd_release (abfd, reloc_cache); - return false; - } - - rptr = (struct hp300hpux_reloc *) relocs; - counter = 0; - cache_ptr = reloc_cache; - - for (; counter < count; counter++, rptr++, cache_ptr++) - { - MY (swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols, - bfd_get_symcount (abfd)); - } - - - bfd_release (abfd, relocs); - asect->relocation = reloc_cache; - asect->reloc_count = count; - return true; -} - - -/************************************************************************/ -/* The following functions are identical to functions in aoutx.h except */ -/* they refer to MY(func) rather than NAME(aout,func) and they also */ -/* call aout_32 versions if the input file was generated by gcc */ -/************************************************************************/ - -long aout_32_get_symtab PARAMS ((bfd * abfd, asymbol ** location)); -long aout_32_get_symtab_upper_bound PARAMS ((bfd * abfd)); - -long aout_32_canonicalize_reloc PARAMS ((bfd * abfd, sec_ptr section, - arelent ** relptr, - asymbol ** symbols)); - -long -MY (get_symtab) (abfd, location) - bfd *abfd; - asymbol **location; -{ - unsigned int counter = 0; - aout_symbol_type *symbase; - - if (obj_aout_subformat (abfd) == gnu_encap_format) - return aout_32_get_symtab (abfd, location); - - if (!MY (slurp_symbol_table) (abfd)) - return -1; - - for (symbase = obj_aout_symbols (abfd); counter++ < bfd_get_symcount (abfd);) - *(location++) = (asymbol *) (symbase++); - *location++ = 0; - return bfd_get_symcount (abfd); -} - -long -MY (get_symtab_upper_bound) (abfd) - bfd *abfd; -{ - if (obj_aout_subformat (abfd) == gnu_encap_format) - return aout_32_get_symtab_upper_bound (abfd); - if (!MY (slurp_symbol_table) (abfd)) - return -1; - - return (bfd_get_symcount (abfd) + 1) * (sizeof (aout_symbol_type *)); -} - - - - -long -MY (canonicalize_reloc) (abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - arelent *tblptr = section->relocation; - unsigned int count; - if (obj_aout_subformat (abfd) == gnu_encap_format) - return aout_32_canonicalize_reloc (abfd, section, relptr, symbols); - - if (!(tblptr || MY (slurp_reloc_table) (abfd, section, symbols))) - return -1; - - if (section->flags & SEC_CONSTRUCTOR) - { - arelent_chain *chain = section->constructor_chain; - for (count = 0; count < section->reloc_count; count++) - { - *relptr++ = &chain->relent; - chain = chain->next; - } - } - else - { - tblptr = section->relocation; - - for (count = 0; count++ < section->reloc_count;) - { - *relptr++ = tblptr++; - } - } - *relptr = 0; - - return section->reloc_count; -} - - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/hppa_stubs.h b/contrib/gdb/bfd/hppa_stubs.h deleted file mode 100644 index ee893e8..0000000 --- a/contrib/gdb/bfd/hppa_stubs.h +++ /dev/null @@ -1,23 +0,0 @@ -/* HPPA linker stub instructions */ - -/* These are the instructions which the linker may insert into the - code stream when building final executables to handle out-of-range - calls and argument relocations. */ - -#define LDO_M4_R31_R31 0x37ff3ff9 /* ldo -4(%r31),%r31 */ -#define LDIL_R1 0x20200000 /* ldil XXX,%r1 */ -#define BE_SR4_R1 0xe0202000 /* be XXX(%sr4,%r1) */ -#define COPY_R31_R2 0x081f0242 /* copy %r31,%r2 */ -#define BLE_SR4_R0 0xe4002000 /* ble XXX(%sr4,%r0) */ -#define BLE_SR4_R1 0xe4202000 /* ble XXX(%sr4,%r1) */ -#define BV_N_0_R31 0xebe0c002 /* bv,n 0(%r31) */ -#define STW_R31_M8R30 0x6bdf3ff1 /* stw %r31,-8(%r30) */ -#define LDW_M8R30_R31 0x4bdf3ff1 /* ldw -8(%r30),%r31 */ -#define STW_ARG_M16R30 0x6bc03fe1 /* stw %argX,-16(%r30) */ -#define LDW_M16R30_ARG 0x4bc03fe1 /* ldw -12(%r30),%argX */ -#define STW_ARG_M12R30 0x6bc03fe9 /* stw %argX,-16(%r30) */ -#define LDW_M12R30_ARG 0x4bc03fe9 /* ldw -12(%r30),%argX */ -#define FSTW_FARG_M16R30 0x27c11200 /* fstws %fargX,-16(%r30) */ -#define FLDW_M16R30_FARG 0x27c11000 /* fldws -16(%r30),%fargX */ -#define FSTD_FARG_M16R30 0x2fc11200 /* fstds %fargX,-16(%r30) */ -#define FLDD_M16R30_FARG 0x2fc11000 /* fldds -16(%r30),%fargX */ diff --git a/contrib/gdb/bfd/hppabsd-core.c b/contrib/gdb/bfd/hppabsd-core.c deleted file mode 100644 index a76ecc5..0000000 --- a/contrib/gdb/bfd/hppabsd-core.c +++ /dev/null @@ -1,305 +0,0 @@ -/* BFD back-end for HPPA BSD core files. - Copyright 1993, 1994 Free Software Foundation, Inc. - - 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. - - Written by the Center for Software Science at the University of Utah - and by Cygnus Support. - - The core file structure for the Utah 4.3BSD and OSF1 ports on the - PA is a mix between traditional cores and hpux cores -- just - different enough that supporting this format would tend to add - gross hacks to trad-core.c or hpux-core.c. So instead we keep any - gross hacks isolated to this file. */ - - -/* This file can only be compiled on systems which use HPPA-BSD style - core files. - - I would not expect this to be of use to any other host/target, but - you never know. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#if defined (HOST_HPPABSD) - -#include "machine/vmparam.h" - -#include <stdio.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/dir.h> -#include <signal.h> -#include <machine/reg.h> -#include <sys/user.h> /* After a.out.h */ -#include <sys/file.h> -#include <errno.h> - -static asection *make_bfd_asection PARAMS ((bfd *, CONST char *, - flagword, bfd_size_type, - file_ptr, unsigned int)); -static asymbol *hppabsd_core_make_empty_symbol PARAMS ((bfd *)); -static const bfd_target *hppabsd_core_core_file_p PARAMS ((bfd *)); -static char *hppabsd_core_core_file_failing_command PARAMS ((bfd *)); -static int hppabsd_core_core_file_failing_signal PARAMS ((bfd *)); -static boolean hppabsd_core_core_file_matches_executable_p - PARAMS ((bfd *, bfd *)); -static void swap_abort PARAMS ((void)); - -/* These are stored in the bfd's tdata. */ - -struct hppabsd_core_struct - { - int sig; - char cmd[MAXCOMLEN + 1]; - asection *data_section; - asection *stack_section; - asection *reg_section; - }; - -#define core_hdr(bfd) ((bfd)->tdata.hppabsd_core_data) -#define core_signal(bfd) (core_hdr(bfd)->sig) -#define core_command(bfd) (core_hdr(bfd)->cmd) -#define core_datasec(bfd) (core_hdr(bfd)->data_section) -#define core_stacksec(bfd) (core_hdr(bfd)->stack_section) -#define core_regsec(bfd) (core_hdr(bfd)->reg_section) - -static asection * -make_bfd_asection (abfd, name, flags, _raw_size, offset, alignment_power) - bfd *abfd; - CONST char *name; - flagword flags; - bfd_size_type _raw_size; - file_ptr offset; - unsigned int alignment_power; -{ - asection *asect; - - asect = bfd_make_section (abfd, name); - if (!asect) - return NULL; - - asect->flags = flags; - asect->_raw_size = _raw_size; - asect->filepos = offset; - asect->alignment_power = alignment_power; - - return asect; -} - -static asymbol * -hppabsd_core_make_empty_symbol (abfd) - bfd *abfd; -{ - asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol)); - if (new) - new->the_bfd = abfd; - return new; -} - -static const bfd_target * -hppabsd_core_core_file_p (abfd) - bfd *abfd; -{ - int val; - struct user u; - struct hppabsd_core_struct *coredata; - int clicksz; - - /* Try to read in the u-area. We will need information from this - to know how to grok the rest of the core structures. */ - val = bfd_read ((void *) &u, 1, sizeof u, abfd); - if (val != sizeof u) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* Get the page size out of the u structure. This will be different - for PA 1.0 machines and PA 1.1 machines. Yuk! */ - clicksz = u.u_pcb.pcb_pgsz; - - /* clicksz must be a power of two >= 2k. */ - if (clicksz < 0x800 - || clicksz != (clicksz & -clicksz)) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - - /* Sanity checks. Make sure the size of the core file matches the - the size computed from information within the core itself. */ - { - FILE *stream = bfd_cache_lookup (abfd); - struct stat statbuf; - if (stream == NULL || fstat (fileno (stream), &statbuf) < 0) - { - bfd_set_error (bfd_error_system_call); - return NULL; - } - if (NBPG * (UPAGES + u.u_dsize + u.u_ssize) > statbuf.st_size) - { - bfd_set_error (bfd_error_file_truncated); - return NULL; - } - if (clicksz * (UPAGES + u.u_dsize + u.u_ssize) < statbuf.st_size) - { - /* The file is too big. Maybe it's not a core file - or we otherwise have bad values for u_dsize and u_ssize). */ - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - } - - /* OK, we believe you. You're a core file (sure, sure). */ - - coredata = (struct hppabsd_core_struct *) - bfd_zalloc (abfd, sizeof (struct hppabsd_core_struct)); - if (!coredata) - return NULL; - - /* Make the core data and available via the tdata part of the BFD. */ - abfd->tdata.hppabsd_core_data = coredata; - - /* Create the sections. */ - core_stacksec (abfd) = make_bfd_asection (abfd, ".stack", - SEC_ALLOC + SEC_HAS_CONTENTS, - clicksz * u.u_ssize, - NBPG * (USIZE + KSTAKSIZE) - + clicksz * u.u_dsize, 2); - core_stacksec (abfd)->vma = USRSTACK; - - core_datasec (abfd) = make_bfd_asection (abfd, ".data", - SEC_ALLOC + SEC_LOAD - + SEC_HAS_CONTENTS, - clicksz * u.u_dsize, - NBPG * (USIZE + KSTAKSIZE), 2); - core_datasec (abfd)->vma = UDATASEG; - - core_regsec (abfd) = make_bfd_asection (abfd, ".reg", - SEC_HAS_CONTENTS, - KSTAKSIZE * NBPG, - NBPG * USIZE, 2); - core_regsec (abfd)->vma = 0; - - strncpy (core_command (abfd), u.u_comm, MAXCOMLEN + 1); - core_signal (abfd) = u.u_code; - return abfd->xvec; -} - -static char * -hppabsd_core_core_file_failing_command (abfd) - bfd *abfd; -{ - return core_command (abfd); -} - -/* ARGSUSED */ -static int -hppabsd_core_core_file_failing_signal (abfd) - bfd *abfd; -{ - return core_signal (abfd); -} - -/* ARGSUSED */ -static boolean -hppabsd_core_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - /* There's no way to know this... */ - return true; -} - - -#define hppabsd_core_get_symtab_upper_bound \ - _bfd_nosymbols_get_symtab_upper_bound -#define hppabsd_core_get_symtab _bfd_nosymbols_get_symtab -#define hppabsd_core_print_symbol _bfd_nosymbols_print_symbol -#define hppabsd_core_get_symbol_info _bfd_nosymbols_get_symbol_info -#define hppabsd_core_bfd_is_local_label _bfd_nosymbols_bfd_is_local_label -#define hppabsd_core_get_lineno _bfd_nosymbols_get_lineno -#define hppabsd_core_find_nearest_line _bfd_nosymbols_find_nearest_line -#define hppabsd_core_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define hppabsd_core_read_minisymbols _bfd_nosymbols_read_minisymbols -#define hppabsd_core_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol - -/* If somebody calls any byte-swapping routines, shoot them. */ -static void -swap_abort () -{ - /* This way doesn't require any declaration for ANSI to fuck up. */ - abort (); -} - -#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort ) -#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort ) -#define NO_SIGNED_GET \ - ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort ) - -const bfd_target hppabsd_core_vec = - { - "hppabsd-core", - bfd_target_unknown_flavour, - BFD_ENDIAN_BIG, /* target byte order */ - BFD_ENDIAN_BIG, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* symbol prefix */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */ - - { /* bfd_check_format */ - _bfd_dummy_target, /* unknown format */ - _bfd_dummy_target, /* object file */ - _bfd_dummy_target, /* archive */ - hppabsd_core_core_file_p /* a core file */ - }, - { /* bfd_set_format */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - { /* bfd_write_contents */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (hppabsd_core), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (hppabsd_core), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (_bfd_generic), - BFD_JUMP_TABLE_LINK (_bfd_nolink), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 /* backend_data */ -}; -#endif diff --git a/contrib/gdb/bfd/hpux-core.c b/contrib/gdb/bfd/hpux-core.c deleted file mode 100644 index 675a5f8..0000000 --- a/contrib/gdb/bfd/hpux-core.c +++ /dev/null @@ -1,270 +0,0 @@ -/* BFD back-end for HP/UX core files. - Copyright 1993, 1994 Free Software Foundation, Inc. - Written by Stu Grossman, Cygnus Support. - Converted to back-end form by Ian Lance Taylor, Cygnus SUpport - -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 can only be compiled on systems which use HP/UX style - core files. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#if defined (HOST_HPPAHPUX) || defined (HOST_HP300HPUX) - -/* FIXME: sys/core.h doesn't exist for HPUX version 7. HPUX version - 5, 6, and 7 core files seem to be standard trad-core.c type core - files; can we just use trad-core.c in addition to this file? */ - -#include <sys/core.h> -#include <sys/utsname.h> - -#endif /* HOST_HPPAHPUX */ - -#ifdef HOST_HPPABSD - -/* Not a very swift place to put it, but that's where the BSD port - puts them. */ -#include "/hpux/usr/include/sys/core.h" - -#endif /* HOST_HPPABSD */ - -#include <stdio.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/dir.h> -#include <signal.h> -#include <machine/reg.h> -#include <sys/user.h> /* After a.out.h */ -#include <sys/file.h> -#include <errno.h> - -/* These are stored in the bfd's tdata */ - -struct hpux_core_struct -{ - int sig; - char cmd[MAXCOMLEN + 1]; -}; - -#define core_hdr(bfd) ((bfd)->tdata.hpux_core_data) -#define core_signal(bfd) (core_hdr(bfd)->sig) -#define core_command(bfd) (core_hdr(bfd)->cmd) - -static asection * -make_bfd_asection (abfd, name, flags, _raw_size, vma, alignment_power) - bfd *abfd; - CONST char *name; - flagword flags; - bfd_size_type _raw_size; - bfd_vma vma; - unsigned int alignment_power; -{ - asection *asect; - - asect = bfd_make_section_anyway (abfd, name); - if (!asect) - return NULL; - - asect->flags = flags; - asect->_raw_size = _raw_size; - asect->vma = vma; - asect->filepos = bfd_tell (abfd); - asect->alignment_power = alignment_power; - - return asect; -} - -static asymbol * -hpux_core_make_empty_symbol (abfd) - bfd *abfd; -{ - asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol)); - if (new) - new->the_bfd = abfd; - return new; -} - -static const bfd_target * -hpux_core_core_file_p (abfd) - bfd *abfd; -{ - core_hdr (abfd) = (struct hpux_core_struct *) - bfd_zalloc (abfd, sizeof (struct hpux_core_struct)); - if (!core_hdr (abfd)) - return NULL; - - while (1) - { - int val; - struct corehead core_header; - - val = bfd_read ((void *) &core_header, 1, sizeof core_header, abfd); - if (val <= 0) - break; - switch (core_header.type) - { - case CORE_KERNEL: - case CORE_FORMAT: - bfd_seek (abfd, core_header.len, SEEK_CUR); /* Just skip this */ - break; - case CORE_EXEC: - { - struct proc_exec proc_exec; - if (bfd_read ((void *) &proc_exec, 1, core_header.len, abfd) - != core_header.len) - break; - strncpy (core_command (abfd), proc_exec.cmd, MAXCOMLEN + 1); - } - break; - case CORE_PROC: - { - struct proc_info proc_info; - if (!make_bfd_asection (abfd, ".reg", - SEC_HAS_CONTENTS, - core_header.len, - (int) &proc_info - (int) & proc_info.hw_regs, - 2)) - return NULL; - - if (bfd_read (&proc_info, 1, core_header.len, abfd) - != core_header.len) - break; - core_signal (abfd) = proc_info.sig; - } - break; - - case CORE_DATA: - case CORE_STACK: - case CORE_TEXT: - case CORE_MMF: - case CORE_SHM: - if (!make_bfd_asection (abfd, ".data", - SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS, - core_header.len, core_header.addr, 2)) - return NULL; - - bfd_seek (abfd, core_header.len, SEEK_CUR); - break; - - default: - /* Falling into here is an error and should prevent this - target from matching. That way systems which use hpux - cores along with other formats can still work. */ - return 0; - } - } - - /* OK, we believe you. You're a core file (sure, sure). */ - - return abfd->xvec; -} - -static char * -hpux_core_core_file_failing_command (abfd) - bfd *abfd; -{ - return core_command (abfd); -} - -/* ARGSUSED */ -static int -hpux_core_core_file_failing_signal (abfd) - bfd *abfd; -{ - return core_signal (abfd); -} - -/* ARGSUSED */ -static boolean -hpux_core_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - return true; /* FIXME, We have no way of telling at this point */ -} - -#define hpux_core_get_symtab_upper_bound _bfd_nosymbols_get_symtab_upper_bound -#define hpux_core_get_symtab _bfd_nosymbols_get_symtab -#define hpux_core_print_symbol _bfd_nosymbols_print_symbol -#define hpux_core_get_symbol_info _bfd_nosymbols_get_symbol_info -#define hpux_core_bfd_is_local_label _bfd_nosymbols_bfd_is_local_label -#define hpux_core_get_lineno _bfd_nosymbols_get_lineno -#define hpux_core_find_nearest_line _bfd_nosymbols_find_nearest_line -#define hpux_core_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define hpux_core_read_minisymbols _bfd_nosymbols_read_minisymbols -#define hpux_core_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol - -/* If somebody calls any byte-swapping routines, shoot them. */ -void -swap_abort() -{ - abort(); /* This way doesn't require any declaration for ANSI to fuck up */ -} -#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort ) -#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort ) -#define NO_SIGNED_GET \ - ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort ) - -const bfd_target hpux_core_vec = - { - "hpux-core", - bfd_target_unknown_flavour, - BFD_ENDIAN_BIG, /* target byte order */ - BFD_ENDIAN_BIG, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* symbol prefix */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */ - - { /* bfd_check_format */ - _bfd_dummy_target, /* unknown format */ - _bfd_dummy_target, /* object file */ - _bfd_dummy_target, /* archive */ - hpux_core_core_file_p /* a core file */ - }, - { /* bfd_set_format */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - { /* bfd_write_contents */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (hpux_core), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (hpux_core), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (_bfd_generic), - BFD_JUMP_TABLE_LINK (_bfd_nolink), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 /* backend_data */ -}; diff --git a/contrib/gdb/bfd/i386dynix.c b/contrib/gdb/bfd/i386dynix.c deleted file mode 100644 index ff50a14..0000000 --- a/contrib/gdb/bfd/i386dynix.c +++ /dev/null @@ -1,80 +0,0 @@ -/* BFD back-end for i386 a.out binaries under dynix. - Copyright (C) 1994, 1995 Free Software Foundation, Inc. - -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 BFD is currently only tested with gdb, writing object files - may not work. */ - -#define BYTES_IN_WORD 4 - -#define TEXT_START_ADDR 4096 -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE - -#include "aout/dynix3.h" - -#define DEFAULT_ARCH bfd_arch_i386 -#define MACHTYPE_OK(mtype) ((mtype) == M_386 || (mtype) == M_UNKNOWN) - -#define MY(OP) CAT(i386dynix_,OP) -#define TARGETNAME "a.out-i386-dynix" -#define NAME(x,y) CAT3(i386dynix,_32_,y) -#define ARCH_SIZE 32 -#define NAME_swap_exec_header_in NAME(i386dynix_32_,swap_exec_header_in) -#define MY_get_section_contents aout_32_get_section_contents - -/* aoutx.h requires definitions for NMAGIC, BMAGIC and QMAGIC. */ -#define NMAGIC 0 -#define BMAGIC OMAGIC -#define QMAGIC XMAGIC - -#include "aoutx.h" - -/* (Ab)use some fields in the internal exec header to be able to read - executables that contain shared data. */ - -#define a_shdata a_tload -#define a_shdrsize a_dload - -void -i386dynix_32_swap_exec_header_in (abfd, raw_bytes, execp) - bfd *abfd; - struct external_exec *raw_bytes; - struct internal_exec *execp; -{ - struct external_exec *bytes = (struct external_exec *)raw_bytes; - - /* The internal_exec structure has some fields that are unused in this - configuration (IE for i960), so ensure that all such uninitialized - fields are zero'd out. There are places where two of these structs - are memcmp'd, and thus the contents do matter. */ - memset ((PTR) execp, 0, sizeof (struct internal_exec)); - /* Now fill in fields in the execp, from the bytes in the raw data. */ - execp->a_info = bfd_h_get_32 (abfd, bytes->e_info); - execp->a_text = GET_WORD (abfd, bytes->e_text); - execp->a_data = GET_WORD (abfd, bytes->e_data); - execp->a_bss = GET_WORD (abfd, bytes->e_bss); - execp->a_syms = GET_WORD (abfd, bytes->e_syms); - execp->a_entry = GET_WORD (abfd, bytes->e_entry); - execp->a_trsize = GET_WORD (abfd, bytes->e_trsize); - execp->a_drsize = GET_WORD (abfd, bytes->e_drsize); - execp->a_shdata = GET_WORD (abfd, bytes->e_shdata); - execp->a_shdrsize = GET_WORD (abfd, bytes->e_shdrsize); -} - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/i386linux.c b/contrib/gdb/bfd/i386linux.c deleted file mode 100644 index a45f97c..0000000 --- a/contrib/gdb/bfd/i386linux.c +++ /dev/null @@ -1,762 +0,0 @@ -/* BFD back-end for linux flavored i386 a.out binaries. - Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc. - -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. */ - -#define TARGET_PAGE_SIZE 4096 -#define ZMAGIC_DISK_BLOCK_SIZE 1024 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define TEXT_START_ADDR 0x0 -#define N_SHARED_LIB(x) 0 -#define BYTES_IN_WORD 4 - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "aout/aout64.h" -#include "aout/stab_gnu.h" -#include "aout/ar.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -#define DEFAULT_ARCH bfd_arch_i386 -#define MY(OP) CAT(i386linux_,OP) -#define TARGETNAME "a.out-i386-linux" - -extern const bfd_target MY(vec); - -/* We always generate QMAGIC files in preference to ZMAGIC files. It - would be possible to make this a linker option, if that ever - becomes important. */ - -static void MY_final_link_callback - PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *)); - -static boolean -i386linux_bfd_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - obj_aout_subformat (abfd) = q_magic_format; - return NAME(aout,final_link) (abfd, info, MY_final_link_callback); -} - -#define MY_bfd_final_link i386linux_bfd_final_link - -/* Set the machine type correctly. */ - -static boolean -i386linux_write_object_contents (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - - N_SET_MACHTYPE (*execp, M_386); - - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - - WRITE_HEADERS(abfd, execp); - - return true; -} - -#define MY_write_object_contents i386linux_write_object_contents - -/* Code to link against Linux a.out shared libraries. */ - -/* See if a symbol name is a reference to the global offset table. */ - -#ifndef GOT_REF_PREFIX -#define GOT_REF_PREFIX "__GOT_" -#endif - -#define IS_GOT_SYM(name) \ - (strncmp (name, GOT_REF_PREFIX, sizeof GOT_REF_PREFIX - 1) == 0) - -/* See if a symbol name is a reference to the procedure linkage table. */ - -#ifndef PLT_REF_PREFIX -#define PLT_REF_PREFIX "__PLT_" -#endif - -#define IS_PLT_SYM(name) \ - (strncmp (name, PLT_REF_PREFIX, sizeof PLT_REF_PREFIX - 1) == 0) - -/* This string is used to generate specialized error messages. */ - -#ifndef NEEDS_SHRLIB -#define NEEDS_SHRLIB "__NEEDS_SHRLIB_" -#endif - -/* This special symbol is a set vector that contains a list of - pointers to fixup tables. It will be present in any dynamicly - linked file. The linker generated fixup table should also be added - to the list, and it should always appear in the second slot (the - first one is a dummy with a magic number that is defined in - crt0.o). */ - -#ifndef SHARABLE_CONFLICTS -#define SHARABLE_CONFLICTS "__SHARABLE_CONFLICTS__" -#endif - -/* We keep a list of fixups. The terminology is a bit strange, but - each fixup contains two 32 bit numbers. A regular fixup contains - an address and a pointer, and at runtime we should store the - address at the location pointed to by the pointer. A builtin fixup - contains two pointers, and we should read the address using one - pointer and store it at the location pointed to by the other - pointer. Builtin fixups come into play when we have duplicate - __GOT__ symbols for the same variable. The builtin fixup will copy - the GOT pointer from one over into the other. */ - -struct fixup -{ - struct fixup *next; - struct linux_link_hash_entry *h; - bfd_vma value; - - /* Nonzero if this is a jump instruction that needs to be fixed, - zero if this is just a pointer */ - char jump; - - char builtin; -}; - -/* We don't need a special hash table entry structure, but we do need - to keep some information between linker passes, so we use a special - hash table. */ - -struct linux_link_hash_entry -{ - struct aout_link_hash_entry root; -}; - -struct linux_link_hash_table -{ - struct aout_link_hash_table root; - - /* First dynamic object found in link. */ - bfd *dynobj; - - /* Number of fixups. */ - size_t fixup_count; - - /* Number of builtin fixups. */ - size_t local_builtins; - - /* List of fixups. */ - struct fixup *fixup_list; -}; - -static struct bfd_hash_entry *linux_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static struct bfd_link_hash_table *linux_link_hash_table_create - PARAMS ((bfd *)); -static struct fixup *new_fixup - PARAMS ((struct bfd_link_info *, struct linux_link_hash_entry *, - bfd_vma, int)); -static boolean linux_link_create_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean linux_add_one_symbol - PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *, - bfd_vma, const char *, boolean, boolean, - struct bfd_link_hash_entry **)); -static boolean linux_tally_symbols - PARAMS ((struct linux_link_hash_entry *, PTR)); -static boolean linux_finish_dynamic_link - PARAMS ((bfd *, struct bfd_link_info *)); - -/* Routine to create an entry in an Linux link hash table. */ - -static struct bfd_hash_entry * -linux_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct linux_link_hash_entry *ret = (struct linux_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct linux_link_hash_entry *) NULL) - ret = ((struct linux_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct linux_link_hash_entry))); - if (ret == NULL) - return (struct bfd_hash_entry *) ret; - - /* Call the allocation method of the superclass. */ - ret = ((struct linux_link_hash_entry *) - NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret, - table, string)); - if (ret != NULL) - { - /* Set local fields; there aren't any. */ - } - - return (struct bfd_hash_entry *) ret; -} - -/* Create a Linux link hash table. */ - -static struct bfd_link_hash_table * -linux_link_hash_table_create (abfd) - bfd *abfd; -{ - struct linux_link_hash_table *ret; - - ret = ((struct linux_link_hash_table *) - bfd_alloc (abfd, sizeof (struct linux_link_hash_table))); - if (ret == (struct linux_link_hash_table *) NULL) - return (struct bfd_link_hash_table *) NULL; - if (! NAME(aout,link_hash_table_init) (&ret->root, abfd, - linux_link_hash_newfunc)) - { - free (ret); - return (struct bfd_link_hash_table *) NULL; - } - - ret->dynobj = NULL; - ret->fixup_count = 0; - ret->local_builtins = 0; - ret->fixup_list = NULL; - - return &ret->root.root; -} - -/* Look up an entry in a Linux link hash table. */ - -#define linux_link_hash_lookup(table, string, create, copy, follow) \ - ((struct linux_link_hash_entry *) \ - aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\ - (follow))) - -/* Traverse a Linux link hash table. */ - -#define linux_link_hash_traverse(table, func, info) \ - (aout_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the Linux link hash table from the info structure. This is - just a cast. */ - -#define linux_hash_table(p) ((struct linux_link_hash_table *) ((p)->hash)) - -/* Store the information for a new fixup. */ - -static struct fixup * -new_fixup (info, h, value, builtin) - struct bfd_link_info *info; - struct linux_link_hash_entry *h; - bfd_vma value; - int builtin; -{ - struct fixup *f; - - f = (struct fixup *) bfd_hash_allocate (&info->hash->table, - sizeof (struct fixup)); - if (f == NULL) - return f; - f->next = linux_hash_table (info)->fixup_list; - linux_hash_table (info)->fixup_list = f; - f->h = h; - f->value = value; - f->builtin = builtin; - f->jump = 0; - ++linux_hash_table (info)->fixup_count; - return f; -} - -/* We come here once we realize that we are going to link to a shared - library. We need to create a special section that contains the - fixup table, and we ultimately need to add a pointer to this into - the set vector for SHARABLE_CONFLICTS. At this point we do not - know the size of the section, but that's OK - we just need to - create it for now. */ - -static boolean -linux_link_create_dynamic_sections (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - flagword flags; - register asection *s; - - /* Note that we set the SEC_IN_MEMORY flag. */ - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - - /* We choose to use the name ".linux-dynamic" for the fixup table. - Why not? */ - s = bfd_make_section (abfd, ".linux-dynamic"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - s->_raw_size = 0; - s->contents = 0; - - return true; -} - -/* Function to add a single symbol to the linker hash table. This is - a wrapper around _bfd_generic_link_add_one_symbol which handles the - tweaking needed for dynamic linking support. */ - -static boolean -linux_add_one_symbol (info, abfd, name, flags, section, value, string, - copy, collect, hashp) - struct bfd_link_info *info; - bfd *abfd; - const char *name; - flagword flags; - asection *section; - bfd_vma value; - const char *string; - boolean copy; - boolean collect; - struct bfd_link_hash_entry **hashp; -{ - struct linux_link_hash_entry *h; - boolean insert; - - /* Look up and see if we already have this symbol in the hash table. - If we do, and the defining entry is from a shared library, we - need to create the dynamic sections. - - FIXME: What if abfd->xvec != info->hash->creator? We may want to - be able to link Linux a.out and ELF objects together, but serious - confusion is possible. */ - - insert = false; - - if (! info->relocateable - && linux_hash_table (info)->dynobj == NULL - && strcmp (name, SHARABLE_CONFLICTS) == 0 - && (flags & BSF_CONSTRUCTOR) != 0 - && abfd->xvec == info->hash->creator) - { - if (! linux_link_create_dynamic_sections (abfd, info)) - return false; - linux_hash_table (info)->dynobj = abfd; - insert = true; - } - - if (bfd_is_abs_section (section) - && abfd->xvec == info->hash->creator) - { - h = linux_link_hash_lookup (linux_hash_table (info), name, false, - false, false); - if (h != NULL - && (h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak)) - { - struct fixup *f; - - if (hashp != NULL) - *hashp = (struct bfd_link_hash_entry *) h; - - f = new_fixup (info, h, value, ! IS_PLT_SYM (name)); - if (f == NULL) - return false; - f->jump = IS_PLT_SYM (name); - - return true; - } - } - - /* Do the usual procedure for adding a symbol. */ - if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, - value, string, copy, collect, - hashp)) - return false; - - /* Insert a pointer to our table in the set vector. The dynamic - linker requires this information */ - if (insert) - { - asection *s; - - /* Here we do our special thing to add the pointer to the - dynamic section in the SHARABLE_CONFLICTS set vector. */ - s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, - ".linux-dynamic"); - BFD_ASSERT (s != NULL); - - if (! (_bfd_generic_link_add_one_symbol - (info, linux_hash_table (info)->dynobj, SHARABLE_CONFLICTS, - BSF_GLOBAL | BSF_CONSTRUCTOR, s, 0, NULL, false, false, NULL))) - return false; - } - - return true; -} - -/* We will crawl the hash table and come here for every global symbol. - We will examine each entry and see if there are indications that we - need to add a fixup. There are two possible cases - one is where - you have duplicate definitions of PLT or GOT symbols - these will - have already been caught and added as "builtin" fixups. If we find - that the corresponding non PLT/GOT symbol is also present, we - convert it to a regular fixup instead. - - This function is called via linux_link_hash_traverse. */ - -static boolean -linux_tally_symbols (h, data) - struct linux_link_hash_entry *h; - PTR data; -{ - struct bfd_link_info *info = (struct bfd_link_info *) data; - struct fixup *f, *f1; - int is_plt; - struct linux_link_hash_entry *h1, *h2; - boolean exists; - - if (h->root.root.type == bfd_link_hash_undefined - && strncmp (h->root.root.root.string, NEEDS_SHRLIB, - sizeof NEEDS_SHRLIB - 1) == 0) - { - const char *name; - char *p; - char *alloc = NULL; - - name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1; - p = strrchr (name, '_'); - if (p != NULL) - alloc = (char *) bfd_malloc (strlen (name) + 1); - - if (p == NULL || alloc == NULL) - (*_bfd_error_handler) ("Output file requires shared library `%s'\n", - name); - else - { - strcpy (alloc, name); - p = strrchr (alloc, '_'); - *p++ = '\0'; - (*_bfd_error_handler) - ("Output file requires shared library `%s.so.%s'\n", - alloc, p); - free (alloc); - } - - abort (); - } - - /* If this symbol is not a PLT/GOT, we do not even need to look at it */ - is_plt = IS_PLT_SYM (h->root.root.root.string); - - if (is_plt || IS_GOT_SYM (h->root.root.root.string)) - { - /* Look up this symbol twice. Once just as a regular lookup, - and then again following all of the indirect links until we - reach a real symbol. */ - h1 = linux_link_hash_lookup (linux_hash_table (info), - (h->root.root.root.string - + sizeof PLT_REF_PREFIX - 1), - false, false, true); - /* h2 does not follow indirect symbols. */ - h2 = linux_link_hash_lookup (linux_hash_table (info), - (h->root.root.root.string - + sizeof PLT_REF_PREFIX - 1), - false, false, false); - - /* The real symbol must exist but if it is also an ABS symbol, - there is no need to have a fixup. This is because they both - came from the same library. If on the other hand, we had to - use an indirect symbol to get to the real symbol, we add the - fixup anyway, since there are cases where these symbols come - from different shared libraries */ - if (h1 != NULL - && (((h1->root.root.type == bfd_link_hash_defined - || h1->root.root.type == bfd_link_hash_defweak) - && ! bfd_is_abs_section (h1->root.root.u.def.section)) - || h2->root.root.type == bfd_link_hash_indirect)) - { - /* See if there is a "builtin" fixup already present - involving this symbol. If so, convert it to a regular - fixup. In the end, this relaxes some of the requirements - about the order of performing fixups. */ - exists = false; - for (f1 = linux_hash_table (info)->fixup_list; - f1 != NULL; - f1 = f1->next) - { - if ((f1->h != h && f1->h != h1) - || (! f1->builtin && ! f1->jump)) - continue; - if (f1->h == h1) - exists = true; - if (! exists - && bfd_is_abs_section (h->root.root.u.def.section)) - { - f = new_fixup (info, h1, f1->h->root.root.u.def.value, 0); - f->jump = is_plt; - } - f1->h = h1; - f1->jump = is_plt; - f1->builtin = 0; - exists = true; - } - if (! exists - && bfd_is_abs_section (h->root.root.u.def.section)) - { - f = new_fixup (info, h1, h->root.root.u.def.value, 0); - if (f == NULL) - { - /* FIXME: No way to return error. */ - abort (); - } - f->jump = is_plt; - } - } - - /* Quick and dirty way of stripping these symbols from the - symtab. */ - if (bfd_is_abs_section (h->root.root.u.def.section)) - h->root.written = true; - } - - return true; -} - -/* This is called to set the size of the .linux-dynamic section is. - It is called by the Linux linker emulation before_allocation - routine. We have finished reading all of the input files, and now - we just scan the hash tables to find out how many additional fixups - are required. */ - -boolean -bfd_i386linux_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - struct fixup *f; - asection *s; - - if (output_bfd->xvec != &MY(vec)) - return true; - - /* First find the fixups... */ - linux_link_hash_traverse (linux_hash_table (info), - linux_tally_symbols, - (PTR) info); - - /* If there are builtin fixups, leave room for a marker. This is - used by the dynamic linker so that it knows that all that follow - are builtin fixups instead of regular fixups. */ - for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next) - { - if (f->builtin) - { - ++linux_hash_table (info)->fixup_count; - ++linux_hash_table (info)->local_builtins; - break; - } - } - - if (linux_hash_table (info)->dynobj == NULL) - { - if (linux_hash_table (info)->fixup_count > 0) - abort (); - return true; - } - - /* Allocate memory for our fixup table. We will fill it in later. */ - s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, - ".linux-dynamic"); - if (s != NULL) - { - s->_raw_size = 8 + linux_hash_table (info)->fixup_count * 8; - s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); - if (s->contents == NULL) - return false; - memset (s->contents, 0, (size_t) s->_raw_size); - } - - return true; -} - -/* We come here once we are ready to actually write the fixup table to - the output file. Scan the fixup tables and so forth and generate - the stuff we need. */ - -static boolean -linux_finish_dynamic_link (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - asection *s, *os, *is; - bfd_byte *fixup_table; - struct linux_link_hash_entry *h; - struct fixup *f; - unsigned int new_addr; - int section_offset; - unsigned int fixups_written; - - if (linux_hash_table (info)->dynobj == NULL) - return true; - - s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, - ".linux-dynamic"); - BFD_ASSERT (s != NULL); - os = s->output_section; - fixups_written = 0; - -#ifdef LINUX_LINK_DEBUG - printf ("Fixup table file offset: %x VMA: %x\n", - os->filepos + s->output_offset, - os->vma + s->output_offset); -#endif - - fixup_table = s->contents; - bfd_put_32 (output_bfd, linux_hash_table (info)->fixup_count, fixup_table); - fixup_table += 4; - - /* Fill in fixup table. */ - for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next) - { - if (f->builtin) - continue; - - if (f->h->root.root.type != bfd_link_hash_defined - && f->h->root.root.type != bfd_link_hash_defweak) - { - (*_bfd_error_handler) - ("Symbol %s not defined for fixups\n", - f->h->root.root.root.string); - continue; - } - - is = f->h->root.root.u.def.section; - section_offset = is->output_section->vma + is->output_offset; - new_addr = f->h->root.root.u.def.value + section_offset; - -#ifdef LINUX_LINK_DEBUG - printf ("Fixup(%d) %s: %x %x\n",f->jump, f->h->root.root.string, - new_addr, f->value); -#endif - - if (f->jump) - { - /* Relative address */ - new_addr = new_addr - (f->value + 5); - bfd_put_32 (output_bfd, new_addr, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, f->value + 1, fixup_table); - fixup_table += 4; - } - else - { - bfd_put_32 (output_bfd, new_addr, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, f->value, fixup_table); - fixup_table += 4; - } - ++fixups_written; - } - - if (linux_hash_table (info)->local_builtins != 0) - { - /* Special marker so we know to switch to the other type of fixup */ - bfd_put_32 (output_bfd, 0, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, 0, fixup_table); - fixup_table += 4; - ++fixups_written; - for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next) - { - if (! f->builtin) - continue; - - if (f->h->root.root.type != bfd_link_hash_defined - && f->h->root.root.type != bfd_link_hash_defweak) - { - (*_bfd_error_handler) - ("Symbol %s not defined for fixups\n", - f->h->root.root.root.string); - continue; - } - - is = f->h->root.root.u.def.section; - section_offset = is->output_section->vma + is->output_offset; - new_addr = f->h->root.root.u.def.value + section_offset; - -#ifdef LINUX_LINK_DEBUG - printf ("Fixup(B) %s: %x %x\n", f->h->root.root.string, - new_addr, f->value); -#endif - - bfd_put_32 (output_bfd, new_addr, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, f->value, fixup_table); - fixup_table += 4; - ++fixups_written; - } - } - - if (linux_hash_table (info)->fixup_count != fixups_written) - { - (*_bfd_error_handler) ("Warning: fixup count mismatch\n"); - while (linux_hash_table (info)->fixup_count > fixups_written) - { - bfd_put_32 (output_bfd, 0, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, 0, fixup_table); - fixup_table += 4; - ++fixups_written; - } - } - - h = linux_link_hash_lookup (linux_hash_table (info), - "__BUILTIN_FIXUPS__", - false, false, false); - - if (h != NULL - && (h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak)) - { - is = h->root.root.u.def.section; - section_offset = is->output_section->vma + is->output_offset; - new_addr = h->root.root.u.def.value + section_offset; - -#ifdef LINUX_LINK_DEBUG - printf ("Builtin fixup table at %x\n", new_addr); -#endif - - bfd_put_32 (output_bfd, new_addr, fixup_table); - } - else - bfd_put_32 (output_bfd, 0, fixup_table); - - if (bfd_seek (output_bfd, os->filepos + s->output_offset, SEEK_SET) != 0) - return false; - - if (bfd_write ((PTR) s->contents, 1, s->_raw_size, output_bfd) - != s->_raw_size) - return false; - - return true; -} - -#define MY_bfd_link_hash_table_create linux_link_hash_table_create -#define MY_add_one_symbol linux_add_one_symbol -#define MY_finish_dynamic_link linux_finish_dynamic_link - -#define MY_zmagic_contiguous 1 - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/i386lynx.c b/contrib/gdb/bfd/i386lynx.c deleted file mode 100644 index 2381cff..0000000 --- a/contrib/gdb/bfd/i386lynx.c +++ /dev/null @@ -1,563 +0,0 @@ -/* BFD back-end for i386 a.out binaries under LynxOS. - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - -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. */ - -#define BYTES_IN_WORD 4 -#define N_SHARED_LIB(x) 0 - -#define TEXT_START_ADDR 0 -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define DEFAULT_ARCH bfd_arch_i386 - -#define MY(OP) CAT(i386lynx_aout_,OP) -#define TARGETNAME "a.out-i386-lynx" - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#ifndef WRITE_HEADERS -#define WRITE_HEADERS(abfd, execp) \ - { \ - bfd_size_type text_size; /* dummy vars */ \ - file_ptr text_end; \ - if (adata(abfd).magic == undecided_magic) \ - NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \ - \ - execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \ - execp->a_entry = bfd_get_start_address (abfd); \ - \ - execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * \ - obj_reloc_entry_size (abfd)); \ - execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * \ - obj_reloc_entry_size (abfd)); \ - NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \ - \ - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) return false; \ - if (bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) \ - != EXEC_BYTES_SIZE) \ - return false; \ - /* Now write out reloc info, followed by syms and strings */ \ - \ - if (bfd_get_symcount (abfd) != 0) \ - { \ - if (bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET) \ - != 0) \ - return false; \ - \ - if (! NAME(aout,write_syms)(abfd)) return false; \ - \ - if (bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET) \ - != 0) \ - return false; \ - \ - if (!NAME(lynx,squirt_out_relocs) (abfd, obj_textsec (abfd))) \ - return false; \ - if (bfd_seek (abfd, (file_ptr)(N_DRELOFF(*execp)), SEEK_SET) \ - != 0) \ - return 0; \ - \ - if (!NAME(lynx,squirt_out_relocs)(abfd, obj_datasec (abfd))) \ - return false; \ - } \ - } -#endif - -#include "libaout.h" -#include "aout/aout64.h" - -#ifdef LYNX_CORE - -char *lynx_core_file_failing_command (); -int lynx_core_file_failing_signal (); -boolean lynx_core_file_matches_executable_p (); -const bfd_target *lynx_core_file_p (); - -#define MY_core_file_failing_command lynx_core_file_failing_command -#define MY_core_file_failing_signal lynx_core_file_failing_signal -#define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p -#define MY_core_file_p lynx_core_file_p - -#endif /* LYNX_CORE */ - - -#define KEEPIT flags - -extern reloc_howto_type aout_32_ext_howto_table[]; -extern reloc_howto_type aout_32_std_howto_table[]; - -/* Standard reloc stuff */ -/* Output standard relocation information to a file in target byte order. */ - -void -NAME(lynx,swap_std_reloc_out) (abfd, g, natptr) - bfd *abfd; - arelent *g; - struct reloc_std_external *natptr; -{ - int r_index; - asymbol *sym = *(g->sym_ptr_ptr); - int r_extern; - unsigned int r_length; - int r_pcrel; - int r_baserel, r_jmptable, r_relative; - unsigned int r_addend; - asection *output_section = sym->section->output_section; - - PUT_WORD (abfd, g->address, natptr->r_address); - - r_length = g->howto->size; /* Size as a power of two */ - r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */ - /* r_baserel, r_jmptable, r_relative??? FIXME-soon */ - r_baserel = 0; - r_jmptable = 0; - r_relative = 0; - - r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; - - /* name was clobbered by aout_write_syms to be symbol index */ - - /* If this relocation is relative to a symbol then set the - r_index to the symbols index, and the r_extern bit. - - Absolute symbols can come in in two ways, either as an offset - from the abs section, or as a symbol which has an abs value. - check for that here - */ - - - if (bfd_is_com_section (output_section) - || bfd_is_abs_section (output_section) - || bfd_is_und_section (output_section)) - { - if (bfd_abs_section_ptr->symbol == sym) - { - /* Whoops, looked like an abs symbol, but is really an offset - from the abs section */ - r_index = 0; - r_extern = 0; - } - else - { - /* Fill in symbol */ - r_extern = 1; - r_index = stoi ((*(g->sym_ptr_ptr))->KEEPIT); - - } - } - else - { - /* Just an ordinary section */ - r_extern = 0; - r_index = output_section->target_index; - } - - /* now the fun stuff */ - if (bfd_header_big_endian (abfd)) - { - natptr->r_index[0] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[2] = r_index; - natptr->r_type[0] = - (r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0) - | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0) - | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0) - | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG); - } - else - { - natptr->r_index[2] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[0] = r_index; - natptr->r_type[0] = - (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0) - | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0) - | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0) - | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE); - } -} - - -/* Extended stuff */ -/* Output extended relocation information to a file in target byte order. */ - -void -NAME(lynx,swap_ext_reloc_out) (abfd, g, natptr) - bfd *abfd; - arelent *g; - register struct reloc_ext_external *natptr; -{ - int r_index; - int r_extern; - unsigned int r_type; - unsigned int r_addend; - asymbol *sym = *(g->sym_ptr_ptr); - asection *output_section = sym->section->output_section; - - PUT_WORD (abfd, g->address, natptr->r_address); - - r_type = (unsigned int) g->howto->type; - - r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; - - - /* If this relocation is relative to a symbol then set the - r_index to the symbols index, and the r_extern bit. - - Absolute symbols can come in in two ways, either as an offset - from the abs section, or as a symbol which has an abs value. - check for that here - */ - - if (bfd_is_com_section (output_section) - || bfd_is_abs_section (output_section) - || bfd_is_und_section (output_section)) - { - if (bfd_abs_section_ptr->symbol == sym) - { - /* Whoops, looked like an abs symbol, but is really an offset - from the abs section */ - r_index = 0; - r_extern = 0; - } - else - { - r_extern = 1; - r_index = stoi ((*(g->sym_ptr_ptr))->KEEPIT); - } - } - else - { - /* Just an ordinary section */ - r_extern = 0; - r_index = output_section->target_index; - } - - - /* now the fun stuff */ - if (bfd_header_big_endian (abfd)) - { - natptr->r_index[0] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[2] = r_index; - natptr->r_type[0] = - (r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0) - | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG); - } - else - { - natptr->r_index[2] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[0] = r_index; - natptr->r_type[0] = - (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0) - | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE); - } - - PUT_WORD (abfd, r_addend, natptr->r_addend); -} - -/* BFD deals internally with all things based from the section they're - in. so, something in 10 bytes into a text section with a base of - 50 would have a symbol (.text+10) and know .text vma was 50. - - Aout keeps all it's symbols based from zero, so the symbol would - contain 60. This macro subs the base of each section from the value - to give the true offset from the section */ - - -#define MOVE_ADDRESS(ad) \ - if (r_extern) { \ - /* undefined symbol */ \ - cache_ptr->sym_ptr_ptr = symbols + r_index; \ - cache_ptr->addend = ad; \ - } else { \ - /* defined, section relative. replace symbol with pointer to \ - symbol which points to section */ \ - switch (r_index) { \ - case N_TEXT: \ - case N_TEXT | N_EXT: \ - cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \ - cache_ptr->addend = ad - su->textsec->vma; \ - break; \ - case N_DATA: \ - case N_DATA | N_EXT: \ - cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \ - cache_ptr->addend = ad - su->datasec->vma; \ - break; \ - case N_BSS: \ - case N_BSS | N_EXT: \ - cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \ - cache_ptr->addend = ad - su->bsssec->vma; \ - break; \ - default: \ - case N_ABS: \ - case N_ABS | N_EXT: \ - cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \ - cache_ptr->addend = ad; \ - break; \ - } \ - } \ - -void -NAME(lynx,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount) - bfd *abfd; - struct reloc_ext_external *bytes; - arelent *cache_ptr; - asymbol **symbols; - bfd_size_type symcount; -{ - int r_index; - int r_extern; - unsigned int r_type; - struct aoutdata *su = &(abfd->tdata.aout_data->a); - - cache_ptr->address = (GET_SWORD (abfd, bytes->r_address)); - - r_index = bytes->r_index[1]; - r_extern = (0 != (bytes->r_index[0] & RELOC_EXT_BITS_EXTERN_BIG)); - r_type = (bytes->r_index[0] & RELOC_EXT_BITS_TYPE_BIG) - >> RELOC_EXT_BITS_TYPE_SH_BIG; - - cache_ptr->howto = aout_32_ext_howto_table + r_type; - MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend)); -} - -void -NAME(lynx,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount) - bfd *abfd; - struct reloc_std_external *bytes; - arelent *cache_ptr; - asymbol **symbols; - bfd_size_type symcount; -{ - int r_index; - int r_extern; - unsigned int r_length; - int r_pcrel; - int r_baserel, r_jmptable, r_relative; - struct aoutdata *su = &(abfd->tdata.aout_data->a); - - cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address); - - r_index = bytes->r_index[1]; - r_extern = (0 != (bytes->r_index[0] & RELOC_STD_BITS_EXTERN_BIG)); - r_pcrel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_PCREL_BIG)); - r_baserel = (0 != (bytes->r_index[0] & RELOC_STD_BITS_BASEREL_BIG)); - r_jmptable = (0 != (bytes->r_index[0] & RELOC_STD_BITS_JMPTABLE_BIG)); - r_relative = (0 != (bytes->r_index[0] & RELOC_STD_BITS_RELATIVE_BIG)); - r_length = (bytes->r_index[0] & RELOC_STD_BITS_LENGTH_BIG) - >> RELOC_STD_BITS_LENGTH_SH_BIG; - - cache_ptr->howto = aout_32_std_howto_table + r_length + 4 * r_pcrel; - /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */ - - MOVE_ADDRESS (0); -} - -/* Reloc hackery */ - -boolean -NAME(lynx,slurp_reloc_table) (abfd, asect, symbols) - bfd *abfd; - sec_ptr asect; - asymbol **symbols; -{ - unsigned int count; - bfd_size_type reloc_size; - PTR relocs; - arelent *reloc_cache; - size_t each_size; - - if (asect->relocation) - return true; - - if (asect->flags & SEC_CONSTRUCTOR) - return true; - - if (asect == obj_datasec (abfd)) - { - reloc_size = exec_hdr (abfd)->a_drsize; - goto doit; - } - - if (asect == obj_textsec (abfd)) - { - reloc_size = exec_hdr (abfd)->a_trsize; - goto doit; - } - - bfd_set_error (bfd_error_invalid_operation); - return false; - -doit: - if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0) - return false; - each_size = obj_reloc_entry_size (abfd); - - count = reloc_size / each_size; - - - reloc_cache = (arelent *) bfd_malloc (count * sizeof (arelent)); - if (!reloc_cache && count != 0) - return false; - memset (reloc_cache, 0, count * sizeof (arelent)); - - relocs = (PTR) bfd_alloc (abfd, reloc_size); - if (!relocs && reloc_size != 0) - { - free (reloc_cache); - return false; - } - - if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) - { - bfd_release (abfd, relocs); - free (reloc_cache); - return false; - } - - if (each_size == RELOC_EXT_SIZE) - { - register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs; - unsigned int counter = 0; - arelent *cache_ptr = reloc_cache; - - for (; counter < count; counter++, rptr++, cache_ptr++) - { - NAME(lynx,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols, - bfd_get_symcount (abfd)); - } - } - else - { - register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs; - unsigned int counter = 0; - arelent *cache_ptr = reloc_cache; - - for (; counter < count; counter++, rptr++, cache_ptr++) - { - NAME(lynx,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols, - bfd_get_symcount (abfd)); - } - - } - - bfd_release (abfd, relocs); - asect->relocation = reloc_cache; - asect->reloc_count = count; - return true; -} - - - -/* Write out a relocation section into an object file. */ - -boolean -NAME(lynx,squirt_out_relocs) (abfd, section) - bfd *abfd; - asection *section; -{ - arelent **generic; - unsigned char *native, *natptr; - size_t each_size; - - unsigned int count = section->reloc_count; - size_t natsize; - - if (count == 0) - return true; - - each_size = obj_reloc_entry_size (abfd); - natsize = each_size * count; - native = (unsigned char *) bfd_zalloc (abfd, natsize); - if (!native) - return false; - - generic = section->orelocation; - - if (each_size == RELOC_EXT_SIZE) - { - for (natptr = native; - count != 0; - --count, natptr += each_size, ++generic) - NAME(lynx,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *) natptr); - } - else - { - for (natptr = native; - count != 0; - --count, natptr += each_size, ++generic) - NAME(lynx,swap_std_reloc_out) (abfd, *generic, (struct reloc_std_external *) natptr); - } - - if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize) - { - bfd_release (abfd, native); - return false; - } - bfd_release (abfd, native); - - return true; -} - -/* This is stupid. This function should be a boolean predicate */ -long -NAME(lynx,canonicalize_reloc) (abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - arelent *tblptr = section->relocation; - unsigned int count; - - if (!(tblptr || NAME(lynx,slurp_reloc_table) (abfd, section, symbols))) - return -1; - - if (section->flags & SEC_CONSTRUCTOR) - { - arelent_chain *chain = section->constructor_chain; - for (count = 0; count < section->reloc_count; count++) - { - *relptr++ = &chain->relent; - chain = chain->next; - } - } - else - { - tblptr = section->relocation; - - for (count = 0; count++ < section->reloc_count;) - { - *relptr++ = tblptr++; - } - } - *relptr = 0; - - return section->reloc_count; -} - -#define MY_canonicalize_reloc NAME(lynx,canonicalize_reloc) - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/i386mach3.c b/contrib/gdb/bfd/i386mach3.c deleted file mode 100644 index 72a28f3..0000000 --- a/contrib/gdb/bfd/i386mach3.c +++ /dev/null @@ -1,65 +0,0 @@ -/* BFD back-end for i386 a.out binaries. - Copyright (C) 1990, 1991 Free Software Foundation, Inc. - -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 is for Mach 3, which uses a.out, not Mach-O. */ - -/* There is no magic number or anything which lets us distinguish this target - from i386aout or i386bsd. So this target is only useful if it is the - default target. */ - -#define TARGET_PAGE_SIZE 1 -#define SEGMENT_SIZE 0x1000 -#define TEXT_START_ADDR 0x10000 -#define ARCH 32 -#define BYTES_IN_WORD 4 -/* This macro is only relevant when N_MAGIC(x) == ZMAGIC. */ -#define N_HEADER_IN_TEXT(x) 1 - -#define N_TXTSIZE(x) ((x).a_text) - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "aout/aout64.h" -#include "aout/stab_gnu.h" -#include "aout/ar.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -#define DEFAULT_ARCH bfd_arch_i386 -#define MY(OP) CAT(i386mach3_,OP) -#define TARGETNAME "a.out-mach3" - -static boolean MY(set_sizes)(); -#define MY_backend_data &MY(backend_data) -static CONST struct aout_backend_data MY(backend_data) = { - 0, /* zmagic contiguous */ - 1, /* text incl header */ - 0, /* exec_hdr_flags */ - 0, /* text vma? */ - MY(set_sizes), - 1, /* exec header not counted */ - 0, /* add_dynamic_symbols */ - 0, /* add_one_symbol */ - 0, /* link_dynamic_object */ - 0, /* write_dynamic_symbol */ - 0, /* check_dynamic_reloc */ - 0 /* finish_dynamic_link */ -}; - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/i386msdos.c b/contrib/gdb/bfd/i386msdos.c deleted file mode 100644 index 24a456b..0000000 --- a/contrib/gdb/bfd/i386msdos.c +++ /dev/null @@ -1,243 +0,0 @@ -/* BFD back-end for MS-DOS executables. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Bryan Ford of the University of Utah. - - Contributed by the Center for Software Science at the - University of Utah (pa-gdb-bugs@cs.utah.edu). - - 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. */ - - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" - -#if 0 -struct exe_header -{ - unsigned short magic; - unsigned short bytes_in_last_page; - unsigned short npages; /* number of 512-byte "pages" including this header */ - unsigned short nrelocs; - unsigned short header_paras; /* number of 16-byte paragraphs in header */ - unsigned short reserved; - unsigned short load_switch; - unsigned short ss_ofs; - unsigned short sp; - unsigned short checksum; - unsigned short ip; - unsigned short cs_ofs; - unsigned short reloc_ofs; - unsigned short reserved2; - unsigned short something1; - unsigned short something2; - unsigned short something3; -}; -#endif - -#define EXE_MAGIC 0x5a4d -#define EXE_LOAD_HIGH 0x0000 -#define EXE_LOAD_LOW 0xffff -#define EXE_PAGE_SIZE 512 - - -static int -msdos_sizeof_headers (abfd, exec) - bfd *abfd; - boolean exec; -{ - return 0; -} - -static boolean -msdos_write_object_contents (abfd) - bfd *abfd; -{ - static char hdr[EXE_PAGE_SIZE]; - file_ptr outfile_size = sizeof(hdr); - bfd_vma high_vma = 0; - asection *sec; - - /* Find the total size of the program on disk and in memory. */ - for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next) - { - if (bfd_get_section_size_before_reloc (sec) == 0) - continue; - if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC) - { - bfd_vma sec_vma = bfd_get_section_vma (abfd, sec) - + bfd_get_section_size_before_reloc (sec); - if (sec_vma > high_vma) - high_vma = sec_vma; - } - if (bfd_get_section_flags (abfd, sec) & SEC_LOAD) - { - file_ptr sec_end = sizeof(hdr) - + bfd_get_section_vma (abfd, sec) - + bfd_get_section_size_before_reloc (sec); - if (sec_end > outfile_size) - outfile_size = sec_end; - } - } - - /* Make sure the program isn't too big. */ - if (high_vma > (bfd_vma)0xffff) - { - bfd_set_error(bfd_error_file_too_big); - return false; - } - - /* constants */ - bfd_h_put_16(abfd, EXE_MAGIC, &hdr[0]); - bfd_h_put_16(abfd, EXE_PAGE_SIZE / 16, &hdr[8]); - bfd_h_put_16(abfd, EXE_LOAD_LOW, &hdr[12]); - bfd_h_put_16(abfd, 0x3e, &hdr[24]); - bfd_h_put_16(abfd, 0x0001, &hdr[28]); /* XXX??? */ - bfd_h_put_16(abfd, 0x30fb, &hdr[30]); /* XXX??? */ - bfd_h_put_16(abfd, 0x726a, &hdr[32]); /* XXX??? */ - - /* bytes in last page (0 = full page) */ - bfd_h_put_16(abfd, outfile_size & (EXE_PAGE_SIZE - 1), &hdr[2]); - - /* number of pages */ - bfd_h_put_16(abfd, (outfile_size + EXE_PAGE_SIZE - 1) / EXE_PAGE_SIZE, - &hdr[4]); - - /* Set the initial stack pointer to the end of the bss. - The program's crt0 code must relocate it to a real stack. */ - bfd_h_put_16(abfd, high_vma, &hdr[16]); - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || bfd_write (hdr, 1, sizeof(hdr), abfd) != sizeof(hdr)) - return false; - - return true; -} - -static boolean -msdos_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - - if (count == 0) - return true; - - section->filepos = EXE_PAGE_SIZE + bfd_get_section_vma (abfd, section); - - if (bfd_get_section_flags (abfd, section) & SEC_LOAD) - { - if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0 - || bfd_write (location, 1, count, abfd) != count) - return false; - } - - return true; -} - - - -#define msdos_mkobject aout_32_mkobject -#define msdos_make_empty_symbol aout_32_make_empty_symbol -#define msdos_bfd_reloc_type_lookup aout_32_reloc_type_lookup - -#define msdos_close_and_cleanup _bfd_generic_close_and_cleanup -#define msdos_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#define msdos_new_section_hook _bfd_generic_new_section_hook -#define msdos_get_section_contents _bfd_generic_get_section_contents -#define msdos_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window -#define msdos_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define msdos_bfd_relax_section bfd_generic_relax_section -#define msdos_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define msdos_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define msdos_bfd_final_link _bfd_generic_final_link -#define msdos_bfd_link_split_section _bfd_generic_link_split_section -#define msdos_set_arch_mach _bfd_generic_set_arch_mach - -#define msdos_get_symtab_upper_bound _bfd_nosymbols_get_symtab_upper_bound -#define msdos_get_symtab _bfd_nosymbols_get_symtab -#define msdos_print_symbol _bfd_nosymbols_print_symbol -#define msdos_get_symbol_info _bfd_nosymbols_get_symbol_info -#define msdos_find_nearest_line _bfd_nosymbols_find_nearest_line -#define msdos_get_lineno _bfd_nosymbols_get_lineno -#define msdos_bfd_is_local_label _bfd_nosymbols_bfd_is_local_label -#define msdos_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define msdos_read_minisymbols _bfd_nosymbols_read_minisymbols -#define msdos_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol - -#define msdos_canonicalize_reloc _bfd_norelocs_canonicalize_reloc -#define msdos_get_reloc_upper_bound _bfd_norelocs_get_reloc_upper_bound -#define msdos_32_bfd_link_split_section _bfd_generic_link_split_section - -const bfd_target i386msdos_vec = -{ - "msdos", /* name */ - bfd_target_msdos_flavour, - BFD_ENDIAN_LITTLE, /* target byte order */ - BFD_ENDIAN_LITTLE, /* target headers byte order */ - (EXEC_P), /* object flags */ - (SEC_CODE | SEC_DATA | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD), /* section flags */ - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - - { - _bfd_dummy_target, - _bfd_dummy_target, /* bfd_check_format */ - _bfd_dummy_target, - _bfd_dummy_target, - }, - { - bfd_false, - msdos_mkobject, - _bfd_generic_mkarchive, - bfd_false, - }, - { /* bfd_write_contents */ - bfd_false, - msdos_write_object_contents, - _bfd_write_archive_contents, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (msdos), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (msdos), - BFD_JUMP_TABLE_RELOCS (msdos), - BFD_JUMP_TABLE_WRITE (msdos), - BFD_JUMP_TABLE_LINK (msdos), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; - - diff --git a/contrib/gdb/bfd/i386netbsd.c b/contrib/gdb/bfd/i386netbsd.c deleted file mode 100644 index 32feaa7..0000000 --- a/contrib/gdb/bfd/i386netbsd.c +++ /dev/null @@ -1,33 +0,0 @@ -/* BFD back-end for NetBSD/386 a.out-ish binaries. - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - -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. */ - -#define BYTES_IN_WORD 4 -#undef TARGET_IS_BIG_ENDIAN_P - -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE - -#define DEFAULT_ARCH bfd_arch_i386 -#define MACHTYPE_OK(mtype) ((mtype) == M_386_NETBSD || (mtype) == M_UNKNOWN) - -#define MY(OP) CAT(i386netbsd_,OP) -/* This needs to start with a.out so GDB knows it is an a.out variant. */ -#define TARGETNAME "a.out-i386-netbsd" - -#include "netbsd.h" diff --git a/contrib/gdb/bfd/i386os9k.c b/contrib/gdb/bfd/i386os9k.c deleted file mode 100644 index fe1a021..0000000 --- a/contrib/gdb/bfd/i386os9k.c +++ /dev/null @@ -1,370 +0,0 @@ -/* BFD back-end for os9000 i386 binaries. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "libaout.h" /* BFD a.out internal data structures */ -#include "os9k.h" - -static const bfd_target *os9k_callback PARAMS ((bfd *)); - -/* Swaps the information in an executable header taken from a raw byte - stream memory image, into the internal exec_header structure. */ -boolean -os9k_swap_exec_header_in (abfd, raw_bytes, execp) - bfd *abfd; - mh_com *raw_bytes; - struct internal_exec *execp; -{ - mh_com *bytes = (mh_com *) raw_bytes; - unsigned int dload, dmemsize, dmemstart; - - /* Now fill in fields in the execp, from the bytes in the raw data. */ - execp->a_info = bfd_h_get_16 (abfd, bytes->m_sync); - execp->a_syms = 0; - execp->a_entry = bfd_h_get_32 (abfd, bytes->m_exec); - execp->a_talign = 2; - execp->a_dalign = 2; - execp->a_balign = 2; - - dload = bfd_h_get_32 (abfd, bytes->m_idata); - execp->a_data = dload + 8; - - if (bfd_seek (abfd, (file_ptr) dload, SEEK_SET) != 0 - || (bfd_read (&dmemstart, sizeof (dmemstart), 1, abfd) - != sizeof (dmemstart)) - || (bfd_read (&dmemsize, sizeof (dmemsize), 1, abfd) - != sizeof (dmemsize))) - return false; - - execp->a_tload = 0; - execp->a_dload = bfd_h_get_32 (abfd, (unsigned char *) &dmemstart); - execp->a_text = dload - execp->a_tload; - execp->a_data = bfd_h_get_32 (abfd, (unsigned char *) &dmemsize); - execp->a_bss = bfd_h_get_32 (abfd, bytes->m_data) - execp->a_data; - - execp->a_trsize = 0; - execp->a_drsize = 0; - - return true; -} - -#if 0 -/* Swaps the information in an internal exec header structure into the - supplied buffer ready for writing to disk. */ - -PROTO (void, os9k_swap_exec_header_out, - (bfd * abfd, - struct internal_exec * execp, - struct mh_com * raw_bytes)); -void -os9k_swap_exec_header_out (abfd, execp, raw_bytes) - bfd *abfd; - struct internal_exec *execp; - mh_com *raw_bytes; -{ - mh_com *bytes = (mh_com *) raw_bytes; - - /* Now fill in fields in the raw data, from the fields in the exec struct. */ - bfd_h_put_32 (abfd, execp->a_info, bytes->e_info); - bfd_h_put_32 (abfd, execp->a_text, bytes->e_text); - bfd_h_put_32 (abfd, execp->a_data, bytes->e_data); - bfd_h_put_32 (abfd, execp->a_bss, bytes->e_bss); - bfd_h_put_32 (abfd, execp->a_syms, bytes->e_syms); - bfd_h_put_32 (abfd, execp->a_entry, bytes->e_entry); - bfd_h_put_32 (abfd, execp->a_trsize, bytes->e_trsize); - bfd_h_put_32 (abfd, execp->a_drsize, bytes->e_drsize); - bfd_h_put_32 (abfd, execp->a_tload, bytes->e_tload); - bfd_h_put_32 (abfd, execp->a_dload, bytes->e_dload); - bytes->e_talign[0] = execp->a_talign; - bytes->e_dalign[0] = execp->a_dalign; - bytes->e_balign[0] = execp->a_balign; - bytes->e_relaxable[0] = execp->a_relaxable; -} - -#endif /* 0 */ - -static const bfd_target * -os9k_object_p (abfd) - bfd *abfd; -{ - struct internal_exec anexec; - mh_com exec_bytes; - - if (bfd_read ((PTR) & exec_bytes, MHCOM_BYTES_SIZE, 1, abfd) - != MHCOM_BYTES_SIZE) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - anexec.a_info = bfd_h_get_16 (abfd, exec_bytes.m_sync); - if (N_BADMAG (anexec)) - { - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - if (! os9k_swap_exec_header_in (abfd, &exec_bytes, &anexec)) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - return aout_32_some_aout_object_p (abfd, &anexec, os9k_callback); -} - - -/* Finish up the opening of a b.out file for reading. Fill in all the - fields that are not handled by common code. */ - -static const bfd_target * -os9k_callback (abfd) - bfd *abfd; -{ - struct internal_exec *execp = exec_hdr (abfd); - unsigned long bss_start; - - /* Architecture and machine type */ - bfd_set_arch_mach (abfd, bfd_arch_i386, 0); - - /* The positions of the string table and symbol table. */ - obj_str_filepos (abfd) = 0; - obj_sym_filepos (abfd) = 0; - - /* The alignments of the sections */ - obj_textsec (abfd)->alignment_power = execp->a_talign; - obj_datasec (abfd)->alignment_power = execp->a_dalign; - obj_bsssec (abfd)->alignment_power = execp->a_balign; - - /* The starting addresses of the sections. */ - obj_textsec (abfd)->vma = execp->a_tload; - obj_datasec (abfd)->vma = execp->a_dload; - - /* And reload the sizes, since the aout module zaps them */ - obj_textsec (abfd)->_raw_size = execp->a_text; - - bss_start = execp->a_dload + execp->a_data; /* BSS = end of data section */ - obj_bsssec (abfd)->vma = align_power (bss_start, execp->a_balign); - - /* The file positions of the sections */ - obj_textsec (abfd)->filepos = execp->a_entry; - obj_datasec (abfd)->filepos = execp->a_dload; - - /* The file positions of the relocation info *** - obj_textsec (abfd)->rel_filepos = N_TROFF(*execp); - obj_datasec (abfd)->rel_filepos = N_DROFF(*execp); - */ - - adata (abfd).page_size = 1; /* Not applicable. */ - adata (abfd).segment_size = 1;/* Not applicable. */ - adata (abfd).exec_bytes_size = MHCOM_BYTES_SIZE; - - return abfd->xvec; -} - -#if 0 -struct bout_data_struct -{ - struct aoutdata a; - struct internal_exec e; -}; - -static boolean -os9k_mkobject (abfd) - bfd *abfd; -{ - struct bout_data_struct *rawptr; - - rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, sizeof (struct bout_data_struct)); - if (rawptr == NULL) - return false; - - abfd->tdata.bout_data = rawptr; - exec_hdr (abfd) = &rawptr->e; - - obj_textsec (abfd) = (asection *) NULL; - obj_datasec (abfd) = (asection *) NULL; - obj_bsssec (abfd) = (asection *) NULL; - - return true; -} - -static boolean -os9k_write_object_contents (abfd) - bfd *abfd; -{ - struct external_exec swapped_hdr; - - if (! aout_32_make_sections (abfd)) - return false; - - exec_hdr (abfd)->a_info = BMAGIC; - - exec_hdr (abfd)->a_text = obj_textsec (abfd)->_raw_size; - exec_hdr (abfd)->a_data = obj_datasec (abfd)->_raw_size; - exec_hdr (abfd)->a_bss = obj_bsssec (abfd)->_raw_size; - exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist); - exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd); - exec_hdr (abfd)->a_trsize = ((obj_textsec (abfd)->reloc_count) * - sizeof (struct relocation_info)); - exec_hdr (abfd)->a_drsize = ((obj_datasec (abfd)->reloc_count) * - sizeof (struct relocation_info)); - - exec_hdr (abfd)->a_talign = obj_textsec (abfd)->alignment_power; - exec_hdr (abfd)->a_dalign = obj_datasec (abfd)->alignment_power; - exec_hdr (abfd)->a_balign = obj_bsssec (abfd)->alignment_power; - - exec_hdr (abfd)->a_tload = obj_textsec (abfd)->vma; - exec_hdr (abfd)->a_dload = obj_datasec (abfd)->vma; - - bout_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr); - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || (bfd_write ((PTR) & swapped_hdr, 1, EXEC_BYTES_SIZE, abfd) - != EXEC_BYTES_SIZE)) - return false; - - /* Now write out reloc info, followed by syms and strings */ - if (bfd_get_symcount (abfd) != 0) - { - if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*exec_hdr (abfd))), SEEK_SET) - != 0) - return false; - - if (!aout_32_write_syms (abfd)) - return false; - - if (bfd_seek (abfd, (file_ptr) (N_TROFF (*exec_hdr (abfd))), SEEK_SET) - != 0) - return false; - - if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd))) - return false; - if (bfd_seek (abfd, (file_ptr) (N_DROFF (*exec_hdr (abfd))), SEEK_SET) - != 0) - return false; - - if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd))) - return false; - } - return true; -} - -static boolean -os9k_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - unsigned char *location; - file_ptr offset; - int count; -{ - - if (abfd->output_has_begun == false) - { /* set by bfd.c handler */ - if (! aout_32_make_sections (abfd)) - return false; - - obj_textsec (abfd)->filepos = sizeof (struct internal_exec); - obj_datasec (abfd)->filepos = obj_textsec (abfd)->filepos - + obj_textsec (abfd)->_raw_size; - - } - /* regardless, once we know what we're doing, we might as well get going */ - if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0) - return false; - - if (count != 0) - { - return (bfd_write ((PTR) location, 1, count, abfd) == count) ? true : false; - } - return true; -} -#endif /* 0 */ - -static int -os9k_sizeof_headers (ignore_abfd, ignore) - bfd *ignore_abfd; - boolean ignore; -{ - return sizeof (struct internal_exec); -} - - -/***********************************************************************/ - -#define aout_32_close_and_cleanup aout_32_bfd_free_cached_info - -#define aout_32_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol - -#define aout_32_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup - -#define aout_32_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -#define os9k_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define os9k_bfd_relax_section bfd_generic_relax_section -#define os9k_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define os9k_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define os9k_bfd_final_link _bfd_generic_final_link -#define os9k_bfd_link_split_section _bfd_generic_link_split_section - -const bfd_target i386os9k_vec = -{ - "i386os9k", /* name */ - bfd_target_os9k_flavour, - BFD_ENDIAN_LITTLE, /* data byte order is little */ - BFD_ENDIAN_LITTLE, /* hdr byte order is little */ - (HAS_RELOC | EXEC_P | WP_TEXT), /* object flags */ - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD), /* section flags */ - 0, /* symbol leading char */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - {_bfd_dummy_target, os9k_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, bfd_false, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, bfd_false, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (aout_32), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd), - BFD_JUMP_TABLE_SYMBOLS (aout_32), - BFD_JUMP_TABLE_RELOCS (aout_32), - BFD_JUMP_TABLE_WRITE (aout_32), - BFD_JUMP_TABLE_LINK (os9k), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0, -}; diff --git a/contrib/gdb/bfd/ieee.c b/contrib/gdb/bfd/ieee.c deleted file mode 100644 index 201f225..0000000 --- a/contrib/gdb/bfd/ieee.c +++ /dev/null @@ -1,3738 +0,0 @@ -/* BFD back-end for ieee-695 objects. - Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support. - -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. */ - -#define KEEPMINUSPCININST 0 - -/* IEEE 695 format is a stream of records, which we parse using a simple one- - token (which is one byte in this lexicon) lookahead recursive decent - parser. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "ieee.h" -#include "libieee.h" - -static boolean ieee_write_byte PARAMS ((bfd *, bfd_byte)); -static boolean ieee_write_2bytes PARAMS ((bfd *, int)); -static boolean ieee_write_int PARAMS ((bfd *, bfd_vma)); -static boolean ieee_write_id PARAMS ((bfd *, const char *)); -static boolean ieee_write_expression - PARAMS ((bfd *, bfd_vma, asymbol *, boolean, unsigned int)); -static void ieee_write_int5 PARAMS ((bfd_byte *, bfd_vma)); -static boolean ieee_write_int5_out PARAMS ((bfd *, bfd_vma)); -static boolean ieee_write_section_part PARAMS ((bfd *)); -static boolean do_with_relocs PARAMS ((bfd *, asection *)); -static boolean do_as_repeat PARAMS ((bfd *, asection *)); -static boolean do_without_relocs PARAMS ((bfd *, asection *)); -static boolean ieee_write_external_part PARAMS ((bfd *)); -static boolean ieee_write_data_part PARAMS ((bfd *)); -static boolean ieee_write_debug_part PARAMS ((bfd *)); -static boolean ieee_write_me_part PARAMS ((bfd *)); -static boolean ieee_write_processor PARAMS ((bfd *)); - -static boolean ieee_slurp_debug PARAMS ((bfd *)); -static boolean ieee_slurp_section_data PARAMS ((bfd *)); - -/* Functions for writing to ieee files in the strange way that the - standard requires. */ - -static boolean -ieee_write_byte (abfd, byte) - bfd *abfd; - bfd_byte byte; -{ - if (bfd_write ((PTR) &byte, 1, 1, abfd) != 1) - return false; - return true; -} - -static boolean -ieee_write_2bytes (abfd, bytes) - bfd *abfd; - int bytes; -{ - bfd_byte buffer[2]; - - buffer[0] = bytes >> 8; - buffer[1] = bytes & 0xff; - if (bfd_write ((PTR) buffer, 1, 2, abfd) != 2) - return false; - return true; -} - -static boolean -ieee_write_int (abfd, value) - bfd *abfd; - bfd_vma value; -{ - if (value <= 127) - { - if (! ieee_write_byte (abfd, (bfd_byte) value)) - return false; - } - else - { - unsigned int length; - - /* How many significant bytes ? */ - /* FIXME FOR LONGER INTS */ - if (value & 0xff000000) - length = 4; - else if (value & 0x00ff0000) - length = 3; - else if (value & 0x0000ff00) - length = 2; - else - length = 1; - - if (! ieee_write_byte (abfd, - (bfd_byte) ((int) ieee_number_repeat_start_enum - + length))) - return false; - switch (length) - { - case 4: - if (! ieee_write_byte (abfd, (bfd_byte) (value >> 24))) - return false; - /* Fall through. */ - case 3: - if (! ieee_write_byte (abfd, (bfd_byte) (value >> 16))) - return false; - /* Fall through. */ - case 2: - if (! ieee_write_byte (abfd, (bfd_byte) (value >> 8))) - return false; - /* Fall through. */ - case 1: - if (! ieee_write_byte (abfd, (bfd_byte) (value))) - return false; - } - } - - return true; -} - -static boolean -ieee_write_id (abfd, id) - bfd *abfd; - const char *id; -{ - size_t length = strlen (id); - - if (length <= 127) - { - if (! ieee_write_byte (abfd, (bfd_byte) length)) - return false; - } - else if (length < 255) - { - if (! ieee_write_byte (abfd, ieee_extension_length_1_enum) - || ! ieee_write_byte (abfd, (bfd_byte) length)) - return false; - } - else if (length < 65535) - { - if (! ieee_write_byte (abfd, ieee_extension_length_2_enum) - || ! ieee_write_2bytes (abfd, (int) length)) - return false; - } - else - { - (*_bfd_error_handler) - ("%s: string too long (%d chars, max 65535)", - bfd_get_filename (abfd), length); - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - if (bfd_write ((PTR) id, 1, length, abfd) != length) - return false; - return true; -} - -/*************************************************************************** -Functions for reading from ieee files in the strange way that the -standard requires: -*/ - -#define this_byte(ieee) *((ieee)->input_p) -#define next_byte(ieee) ((ieee)->input_p++) -#define this_byte_and_next(ieee) (*((ieee)->input_p++)) - -static unsigned short -read_2bytes (ieee) - common_header_type *ieee; -{ - unsigned char c1 = this_byte_and_next (ieee); - unsigned char c2 = this_byte_and_next (ieee); - return (c1 << 8) | c2; -} - -static void -bfd_get_string (ieee, string, length) - common_header_type *ieee; - char *string; - size_t length; -{ - size_t i; - for (i = 0; i < length; i++) - { - string[i] = this_byte_and_next (ieee); - } -} - -static char * -read_id (ieee) - common_header_type *ieee; -{ - size_t length; - char *string; - length = this_byte_and_next (ieee); - if (length <= 0x7f) - { - /* Simple string of length 0 to 127 */ - } - else if (length == 0xde) - { - /* Length is next byte, allowing 0..255 */ - length = this_byte_and_next (ieee); - } - else if (length == 0xdf) - { - /* Length is next two bytes, allowing 0..65535 */ - length = this_byte_and_next (ieee); - length = (length * 256) + this_byte_and_next (ieee); - } - /* Buy memory and read string */ - string = bfd_alloc (ieee->abfd, length + 1); - if (!string) - return NULL; - bfd_get_string (ieee, string, length); - string[length] = 0; - return string; -} - -static boolean -ieee_write_expression (abfd, value, symbol, pcrel, index) - bfd *abfd; - bfd_vma value; - asymbol *symbol; - boolean pcrel; - unsigned int index; -{ - unsigned int term_count = 0; - - if (value != 0) - { - if (! ieee_write_int (abfd, value)) - return false; - term_count++; - } - - if (bfd_is_com_section (symbol->section) - || bfd_is_und_section (symbol->section)) - { - /* Def of a common symbol */ - if (! ieee_write_byte (abfd, ieee_variable_X_enum) - || ! ieee_write_int (abfd, symbol->value)) - return false; - term_count++; - } - else if (! bfd_is_abs_section (symbol->section)) - { - /* Ref to defined symbol - */ - - if (symbol->flags & BSF_GLOBAL) - { - if (! ieee_write_byte (abfd, ieee_variable_I_enum) - || ! ieee_write_int (abfd, symbol->value)) - return false; - term_count++; - } - else if (symbol->flags & (BSF_LOCAL | BSF_SECTION_SYM)) - { - /* This is a reference to a defined local symbol. We can - easily do a local as a section+offset. */ - if (! ieee_write_byte (abfd, ieee_variable_R_enum) - || ! ieee_write_byte (abfd, - (bfd_byte) (symbol->section->index - + IEEE_SECTION_NUMBER_BASE))) - return false; - term_count++; - if (symbol->value != 0) - { - if (! ieee_write_int (abfd, symbol->value)) - return false; - term_count++; - } - } - else - { - (*_bfd_error_handler) - ("%s: unrecognized symbol `%s' flags 0x%x", - bfd_get_filename (abfd), bfd_asymbol_name (symbol), - symbol->flags); - bfd_set_error (bfd_error_invalid_operation); - return false; - } - } - - if (pcrel) - { - /* subtract the pc from here by asking for PC of this section*/ - if (! ieee_write_byte (abfd, ieee_variable_P_enum) - || ! ieee_write_byte (abfd, - (bfd_byte) (index + IEEE_SECTION_NUMBER_BASE)) - || ! ieee_write_byte (abfd, ieee_function_minus_enum)) - return false; - } - - /* Handle the degenerate case of a 0 address. */ - if (term_count == 0) - { - if (! ieee_write_int (abfd, 0)) - return false; - } - - while (term_count > 1) - { - if (! ieee_write_byte (abfd, ieee_function_plus_enum)) - return false; - term_count--; - } - - return true; -} - -/*****************************************************************************/ - -/* -writes any integer into the buffer supplied and always takes 5 bytes -*/ -static void -ieee_write_int5 (buffer, value) - bfd_byte *buffer; - bfd_vma value; -{ - buffer[0] = (bfd_byte) ieee_number_repeat_4_enum; - buffer[1] = (value >> 24) & 0xff; - buffer[2] = (value >> 16) & 0xff; - buffer[3] = (value >> 8) & 0xff; - buffer[4] = (value >> 0) & 0xff; -} - -static boolean -ieee_write_int5_out (abfd, value) - bfd *abfd; - bfd_vma value; -{ - bfd_byte b[5]; - - ieee_write_int5 (b, value); - if (bfd_write ((PTR) b, 1, 5, abfd) != 5) - return false; - return true; -} - -static boolean -parse_int (ieee, value_ptr) - common_header_type *ieee; - bfd_vma *value_ptr; -{ - int value = this_byte (ieee); - int result; - if (value >= 0 && value <= 127) - { - *value_ptr = value; - next_byte (ieee); - return true; - } - else if (value >= 0x80 && value <= 0x88) - { - unsigned int count = value & 0xf; - result = 0; - next_byte (ieee); - while (count) - { - result = (result << 8) | this_byte_and_next (ieee); - count--; - } - *value_ptr = result; - return true; - } - return false; -} - -static int -parse_i (ieee, ok) - common_header_type *ieee; - boolean *ok; -{ - bfd_vma x; - *ok = parse_int (ieee, &x); - return x; -} - -static bfd_vma -must_parse_int (ieee) - common_header_type *ieee; -{ - bfd_vma result; - BFD_ASSERT (parse_int (ieee, &result) == true); - return result; -} - -typedef struct -{ - bfd_vma value; - asection *section; - ieee_symbol_index_type symbol; -} ieee_value_type; - - -#ifdef KEEPMINUSPCININST - -#define SRC_MASK(arg) arg -#define PCREL_OFFSET false - -#else - -#define SRC_MASK(arg) 0 -#define PCREL_OFFSET true - -#endif - -static reloc_howto_type abs32_howto = - HOWTO (1, - 0, - 2, - 32, - false, - 0, - complain_overflow_bitfield, - 0, - "abs32", - true, - 0xffffffff, - 0xffffffff, - false); - -static reloc_howto_type abs16_howto = - HOWTO (1, - 0, - 1, - 16, - false, - 0, - complain_overflow_bitfield, - 0, - "abs16", - true, - 0x0000ffff, - 0x0000ffff, - false); - -static reloc_howto_type abs8_howto = - HOWTO (1, - 0, - 0, - 8, - false, - 0, - complain_overflow_bitfield, - 0, - "abs8", - true, - 0x000000ff, - 0x000000ff, - false); - -static reloc_howto_type rel32_howto = - HOWTO (1, - 0, - 2, - 32, - true, - 0, - complain_overflow_signed, - 0, - "rel32", - true, - SRC_MASK (0xffffffff), - 0xffffffff, - PCREL_OFFSET); - -static reloc_howto_type rel16_howto = - HOWTO (1, - 0, - 1, - 16, - true, - 0, - complain_overflow_signed, - 0, - "rel16", - true, - SRC_MASK (0x0000ffff), - 0x0000ffff, - PCREL_OFFSET); - -static reloc_howto_type rel8_howto = - HOWTO (1, - 0, - 0, - 8, - true, - 0, - complain_overflow_signed, - 0, - "rel8", - true, - SRC_MASK (0x000000ff), - 0x000000ff, - PCREL_OFFSET); - -static ieee_symbol_index_type NOSYMBOL = {0, 0}; - -static void -parse_expression (ieee, value, symbol, pcrel, extra, section) - ieee_data_type *ieee; - bfd_vma *value; - ieee_symbol_index_type *symbol; - boolean *pcrel; - unsigned int *extra; - asection **section; - -{ -#define POS sp[1] -#define TOS sp[0] -#define NOS sp[-1] -#define INC sp++; -#define DEC sp--; - - boolean loop = true; - ieee_value_type stack[10]; - - /* The stack pointer always points to the next unused location */ -#define PUSH(x,y,z) TOS.symbol=x;TOS.section=y;TOS.value=z;INC; -#define POP(x,y,z) DEC;x=TOS.symbol;y=TOS.section;z=TOS.value; - ieee_value_type *sp = stack; - - while (loop) - { - switch (this_byte (&(ieee->h))) - { - case ieee_variable_P_enum: - /* P variable, current program counter for section n */ - { - int section_n; - next_byte (&(ieee->h)); - *pcrel = true; - section_n = must_parse_int (&(ieee->h)); - PUSH (NOSYMBOL, bfd_abs_section_ptr, 0); - break; - } - case ieee_variable_L_enum: - /* L variable address of section N */ - next_byte (&(ieee->h)); - PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0); - break; - case ieee_variable_R_enum: - /* R variable, logical address of section module */ - /* FIXME, this should be different to L */ - next_byte (&(ieee->h)); - PUSH (NOSYMBOL, ieee->section_table[must_parse_int (&(ieee->h))], 0); - break; - case ieee_variable_S_enum: - /* S variable, size in MAUS of section module */ - next_byte (&(ieee->h)); - PUSH (NOSYMBOL, - 0, - ieee->section_table[must_parse_int (&(ieee->h))]->_raw_size); - break; - case ieee_variable_I_enum: - /* Push the address of variable n */ - { - ieee_symbol_index_type sy; - next_byte (&(ieee->h)); - sy.index = (int) must_parse_int (&(ieee->h)); - sy.letter = 'I'; - - PUSH (sy, bfd_abs_section_ptr, 0); - } - break; - case ieee_variable_X_enum: - /* Push the address of external variable n */ - { - ieee_symbol_index_type sy; - next_byte (&(ieee->h)); - sy.index = (int) (must_parse_int (&(ieee->h))); - sy.letter = 'X'; - - PUSH (sy, bfd_und_section_ptr, 0); - } - break; - case ieee_function_minus_enum: - { - bfd_vma value1, value2; - asection *section1, *section_dummy; - ieee_symbol_index_type sy; - next_byte (&(ieee->h)); - - POP (sy, section1, value1); - POP (sy, section_dummy, value2); - PUSH (sy, section1 ? section1 : section_dummy, value2 - value1); - } - break; - case ieee_function_plus_enum: - { - bfd_vma value1, value2; - asection *section1; - asection *section2; - ieee_symbol_index_type sy1; - ieee_symbol_index_type sy2; - next_byte (&(ieee->h)); - - POP (sy1, section1, value1); - POP (sy2, section2, value2); - PUSH (sy1.letter ? sy1 : sy2, - bfd_is_abs_section (section1) ? section2 : section1, - value1 + value2); - } - break; - default: - { - bfd_vma va; - BFD_ASSERT (this_byte (&(ieee->h)) < (int) ieee_variable_A_enum - || this_byte (&(ieee->h)) > (int) ieee_variable_Z_enum); - if (parse_int (&(ieee->h), &va)) - { - PUSH (NOSYMBOL, bfd_abs_section_ptr, va); - } - else - { - /* - Thats all that we can understand. As far as I can see - there is a bug in the Microtec IEEE output which I'm - using to scan, whereby the comma operator is omitted - sometimes in an expression, giving expressions with too - many terms. We can tell if that's the case by ensuring - that sp == stack here. If not, then we've pushed - something too far, so we keep adding. */ - - while (sp != stack + 1) - { - asection *section1; - ieee_symbol_index_type sy1; - POP (sy1, section1, *extra); - } - { - asection *dummy; - - POP (*symbol, dummy, *value); - if (section) - *section = dummy; - } - - loop = false; - } - } - } - } -} - - -#define ieee_seek(abfd, offset) \ - IEEE_DATA(abfd)->h.input_p = IEEE_DATA(abfd)->h.first_byte + offset - -#define ieee_pos(abfd) \ - (IEEE_DATA(abfd)->h.input_p - IEEE_DATA(abfd)->h.first_byte) - -static unsigned int last_index; -static char last_type; /* is the index for an X or a D */ - -static ieee_symbol_type * -get_symbol (abfd, - ieee, - last_symbol, - symbol_count, - pptr, - max_index, - this_type -) - bfd *abfd; - ieee_data_type *ieee; - ieee_symbol_type *last_symbol; - unsigned int *symbol_count; - ieee_symbol_type ***pptr; - unsigned int *max_index; - char this_type - ; -{ - /* Need a new symbol */ - unsigned int new_index = must_parse_int (&(ieee->h)); - if (new_index != last_index || this_type != last_type) - { - ieee_symbol_type *new_symbol = (ieee_symbol_type *) bfd_alloc (ieee->h.abfd, - sizeof (ieee_symbol_type)); - if (!new_symbol) - return NULL; - - new_symbol->index = new_index; - last_index = new_index; - (*symbol_count)++; - **pptr = new_symbol; - *pptr = &new_symbol->next; - if (new_index > *max_index) - { - *max_index = new_index; - } - last_type = this_type; - new_symbol->symbol.section = bfd_abs_section_ptr; - return new_symbol; - } - return last_symbol; -} - -static boolean -ieee_slurp_external_symbols (abfd) - bfd *abfd; -{ - ieee_data_type *ieee = IEEE_DATA (abfd); - file_ptr offset = ieee->w.r.external_part; - - ieee_symbol_type **prev_symbols_ptr = &ieee->external_symbols; - ieee_symbol_type **prev_reference_ptr = &ieee->external_reference; - ieee_symbol_type *symbol = (ieee_symbol_type *) NULL; - unsigned int symbol_count = 0; - boolean loop = true; - last_index = 0xffffff; - ieee->symbol_table_full = true; - - ieee_seek (abfd, offset); - - while (loop) - { - switch (this_byte (&(ieee->h))) - { - case ieee_nn_record: - next_byte (&(ieee->h)); - - symbol = get_symbol (abfd, ieee, symbol, &symbol_count, - &prev_symbols_ptr, - &ieee->external_symbol_max_index, 'I'); - if (symbol == NULL) - return false; - - symbol->symbol.the_bfd = abfd; - symbol->symbol.name = read_id (&(ieee->h)); - symbol->symbol.udata.p = (PTR) NULL; - symbol->symbol.flags = BSF_NO_FLAGS; - break; - case ieee_external_symbol_enum: - next_byte (&(ieee->h)); - - symbol = get_symbol (abfd, ieee, symbol, &symbol_count, - &prev_symbols_ptr, - &ieee->external_symbol_max_index, 'D'); - if (symbol == NULL) - return false; - - BFD_ASSERT (symbol->index >= ieee->external_symbol_min_index); - - symbol->symbol.the_bfd = abfd; - symbol->symbol.name = read_id (&(ieee->h)); - symbol->symbol.udata.p = (PTR) NULL; - symbol->symbol.flags = BSF_NO_FLAGS; - break; - case ieee_attribute_record_enum >> 8: - { - unsigned int symbol_name_index; - unsigned int symbol_type_index; - unsigned int symbol_attribute_def; - bfd_vma value; - switch (read_2bytes (ieee)) - { - case ieee_attribute_record_enum: - symbol_name_index = must_parse_int (&(ieee->h)); - symbol_type_index = must_parse_int (&(ieee->h)); - symbol_attribute_def = must_parse_int (&(ieee->h)); - switch (symbol_attribute_def) - { - case 8: - case 19: - parse_int (&ieee->h, &value); - break; - default: - (*_bfd_error_handler) - ("%s: unimplemented ATI record %u for symbol %u", - bfd_get_filename (abfd), symbol_attribute_def, - symbol_name_index); - bfd_set_error (bfd_error_bad_value); - return false; - break; - } - break; - case ieee_external_reference_info_record_enum: - /* Skip over ATX record. */ - parse_int (&(ieee->h), &value); - parse_int (&(ieee->h), &value); - parse_int (&(ieee->h), &value); - parse_int (&(ieee->h), &value); - break; - } - } - break; - case ieee_value_record_enum >> 8: - { - unsigned int symbol_name_index; - ieee_symbol_index_type symbol_ignore; - boolean pcrel_ignore; - unsigned int extra; - next_byte (&(ieee->h)); - next_byte (&(ieee->h)); - - symbol_name_index = must_parse_int (&(ieee->h)); - parse_expression (ieee, - &symbol->symbol.value, - &symbol_ignore, - &pcrel_ignore, - &extra, - &symbol->symbol.section); - - symbol->symbol.flags = BSF_GLOBAL | BSF_EXPORT; - - } - break; - case ieee_weak_external_reference_enum: - { - bfd_vma size; - bfd_vma value; - next_byte (&(ieee->h)); - /* Throw away the external reference index */ - (void) must_parse_int (&(ieee->h)); - /* Fetch the default size if not resolved */ - size = must_parse_int (&(ieee->h)); - /* Fetch the defautlt value if available */ - if (parse_int (&(ieee->h), &value) == false) - { - value = 0; - } - /* This turns into a common */ - symbol->symbol.section = bfd_com_section_ptr; - symbol->symbol.value = size; - } - break; - - case ieee_external_reference_enum: - next_byte (&(ieee->h)); - - symbol = get_symbol (abfd, ieee, symbol, &symbol_count, - &prev_reference_ptr, - &ieee->external_reference_max_index, 'X'); - if (symbol == NULL) - return false; - - symbol->symbol.the_bfd = abfd; - symbol->symbol.name = read_id (&(ieee->h)); - symbol->symbol.udata.p = (PTR) NULL; - symbol->symbol.section = bfd_und_section_ptr; - symbol->symbol.value = (bfd_vma) 0; - symbol->symbol.flags = 0; - - BFD_ASSERT (symbol->index >= ieee->external_reference_min_index); - break; - - default: - loop = false; - } - } - - if (ieee->external_symbol_max_index != 0) - { - ieee->external_symbol_count = - ieee->external_symbol_max_index - - ieee->external_symbol_min_index + 1; - } - else - { - ieee->external_symbol_count = 0; - } - - if (ieee->external_reference_max_index != 0) - { - ieee->external_reference_count = - ieee->external_reference_max_index - - ieee->external_reference_min_index + 1; - } - else - { - ieee->external_reference_count = 0; - } - - abfd->symcount = - ieee->external_reference_count + ieee->external_symbol_count; - - if (symbol_count != abfd->symcount) - { - /* There are gaps in the table -- */ - ieee->symbol_table_full = false; - } - - *prev_symbols_ptr = (ieee_symbol_type *) NULL; - *prev_reference_ptr = (ieee_symbol_type *) NULL; - - return true; -} - -static boolean -ieee_slurp_symbol_table (abfd) - bfd *abfd; -{ - if (IEEE_DATA (abfd)->read_symbols == false) - { - if (! ieee_slurp_external_symbols (abfd)) - return false; - IEEE_DATA (abfd)->read_symbols = true; - } - return true; -} - -long -ieee_get_symtab_upper_bound (abfd) - bfd *abfd; -{ - if (! ieee_slurp_symbol_table (abfd)) - return -1; - - return (abfd->symcount != 0) ? - (abfd->symcount + 1) * (sizeof (ieee_symbol_type *)) : 0; -} - -/* -Move from our internal lists to the canon table, and insert in -symbol index order -*/ - -extern const bfd_target ieee_vec; - -long -ieee_get_symtab (abfd, location) - bfd *abfd; - asymbol **location; -{ - ieee_symbol_type *symp; - static bfd dummy_bfd; - static asymbol empty_symbol = - /* the_bfd, name, value, attr, section */ - {&dummy_bfd, " ieee empty", (symvalue) 0, BSF_DEBUGGING, bfd_abs_section_ptr}; - - if (abfd->symcount) - { - ieee_data_type *ieee = IEEE_DATA (abfd); - dummy_bfd.xvec = &ieee_vec; - if (! ieee_slurp_symbol_table (abfd)) - return -1; - - if (ieee->symbol_table_full == false) - { - /* Arrgh - there are gaps in the table, run through and fill them */ - /* up with pointers to a null place */ - unsigned int i; - for (i = 0; i < abfd->symcount; i++) - { - location[i] = &empty_symbol; - } - } - - ieee->external_symbol_base_offset = -ieee->external_symbol_min_index; - for (symp = IEEE_DATA (abfd)->external_symbols; - symp != (ieee_symbol_type *) NULL; - symp = symp->next) - { - /* Place into table at correct index locations */ - location[symp->index + ieee->external_symbol_base_offset] = &symp->symbol; - } - - /* The external refs are indexed in a bit */ - ieee->external_reference_base_offset = - -ieee->external_reference_min_index + ieee->external_symbol_count; - - for (symp = IEEE_DATA (abfd)->external_reference; - symp != (ieee_symbol_type *) NULL; - symp = symp->next) - { - location[symp->index + ieee->external_reference_base_offset] = - &symp->symbol; - - } - } - if (abfd->symcount) - { - location[abfd->symcount] = (asymbol *) NULL; - } - return abfd->symcount; -} - -static asection * -get_section_entry (abfd, ieee, index) - bfd *abfd; - ieee_data_type *ieee; - unsigned int index; -{ - if (ieee->section_table[index] == (asection *) NULL) - { - char *tmp = bfd_alloc (abfd, 11); - asection *section; - - if (!tmp) - return NULL; - sprintf (tmp, " fsec%4d", index); - section = bfd_make_section (abfd, tmp); - ieee->section_table[index] = section; - section->flags = SEC_NO_FLAGS; - section->target_index = index; - ieee->section_table[index] = section; - } - return ieee->section_table[index]; -} - -static void -ieee_slurp_sections (abfd) - bfd *abfd; -{ - ieee_data_type *ieee = IEEE_DATA (abfd); - file_ptr offset = ieee->w.r.section_part; - asection *section = (asection *) NULL; - char *name; - - if (offset != 0) - { - bfd_byte section_type[3]; - ieee_seek (abfd, offset); - while (true) - { - switch (this_byte (&(ieee->h))) - { - case ieee_section_type_enum: - { - unsigned int section_index; - next_byte (&(ieee->h)); - section_index = must_parse_int (&(ieee->h)); - /* Fixme to be nice about a silly number of sections */ - BFD_ASSERT (section_index < NSECTIONS); - - section = get_section_entry (abfd, ieee, section_index); - - section_type[0] = this_byte_and_next (&(ieee->h)); - - /* Set minimal section attributes. Attributes are - extended later, based on section contents. */ - - switch (section_type[0]) - { - case 0xC1: - /* Normal attributes for absolute sections */ - section_type[1] = this_byte (&(ieee->h)); - section->flags = SEC_ALLOC; - switch (section_type[1]) - { - case 0xD3: /* AS Absolute section attributes */ - next_byte (&(ieee->h)); - section_type[2] = this_byte (&(ieee->h)); - switch (section_type[2]) - { - case 0xD0: - /* Normal code */ - next_byte (&(ieee->h)); - section->flags |= SEC_CODE; - break; - case 0xC4: - /* Normal data */ - next_byte (&(ieee->h)); - section->flags |= SEC_DATA; - break; - case 0xD2: - next_byte (&(ieee->h)); - /* Normal rom data */ - section->flags |= SEC_ROM | SEC_DATA; - break; - default: - break; - } - } - break; - case 0xC3: /* Named relocatable sections (type C) */ - section_type[1] = this_byte (&(ieee->h)); - section->flags = SEC_ALLOC; - switch (section_type[1]) - { - case 0xD0: /* Normal code (CP) */ - next_byte (&(ieee->h)); - section->flags |= SEC_CODE; - break; - case 0xC4: /* Normal data (CD) */ - next_byte (&(ieee->h)); - section->flags |= SEC_DATA; - break; - case 0xD2: /* Normal rom data (CR) */ - next_byte (&(ieee->h)); - section->flags |= SEC_ROM | SEC_DATA; - break; - default: - break; - } - } - - /* Read section name, use it if non empty. */ - name = read_id (&ieee->h); - if (name[0]) - section->name = name; - - /* Skip these fields, which we don't care about */ - { - bfd_vma parent, brother, context; - parse_int (&(ieee->h), &parent); - parse_int (&(ieee->h), &brother); - parse_int (&(ieee->h), &context); - } - } - break; - case ieee_section_alignment_enum: - { - unsigned int section_index; - bfd_vma value; - asection *section; - next_byte (&(ieee->h)); - section_index = must_parse_int (&ieee->h); - section = get_section_entry (abfd, ieee, section_index); - if (section_index > ieee->section_count) - { - ieee->section_count = section_index; - } - section->alignment_power = - bfd_log2 (must_parse_int (&ieee->h)); - (void) parse_int (&(ieee->h), &value); - } - break; - case ieee_e2_first_byte_enum: - { - ieee_record_enum_type t = (ieee_record_enum_type) (read_2bytes (&(ieee->h))); - - switch (t) - { - case ieee_section_size_enum: - section = ieee->section_table[must_parse_int (&(ieee->h))]; - section->_raw_size = must_parse_int (&(ieee->h)); - break; - case ieee_physical_region_size_enum: - section = ieee->section_table[must_parse_int (&(ieee->h))]; - section->_raw_size = must_parse_int (&(ieee->h)); - break; - case ieee_region_base_address_enum: - section = ieee->section_table[must_parse_int (&(ieee->h))]; - section->vma = must_parse_int (&(ieee->h)); - section->lma = section->vma; - break; - case ieee_mau_size_enum: - must_parse_int (&(ieee->h)); - must_parse_int (&(ieee->h)); - break; - case ieee_m_value_enum: - must_parse_int (&(ieee->h)); - must_parse_int (&(ieee->h)); - break; - case ieee_section_base_address_enum: - section = ieee->section_table[must_parse_int (&(ieee->h))]; - section->vma = must_parse_int (&(ieee->h)); - section->lma = section->vma; - break; - case ieee_section_offset_enum: - (void) must_parse_int (&(ieee->h)); - (void) must_parse_int (&(ieee->h)); - break; - default: - return; - } - } - break; - default: - return; - } - } - } -} - -/* Make a section for the debugging information, if any. We don't try - to interpret the debugging information; we just point the section - at the area in the file so that program which understand can dig it - out. */ - -static boolean -ieee_slurp_debug (abfd) - bfd *abfd; -{ - ieee_data_type *ieee = IEEE_DATA (abfd); - asection *sec; - - if (ieee->w.r.debug_information_part == 0) - return true; - - sec = bfd_make_section (abfd, ".debug"); - if (sec == NULL) - return false; - sec->flags |= SEC_DEBUGGING | SEC_HAS_CONTENTS; - sec->filepos = ieee->w.r.debug_information_part; - sec->_raw_size = ieee->w.r.data_part - ieee->w.r.debug_information_part; - - return true; -} - -/*********************************************************************** -* archive stuff -*/ - -const bfd_target * -ieee_archive_p (abfd) - bfd *abfd; -{ - char *library; - boolean loop; - unsigned int i; - unsigned char buffer[512]; - file_ptr buffer_offset = 0; - ieee_ar_data_type *save = abfd->tdata.ieee_ar_data; - ieee_ar_data_type *ieee; - abfd->tdata.ieee_ar_data = (ieee_ar_data_type *) bfd_alloc (abfd, sizeof (ieee_ar_data_type)); - if (!abfd->tdata.ieee_ar_data) - return NULL; - ieee = IEEE_AR_DATA (abfd); - - /* FIXME: Check return value. I'm not sure whether it needs to read - the entire buffer or not. */ - bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd); - - ieee->h.first_byte = buffer; - ieee->h.input_p = buffer; - - ieee->h.abfd = abfd; - - if (this_byte (&(ieee->h)) != Module_Beginning) - { - abfd->tdata.ieee_ar_data = save; - return (const bfd_target *) NULL; - } - - next_byte (&(ieee->h)); - library = read_id (&(ieee->h)); - if (strcmp (library, "LIBRARY") != 0) - { - bfd_release (abfd, ieee); - abfd->tdata.ieee_ar_data = save; - return (const bfd_target *) NULL; - } - /* Throw away the filename */ - read_id (&(ieee->h)); - - ieee->element_count = 0; - ieee->element_index = 0; - - next_byte (&(ieee->h)); /* Drop the ad part */ - must_parse_int (&(ieee->h)); /* And the two dummy numbers */ - must_parse_int (&(ieee->h)); - - loop = true; - /* Read the index of the BB table */ - while (loop) - { - ieee_ar_obstack_type t; - int rec = read_2bytes (&(ieee->h)); - if (rec == (int) ieee_assign_value_to_variable_enum) - { - must_parse_int (&(ieee->h)); - t.file_offset = must_parse_int (&(ieee->h)); - t.abfd = (bfd *) NULL; - ieee->element_count++; - - bfd_alloc_grow (abfd, (PTR) &t, sizeof t); - - /* Make sure that we don't go over the end of the buffer */ - - if ((size_t) ieee_pos (abfd) > sizeof (buffer) / 2) - { - /* Past half way, reseek and reprime */ - buffer_offset += ieee_pos (abfd); - if (bfd_seek (abfd, buffer_offset, SEEK_SET) != 0) - return NULL; - /* FIXME: Check return value. I'm not sure whether it - needs to read the entire buffer or not. */ - bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd); - ieee->h.first_byte = buffer; - ieee->h.input_p = buffer; - } - } - else - loop = false; - } - - ieee->elements = (ieee_ar_obstack_type *) bfd_alloc_finish (abfd); - if (!ieee->elements) - return (const bfd_target *) NULL; - - /* Now scan the area again, and replace BB offsets with file */ - /* offsets */ - - for (i = 2; i < ieee->element_count; i++) - { - if (bfd_seek (abfd, ieee->elements[i].file_offset, SEEK_SET) != 0) - return NULL; - /* FIXME: Check return value. I'm not sure whether it needs to - read the entire buffer or not. */ - bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd); - ieee->h.first_byte = buffer; - ieee->h.input_p = buffer; - - next_byte (&(ieee->h)); /* Drop F8 */ - next_byte (&(ieee->h)); /* Drop 14 */ - must_parse_int (&(ieee->h)); /* Drop size of block */ - if (must_parse_int (&(ieee->h)) != 0) - { - /* This object has been deleted */ - ieee->elements[i].file_offset = 0; - } - else - { - ieee->elements[i].file_offset = must_parse_int (&(ieee->h)); - } - } - -/* abfd->has_armap = ;*/ - return abfd->xvec; -} - -static boolean -ieee_mkobject (abfd) - bfd *abfd; -{ - abfd->tdata.ieee_data = (ieee_data_type *) bfd_zalloc (abfd, sizeof (ieee_data_type)); - return abfd->tdata.ieee_data ? true : false; -} - -const bfd_target * -ieee_object_p (abfd) - bfd *abfd; -{ - char *processor; - unsigned int part; - ieee_data_type *ieee; - unsigned char buffer[300]; - ieee_data_type *save = IEEE_DATA (abfd); - - abfd->tdata.ieee_data = 0; - ieee_mkobject (abfd); - - ieee = IEEE_DATA (abfd); - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - goto fail; - /* Read the first few bytes in to see if it makes sense */ - /* FIXME: Check return value. I'm not sure whether it needs to read - the entire buffer or not. */ - bfd_read ((PTR) buffer, 1, sizeof (buffer), abfd); - - ieee->h.input_p = buffer; - if (this_byte_and_next (&(ieee->h)) != Module_Beginning) - goto got_wrong_format; - - ieee->read_symbols = false; - ieee->read_data = false; - ieee->section_count = 0; - ieee->external_symbol_max_index = 0; - ieee->external_symbol_min_index = IEEE_PUBLIC_BASE; - ieee->external_reference_min_index = IEEE_REFERENCE_BASE; - ieee->external_reference_max_index = 0; - ieee->h.abfd = abfd; - memset ((PTR) ieee->section_table, 0, sizeof (ieee->section_table)); - - processor = ieee->mb.processor = read_id (&(ieee->h)); - if (strcmp (processor, "LIBRARY") == 0) - goto got_wrong_format; - ieee->mb.module_name = read_id (&(ieee->h)); - if (abfd->filename == (CONST char *) NULL) - { - abfd->filename = ieee->mb.module_name; - } - /* Determine the architecture and machine type of the object file. - */ - { - const bfd_arch_info_type *arch = bfd_scan_arch (processor); - if (arch == 0) - goto got_wrong_format; - abfd->arch_info = arch; - } - - if (this_byte (&(ieee->h)) != (int) ieee_address_descriptor_enum) - { - goto fail; - } - next_byte (&(ieee->h)); - - if (parse_int (&(ieee->h), &ieee->ad.number_of_bits_mau) == false) - { - goto fail; - } - if (parse_int (&(ieee->h), &ieee->ad.number_of_maus_in_address) == false) - { - goto fail; - } - - /* If there is a byte order info, take it */ - if (this_byte (&(ieee->h)) == (int) ieee_variable_L_enum || - this_byte (&(ieee->h)) == (int) ieee_variable_M_enum) - next_byte (&(ieee->h)); - - for (part = 0; part < N_W_VARIABLES; part++) - { - boolean ok; - if (read_2bytes (&(ieee->h)) != (int) ieee_assign_value_to_variable_enum) - { - goto fail; - } - if (this_byte_and_next (&(ieee->h)) != part) - { - goto fail; - } - - ieee->w.offset[part] = parse_i (&(ieee->h), &ok); - if (ok == false) - { - goto fail; - } - - } - - if (ieee->w.r.external_part != 0) - abfd->flags = HAS_SYMS; - - /* By now we know that this is a real IEEE file, we're going to read - the whole thing into memory so that we can run up and down it - quickly. We can work out how big the file is from the trailer - record */ - - IEEE_DATA (abfd)->h.first_byte = - (unsigned char *) bfd_alloc (ieee->h.abfd, ieee->w.r.me_record + 1); - if (!IEEE_DATA (abfd)->h.first_byte) - goto fail; - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - goto fail; - /* FIXME: Check return value. I'm not sure whether it needs to read - the entire buffer or not. */ - bfd_read ((PTR) (IEEE_DATA (abfd)->h.first_byte), 1, - ieee->w.r.me_record + 1, abfd); - - ieee_slurp_sections (abfd); - - if (! ieee_slurp_debug (abfd)) - goto fail; - - /* Parse section data to activate file and section flags implied by - section contents. */ - - if (! ieee_slurp_section_data (abfd)) - goto fail; - - return abfd->xvec; -got_wrong_format: - bfd_set_error (bfd_error_wrong_format); -fail: - (void) bfd_release (abfd, ieee); - abfd->tdata.ieee_data = save; - return (const bfd_target *) NULL; -} - -void -ieee_get_symbol_info (ignore_abfd, symbol, ret) - bfd *ignore_abfd; - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); - if (symbol->name[0] == ' ') - ret->name = "* empty table entry "; - if (!symbol->section) - ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A'; -} - -void -ieee_print_symbol (ignore_abfd, afile, symbol, how) - bfd *ignore_abfd; - PTR afile; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *) afile; - - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - case bfd_print_symbol_more: -#if 0 - fprintf (file, "%4x %2x", aout_symbol (symbol)->desc & 0xffff, - aout_symbol (symbol)->other & 0xff); -#endif - BFD_FAIL (); - break; - case bfd_print_symbol_all: - { - const char *section_name = - (symbol->section == (asection *) NULL - ? "*abs" - : symbol->section->name); - if (symbol->name[0] == ' ') - { - fprintf (file, "* empty table entry "); - } - else - { - bfd_print_symbol_vandf ((PTR) file, symbol); - - fprintf (file, " %-5s %04x %02x %s", - section_name, - (unsigned) ieee_symbol (symbol)->index, - (unsigned) 0, - symbol->name); - } - } - break; - } -} - -static boolean -do_one (ieee, current_map, location_ptr, s, iterations) - ieee_data_type *ieee; - ieee_per_section_type *current_map; - unsigned char *location_ptr; - asection *s; - int iterations; -{ - switch (this_byte (&(ieee->h))) - { - case ieee_load_constant_bytes_enum: - { - unsigned int number_of_maus; - unsigned int i; - next_byte (&(ieee->h)); - number_of_maus = must_parse_int (&(ieee->h)); - - for (i = 0; i < number_of_maus; i++) - { - location_ptr[current_map->pc++] = this_byte (&(ieee->h)); - next_byte (&(ieee->h)); - } - } - break; - - case ieee_load_with_relocation_enum: - { - boolean loop = true; - next_byte (&(ieee->h)); - while (loop) - { - switch (this_byte (&(ieee->h))) - { - case ieee_variable_R_enum: - - case ieee_function_signed_open_b_enum: - case ieee_function_unsigned_open_b_enum: - case ieee_function_either_open_b_enum: - { - unsigned int extra = 4; - boolean pcrel = false; - asection *section; - ieee_reloc_type *r = - (ieee_reloc_type *) bfd_alloc (ieee->h.abfd, - sizeof (ieee_reloc_type)); - if (!r) - return false; - - *(current_map->reloc_tail_ptr) = r; - current_map->reloc_tail_ptr = &r->next; - r->next = (ieee_reloc_type *) NULL; - next_byte (&(ieee->h)); -/* abort();*/ - r->relent.sym_ptr_ptr = 0; - parse_expression (ieee, - &r->relent.addend, - &r->symbol, - &pcrel, &extra, §ion); - r->relent.address = current_map->pc; - s->flags |= SEC_RELOC; - s->owner->flags |= HAS_RELOC; - s->reloc_count++; - if (r->relent.sym_ptr_ptr == 0) - { - r->relent.sym_ptr_ptr = section->symbol_ptr_ptr; - } - - if (this_byte (&(ieee->h)) == (int) ieee_comma) - { - next_byte (&(ieee->h)); - /* Fetch number of bytes to pad */ - extra = must_parse_int (&(ieee->h)); - }; - - switch (this_byte (&(ieee->h))) - { - case ieee_function_signed_close_b_enum: - next_byte (&(ieee->h)); - break; - case ieee_function_unsigned_close_b_enum: - next_byte (&(ieee->h)); - break; - case ieee_function_either_close_b_enum: - next_byte (&(ieee->h)); - break; - default: - break; - } - /* Build a relocation entry for this type */ - /* If pc rel then stick -ve pc into instruction - and take out of reloc .. - - I've changed this. It's all too complicated. I - keep 0 in the instruction now. */ - - switch (extra) - { - case 0: - case 4: - - if (pcrel == true) - { -#if KEEPMINUSPCININST - bfd_put_32 (ieee->h.abfd, -current_map->pc, location_ptr + - current_map->pc); - r->relent.howto = &rel32_howto; - r->relent.addend -= - current_map->pc; -#else - bfd_put_32 (ieee->h.abfd, 0, location_ptr + - current_map->pc); - r->relent.howto = &rel32_howto; -#endif - } - else - { - bfd_put_32 (ieee->h.abfd, 0, location_ptr + - current_map->pc); - r->relent.howto = &abs32_howto; - } - current_map->pc += 4; - break; - case 2: - if (pcrel == true) - { -#if KEEPMINUSPCININST - bfd_put_16 (ieee->h.abfd, (int) (-current_map->pc), location_ptr + current_map->pc); - r->relent.addend -= current_map->pc; - r->relent.howto = &rel16_howto; -#else - - bfd_put_16 (ieee->h.abfd, 0, location_ptr + current_map->pc); - r->relent.howto = &rel16_howto; -#endif - } - - else - { - bfd_put_16 (ieee->h.abfd, 0, location_ptr + current_map->pc); - r->relent.howto = &abs16_howto; - } - current_map->pc += 2; - break; - case 1: - if (pcrel == true) - { -#if KEEPMINUSPCININST - bfd_put_8 (ieee->h.abfd, (int) (-current_map->pc), location_ptr + current_map->pc); - r->relent.addend -= current_map->pc; - r->relent.howto = &rel8_howto; -#else - bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc); - r->relent.howto = &rel8_howto; -#endif - } - else - { - bfd_put_8 (ieee->h.abfd, 0, location_ptr + current_map->pc); - r->relent.howto = &abs8_howto; - } - current_map->pc += 1; - break; - - default: - BFD_FAIL (); - return false; - } - } - break; - default: - { - bfd_vma this_size; - if (parse_int (&(ieee->h), &this_size) == true) - { - unsigned int i; - for (i = 0; i < this_size; i++) - { - location_ptr[current_map->pc++] = this_byte (&(ieee->h)); - next_byte (&(ieee->h)); - } - } - else - { - loop = false; - } - } - } - - /* Prevent more than the first load-item of an LR record - from being repeated (MRI convention). */ - if (iterations != 1) - loop = false; - } - } - } - return true; -} - -/* Read in all the section data and relocation stuff too */ -static boolean -ieee_slurp_section_data (abfd) - bfd *abfd; -{ - bfd_byte *location_ptr = (bfd_byte *) NULL; - ieee_data_type *ieee = IEEE_DATA (abfd); - unsigned int section_number; - - ieee_per_section_type *current_map = (ieee_per_section_type *) NULL; - asection *s; - /* Seek to the start of the data area */ - if (ieee->read_data == true) - return true; - ieee->read_data = true; - ieee_seek (abfd, ieee->w.r.data_part); - - /* Allocate enough space for all the section contents */ - - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - ieee_per_section_type *per = (ieee_per_section_type *) s->used_by_bfd; - if ((s->flags & SEC_DEBUGGING) != 0) - continue; - per->data = (bfd_byte *) bfd_alloc (ieee->h.abfd, s->_raw_size); - if (!per->data) - return false; - /*SUPPRESS 68*/ - per->reloc_tail_ptr = - (ieee_reloc_type **) & (s->relocation); - } - - while (true) - { - switch (this_byte (&(ieee->h))) - { - /* IF we see anything strange then quit */ - default: - return true; - - case ieee_set_current_section_enum: - next_byte (&(ieee->h)); - section_number = must_parse_int (&(ieee->h)); - s = ieee->section_table[section_number]; - s->flags |= SEC_LOAD | SEC_HAS_CONTENTS; - current_map = (ieee_per_section_type *) s->used_by_bfd; - location_ptr = current_map->data - s->vma; - /* The document I have says that Microtec's compilers reset */ - /* this after a sec section, even though the standard says not */ - /* to. SO .. */ - current_map->pc = s->vma; - break; - - case ieee_e2_first_byte_enum: - next_byte (&(ieee->h)); - switch (this_byte (&(ieee->h))) - { - case ieee_set_current_pc_enum & 0xff: - { - bfd_vma value; - ieee_symbol_index_type symbol; - unsigned int extra; - boolean pcrel; - next_byte (&(ieee->h)); - must_parse_int (&(ieee->h)); /* Thow away section #*/ - parse_expression (ieee, &value, - &symbol, - &pcrel, &extra, - 0); - current_map->pc = value; - BFD_ASSERT ((unsigned) (value - s->vma) <= s->_raw_size); - } - break; - - case ieee_value_starting_address_enum & 0xff: - /* We've got to the end of the data now - */ - return true; - default: - BFD_FAIL (); - return false; - } - break; - case ieee_repeat_data_enum: - { - /* Repeat the following LD or LR n times - we do this by - remembering the stream pointer before running it and - resetting it and running it n times. We special case - the repetition of a repeat_data/load_constant - */ - - unsigned int iterations; - unsigned char *start; - next_byte (&(ieee->h)); - iterations = must_parse_int (&(ieee->h)); - start = ieee->h.input_p; - if (start[0] == (int) ieee_load_constant_bytes_enum && - start[1] == 1) - { - while (iterations != 0) - { - location_ptr[current_map->pc++] = start[2]; - iterations--; - } - next_byte (&(ieee->h)); - next_byte (&(ieee->h)); - next_byte (&(ieee->h)); - } - else - { - while (iterations != 0) - { - ieee->h.input_p = start; - if (!do_one (ieee, current_map, location_ptr, s, - iterations)) - return false; - iterations--; - } - } - } - break; - case ieee_load_constant_bytes_enum: - case ieee_load_with_relocation_enum: - { - if (!do_one (ieee, current_map, location_ptr, s, 1)) - return false; - } - } - } -} - -boolean -ieee_new_section_hook (abfd, newsect) - bfd *abfd; - asection *newsect; -{ - newsect->used_by_bfd = (PTR) - bfd_alloc (abfd, sizeof (ieee_per_section_type)); - if (!newsect->used_by_bfd) - return false; - ieee_per_section (newsect)->data = (bfd_byte *) NULL; - ieee_per_section (newsect)->section = newsect; - return true; -} - -long -ieee_get_reloc_upper_bound (abfd, asect) - bfd *abfd; - sec_ptr asect; -{ - if ((asect->flags & SEC_DEBUGGING) != 0) - return 0; - if (! ieee_slurp_section_data (abfd)) - return -1; - return (asect->reloc_count + 1) * sizeof (arelent *); -} - -static boolean -ieee_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd; - if ((section->flags & SEC_DEBUGGING) != 0) - return _bfd_generic_get_section_contents (abfd, section, location, - offset, count); - ieee_slurp_section_data (abfd); - (void) memcpy ((PTR) location, (PTR) (p->data + offset), (unsigned) count); - return true; -} - -long -ieee_canonicalize_reloc (abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ -/* ieee_per_section_type *p = (ieee_per_section_type *) section->used_by_bfd;*/ - ieee_reloc_type *src = (ieee_reloc_type *) (section->relocation); - ieee_data_type *ieee = IEEE_DATA (abfd); - - if ((section->flags & SEC_DEBUGGING) != 0) - return 0; - - while (src != (ieee_reloc_type *) NULL) - { - /* Work out which symbol to attach it this reloc to */ - switch (src->symbol.letter) - { - case 'I': - src->relent.sym_ptr_ptr = - symbols + src->symbol.index + ieee->external_symbol_base_offset; - break; - case 'X': - src->relent.sym_ptr_ptr = - symbols + src->symbol.index + ieee->external_reference_base_offset; - break; - case 0: - src->relent.sym_ptr_ptr = - src->relent.sym_ptr_ptr[0]->section->symbol_ptr_ptr; - break; - default: - - BFD_FAIL (); - } - *relptr++ = &src->relent; - src = src->next; - } - *relptr = (arelent *) NULL; - return section->reloc_count; -} - -static int -comp (ap, bp) - CONST PTR ap; - CONST PTR bp; -{ - arelent *a = *((arelent **) ap); - arelent *b = *((arelent **) bp); - return a->address - b->address; -} - -/* Write the section headers. */ - -static boolean -ieee_write_section_part (abfd) - bfd *abfd; -{ - ieee_data_type *ieee = IEEE_DATA (abfd); - asection *s; - ieee->w.r.section_part = bfd_tell (abfd); - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - if (! bfd_is_abs_section (s) - && (s->flags & SEC_DEBUGGING) == 0) - { - if (! ieee_write_byte (abfd, ieee_section_type_enum) - || ! ieee_write_byte (abfd, - (bfd_byte) (s->index - + IEEE_SECTION_NUMBER_BASE))) - return false; - - if (abfd->flags & EXEC_P) - { - /* This image is executable, so output absolute sections */ - if (! ieee_write_byte (abfd, ieee_variable_A_enum) - || ! ieee_write_byte (abfd, ieee_variable_S_enum)) - return false; - } - else - { - if (! ieee_write_byte (abfd, ieee_variable_C_enum)) - return false; - } - - switch (s->flags & (SEC_CODE | SEC_DATA | SEC_ROM)) - { - case SEC_CODE | SEC_LOAD: - case SEC_CODE: - if (! ieee_write_byte (abfd, ieee_variable_P_enum)) - return false; - break; - case SEC_DATA: - default: - if (! ieee_write_byte (abfd, ieee_variable_D_enum)) - return false; - break; - case SEC_ROM: - case SEC_ROM | SEC_DATA: - case SEC_ROM | SEC_LOAD: - case SEC_ROM | SEC_DATA | SEC_LOAD: - if (! ieee_write_byte (abfd, ieee_variable_R_enum)) - return false; - } - - - if (! ieee_write_id (abfd, s->name)) - return false; -#if 0 - ieee_write_int (abfd, 0); /* Parent */ - ieee_write_int (abfd, 0); /* Brother */ - ieee_write_int (abfd, 0); /* Context */ -#endif - /* Alignment */ - if (! ieee_write_byte (abfd, ieee_section_alignment_enum) - || ! ieee_write_byte (abfd, - (bfd_byte) (s->index - + IEEE_SECTION_NUMBER_BASE)) - || ! ieee_write_int (abfd, 1 << s->alignment_power)) - return false; - - /* Size */ - if (! ieee_write_2bytes (abfd, ieee_section_size_enum) - || ! ieee_write_byte (abfd, - (bfd_byte) (s->index - + IEEE_SECTION_NUMBER_BASE)) - || ! ieee_write_int (abfd, s->_raw_size)) - return false; - if (abfd->flags & EXEC_P) - { - /* Relocateable sections don't have asl records */ - /* Vma */ - if (! ieee_write_2bytes (abfd, ieee_section_base_address_enum) - || ! ieee_write_byte (abfd, - ((bfd_byte) - (s->index - + IEEE_SECTION_NUMBER_BASE))) - || ! ieee_write_int (abfd, s->vma)) - return false; - } - } - } - - return true; -} - - -static boolean -do_with_relocs (abfd, s) - bfd *abfd; - asection *s; -{ - unsigned int number_of_maus_in_address = - bfd_arch_bits_per_address (abfd) / bfd_arch_bits_per_byte (abfd); - unsigned int relocs_to_go = s->reloc_count; - bfd_byte *stream = ieee_per_section (s)->data; - arelent **p = s->orelocation; - bfd_size_type current_byte_index = 0; - - qsort (s->orelocation, - relocs_to_go, - sizeof (arelent **), - comp); - - /* Output the section preheader */ - if (! ieee_write_byte (abfd, ieee_set_current_section_enum) - || ! ieee_write_byte (abfd, - (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE)) - || ! ieee_write_2bytes (abfd, ieee_set_current_pc_enum) - || ! ieee_write_byte (abfd, - (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE))) - return false; - if ((abfd->flags & EXEC_P) != 0 && relocs_to_go == 0) - { - if (! ieee_write_int (abfd, s->vma)) - return false; - } - else - { - if (! ieee_write_expression (abfd, 0, s->symbol, 0, 0)) - return false; - } - - if (relocs_to_go == 0) - { - /* If there aren't any relocations then output the load constant - byte opcode rather than the load with relocation opcode */ - - while (current_byte_index < s->_raw_size) - { - bfd_size_type run; - unsigned int MAXRUN = 127; - run = MAXRUN; - if (run > s->_raw_size - current_byte_index) - { - run = s->_raw_size - current_byte_index; - } - - if (run != 0) - { - if (! ieee_write_byte (abfd, ieee_load_constant_bytes_enum)) - return false; - /* Output a stream of bytes */ - if (! ieee_write_int (abfd, run)) - return false; - if (bfd_write ((PTR) (stream + current_byte_index), - 1, - run, - abfd) - != run) - return false; - current_byte_index += run; - } - } - } - else - { - if (! ieee_write_byte (abfd, ieee_load_with_relocation_enum)) - return false; - - /* Output the data stream as the longest sequence of bytes - possible, allowing for the a reasonable packet size and - relocation stuffs. */ - - if ((PTR) stream == (PTR) NULL) - { - /* Outputting a section without data, fill it up */ - stream = (unsigned char *) (bfd_alloc (abfd, s->_raw_size)); - if (!stream) - return false; - memset ((PTR) stream, 0, (size_t) s->_raw_size); - } - while (current_byte_index < s->_raw_size) - { - bfd_size_type run; - unsigned int MAXRUN = 127; - if (relocs_to_go) - { - run = (*p)->address - current_byte_index; - if (run > MAXRUN) - run = MAXRUN; - } - else - { - run = MAXRUN; - } - if (run > s->_raw_size - current_byte_index) - { - run = s->_raw_size - current_byte_index; - } - - if (run != 0) - { - /* Output a stream of bytes */ - if (! ieee_write_int (abfd, run)) - return false; - if (bfd_write ((PTR) (stream + current_byte_index), - 1, - run, - abfd) - != run) - return false; - current_byte_index += run; - } - /* Output any relocations here */ - if (relocs_to_go && (*p) && (*p)->address == current_byte_index) - { - while (relocs_to_go - && (*p) && (*p)->address == current_byte_index) - { - arelent *r = *p; - bfd_signed_vma ov; - -#if 0 - if (r->howto->pc_relative) - { - r->addend += current_byte_index; - } -#endif - - switch (r->howto->size) - { - case 2: - - ov = bfd_get_signed_32 (abfd, - stream + current_byte_index); - current_byte_index += 4; - break; - case 1: - ov = bfd_get_signed_16 (abfd, - stream + current_byte_index); - current_byte_index += 2; - break; - case 0: - ov = bfd_get_signed_8 (abfd, - stream + current_byte_index); - current_byte_index++; - break; - default: - ov = 0; - BFD_FAIL (); - return false; - } - - ov &= r->howto->src_mask; - - if (r->howto->pc_relative - && ! r->howto->pcrel_offset) - ov += r->address; - - if (! ieee_write_byte (abfd, - ieee_function_either_open_b_enum)) - return false; - -/* abort();*/ - - if (r->sym_ptr_ptr != (asymbol **) NULL) - { - if (! ieee_write_expression (abfd, r->addend + ov, - *(r->sym_ptr_ptr), - r->howto->pc_relative, - s->index)) - return false; - } - else - { - if (! ieee_write_expression (abfd, r->addend + ov, - (asymbol *) NULL, - r->howto->pc_relative, - s->index)) - return false; - } - - if (number_of_maus_in_address - != bfd_get_reloc_size (r->howto)) - { - if (! ieee_write_int (abfd, - bfd_get_reloc_size (r->howto))) - return false; - } - if (! ieee_write_byte (abfd, - ieee_function_either_close_b_enum)) - return false; - - relocs_to_go--; - p++; - } - - } - } - } - - return true; -} - -/* If there are no relocations in the output section then we can be - clever about how we write. We block items up into a max of 127 - bytes. */ - -static boolean -do_as_repeat (abfd, s) - bfd *abfd; - asection *s; -{ - if (s->_raw_size) - { - if (! ieee_write_byte (abfd, ieee_set_current_section_enum) - || ! ieee_write_byte (abfd, - (bfd_byte) (s->index - + IEEE_SECTION_NUMBER_BASE)) - || ! ieee_write_byte (abfd, ieee_set_current_pc_enum >> 8) - || ! ieee_write_byte (abfd, ieee_set_current_pc_enum & 0xff) - || ! ieee_write_byte (abfd, - (bfd_byte) (s->index - + IEEE_SECTION_NUMBER_BASE)) - || ! ieee_write_int (abfd, s->vma) - || ! ieee_write_byte (abfd, ieee_repeat_data_enum) - || ! ieee_write_int (abfd, s->_raw_size) - || ! ieee_write_byte (abfd, ieee_load_constant_bytes_enum) - || ! ieee_write_byte (abfd, 1) - || ! ieee_write_byte (abfd, 0)) - return false; - } - - return true; -} - -static boolean -do_without_relocs (abfd, s) - bfd *abfd; - asection *s; -{ - bfd_byte *stream = ieee_per_section (s)->data; - - if (stream == 0 || ((s->flags & SEC_LOAD) == 0)) - { - if (! do_as_repeat (abfd, s)) - return false; - } - else - { - unsigned int i; - for (i = 0; i < s->_raw_size; i++) - { - if (stream[i] != 0) - { - if (! do_with_relocs (abfd, s)) - return false; - return true; - } - } - if (! do_as_repeat (abfd, s)) - return false; - } - - return true; -} - - -static unsigned char *output_ptr_start; -static unsigned char *output_ptr; -static unsigned char *output_ptr_end; -static unsigned char *input_ptr_start; -static unsigned char *input_ptr; -static unsigned char *input_ptr_end; -static bfd *input_bfd; -static bfd *output_bfd; -static int output_buffer; - -static void -fill () -{ - /* FIXME: Check return value. I'm not sure whether it needs to read - the entire buffer or not. */ - bfd_read ((PTR) input_ptr_start, 1, input_ptr_end - input_ptr_start, input_bfd); - input_ptr = input_ptr_start; -} -static void -flush () -{ - if (bfd_write ((PTR) (output_ptr_start), 1, output_ptr - output_ptr_start, - output_bfd) - != (bfd_size_type) (output_ptr - output_ptr_start)) - abort (); - output_ptr = output_ptr_start; - output_buffer++; -} - -#define THIS() ( *input_ptr ) -#define NEXT() { input_ptr++; if (input_ptr == input_ptr_end) fill(); } -#define OUT(x) { *output_ptr++ = (x); if(output_ptr == output_ptr_end) flush(); } - -static void -write_int (value) - int value; -{ - if (value >= 0 && value <= 127) - { - OUT (value); - } - else - { - unsigned int length; - /* How many significant bytes ? */ - /* FIXME FOR LONGER INTS */ - if (value & 0xff000000) - { - length = 4; - } - else if (value & 0x00ff0000) - { - length = 3; - } - else if (value & 0x0000ff00) - { - length = 2; - } - else - length = 1; - - OUT ((int) ieee_number_repeat_start_enum + length); - switch (length) - { - case 4: - OUT (value >> 24); - case 3: - OUT (value >> 16); - case 2: - OUT (value >> 8); - case 1: - OUT (value); - } - - } -} - -static void -copy_id () -{ - int length = THIS (); - char ch; - OUT (length); - NEXT (); - while (length--) - { - ch = THIS (); - OUT (ch); - NEXT (); - } -} - -#define VAR(x) ((x | 0x80)) -static void -copy_expression () -{ - int stack[10]; - int *tos = stack; - int value = 0; - while (1) - { - switch (THIS ()) - { - case 0x84: - NEXT (); - value = THIS (); - NEXT (); - value = (value << 8) | THIS (); - NEXT (); - value = (value << 8) | THIS (); - NEXT (); - value = (value << 8) | THIS (); - NEXT (); - *tos++ = value; - break; - case 0x83: - NEXT (); - value = THIS (); - NEXT (); - value = (value << 8) | THIS (); - NEXT (); - value = (value << 8) | THIS (); - NEXT (); - *tos++ = value; - break; - case 0x82: - NEXT (); - value = THIS (); - NEXT (); - value = (value << 8) | THIS (); - NEXT (); - *tos++ = value; - break; - case 0x81: - NEXT (); - value = THIS (); - NEXT (); - *tos++ = value; - break; - case 0x80: - NEXT (); - *tos++ = 0; - break; - default: - if (THIS () > 0x84) - { - /* Not a number, just bug out with the answer */ - write_int (*(--tos)); - return; - } - *tos++ = THIS (); - NEXT (); - value = 0; - break; - case 0xa5: - /* PLUS anything */ - { - int value = *(--tos); - value += *(--tos); - *tos++ = value; - NEXT (); - } - break; - case VAR ('R'): - { - int section_number; - ieee_data_type *ieee; - asection *s; - NEXT (); - section_number = THIS (); - - NEXT (); - ieee = IEEE_DATA (input_bfd); - s = ieee->section_table[section_number]; - if (s->output_section) - { - value = s->output_section->vma; - } - else - { - value = 0; - } - value += s->output_offset; - *tos++ = value; - value = 0; - } - break; - case 0x90: - { - NEXT (); - write_int (*(--tos)); - OUT (0x90); - return; - - } - } - } - -} - -/* Drop the int in the buffer, and copy a null into the gap, which we - will overwrite later */ - -struct output_buffer_struct -{ - unsigned char *ptrp; - int buffer; -}; - -static void -fill_int (buf) - struct output_buffer_struct *buf; -{ - if (buf->buffer == output_buffer) - { - /* Still a chance to output the size */ - int value = output_ptr - buf->ptrp + 3; - buf->ptrp[0] = value >> 24; - buf->ptrp[1] = value >> 16; - buf->ptrp[2] = value >> 8; - buf->ptrp[3] = value >> 0; - } -} - -static void -drop_int (buf) - struct output_buffer_struct *buf; -{ - int type = THIS (); - int ch; - if (type <= 0x84) - { - NEXT (); - switch (type) - { - case 0x84: - ch = THIS (); - NEXT (); - case 0x83: - ch = THIS (); - NEXT (); - case 0x82: - ch = THIS (); - NEXT (); - case 0x81: - ch = THIS (); - NEXT (); - case 0x80: - break; - } - } - OUT (0x84); - buf->ptrp = output_ptr; - buf->buffer = output_buffer; - OUT (0); - OUT (0); - OUT (0); - OUT (0); -} - -static void -copy_int () -{ - int type = THIS (); - int ch; - if (type <= 0x84) - { - OUT (type); - NEXT (); - switch (type) - { - case 0x84: - ch = THIS (); - NEXT (); - OUT (ch); - case 0x83: - ch = THIS (); - NEXT (); - OUT (ch); - case 0x82: - ch = THIS (); - NEXT (); - OUT (ch); - case 0x81: - ch = THIS (); - NEXT (); - OUT (ch); - case 0x80: - break; - } - } -} - -#define ID copy_id() -#define INT copy_int() -#define EXP copy_expression() -static void copy_till_end (); -#define INTn(q) copy_int() -#define EXPn(q) copy_expression() - -static void -f1_record () -{ - int ch; - /* ATN record */ - NEXT (); - ch = THIS (); - switch (ch) - { - default: - OUT (0xf1); - OUT (ch); - break; - case 0xc9: - NEXT (); - OUT (0xf1); - OUT (0xc9); - INT; - INT; - ch = THIS (); - switch (ch) - { - case 0x16: - NEXT (); - break; - case 0x01: - NEXT (); - break; - case 0x00: - NEXT (); - INT; - break; - case 0x03: - NEXT (); - INT; - break; - case 0x13: - EXPn (instruction address); - break; - default: - break; - } - break; - case 0xd8: - /* EXternal ref */ - NEXT (); - OUT (0xf1); - OUT (0xd8); - EXP; - EXP; - EXP; - EXP; - break; - case 0xce: - NEXT (); - OUT (0xf1); - OUT (0xce); - INT; - INT; - ch = THIS (); - INT; - switch (ch) - { - case 0x01: - INT; - INT; - break; - case 0x02: - INT; - break; - case 0x04: - EXPn (external function); - break; - case 0x05: - break; - case 0x07: - INTn (line number); - INT; - case 0x08: - break; - case 0x0a: - INTn (locked register); - INT; - break; - case 0x3f: - copy_till_end (); - break; - case 0x3e: - copy_till_end (); - break; - case 0x40: - copy_till_end (); - break; - case 0x41: - ID; - break; - } - } - -} - -static void -f0_record () -{ - /* Attribute record */ - NEXT (); - OUT (0xf0); - INTn (Symbol name); - ID; -} - -static void -copy_till_end () -{ - int ch = THIS (); - while (1) - { - while (ch <= 0x80) - { - OUT (ch); - NEXT (); - ch = THIS (); - } - switch (ch) - { - case 0x84: - OUT (THIS ()); - NEXT (); - case 0x83: - OUT (THIS ()); - NEXT (); - case 0x82: - OUT (THIS ()); - NEXT (); - case 0x81: - OUT (THIS ()); - NEXT (); - OUT (THIS ()); - NEXT (); - - ch = THIS (); - break; - default: - return; - } - } - -} - -static void -f2_record () -{ - NEXT (); - OUT (0xf2); - INT; - NEXT (); - OUT (0xce); - INT; - copy_till_end (); -} - - -static void block (); -static void -f8_record () -{ - int ch; - NEXT (); - ch = THIS (); - switch (ch) - { - case 0x01: - case 0x02: - case 0x03: - /* Unique typedefs for module */ - /* GLobal typedefs */ - /* High level module scope beginning */ - { - struct output_buffer_struct ob; - NEXT (); - OUT (0xf8); - OUT (ch); - drop_int (&ob); - ID; - - block (); - - NEXT (); - fill_int (&ob); - OUT (0xf9); - } - break; - case 0x04: - /* Global function */ - { - struct output_buffer_struct ob; - NEXT (); - OUT (0xf8); - OUT (0x04); - drop_int (&ob); - ID; - INTn (stack size); - INTn (ret val); - EXPn (offset); - - block (); - - NEXT (); - OUT (0xf9); - EXPn (size of block); - fill_int (&ob); - } - break; - - case 0x05: - /* File name for source line numbers */ - { - struct output_buffer_struct ob; - NEXT (); - OUT (0xf8); - OUT (0x05); - drop_int (&ob); - ID; - INTn (year); - INTn (month); - INTn (day); - INTn (hour); - INTn (monute); - INTn (second); - block (); - NEXT (); - OUT (0xf9); - fill_int (&ob); - } - break; - - case 0x06: - /* Local function */ - { - struct output_buffer_struct ob; - NEXT (); - OUT (0xf8); - OUT (0x06); - drop_int (&ob); - ID; - INTn (stack size); - INTn (type return); - EXPn (offset); - block (); - NEXT (); - OUT (0xf9); - EXPn (size); - fill_int (&ob); - } - break; - - case 0x0a: - /* Assembler module scope beginning -*/ - { - struct output_buffer_struct ob; - - NEXT (); - OUT (0xf8); - OUT (0x0a); - drop_int (&ob); - ID; - ID; - INT; - ID; - INT; - INT; - INT; - INT; - INT; - INT; - - block (); - - NEXT (); - OUT (0xf9); - fill_int (&ob); - } - break; - case 0x0b: - { - struct output_buffer_struct ob; - NEXT (); - OUT (0xf8); - OUT (0x0b); - drop_int (&ob); - ID; - INT; - INTn (section index); - EXPn (offset); - INTn (stuff); - - block (); - - OUT (0xf9); - NEXT (); - EXPn (Size in Maus); - fill_int (&ob); - } - break; - } -} - -static void -e2_record () -{ - OUT (0xe2); - NEXT (); - OUT (0xce); - NEXT (); - INT; - EXP; -} - -static void -block () -{ - int ch; - while (1) - { - ch = THIS (); - switch (ch) - { - case 0xe1: - case 0xe5: - return; - case 0xf9: - return; - case 0xf0: - f0_record (); - break; - case 0xf1: - f1_record (); - break; - case 0xf2: - f2_record (); - break; - case 0xf8: - f8_record (); - break; - case 0xe2: - e2_record (); - break; - - } - } -} - - - -/* relocate_debug, - moves all the debug information from the source bfd to the output - bfd, and relocates any expressions it finds -*/ - -static void -relocate_debug (output, input) - bfd *output; - bfd *input; -{ -#define IBS 400 -#define OBS 400 - unsigned char input_buffer[IBS]; - - input_ptr_start = input_ptr = input_buffer; - input_ptr_end = input_buffer + IBS; - input_bfd = input; - /* FIXME: Check return value. I'm not sure whether it needs to read - the entire buffer or not. */ - bfd_read ((PTR) input_ptr_start, 1, IBS, input); - block (); -} - -/* - During linking, we we told about the bfds which made up our - contents, we have a list of them. They will still be open, so go to - the debug info in each, and copy it out, relocating it as we go. -*/ - -static boolean -ieee_write_debug_part (abfd) - bfd *abfd; -{ - ieee_data_type *ieee = IEEE_DATA (abfd); - bfd_chain_type *chain = ieee->chain_root; - unsigned char output_buffer[OBS]; - boolean some_debug = false; - file_ptr here = bfd_tell (abfd); - - output_ptr_start = output_ptr = output_buffer; - output_ptr_end = output_buffer + OBS; - output_ptr = output_buffer; - output_bfd = abfd; - - if (chain == (bfd_chain_type *) NULL) - { - asection *s; - - for (s = abfd->sections; s != NULL; s = s->next) - if ((s->flags & SEC_DEBUGGING) != 0) - break; - if (s == NULL) - { - ieee->w.r.debug_information_part = 0; - return true; - } - - ieee->w.r.debug_information_part = here; - if (bfd_write (s->contents, 1, s->_raw_size, abfd) != s->_raw_size) - return false; - } - else - { - while (chain != (bfd_chain_type *) NULL) - { - bfd *entry = chain->this; - ieee_data_type *entry_ieee = IEEE_DATA (entry); - if (entry_ieee->w.r.debug_information_part) - { - if (bfd_seek (entry, entry_ieee->w.r.debug_information_part, - SEEK_SET) - != 0) - return false; - relocate_debug (abfd, entry); - } - - chain = chain->next; - } - if (some_debug) - { - ieee->w.r.debug_information_part = here; - } - else - { - ieee->w.r.debug_information_part = 0; - } - - flush (); - } - - return true; -} - -/* Write the data in an ieee way. */ - -static boolean -ieee_write_data_part (abfd) - bfd *abfd; -{ - asection *s; - ieee_data_type *ieee = IEEE_DATA (abfd); - ieee->w.r.data_part = bfd_tell (abfd); - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - /* Skip sections that have no loadable contents (.bss, - debugging, etc.) */ - if ((s->flags & SEC_LOAD) == 0) - continue; - - /* Sort the reloc records so we can insert them in the correct - places */ - if (s->reloc_count != 0) - { - if (! do_with_relocs (abfd, s)) - return false; - } - else - { - if (! do_without_relocs (abfd, s)) - return false; - } - } - - return true; -} - - -static boolean -init_for_output (abfd) - bfd *abfd; -{ - asection *s; - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - if ((s->flags & SEC_DEBUGGING) != 0) - continue; - if (s->_raw_size != 0) - { - ieee_per_section (s)->data = (bfd_byte *) (bfd_alloc (abfd, s->_raw_size)); - if (!ieee_per_section (s)->data) - return false; - } - } - return true; -} - -/** exec and core file sections */ - -/* set section contents is complicated with IEEE since the format is -* not a byte image, but a record stream. -*/ -boolean -ieee_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if ((section->flags & SEC_DEBUGGING) != 0) - { - if (section->contents == NULL) - { - section->contents = bfd_alloc (abfd, section->_raw_size); - if (section->contents == NULL) - return false; - } - /* bfd_set_section_contents has already checked that everything - is within range. */ - memcpy (section->contents + offset, location, count); - return true; - } - - if (ieee_per_section (section)->data == (bfd_byte *) NULL) - { - if (!init_for_output (abfd)) - return false; - } - memcpy ((PTR) (ieee_per_section (section)->data + offset), - (PTR) location, - (unsigned int) count); - return true; -} - -/* Write the external symbols of a file. IEEE considers two sorts of - external symbols, public, and referenced. It uses to internal - forms to index them as well. When we write them out we turn their - symbol values into indexes from the right base. */ - -static boolean -ieee_write_external_part (abfd) - bfd *abfd; -{ - asymbol **q; - ieee_data_type *ieee = IEEE_DATA (abfd); - - unsigned int reference_index = IEEE_REFERENCE_BASE; - unsigned int public_index = IEEE_PUBLIC_BASE + 2; - file_ptr here = bfd_tell (abfd); - boolean hadone = false; - if (abfd->outsymbols != (asymbol **) NULL) - { - - for (q = abfd->outsymbols; *q != (asymbol *) NULL; q++) - { - asymbol *p = *q; - hadone = true; - if (bfd_is_und_section (p->section)) - { - /* This must be a symbol reference .. */ - if (! ieee_write_byte (abfd, ieee_external_reference_enum) - || ! ieee_write_int (abfd, reference_index) - || ! ieee_write_id (abfd, p->name)) - return false; - p->value = reference_index; - reference_index++; - } - else if (bfd_is_com_section (p->section)) - { - /* This is a weak reference */ - if (! ieee_write_byte (abfd, ieee_external_reference_enum) - || ! ieee_write_int (abfd, reference_index) - || ! ieee_write_id (abfd, p->name) - || ! ieee_write_byte (abfd, - ieee_weak_external_reference_enum) - || ! ieee_write_int (abfd, reference_index) - || ! ieee_write_int (abfd, p->value)) - return false; - p->value = reference_index; - reference_index++; - } - else if (p->flags & BSF_GLOBAL) - { - /* This must be a symbol definition */ - - if (! ieee_write_byte (abfd, ieee_external_symbol_enum) - || ! ieee_write_int (abfd, public_index) - || ! ieee_write_id (abfd, p->name) - || ! ieee_write_2bytes (abfd, ieee_attribute_record_enum) - || ! ieee_write_int (abfd, public_index) - || ! ieee_write_byte (abfd, 15) /* instruction address */ - || ! ieee_write_byte (abfd, 19) /* static symbol */ - || ! ieee_write_byte (abfd, 1)) /* one of them */ - return false; - - /* Write out the value */ - if (! ieee_write_2bytes (abfd, ieee_value_record_enum) - || ! ieee_write_int (abfd, public_index)) - return false; - if (! bfd_is_abs_section (p->section)) - { - if (abfd->flags & EXEC_P) - { - /* If fully linked, then output all symbols - relocated */ - if (! (ieee_write_int - (abfd, - (p->value - + p->section->output_offset - + p->section->output_section->vma)))) - return false; - } - else - { - if (! (ieee_write_expression - (abfd, - p->value + p->section->output_offset, - p->section->output_section->symbol, - false, 0))) - return false; - } - } - else - { - if (! ieee_write_expression (abfd, - p->value, - bfd_abs_section_ptr->symbol, - false, 0)) - return false; - } - p->value = public_index; - public_index++; - } - else - { - /* This can happen - when there are gaps in the symbols read */ - /* from an input ieee file */ - } - } - } - if (hadone) - ieee->w.r.external_part = here; - - return true; -} - - -static CONST unsigned char exten[] = -{ - 0xf0, 0x20, 0x00, - 0xf1, 0xce, 0x20, 0x00, 37, 3, 3, /* Set version 3 rev 3 */ - 0xf1, 0xce, 0x20, 0x00, 39, 2,/* keep symbol in original case */ - 0xf1, 0xce, 0x20, 0x00, 38 /* set object type relocateable to x */ -}; - -static CONST unsigned char envi[] = -{ - 0xf0, 0x21, 0x00, - -/* 0xf1, 0xce, 0x21, 00, 50, 0x82, 0x07, 0xc7, 0x09, 0x11, 0x11, - 0x19, 0x2c, -*/ - 0xf1, 0xce, 0x21, 00, 52, 0x00, /* exec ok */ - - 0xf1, 0xce, 0x21, 0, 53, 0x03,/* host unix */ -/* 0xf1, 0xce, 0x21, 0, 54, 2,1,1 tool & version # */ -}; - -static boolean -ieee_write_me_part (abfd) - bfd *abfd; -{ - ieee_data_type *ieee = IEEE_DATA (abfd); - ieee->w.r.trailer_part = bfd_tell (abfd); - if (abfd->start_address) - { - if (! ieee_write_2bytes (abfd, ieee_value_starting_address_enum) - || ! ieee_write_byte (abfd, ieee_function_either_open_b_enum) - || ! ieee_write_int (abfd, abfd->start_address) - || ! ieee_write_byte (abfd, ieee_function_either_close_b_enum)) - return false; - } - ieee->w.r.me_record = bfd_tell (abfd); - if (! ieee_write_byte (abfd, ieee_module_end_enum)) - return false; - return true; -} - -/* Write out the IEEE processor ID. */ - -static boolean -ieee_write_processor (abfd) - bfd *abfd; -{ - const bfd_arch_info_type *arch; - - arch = bfd_get_arch_info (abfd); - switch (arch->arch) - { - default: - if (! ieee_write_id (abfd, bfd_printable_name (abfd))) - return false; - break; - - case bfd_arch_a29k: - if (! ieee_write_id (abfd, "29000")) - return false; - break; - - case bfd_arch_h8300: - if (! ieee_write_id (abfd, "H8/300")) - return false; - break; - - case bfd_arch_h8500: - if (! ieee_write_id (abfd, "H8/500")) - return false; - break; - - case bfd_arch_i960: - switch (arch->mach) - { - default: - case bfd_mach_i960_core: - case bfd_mach_i960_ka_sa: - if (! ieee_write_id (abfd, "80960KA")) - return false; - break; - - case bfd_mach_i960_kb_sb: - if (! ieee_write_id (abfd, "80960KB")) - return false; - break; - - case bfd_mach_i960_ca: - if (! ieee_write_id (abfd, "80960CA")) - return false; - break; - - case bfd_mach_i960_mc: - case bfd_mach_i960_xa: - if (! ieee_write_id (abfd, "80960MC")) - return false; - break; - } - break; - - case bfd_arch_m68k: - { - char ab[20]; - - sprintf (ab, "%lu", arch->mach); - if (! ieee_write_id (abfd, ab)) - return false; - } - break; - } - - return true; -} - -boolean -ieee_write_object_contents (abfd) - bfd *abfd; -{ - ieee_data_type *ieee = IEEE_DATA (abfd); - unsigned int i; - file_ptr old; - - /* Fast forward over the header area */ - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - return false; - - if (! ieee_write_byte (abfd, ieee_module_beginning_enum) - || ! ieee_write_processor (abfd) - || ! ieee_write_id (abfd, abfd->filename)) - return false; - - /* Fast forward over the variable bits */ - if (! ieee_write_byte (abfd, ieee_address_descriptor_enum)) - return false; - - /* Bits per MAU */ - if (! ieee_write_byte (abfd, (bfd_byte) (bfd_arch_bits_per_byte (abfd)))) - return false; - /* MAU's per address */ - if (! ieee_write_byte (abfd, - (bfd_byte) (bfd_arch_bits_per_address (abfd) - / bfd_arch_bits_per_byte (abfd)))) - return false; - - old = bfd_tell (abfd); - if (bfd_seek (abfd, (file_ptr) (8 * N_W_VARIABLES), SEEK_CUR) != 0) - return false; - - ieee->w.r.extension_record = bfd_tell (abfd); - if (bfd_write ((char *) exten, 1, sizeof (exten), abfd) != sizeof (exten)) - return false; - if (abfd->flags & EXEC_P) - { - if (! ieee_write_byte (abfd, 0x1)) /* Absolute */ - return false; - } - else - { - if (! ieee_write_byte (abfd, 0x2)) /* Relocateable */ - return false; - } - - ieee->w.r.environmental_record = bfd_tell (abfd); - if (bfd_write ((char *) envi, 1, sizeof (envi), abfd) != sizeof (envi)) - return false; - output_bfd = abfd; - - flush (); - - if (! ieee_write_section_part (abfd)) - return false; - /* First write the symbols. This changes their values into table - indeces so we cant use it after this point. */ - if (! ieee_write_external_part (abfd)) - return false; - - /* ieee_write_byte(abfd, ieee_record_seperator_enum);*/ - - /* ieee_write_byte(abfd, ieee_record_seperator_enum);*/ - - - /* Write any debugs we have been told about. */ - if (! ieee_write_debug_part (abfd)) - return false; - - /* Can only write the data once the symbols have been written, since - the data contains relocation information which points to the - symbols. */ - if (! ieee_write_data_part (abfd)) - return false; - - /* At the end we put the end! */ - if (! ieee_write_me_part (abfd)) - return false; - - /* Generate the header */ - if (bfd_seek (abfd, old, SEEK_SET) != 0) - return false; - - for (i = 0; i < N_W_VARIABLES; i++) - { - if (! ieee_write_2bytes (abfd, ieee_assign_value_to_variable_enum) - || ! ieee_write_byte (abfd, (bfd_byte) i) - || ! ieee_write_int5_out (abfd, ieee->w.offset[i])) - return false; - } - - return true; -} - -/* Native-level interface to symbols. */ - -/* We read the symbols into a buffer, which is discarded when this - function exits. We read the strings into a buffer large enough to - hold them all plus all the cached symbol entries. */ - -asymbol * -ieee_make_empty_symbol (abfd) - bfd *abfd; -{ - ieee_symbol_type *new = - (ieee_symbol_type *) bfd_zmalloc (sizeof (ieee_symbol_type)); - if (!new) - return NULL; - new->symbol.the_bfd = abfd; - return &new->symbol; -} - -static bfd * -ieee_openr_next_archived_file (arch, prev) - bfd *arch; - bfd *prev; -{ - ieee_ar_data_type *ar = IEEE_AR_DATA (arch); - /* take the next one from the arch state, or reset */ - if (prev == (bfd *) NULL) - { - /* Reset the index - the first two entries are bogus*/ - ar->element_index = 2; - } - while (true) - { - ieee_ar_obstack_type *p = ar->elements + ar->element_index; - ar->element_index++; - if (ar->element_index <= ar->element_count) - { - if (p->file_offset != (file_ptr) 0) - { - if (p->abfd == (bfd *) NULL) - { - p->abfd = _bfd_create_empty_archive_element_shell (arch); - p->abfd->origin = p->file_offset; - } - return p->abfd; - } - } - else - { - bfd_set_error (bfd_error_no_more_archived_files); - return (bfd *) NULL; - } - - } -} - -static boolean -ieee_find_nearest_line (abfd, - section, - symbols, - offset, - filename_ptr, - functionname_ptr, - line_ptr) - bfd *abfd; - asection *section; - asymbol **symbols; - bfd_vma offset; - char **filename_ptr; - char **functionname_ptr; - int *line_ptr; -{ - return false; -} - -static int -ieee_generic_stat_arch_elt (abfd, buf) - bfd *abfd; - struct stat *buf; -{ - ieee_ar_data_type *ar = abfd->my_archive->tdata.ieee_ar_data; - if (ar == (ieee_ar_data_type *) NULL) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - else if (ieee_object_p (abfd)) - { - ieee_data_type *ieee = IEEE_DATA (abfd); - - buf->st_size = ieee->w.r.me_record + 1; - buf->st_mode = 0644; - return 0; - } - else - return -1; -} - -static int -ieee_sizeof_headers (abfd, x) - bfd *abfd; - boolean x; -{ - return 0; -} - - -/* The debug info routines are never used. */ -#if 0 - -static void -ieee_bfd_debug_info_start (abfd) - bfd *abfd; -{ - -} - -static void -ieee_bfd_debug_info_end (abfd) - bfd *abfd; -{ - -} - - -/* Add this section to the list of sections we have debug info for, to - be ready to output it at close time - */ -static void -ieee_bfd_debug_info_accumulate (abfd, section) - bfd *abfd; - asection *section; -{ - ieee_data_type *ieee = IEEE_DATA (section->owner); - ieee_data_type *output_ieee = IEEE_DATA (abfd); - /* can only accumulate data from other ieee bfds */ - if (section->owner->xvec != abfd->xvec) - return; - /* Only bother once per bfd */ - if (ieee->done_debug == true) - return; - ieee->done_debug = true; - - /* Don't bother if there is no debug info */ - if (ieee->w.r.debug_information_part == 0) - return; - - - /* Add to chain */ - { - bfd_chain_type *n = (bfd_chain_type *) bfd_alloc (abfd, sizeof (bfd_chain_type)); - if (!n) - abort (); /* FIXME */ - n->this = section->owner; - n->next = (bfd_chain_type *) NULL; - - if (output_ieee->chain_head) - { - output_ieee->chain_head->next = n; - } - else - { - output_ieee->chain_root = n; - - } - output_ieee->chain_head = n; - } -} - -#endif - -#define ieee_close_and_cleanup _bfd_generic_close_and_cleanup -#define ieee_bfd_free_cached_info _bfd_generic_bfd_free_cached_info - -#define ieee_slurp_armap bfd_true -#define ieee_slurp_extended_name_table bfd_true -#define ieee_construct_extended_name_table \ - ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \ - bfd_true) -#define ieee_truncate_arname bfd_dont_truncate_arname -#define ieee_write_armap \ - ((boolean (*) \ - PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \ - bfd_true) -#define ieee_read_ar_hdr bfd_nullvoidptr -#define ieee_update_armap_timestamp bfd_true -#define ieee_get_elt_at_index _bfd_generic_get_elt_at_index - -#define ieee_bfd_is_local_label bfd_generic_is_local_label -#define ieee_get_lineno _bfd_nosymbols_get_lineno -#define ieee_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define ieee_read_minisymbols _bfd_generic_read_minisymbols -#define ieee_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol - -#define ieee_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup - -#define ieee_set_arch_mach _bfd_generic_set_arch_mach - -#define ieee_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window -#define ieee_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define ieee_bfd_relax_section bfd_generic_relax_section -#define ieee_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define ieee_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define ieee_bfd_final_link _bfd_generic_final_link -#define ieee_bfd_link_split_section _bfd_generic_link_split_section - -/*SUPPRESS 460 */ -const bfd_target ieee_vec = -{ - "ieee", /* name */ - bfd_target_ieee_flavour, - BFD_ENDIAN_UNKNOWN, /* target byte order */ - BFD_ENDIAN_UNKNOWN, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, - ieee_object_p, /* bfd_check_format */ - ieee_archive_p, - _bfd_dummy_target, - }, - { - bfd_false, - ieee_mkobject, - _bfd_generic_mkarchive, - bfd_false - }, - { - bfd_false, - ieee_write_object_contents, - _bfd_write_archive_contents, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (ieee), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (ieee), - BFD_JUMP_TABLE_SYMBOLS (ieee), - BFD_JUMP_TABLE_RELOCS (ieee), - BFD_JUMP_TABLE_WRITE (ieee), - BFD_JUMP_TABLE_LINK (ieee), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; diff --git a/contrib/gdb/bfd/irix-core.c b/contrib/gdb/bfd/irix-core.c deleted file mode 100644 index 3fd3977..0000000 --- a/contrib/gdb/bfd/irix-core.c +++ /dev/null @@ -1,263 +0,0 @@ -/* BFD back-end for Irix core files. - Copyright 1993, 1994 Free Software Foundation, Inc. - Written by Stu Grossman, Cygnus Support. - Converted to back-end form by Ian Lance Taylor, Cygnus Support - -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 can only be compiled on systems which use Irix style core - files (namely, Irix 4 and Irix 5, so far). */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#ifdef IRIX_CORE - -#include <core.out.h> - -struct sgi_core_struct -{ - int sig; - char cmd[CORE_NAMESIZE]; -}; - -#define core_hdr(bfd) ((bfd)->tdata.sgi_core_data) -#define core_signal(bfd) (core_hdr(bfd)->sig) -#define core_command(bfd) (core_hdr(bfd)->cmd) - -static asection * -make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos) - bfd *abfd; - CONST char *name; - flagword flags; - bfd_size_type _raw_size; - bfd_vma vma; - file_ptr filepos; -{ - asection *asect; - - asect = bfd_make_section_anyway (abfd, name); - if (!asect) - return NULL; - - asect->flags = flags; - asect->_raw_size = _raw_size; - asect->vma = vma; - asect->filepos = filepos; - asect->alignment_power = 4; - - return asect; -} - -static const bfd_target * -irix_core_core_file_p (abfd) - bfd *abfd; -{ - int val; - int i; - char *secname; - struct coreout coreout; - struct idesc *idg, *idf, *ids; - - val = bfd_read ((PTR)&coreout, 1, sizeof coreout, abfd); - if (val != sizeof coreout) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - if (coreout.c_magic != CORE_MAGIC - || coreout.c_version != CORE_VERSION1) - return 0; - - core_hdr (abfd) = (struct sgi_core_struct *) bfd_zalloc (abfd, sizeof (struct sgi_core_struct)); - if (!core_hdr (abfd)) - return NULL; - - strncpy (core_command (abfd), coreout.c_name, CORE_NAMESIZE); - core_signal (abfd) = coreout.c_sigcause; - - if (bfd_seek (abfd, coreout.c_vmapoffset, SEEK_SET) != 0) - return NULL; - - for (i = 0; i < coreout.c_nvmap; i++) - { - struct vmap vmap; - - val = bfd_read ((PTR)&vmap, 1, sizeof vmap, abfd); - if (val != sizeof vmap) - break; - - switch (vmap.v_type) - { - case VDATA: - secname = ".data"; - break; - case VSTACK: - secname = ".stack"; - break; -#ifdef VMAPFILE - case VMAPFILE: - secname = ".mapfile"; - break; -#endif - default: - continue; - } - - /* A file offset of zero means that the section is not contained - in the corefile. */ - if (vmap.v_offset == 0) - continue; - - if (!make_bfd_asection (abfd, secname, - SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS, - vmap.v_len, - vmap.v_vaddr, - vmap.v_offset, - 2)) - return NULL; - } - - /* Make sure that the regs are contiguous within the core file. */ - - idg = &coreout.c_idesc[I_GPREGS]; - idf = &coreout.c_idesc[I_FPREGS]; - ids = &coreout.c_idesc[I_SPECREGS]; - - if (idg->i_offset + idg->i_len != idf->i_offset - || idf->i_offset + idf->i_len != ids->i_offset) - return 0; /* Can't deal with non-contig regs */ - - if (bfd_seek (abfd, idg->i_offset, SEEK_SET) != 0) - return NULL; - - make_bfd_asection (abfd, ".reg", - SEC_HAS_CONTENTS, - idg->i_len + idf->i_len + ids->i_len, - 0, - idg->i_offset); - - /* OK, we believe you. You're a core file (sure, sure). */ - - return abfd->xvec; -} - -static char * -irix_core_core_file_failing_command (abfd) - bfd *abfd; -{ - return core_command (abfd); -} - -static int -irix_core_core_file_failing_signal (abfd) - bfd *abfd; -{ - return core_signal (abfd); -} - -static boolean -irix_core_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - return true; /* XXX - FIXME */ -} - -static asymbol * -irix_core_make_empty_symbol (abfd) - bfd *abfd; -{ - asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol)); - if (new) - new->the_bfd = abfd; - return new; -} - -#define irix_core_get_symtab_upper_bound _bfd_nosymbols_get_symtab_upper_bound -#define irix_core_get_symtab _bfd_nosymbols_get_symtab -#define irix_core_print_symbol _bfd_nosymbols_print_symbol -#define irix_core_get_symbol_info _bfd_nosymbols_get_symbol_info -#define irix_core_bfd_is_local_label _bfd_nosymbols_bfd_is_local_label -#define irix_core_get_lineno _bfd_nosymbols_get_lineno -#define irix_core_find_nearest_line _bfd_nosymbols_find_nearest_line -#define irix_core_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define irix_core_read_minisymbols _bfd_nosymbols_read_minisymbols -#define irix_core_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol - -/* If somebody calls any byte-swapping routines, shoot them. */ -void -swap_abort() -{ - abort(); /* This way doesn't require any declaration for ANSI to fuck up */ -} -#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort ) -#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort ) -#define NO_SIGNED_GET \ - ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort ) - -const bfd_target irix_core_vec = - { - "irix-core", - bfd_target_unknown_flavour, - BFD_ENDIAN_BIG, /* target byte order */ - BFD_ENDIAN_BIG, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* symbol prefix */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */ - - { /* bfd_check_format */ - _bfd_dummy_target, /* unknown format */ - _bfd_dummy_target, /* object file */ - _bfd_dummy_target, /* archive */ - irix_core_core_file_p /* a core file */ - }, - { /* bfd_set_format */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - { /* bfd_write_contents */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (irix_core), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (irix_core), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (_bfd_generic), - BFD_JUMP_TABLE_LINK (_bfd_nolink), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 /* backend_data */ -}; - -#endif /* IRIX_CORE */ diff --git a/contrib/gdb/bfd/libbfd-in.h b/contrib/gdb/bfd/libbfd-in.h deleted file mode 100644 index 14935eb..0000000 --- a/contrib/gdb/bfd/libbfd-in.h +++ /dev/null @@ -1,503 +0,0 @@ -/* libbfd.h -- Declarations used by bfd library *implementation*. - (This include file is not for users of the library.) - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -** NOTE: libbfd.h is a GENERATED file. Don't change it; instead, -** change libbfd-in.h or the other BFD source files processed to -** generate this file. - -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. */ - -/* Align an address upward to a boundary, expressed as a number of bytes. - E.g. align to an 8-byte boundary with argument of 8. */ -#define BFD_ALIGN(this, boundary) \ - ((( (this) + ((boundary) -1)) & (~((boundary)-1)))) - -/* If you want to read and write large blocks, you might want to do it - in quanta of this amount */ -#define DEFAULT_BUFFERSIZE 8192 - -/* Set a tdata field. Can't use the other macros for this, since they - do casts, and casting to the left of assignment isn't portable. */ -#define set_tdata(bfd, v) ((bfd)->tdata.any = (PTR) (v)) - -/* If BFD_IN_MEMORY is set for a BFD, then the iostream fields points - to an instance of this structure. */ - -struct bfd_in_memory -{ - /* Size of buffer. */ - bfd_size_type size; - /* Buffer holding contents of BFD. */ - bfd_byte *buffer; -}; - -/* tdata for an archive. For an input archive, cache - needs to be free()'d. For an output archive, symdefs do. */ - -struct artdata { - file_ptr first_file_filepos; - /* Speed up searching the armap */ - struct ar_cache *cache; - bfd *archive_head; /* Only interesting in output routines */ - carsym *symdefs; /* the symdef entries */ - symindex symdef_count; /* how many there are */ - char *extended_names; /* clever intel extension */ - /* when more compilers are standard C, this can be a time_t */ - long armap_timestamp; /* Timestamp value written into armap. - This is used for BSD archives to check - that the timestamp is recent enough - for the BSD linker to not complain, - just before we finish writing an - archive. */ - file_ptr armap_datepos; /* Position within archive to seek to - rewrite the date field. */ - PTR tdata; /* Backend specific information. */ -}; - -#define bfd_ardata(bfd) ((bfd)->tdata.aout_ar_data) - -/* Goes in bfd's arelt_data slot */ -struct areltdata { - char * arch_header; /* it's actually a string */ - unsigned int parsed_size; /* octets of filesize not including ar_hdr */ - char *filename; /* null-terminated */ -}; - -#define arelt_size(bfd) (((struct areltdata *)((bfd)->arelt_data))->parsed_size) - -extern PTR bfd_malloc PARAMS ((size_t)); -extern PTR bfd_realloc PARAMS ((PTR, size_t)); -extern PTR bfd_zmalloc PARAMS ((size_t)); - -extern bfd_error_handler_type _bfd_error_handler; - -/* These routines allocate and free things on the BFD's obstack. */ - -PTR bfd_alloc PARAMS ((bfd *abfd, size_t size)); -PTR bfd_zalloc PARAMS ((bfd *abfd, size_t size)); -void bfd_alloc_grow PARAMS ((bfd *abfd, PTR thing, size_t size)); -PTR bfd_alloc_finish PARAMS ((bfd *abfd)); -PTR bfd_alloc_by_size_t PARAMS ((bfd *abfd, size_t wanted)); - -#define bfd_release(x,y) (void) obstack_free(&(x->memory),y) - -bfd * _bfd_create_empty_archive_element_shell PARAMS ((bfd *obfd)); -bfd * _bfd_look_for_bfd_in_cache PARAMS ((bfd *arch_bfd, file_ptr index)); -boolean _bfd_add_bfd_to_archive_cache PARAMS ((bfd *, file_ptr, bfd *)); -boolean _bfd_generic_mkarchive PARAMS ((bfd *abfd)); -const bfd_target *bfd_generic_archive_p PARAMS ((bfd *abfd)); -boolean bfd_slurp_armap PARAMS ((bfd *abfd)); -boolean bfd_slurp_bsd_armap_f2 PARAMS ((bfd *abfd)); -#define bfd_slurp_bsd_armap bfd_slurp_armap -#define bfd_slurp_coff_armap bfd_slurp_armap -boolean _bfd_slurp_extended_name_table PARAMS ((bfd *abfd)); -extern boolean _bfd_construct_extended_name_table - PARAMS ((bfd *, boolean, char **, bfd_size_type *)); -boolean _bfd_write_archive_contents PARAMS ((bfd *abfd)); -boolean _bfd_compute_and_write_armap PARAMS ((bfd *, unsigned int elength)); -bfd *_bfd_get_elt_at_filepos PARAMS ((bfd *archive, file_ptr filepos)); -extern bfd *_bfd_generic_get_elt_at_index PARAMS ((bfd *, symindex)); -bfd * _bfd_new_bfd PARAMS ((void)); - -boolean bfd_false PARAMS ((bfd *ignore)); -boolean bfd_true PARAMS ((bfd *ignore)); -PTR bfd_nullvoidptr PARAMS ((bfd *ignore)); -int bfd_0 PARAMS ((bfd *ignore)); -unsigned int bfd_0u PARAMS ((bfd *ignore)); -long bfd_0l PARAMS ((bfd *ignore)); -long _bfd_n1 PARAMS ((bfd *ignore)); -void bfd_void PARAMS ((bfd *ignore)); - -bfd *_bfd_new_bfd_contained_in PARAMS ((bfd *)); -const bfd_target *_bfd_dummy_target PARAMS ((bfd *abfd)); - -void bfd_dont_truncate_arname PARAMS ((bfd *abfd, CONST char *filename, - char *hdr)); -void bfd_bsd_truncate_arname PARAMS ((bfd *abfd, CONST char *filename, - char *hdr)); -void bfd_gnu_truncate_arname PARAMS ((bfd *abfd, CONST char *filename, - char *hdr)); - -boolean bsd_write_armap PARAMS ((bfd *arch, unsigned int elength, - struct orl *map, unsigned int orl_count, int stridx)); - -boolean coff_write_armap PARAMS ((bfd *arch, unsigned int elength, - struct orl *map, unsigned int orl_count, int stridx)); - -extern PTR _bfd_generic_read_ar_hdr PARAMS ((bfd *)); - -extern PTR _bfd_generic_read_ar_hdr_mag PARAMS ((bfd *, const char *)); - -bfd * bfd_generic_openr_next_archived_file PARAMS ((bfd *archive, - bfd *last_file)); - -int bfd_generic_stat_arch_elt PARAMS ((bfd *, struct stat *)); - -#define _bfd_read_ar_hdr(abfd) \ - BFD_SEND (abfd, _bfd_read_ar_hdr_fn, (abfd)) - -/* Generic routines to use for BFD_JUMP_TABLE_GENERIC. Use - BFD_JUMP_TABLE_GENERIC (_bfd_generic). */ - -#define _bfd_generic_close_and_cleanup bfd_true -#define _bfd_generic_bfd_free_cached_info bfd_true -#define _bfd_generic_new_section_hook \ - ((boolean (*) PARAMS ((bfd *, asection *))) bfd_true) -extern boolean _bfd_generic_get_section_contents - PARAMS ((bfd *, asection *, PTR location, file_ptr offset, - bfd_size_type count)); -extern boolean _bfd_generic_get_section_contents_in_window - PARAMS ((bfd *, asection *, bfd_window *, file_ptr, bfd_size_type)); - -/* Generic routines to use for BFD_JUMP_TABLE_COPY. Use - BFD_JUMP_TABLE_COPY (_bfd_generic). */ - -#define _bfd_generic_bfd_copy_private_bfd_data \ - ((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true) -#define _bfd_generic_bfd_merge_private_bfd_data \ - ((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true) -#define _bfd_generic_bfd_set_private_flags \ - ((boolean (*) PARAMS ((bfd *, flagword))) bfd_true) -#define _bfd_generic_bfd_copy_private_section_data \ - ((boolean (*) PARAMS ((bfd *, asection *, bfd *, asection *))) bfd_true) -#define _bfd_generic_bfd_copy_private_symbol_data \ - ((boolean (*) PARAMS ((bfd *, asymbol *, bfd *, asymbol *))) bfd_true) -#define _bfd_generic_bfd_print_private_bfd_data \ - ((boolean (*) PARAMS ((bfd *, PTR))) bfd_true) - -/* Routines to use for BFD_JUMP_TABLE_CORE when there is no core file - support. Use BFD_JUMP_TABLE_CORE (_bfd_nocore). */ - -extern char *_bfd_nocore_core_file_failing_command PARAMS ((bfd *)); -extern int _bfd_nocore_core_file_failing_signal PARAMS ((bfd *)); -extern boolean _bfd_nocore_core_file_matches_executable_p - PARAMS ((bfd *, bfd *)); - -/* Routines to use for BFD_JUMP_TABLE_ARCHIVE when there is no archive - file support. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive). */ - -#define _bfd_noarchive_slurp_armap bfd_false -#define _bfd_noarchive_slurp_extended_name_table bfd_false -#define _bfd_noarchive_construct_extended_name_table \ - ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \ - bfd_false) -#define _bfd_noarchive_truncate_arname \ - ((void (*) PARAMS ((bfd *, const char *, char *))) bfd_void) -#define _bfd_noarchive_write_armap \ - ((boolean (*) \ - PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \ - bfd_false) -#define _bfd_noarchive_read_ar_hdr bfd_nullvoidptr -#define _bfd_noarchive_openr_next_archived_file \ - ((bfd *(*) PARAMS ((bfd *, bfd *))) bfd_nullvoidptr) -#define _bfd_noarchive_get_elt_at_index \ - ((bfd *(*) PARAMS ((bfd *, symindex))) bfd_nullvoidptr) -#define _bfd_noarchive_generic_stat_arch_elt bfd_generic_stat_arch_elt -#define _bfd_noarchive_update_armap_timestamp bfd_false - -/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get BSD style - archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd). */ - -#define _bfd_archive_bsd_slurp_armap bfd_slurp_bsd_armap -#define _bfd_archive_bsd_slurp_extended_name_table \ - _bfd_slurp_extended_name_table -extern boolean _bfd_archive_bsd_construct_extended_name_table - PARAMS ((bfd *, char **, bfd_size_type *, const char **)); -#define _bfd_archive_bsd_truncate_arname bfd_bsd_truncate_arname -#define _bfd_archive_bsd_write_armap bsd_write_armap -#define _bfd_archive_bsd_read_ar_hdr _bfd_generic_read_ar_hdr -#define _bfd_archive_bsd_openr_next_archived_file \ - bfd_generic_openr_next_archived_file -#define _bfd_archive_bsd_get_elt_at_index _bfd_generic_get_elt_at_index -#define _bfd_archive_bsd_generic_stat_arch_elt \ - bfd_generic_stat_arch_elt -extern boolean _bfd_archive_bsd_update_armap_timestamp PARAMS ((bfd *)); - -/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get COFF style - archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff). */ - -#define _bfd_archive_coff_slurp_armap bfd_slurp_coff_armap -#define _bfd_archive_coff_slurp_extended_name_table \ - _bfd_slurp_extended_name_table -extern boolean _bfd_archive_coff_construct_extended_name_table - PARAMS ((bfd *, char **, bfd_size_type *, const char **)); -#define _bfd_archive_coff_truncate_arname bfd_dont_truncate_arname -#define _bfd_archive_coff_write_armap coff_write_armap -#define _bfd_archive_coff_read_ar_hdr _bfd_generic_read_ar_hdr -#define _bfd_archive_coff_openr_next_archived_file \ - bfd_generic_openr_next_archived_file -#define _bfd_archive_coff_get_elt_at_index _bfd_generic_get_elt_at_index -#define _bfd_archive_coff_generic_stat_arch_elt \ - bfd_generic_stat_arch_elt -#define _bfd_archive_coff_update_armap_timestamp bfd_true - -/* Routines to use for BFD_JUMP_TABLE_SYMBOLS where there is no symbol - support. Use BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols). */ - -#define _bfd_nosymbols_get_symtab_upper_bound _bfd_n1 -#define _bfd_nosymbols_get_symtab \ - ((long (*) PARAMS ((bfd *, asymbol **))) _bfd_n1) -#define _bfd_nosymbols_make_empty_symbol \ - ((asymbol *(*) PARAMS ((bfd *))) bfd_nullvoidptr) -#define _bfd_nosymbols_print_symbol \ - ((void (*) PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type))) bfd_void) -#define _bfd_nosymbols_get_symbol_info \ - ((void (*) PARAMS ((bfd *, asymbol *, symbol_info *))) bfd_void) -#define _bfd_nosymbols_bfd_is_local_label \ - ((boolean (*) PARAMS ((bfd *, asymbol *))) bfd_false) -#define _bfd_nosymbols_get_lineno \ - ((alent *(*) PARAMS ((bfd *, asymbol *))) bfd_nullvoidptr) -#define _bfd_nosymbols_find_nearest_line \ - ((boolean (*) \ - PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **, \ - const char **, unsigned int *))) \ - bfd_false) -#define _bfd_nosymbols_bfd_make_debug_symbol \ - ((asymbol *(*) PARAMS ((bfd *, PTR, unsigned long))) bfd_nullvoidptr) -#define _bfd_nosymbols_read_minisymbols \ - ((long (*) PARAMS ((bfd *, boolean, PTR *, unsigned int *))) _bfd_n1) -#define _bfd_nosymbols_minisymbol_to_symbol \ - ((asymbol *(*) PARAMS ((bfd *, boolean, const PTR, asymbol *))) \ - bfd_nullvoidptr) - -/* Routines to use for BFD_JUMP_TABLE_RELOCS when there is no reloc - support. Use BFD_JUMP_TABLE_RELOCS (_bfd_norelocs). */ - -#define _bfd_norelocs_get_reloc_upper_bound \ - ((long (*) PARAMS ((bfd *, asection *))) _bfd_n1) -#define _bfd_norelocs_canonicalize_reloc \ - ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) _bfd_n1) -#define _bfd_norelocs_bfd_reloc_type_lookup \ - ((reloc_howto_type *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) \ - bfd_nullvoidptr) - -/* Routines to use for BFD_JUMP_TABLE_WRITE for targets which may not - be written. Use BFD_JUMP_TABLE_WRITE (_bfd_nowrite). */ - -#define _bfd_nowrite_set_arch_mach \ - ((boolean (*) PARAMS ((bfd *, enum bfd_architecture, unsigned long))) \ - bfd_false) -#define _bfd_nowrite_set_section_contents \ - ((boolean (*) PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type))) \ - bfd_false) - -/* Generic routines to use for BFD_JUMP_TABLE_WRITE. Use - BFD_JUMP_TABLE_WRITE (_bfd_generic). */ - -#define _bfd_generic_set_arch_mach bfd_default_set_arch_mach -extern boolean _bfd_generic_set_section_contents - PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); - -/* Routines to use for BFD_JUMP_TABLE_LINK for targets which do not - support linking. Use BFD_JUMP_TABLE_LINK (_bfd_nolink). */ - -#define _bfd_nolink_sizeof_headers ((int (*) PARAMS ((bfd *, boolean))) bfd_0) -#define _bfd_nolink_bfd_get_relocated_section_contents \ - ((bfd_byte *(*) \ - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, \ - bfd_byte *, boolean, asymbol **))) \ - bfd_nullvoidptr) -#define _bfd_nolink_bfd_relax_section \ - ((boolean (*) \ - PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *))) \ - bfd_false) -#define _bfd_nolink_bfd_link_hash_table_create \ - ((struct bfd_link_hash_table *(*) PARAMS ((bfd *))) bfd_nullvoidptr) -#define _bfd_nolink_bfd_link_add_symbols \ - ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false) -#define _bfd_nolink_bfd_final_link \ - ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false) -#define _bfd_nolink_bfd_link_split_section \ - ((boolean (*) PARAMS ((bfd *, struct sec *))) bfd_false) - -/* Routines to use for BFD_JUMP_TABLE_DYNAMIC for targets which do not - have dynamic symbols or relocs. Use BFD_JUMP_TABLE_DYNAMIC - (_bfd_nodynamic). */ - -#define _bfd_nodynamic_get_dynamic_symtab_upper_bound _bfd_n1 -#define _bfd_nodynamic_canonicalize_dynamic_symtab \ - ((long (*) PARAMS ((bfd *, asymbol **))) _bfd_n1) -#define _bfd_nodynamic_get_dynamic_reloc_upper_bound _bfd_n1 -#define _bfd_nodynamic_canonicalize_dynamic_reloc \ - ((long (*) PARAMS ((bfd *, arelent **, asymbol **))) _bfd_n1) - -/* Generic routine to determine of the given symbol is a local - label. */ -extern boolean bfd_generic_is_local_label PARAMS ((bfd *, asymbol *)); - -/* Generic minisymbol routines. */ -extern long _bfd_generic_read_minisymbols - PARAMS ((bfd *, boolean, PTR *, unsigned int *)); -extern asymbol *_bfd_generic_minisymbol_to_symbol - PARAMS ((bfd *, boolean, const PTR, asymbol *)); - -/* Find the nearest line using .stab/.stabstr sections. */ -extern boolean _bfd_stab_section_find_nearest_line - PARAMS ((bfd *, asymbol **, asection *, bfd_vma, boolean *, const char **, - const char **, unsigned int *, PTR *)); - -/* A routine to create entries for a bfd_link_hash_table. */ -extern struct bfd_hash_entry *_bfd_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string)); - -/* Initialize a bfd_link_hash_table. */ -extern boolean _bfd_link_hash_table_init - PARAMS ((struct bfd_link_hash_table *, bfd *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *))); - -/* Generic link hash table creation routine. */ -extern struct bfd_link_hash_table *_bfd_generic_link_hash_table_create - PARAMS ((bfd *)); - -/* Generic add symbol routine. */ -extern boolean _bfd_generic_link_add_symbols - PARAMS ((bfd *, struct bfd_link_info *)); - -/* Generic add symbol routine. This version is used by targets for - which the linker must collect constructors and destructors by name, - as the collect2 program does. */ -extern boolean _bfd_generic_link_add_symbols_collect - PARAMS ((bfd *, struct bfd_link_info *)); - -/* Generic archive add symbol routine. */ -extern boolean _bfd_generic_link_add_archive_symbols - PARAMS ((bfd *, struct bfd_link_info *, - boolean (*checkfn) (bfd *, struct bfd_link_info *, boolean *))); - -/* Forward declaration to avoid prototype errors. */ -typedef struct bfd_link_hash_entry _bfd_link_hash_entry; - -/* Generic routine to add a single symbol. */ -extern boolean _bfd_generic_link_add_one_symbol - PARAMS ((struct bfd_link_info *, bfd *, const char *name, flagword, - asection *, bfd_vma, const char *, boolean copy, - boolean constructor, struct bfd_link_hash_entry **)); - -/* Generic link routine. */ -extern boolean _bfd_generic_final_link - PARAMS ((bfd *, struct bfd_link_info *)); - -extern boolean _bfd_generic_link_split_section - PARAMS ((bfd *, struct sec *)); - -/* Generic reloc_link_order processing routine. */ -extern boolean _bfd_generic_reloc_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *)); - -/* Default link order processing routine. */ -extern boolean _bfd_default_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *)); - -/* Count the number of reloc entries in a link order list. */ -extern unsigned int _bfd_count_link_order_relocs - PARAMS ((struct bfd_link_order *)); - -/* Final link relocation routine. */ -extern bfd_reloc_status_type _bfd_final_link_relocate - PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, - bfd_vma address, bfd_vma value, bfd_vma addend)); - -/* Relocate a particular location by a howto and a value. */ -extern bfd_reloc_status_type _bfd_relocate_contents - PARAMS ((reloc_howto_type *, bfd *, bfd_vma, bfd_byte *)); - -/* Create a string table. */ -extern struct bfd_strtab_hash *_bfd_stringtab_init PARAMS ((void)); - -/* Create an XCOFF .debug section style string table. */ -extern struct bfd_strtab_hash *_bfd_xcoff_stringtab_init PARAMS ((void)); - -/* Free a string table. */ -extern void _bfd_stringtab_free PARAMS ((struct bfd_strtab_hash *)); - -/* Get the size of a string table. */ -extern bfd_size_type _bfd_stringtab_size PARAMS ((struct bfd_strtab_hash *)); - -/* Add a string to a string table. */ -extern bfd_size_type _bfd_stringtab_add - PARAMS ((struct bfd_strtab_hash *, const char *, boolean hash, - boolean copy)); - -/* Write out a string table. */ -extern boolean _bfd_stringtab_emit PARAMS ((bfd *, struct bfd_strtab_hash *)); - -/* Macros to tell if bfds are read or write enabled. - - Note that bfds open for read may be scribbled into if the fd passed - to bfd_fdopenr is actually open both for read and write - simultaneously. However an output bfd will never be open for - read. Therefore sometimes you want to check bfd_read_p or - !bfd_read_p, and only sometimes bfd_write_p. -*/ - -#define bfd_read_p(abfd) ((abfd)->direction == read_direction || (abfd)->direction == both_direction) -#define bfd_write_p(abfd) ((abfd)->direction == write_direction || (abfd)->direction == both_direction) - -void bfd_assert PARAMS ((const char*,int)); - -#define BFD_ASSERT(x) \ -{ if (!(x)) bfd_assert(__FILE__,__LINE__); } - -#define BFD_FAIL() \ -{ bfd_assert(__FILE__,__LINE__); } - -FILE * bfd_cache_lookup_worker PARAMS ((bfd *)); - -extern bfd *bfd_last_cache; - -/* Now Steve, what's the story here? */ -#ifdef lint -#define itos(x) "l" -#define stoi(x) 1 -#else -#define itos(x) ((char*)(x)) -#define stoi(x) ((int)(x)) -#endif - -/* List of supported target vectors, and the default vector (if - bfd_default_vector[0] is NULL, there is no default). */ -extern const bfd_target * const bfd_target_vector[]; -extern const bfd_target * const bfd_default_vector[]; - -/* Functions shared by the ECOFF and MIPS ELF backends, which have no - other common header files. */ - -#if defined(__STDC__) || defined(ALMOST_STDC) -struct ecoff_find_line; -#endif - -extern boolean _bfd_ecoff_locate_line - PARAMS ((bfd *, asection *, bfd_vma, struct ecoff_debug_info * const, - const struct ecoff_debug_swap * const, struct ecoff_find_line *, - const char **, const char **, unsigned int *)); -extern boolean _bfd_ecoff_get_accumulated_pdr PARAMS ((PTR, bfd_byte *)); -extern boolean _bfd_ecoff_get_accumulated_sym PARAMS ((PTR, bfd_byte *)); -extern boolean _bfd_ecoff_get_accumulated_ss PARAMS ((PTR, bfd_byte *)); - -extern bfd_vma _bfd_get_gp_value PARAMS ((bfd *)); -extern void _bfd_set_gp_value PARAMS ((bfd *, bfd_vma)); - -/* And more follows */ - diff --git a/contrib/gdb/bfd/libcoff-in.h b/contrib/gdb/bfd/libcoff-in.h deleted file mode 100644 index 648ed80..0000000 --- a/contrib/gdb/bfd/libcoff-in.h +++ /dev/null @@ -1,482 +0,0 @@ -/* BFD COFF object file private structure. - Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -** NOTE: libcoff.h is a GENERATED file. Don't change it; instead, -** change libcoff-in.h or coffcode.h. - -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. */ - -#include "bfdlink.h" - -/* Object file tdata; access macros */ - -#define coff_data(bfd) ((bfd)->tdata.coff_obj_data) -#define exec_hdr(bfd) (coff_data(bfd)->hdr) -#define obj_pe(bfd) (coff_data(bfd)->pe) -#define obj_symbols(bfd) (coff_data(bfd)->symbols) -#define obj_sym_filepos(bfd) (coff_data(bfd)->sym_filepos) - -#define obj_relocbase(bfd) (coff_data(bfd)->relocbase) -#define obj_raw_syments(bfd) (coff_data(bfd)->raw_syments) -#define obj_raw_syment_count(bfd) (coff_data(bfd)->raw_syment_count) -#define obj_convert(bfd) (coff_data(bfd)->conversion_table) -#define obj_conv_table_size(bfd) (coff_data(bfd)->conv_table_size) - -#define obj_coff_external_syms(bfd) (coff_data (bfd)->external_syms) -#define obj_coff_keep_syms(bfd) (coff_data (bfd)->keep_syms) -#define obj_coff_strings(bfd) (coff_data (bfd)->strings) -#define obj_coff_keep_strings(bfd) (coff_data (bfd)->keep_strings) -#define obj_coff_sym_hashes(bfd) (coff_data (bfd)->sym_hashes) - -#define obj_coff_local_toc_table(bfd) (coff_data(bfd)->local_toc_sym_map) - -/* `Tdata' information kept for COFF files. */ - -typedef struct coff_tdata -{ - struct coff_symbol_struct *symbols; /* symtab for input bfd */ - unsigned int *conversion_table; - int conv_table_size; - file_ptr sym_filepos; - - struct coff_ptr_struct *raw_syments; - unsigned int raw_syment_count; - - /* These are only valid once writing has begun */ - long int relocbase; - - /* These members communicate important constants about the symbol table - to GDB's symbol-reading code. These `constants' unfortunately vary - from coff implementation to implementation... */ - unsigned local_n_btmask; - unsigned local_n_btshft; - unsigned local_n_tmask; - unsigned local_n_tshift; - unsigned local_symesz; - unsigned local_auxesz; - unsigned local_linesz; - - /* The unswapped external symbols. May be NULL. Read by - _bfd_coff_get_external_symbols. */ - PTR external_syms; - /* If this is true, the external_syms may not be freed. */ - boolean keep_syms; - - /* The string table. May be NULL. Read by - _bfd_coff_read_string_table. */ - char *strings; - /* If this is true, the strings may not be freed. */ - boolean keep_strings; - - /* is this a PE format coff file */ - int pe; - /* Used by the COFF backend linker. */ - struct coff_link_hash_entry **sym_hashes; - - /* used by the pe linker for PowerPC */ - int *local_toc_sym_map; - - struct bfd_link_info *link_info; - - /* Used by coff_find_nearest_line. */ - PTR line_info; -} coff_data_type; - -/* Tdata for pe image files. */ -typedef struct pe_tdata -{ - coff_data_type coff; - struct internal_extra_pe_aouthdr pe_opthdr; - int dll; - int has_reloc_section; - boolean (*in_reloc_p) PARAMS((bfd *, reloc_howto_type *)); - flagword real_flags; -} pe_data_type; - -#define pe_data(bfd) ((bfd)->tdata.pe_obj_data) - -/* Tdata for XCOFF files. */ - -struct xcoff_tdata -{ - /* Basic COFF information. */ - coff_data_type coff; - - /* True if a large a.out header should be generated. */ - boolean full_aouthdr; - - /* TOC value. */ - bfd_vma toc; - - /* Index of section holding TOC. */ - int sntoc; - - /* Index of section holding entry point. */ - int snentry; - - /* .text alignment from optional header. */ - int text_align_power; - - /* .data alignment from optional header. */ - int data_align_power; - - /* modtype from optional header. */ - short modtype; - - /* cputype from optional header. */ - short cputype; - - /* maxdata from optional header. */ - bfd_size_type maxdata; - - /* maxstack from optional header. */ - bfd_size_type maxstack; - - /* Used by the XCOFF backend linker. */ - asection **csects; - unsigned long *debug_indices; - unsigned int import_file_id; -}; - -#define xcoff_data(abfd) ((abfd)->tdata.xcoff_obj_data) - -/* We take the address of the first element of a asymbol to ensure that the - * macro is only ever applied to an asymbol. */ -#define coffsymbol(asymbol) ((coff_symbol_type *)(&((asymbol)->the_bfd))) - -/* The used_by_bfd field of a section may be set to a pointer to this - structure. */ - -struct coff_section_tdata -{ - /* The relocs, swapped into COFF internal form. This may be NULL. */ - struct internal_reloc *relocs; - /* If this is true, the relocs entry may not be freed. */ - boolean keep_relocs; - /* The section contents. This may be NULL. */ - bfd_byte *contents; - /* If this is true, the contents entry may not be freed. */ - boolean keep_contents; - /* Information cached by coff_find_nearest_line. */ - bfd_vma offset; - unsigned int i; - const char *function; - int line_base; - /* Available for individual backends. */ - PTR tdata; -}; - -/* An accessor macro for the coff_section_tdata structure. */ -#define coff_section_data(abfd, sec) \ - ((struct coff_section_tdata *) (sec)->used_by_bfd) - -/* Tdata for sections in XCOFF files. This is used by the linker. */ - -struct xcoff_section_tdata -{ - /* Used for XCOFF csects created by the linker; points to the real - XCOFF section which contains this csect. */ - asection *enclosing; - /* The lineno_count field for the enclosing section, because we are - going to clobber it there. */ - unsigned int lineno_count; - /* The first and one past the last symbol indices for symbols used - by this csect. */ - unsigned long first_symndx; - unsigned long last_symndx; -}; - -/* An accessor macro the xcoff_section_tdata structure. */ -#define xcoff_section_data(abfd, sec) \ - ((struct xcoff_section_tdata *) coff_section_data ((abfd), (sec))->tdata) - -/* COFF linker hash table entries. */ - -struct coff_link_hash_entry -{ - struct bfd_link_hash_entry root; - - /* Symbol index in output file. Set to -1 initially. Set to -2 if - there is a reloc against this symbol. */ - long indx; - - /* Symbol type. */ - unsigned short type; - - /* Symbol class. */ - unsigned char class; - - /* Number of auxiliary entries. */ - char numaux; - - /* BFD to take auxiliary entries from. */ - bfd *auxbfd; - - /* Pointer to array of auxiliary entries, if any. */ - union internal_auxent *aux; -}; - -/* COFF linker hash table. */ - -struct coff_link_hash_table -{ - struct bfd_link_hash_table root; -}; - -/* Look up an entry in a COFF linker hash table. */ - -#define coff_link_hash_lookup(table, string, create, copy, follow) \ - ((struct coff_link_hash_entry *) \ - bfd_link_hash_lookup (&(table)->root, (string), (create), \ - (copy), (follow))) - -/* Traverse a COFF linker hash table. */ - -#define coff_link_hash_traverse(table, func, info) \ - (bfd_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the COFF linker hash table from a link_info structure. */ - -#define coff_hash_table(p) ((struct coff_link_hash_table *) ((p)->hash)) - -/* Functions in coffgen.c. */ -extern const bfd_target *coff_object_p PARAMS ((bfd *)); -extern struct sec *coff_section_from_bfd_index PARAMS ((bfd *, int)); -extern long coff_get_symtab_upper_bound PARAMS ((bfd *)); -extern long coff_get_symtab PARAMS ((bfd *, asymbol **)); -extern int coff_count_linenumbers PARAMS ((bfd *)); -extern struct coff_symbol_struct *coff_symbol_from PARAMS ((bfd *, asymbol *)); -extern boolean coff_renumber_symbols PARAMS ((bfd *, int *)); -extern void coff_mangle_symbols PARAMS ((bfd *)); -extern boolean coff_write_symbols PARAMS ((bfd *)); -extern boolean coff_write_linenumbers PARAMS ((bfd *)); -extern alent *coff_get_lineno PARAMS ((bfd *, asymbol *)); -extern asymbol *coff_section_symbol PARAMS ((bfd *, char *)); -extern boolean _bfd_coff_get_external_symbols PARAMS ((bfd *)); -extern const char *_bfd_coff_read_string_table PARAMS ((bfd *)); -extern boolean _bfd_coff_free_symbols PARAMS ((bfd *)); -extern struct coff_ptr_struct *coff_get_normalized_symtab PARAMS ((bfd *)); -extern long coff_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr)); -extern asymbol *coff_make_empty_symbol PARAMS ((bfd *)); -extern void coff_print_symbol PARAMS ((bfd *, PTR filep, asymbol *, - bfd_print_symbol_type how)); -extern void coff_get_symbol_info PARAMS ((bfd *, asymbol *, - symbol_info *ret)); -extern asymbol *coff_bfd_make_debug_symbol PARAMS ((bfd *, PTR, - unsigned long)); -extern boolean coff_find_nearest_line PARAMS ((bfd *, - asection *, - asymbol **, - bfd_vma offset, - CONST char **filename_ptr, - CONST char **functionname_ptr, - unsigned int *line_ptr)); -extern int coff_sizeof_headers PARAMS ((bfd *, boolean reloc)); -extern boolean bfd_coff_reloc16_relax_section - PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *)); -extern bfd_byte *bfd_coff_reloc16_get_relocated_section_contents - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *, boolean relocateable, asymbol **)); -extern bfd_vma bfd_coff_reloc16_get_value PARAMS ((arelent *, - struct bfd_link_info *, - asection *)); -extern void bfd_perform_slip PARAMS ((bfd *abfd, unsigned int slip, - asection *input_section, - bfd_vma val)); - -/* Functions and types in cofflink.c. */ - -#define STRING_SIZE_SIZE (4) - -/* We use a hash table to merge identical enum, struct, and union - definitions in the linker. */ - -/* Information we keep for a single element (an enum value, a - structure or union field) in the debug merge hash table. */ - -struct coff_debug_merge_element -{ - /* Next element. */ - struct coff_debug_merge_element *next; - - /* Name. */ - const char *name; - - /* Type. */ - unsigned int type; - - /* Symbol index for complex type. */ - long tagndx; -}; - -/* A linked list of debug merge entries for a given name. */ - -struct coff_debug_merge_type -{ - /* Next type with the same name. */ - struct coff_debug_merge_type *next; - - /* Class of type. */ - int class; - - /* Symbol index where this type is defined. */ - long indx; - - /* List of elements. */ - struct coff_debug_merge_element *elements; -}; - -/* Information we store in the debug merge hash table. */ - -struct coff_debug_merge_hash_entry -{ - struct bfd_hash_entry root; - - /* A list of types with this name. */ - struct coff_debug_merge_type *types; -}; - -/* The debug merge hash table. */ - -struct coff_debug_merge_hash_table -{ - struct bfd_hash_table root; -}; - -/* Initialize a COFF debug merge hash table. */ - -#define coff_debug_merge_hash_table_init(table) \ - (bfd_hash_table_init (&(table)->root, _bfd_coff_debug_merge_hash_newfunc)) - -/* Free a COFF debug merge hash table. */ - -#define coff_debug_merge_hash_table_free(table) \ - (bfd_hash_table_free (&(table)->root)) - -/* Look up an entry in a COFF debug merge hash table. */ - -#define coff_debug_merge_hash_lookup(table, string, create, copy) \ - ((struct coff_debug_merge_hash_entry *) \ - bfd_hash_lookup (&(table)->root, (string), (create), (copy))) - -/* Information we keep for each section in the output file when doing - a relocateable link. */ - -struct coff_link_section_info -{ - /* The relocs to be output. */ - struct internal_reloc *relocs; - /* For each reloc against a global symbol whose index was not known - when the reloc was handled, the global hash table entry. */ - struct coff_link_hash_entry **rel_hashes; -}; - -/* Information that we pass around while doing the final link step. */ - -struct coff_final_link_info -{ - /* General link information. */ - struct bfd_link_info *info; - /* Output BFD. */ - bfd *output_bfd; - /* Used to indicate failure in traversal routine. */ - boolean failed; - /* Hash table for long symbol names. */ - struct bfd_strtab_hash *strtab; - /* When doing a relocateable link, an array of information kept for - each output section, indexed by the target_index field. */ - struct coff_link_section_info *section_info; - /* Symbol index of last C_FILE symbol (-1 if none). */ - long last_file_index; - /* Contents of last C_FILE symbol. */ - struct internal_syment last_file; - /* Hash table used to merge debug information. */ - struct coff_debug_merge_hash_table debug_merge; - /* Buffer large enough to hold swapped symbols of any input file. */ - struct internal_syment *internal_syms; - /* Buffer large enough to hold sections of symbols of any input file. */ - asection **sec_ptrs; - /* Buffer large enough to hold output indices of symbols of any - input file. */ - long *sym_indices; - /* Buffer large enough to hold output symbols for any input file. */ - bfd_byte *outsyms; - /* Buffer large enough to hold external line numbers for any input - section. */ - bfd_byte *linenos; - /* Buffer large enough to hold any input section. */ - bfd_byte *contents; - /* Buffer large enough to hold external relocs of any input section. */ - bfd_byte *external_relocs; - /* Buffer large enough to hold swapped relocs of any input section. */ - struct internal_reloc *internal_relocs; -}; - -extern struct bfd_hash_entry *_bfd_coff_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -extern boolean _bfd_coff_link_hash_table_init - PARAMS ((struct coff_link_hash_table *, bfd *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *))); -extern struct bfd_link_hash_table *_bfd_coff_link_hash_table_create - PARAMS ((bfd *)); -extern const char *_bfd_coff_internal_syment_name - PARAMS ((bfd *, const struct internal_syment *, char *)); -extern boolean _bfd_coff_link_add_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean _bfd_coff_final_link - PARAMS ((bfd *, struct bfd_link_info *)); -extern struct internal_reloc *_bfd_coff_read_internal_relocs - PARAMS ((bfd *, asection *, boolean, bfd_byte *, boolean, - struct internal_reloc *)); -extern boolean _bfd_coff_generic_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - struct internal_reloc *, struct internal_syment *, asection **)); - -extern struct bfd_hash_entry *_bfd_coff_debug_merge_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -extern boolean _bfd_coff_write_global_sym - PARAMS ((struct coff_link_hash_entry *, PTR)); -extern boolean _bfd_coff_link_input_bfd - PARAMS ((struct coff_final_link_info *, bfd *)); -extern boolean _bfd_coff_reloc_link_order - PARAMS ((bfd *, struct coff_final_link_info *, asection *, - struct bfd_link_order *)); - - -#define coff_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -/* Functions in xcofflink.c. */ - -extern struct bfd_link_hash_table *_bfd_xcoff_bfd_link_hash_table_create - PARAMS ((bfd *)); -extern boolean _bfd_xcoff_bfd_link_add_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean _bfd_xcoff_bfd_final_link - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean _bfd_ppc_xcoff_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - struct internal_reloc *, struct internal_syment *, asection **)); - -/* And more taken from the source .. */ - diff --git a/contrib/gdb/bfd/libhppa.h b/contrib/gdb/bfd/libhppa.h deleted file mode 100644 index fa97b68..0000000 --- a/contrib/gdb/bfd/libhppa.h +++ /dev/null @@ -1,549 +0,0 @@ -/* HP PA-RISC SOM object file format: definitions internal to BFD. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - - Contributed by the Center for Software Science at the - University of Utah (pa-gdb-bugs@cs.utah.edu). - - 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. */ - -#ifndef _HPPA_H -#define _HPPA_H - -#define BYTES_IN_WORD 4 -#define PA_PAGESIZE 0x1000 - -#ifndef INLINE -#ifdef __GNUC__ -#define INLINE inline -#else -#define INLINE -#endif /* GNU C? */ -#endif /* INLINE */ - -/* The PA instruction set variants. */ -enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20}; - -/* HP PA-RISC relocation types */ - -enum hppa_reloc_field_selector_type - { - R_HPPA_FSEL = 0x0, - R_HPPA_LSSEL = 0x1, - R_HPPA_RSSEL = 0x2, - R_HPPA_LSEL = 0x3, - R_HPPA_RSEL = 0x4, - R_HPPA_LDSEL = 0x5, - R_HPPA_RDSEL = 0x6, - R_HPPA_LRSEL = 0x7, - R_HPPA_RRSEL = 0x8, - R_HPPA_NSEL = 0x9, - R_HPPA_NLSEL = 0xa, - R_HPPA_NLRSEL = 0xb, - R_HPPA_PSEL = 0xc, - R_HPPA_LPSEL = 0xd, - R_HPPA_RPSEL = 0xe, - R_HPPA_TSEL = 0xf, - R_HPPA_LTSEL = 0x10, - R_HPPA_RTSEL = 0x11 - }; - -/* /usr/include/reloc.h defines these to constants. We want to use - them in enums, so #undef them before we start using them. We might - be able to fix this another way by simply managing not to include - /usr/include/reloc.h, but currently GDB picks up these defines - somewhere. */ -#undef e_fsel -#undef e_lssel -#undef e_rssel -#undef e_lsel -#undef e_rsel -#undef e_ldsel -#undef e_rdsel -#undef e_lrsel -#undef e_rrsel -#undef e_nsel -#undef e_nlsel -#undef e_nlrsel -#undef e_psel -#undef e_lpsel -#undef e_rpsel -#undef e_tsel -#undef e_ltsel -#undef e_rtsel -#undef e_one -#undef e_two -#undef e_pcrel -#undef e_con -#undef e_plabel -#undef e_abs - -/* for compatibility */ -enum hppa_reloc_field_selector_type_alt - { - e_fsel = R_HPPA_FSEL, - e_lssel = R_HPPA_LSSEL, - e_rssel = R_HPPA_RSSEL, - e_lsel = R_HPPA_LSEL, - e_rsel = R_HPPA_RSEL, - e_ldsel = R_HPPA_LDSEL, - e_rdsel = R_HPPA_RDSEL, - e_lrsel = R_HPPA_LRSEL, - e_rrsel = R_HPPA_RRSEL, - e_nsel = R_HPPA_NSEL, - e_nlsel = R_HPPA_NLSEL, - e_nlrsel = R_HPPA_NLRSEL, - e_psel = R_HPPA_PSEL, - e_lpsel = R_HPPA_LPSEL, - e_rpsel = R_HPPA_RPSEL, - e_tsel = R_HPPA_TSEL, - e_ltsel = R_HPPA_LTSEL, - e_rtsel = R_HPPA_RTSEL - }; - -enum hppa_reloc_expr_type - { - R_HPPA_E_ONE = 0, - R_HPPA_E_TWO = 1, - R_HPPA_E_PCREL = 2, - R_HPPA_E_CON = 3, - R_HPPA_E_PLABEL = 7, - R_HPPA_E_ABS = 18 - }; - -/* for compatibility */ -enum hppa_reloc_expr_type_alt - { - e_one = R_HPPA_E_ONE, - e_two = R_HPPA_E_TWO, - e_pcrel = R_HPPA_E_PCREL, - e_con = R_HPPA_E_CON, - e_plabel = R_HPPA_E_PLABEL, - e_abs = R_HPPA_E_ABS - }; - - -/* Relocations for function calls must be accompanied by parameter - relocation bits. These bits describe exactly where the caller has - placed the function's arguments and where it expects to find a return - value. - - Both ELF and SOM encode this information within the addend field - of the call relocation. (Note this could break very badly if one - was to make a call like bl foo + 0x12345678). - - The high order 10 bits contain parameter relocation information, - the low order 22 bits contain the constant offset. */ - -#define HPPA_R_ARG_RELOC(a) (((a) >> 22) & 0x3FF) -#define HPPA_R_CONSTANT(a) ((((int)(a)) << 10) >> 10) -#define HPPA_R_ADDEND(r,c) (((r) << 22) + ((c) & 0x3FFFFF)) - -/* Some functions to manipulate PA instructions. */ -static INLINE unsigned int -assemble_3 (x) - unsigned int x; -{ - return (((x & 1) << 2) | ((x & 6) >> 1)) & 7; -} - -static INLINE void -dis_assemble_3 (x, r) - unsigned int x; - unsigned int *r; -{ - *r = (((x & 4) >> 2) | ((x & 3) << 1)) & 7; -} - -static INLINE unsigned int -assemble_12 (x, y) - unsigned int x, y; -{ - return (((y & 1) << 11) | ((x & 1) << 10) | ((x & 0x7fe) >> 1)) & 0xfff; -} - -static INLINE void -dis_assemble_12 (as12, x, y) - unsigned int as12; - unsigned int *x, *y; -{ - *y = (as12 & 0x800) >> 11; - *x = ((as12 & 0x3ff) << 1) | ((as12 & 0x400) >> 10); -} - -static INLINE unsigned long -assemble_17 (x, y, z) - unsigned int x, y, z; -{ - unsigned long temp; - - temp = ((z & 1) << 16) | - ((x & 0x1f) << 11) | - ((y & 1) << 10) | - ((y & 0x7fe) >> 1); - return temp & 0x1ffff; -} - -static INLINE void -dis_assemble_17 (as17, x, y, z) - unsigned int as17; - unsigned int *x, *y, *z; -{ - - *z = (as17 & 0x10000) >> 16; - *x = (as17 & 0x0f800) >> 11; - *y = (((as17 & 0x00400) >> 10) | ((as17 & 0x3ff) << 1)) & 0x7ff; -} - -static INLINE unsigned long -assemble_21 (x) - unsigned int x; -{ - unsigned long temp; - - temp = ((x & 1) << 20) | - ((x & 0xffe) << 8) | - ((x & 0xc000) >> 7) | - ((x & 0x1f0000) >> 14) | - ((x & 0x003000) >> 12); - return temp & 0x1fffff; -} - -static INLINE void -dis_assemble_21 (as21, x) - unsigned int as21, *x; -{ - unsigned long temp; - - - temp = (as21 & 0x100000) >> 20; - temp |= (as21 & 0x0ffe00) >> 8; - temp |= (as21 & 0x000180) << 7; - temp |= (as21 & 0x00007c) << 14; - temp |= (as21 & 0x000003) << 12; - *x = temp; -} - -static INLINE unsigned long -sign_extend (x, len) - unsigned int x, len; -{ - return (int)(x >> (len - 1) ? (-1 << len) | x : x); -} - -static INLINE unsigned int -ones (n) - int n; -{ - unsigned int len_ones; - int i; - - i = 0; - len_ones = 0; - while (i < n) - { - len_ones = (len_ones << 1) | 1; - i++; - } - - return len_ones; -} - -static INLINE void -sign_unext (x, len, result) - unsigned int x, len; - unsigned int *result; -{ - unsigned int len_ones; - - len_ones = ones (len); - - *result = x & len_ones; -} - -static INLINE unsigned long -low_sign_extend (x, len) - unsigned int x, len; -{ - return (int)((x & 0x1 ? (-1 << (len - 1)) : 0) | x >> 1); -} - -static INLINE void -low_sign_unext (x, len, result) - unsigned int x, len; - unsigned int *result; -{ - unsigned int temp; - unsigned int sign; - unsigned int rest; - unsigned int one_bit_at_len; - unsigned int len_ones; - - len_ones = ones (len); - one_bit_at_len = 1 << (len - 1); - - sign_unext (x, len, &temp); - sign = temp & one_bit_at_len; - sign >>= (len - 1); - - rest = temp & (len_ones ^ one_bit_at_len); - rest <<= 1; - - *result = rest | sign; -} - -/* Handle field selectors for PA instructions. */ - -static INLINE unsigned long -hppa_field_adjust (value, constant_value, r_field) - unsigned long value; - unsigned long constant_value; - unsigned short r_field; -{ - switch (r_field) - { - case e_fsel: /* F : no change */ - case e_nsel: /* N : no change */ - value += constant_value; - break; - - case e_lssel: /* LS : if (bit 21) then add 0x800 - arithmetic shift right 11 bits */ - value += constant_value; - if (value & 0x00000400) - value += 0x800; - value = (value & 0xfffff800) >> 11; - break; - - case e_rssel: /* RS : Sign extend from bit 21 */ - value += constant_value; - if (value & 0x00000400) - value |= 0xfffff800; - else - value &= 0x7ff; - break; - - case e_lsel: /* L : Arithmetic shift right 11 bits */ - case e_nlsel: /* NL : Arithmetic shift right 11 bits */ - value += constant_value; - value = (value & 0xfffff800) >> 11; - break; - - case e_rsel: /* R : Set bits 0-20 to zero */ - value += constant_value; - value = value & 0x7ff; - break; - - case e_ldsel: /* LD : Add 0x800, arithmetic shift - right 11 bits */ - value += constant_value; - value += 0x800; - value = (value & 0xfffff800) >> 11; - break; - - case e_rdsel: /* RD : Set bits 0-20 to one */ - value += constant_value; - value |= 0xfffff800; - break; - - case e_lrsel: /* LR : L with "rounded" constant */ - case e_nlrsel: /* NLR : NL with "rounded" constant */ - value = value + ((constant_value + 0x1000) & 0xffffe000); - value = (value & 0xfffff800) >> 11; - break; - - case e_rrsel: /* RR : R with "rounded" constant */ - value = value + ((constant_value + 0x1000) & 0xffffe000); - value = (value & 0x7ff) + constant_value - ((constant_value + 0x1000) & 0xffffe000); - break; - - default: - abort (); - } - return value; - -} - -/* PA-RISC OPCODES */ -#define get_opcode(insn) ((insn) & 0xfc000000) >> 26 - -/* FIXME: this list is incomplete. It should also be an enumerated - type rather than #defines. */ - -#define LDO 0x0d -#define LDB 0x10 -#define LDH 0x11 -#define LDW 0x12 -#define LDWM 0x13 -#define STB 0x18 -#define STH 0x19 -#define STW 0x1a -#define STWM 0x1b -#define COMICLR 0x24 -#define SUBI 0x25 -#define SUBIO 0x25 -#define ADDIT 0x2c -#define ADDITO 0x2c -#define ADDI 0x2d -#define ADDIO 0x2d -#define LDIL 0x08 -#define ADDIL 0x0a - -#define MOVB 0x32 -#define MOVIB 0x33 -#define COMBT 0x20 -#define COMBF 0x22 -#define COMIBT 0x21 -#define COMIBF 0x23 -#define ADDBT 0x28 -#define ADDBF 0x2a -#define ADDIBT 0x29 -#define ADDIBF 0x2b -#define BVB 0x30 -#define BB 0x31 - -#define BL 0x3a -#define BLE 0x39 -#define BE 0x38 - - -/* Given a machine instruction, return its format. - - FIXME: opcodes which do not map to a known format - should return an error of some sort. */ - -static INLINE char -bfd_hppa_insn2fmt (insn) - unsigned long insn; -{ - char fmt = -1; - unsigned char op = get_opcode (insn); - - switch (op) - { - case ADDI: - case ADDIT: - case SUBI: - fmt = 11; - break; - case MOVB: - case MOVIB: - case COMBT: - case COMBF: - case COMIBT: - case COMIBF: - case ADDBT: - case ADDBF: - case ADDIBT: - case ADDIBF: - case BVB: - case BB: - fmt = 12; - break; - case LDO: - case LDB: - case LDH: - case LDW: - case LDWM: - case STB: - case STH: - case STW: - case STWM: - fmt = 14; - break; - case BL: - case BE: - case BLE: - fmt = 17; - break; - case LDIL: - case ADDIL: - fmt = 21; - break; - default: - fmt = 32; - break; - } - return fmt; -} - - -/* Insert VALUE into INSN using R_FORMAT to determine exactly what - bits to change. */ - -static INLINE unsigned long -hppa_rebuild_insn (abfd, insn, value, r_format) - bfd *abfd; - unsigned long insn; - unsigned long value; - unsigned long r_format; -{ - unsigned long const_part; - unsigned long rebuilt_part; - - switch (r_format) - { - case 11: - { - unsigned w1, w; - - const_part = insn & 0xffffe002; - dis_assemble_12 (value, &w1, &w); - rebuilt_part = (w1 << 2) | w; - return const_part | rebuilt_part; - } - - case 12: - { - unsigned w1, w; - - const_part = insn & 0xffffe002; - dis_assemble_12 (value, &w1, &w); - rebuilt_part = (w1 << 2) | w; - return const_part | rebuilt_part; - } - - case 14: - const_part = insn & 0xffffc000; - low_sign_unext (value, 14, &rebuilt_part); - return const_part | rebuilt_part; - - case 17: - { - unsigned w1, w2, w; - - const_part = insn & 0xffe0e002; - dis_assemble_17 (value, &w1, &w2, &w); - rebuilt_part = (w2 << 2) | (w1 << 16) | w; - return const_part | rebuilt_part; - } - - case 21: - const_part = insn & 0xffe00000; - dis_assemble_21 (value, &rebuilt_part); - return const_part | rebuilt_part; - - case 32: - const_part = 0; - return value; - - default: - abort (); - } - return insn; -} - -#endif /* _HPPA_H */ diff --git a/contrib/gdb/bfd/libieee.h b/contrib/gdb/bfd/libieee.h deleted file mode 100644 index c3729cb..0000000 --- a/contrib/gdb/bfd/libieee.h +++ /dev/null @@ -1,135 +0,0 @@ -/* IEEE-695 object file formats: definitions internal to BFD. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Cygnus Support. Mostly Steve Chamberlain's fault. - -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. */ - -typedef struct { - unsigned int index:24; - char letter; -} ieee_symbol_index_type; - -typedef struct ct { - bfd *this; - struct ct *next; -} bfd_chain_type; - -typedef struct ieee_symbol -{ - asymbol symbol; - struct ieee_symbol *next; - - unsigned int index; -} ieee_symbol_type; - - -typedef struct ieee_reloc { - arelent relent; - struct ieee_reloc *next; - ieee_symbol_index_type symbol; - -} ieee_reloc_type; - -#define ieee_symbol(x) ((ieee_symbol_type *)(x)) - -typedef struct ieee_per_section -{ - asection *section; - bfd_byte *data; - bfd_vma offset; - bfd_vma pc; - /* For output */ - file_ptr current_pos; - unsigned int current_byte; - boolean initialized; - ieee_reloc_type **reloc_tail_ptr; -} ieee_per_section_type; - -#define ieee_per_section(x) ((ieee_per_section_type *)((x)->used_by_bfd)) -/* FIXME! There should be no limit to the number of sections! */ -#define NSECTIONS 20 - - -typedef struct { - unsigned char *input_p; - unsigned char *first_byte; - bfd *abfd; -} common_header_type ; - -typedef struct ieee_data_struct -{ - common_header_type h; - boolean read_symbols; - boolean read_data; - file_ptr output_cursor; - /* Map of section indexes to section ptrs */ - asection * section_table[NSECTIONS]; - ieee_address_descriptor_type ad; - ieee_module_begin_type mb; - ieee_w_variable_type w; - - unsigned int section_count; - - unsigned int map_idx; - /* List of GLOBAL EXPORT symbols */ - ieee_symbol_type *external_symbols; - /* List of UNDEFINED symbols */ - ieee_symbol_type *external_reference; - - /* When the symbols have been canonicalized, they are in a - * special order, we remember various bases here.. */ - unsigned int external_symbol_max_index; - unsigned int external_symbol_min_index; - unsigned int external_symbol_count; - int external_symbol_base_offset; - - unsigned int external_reference_max_index; - unsigned int external_reference_min_index; - unsigned int external_reference_count; - int external_reference_base_offset; - - - boolean symbol_table_full; - - -boolean done_debug; - - -bfd_chain_type *chain_head; -bfd_chain_type *chain_root; - -} ieee_data_type; - -typedef struct { - file_ptr file_offset; - bfd *abfd; -} ieee_ar_obstack_type; - -typedef struct ieee_ar_data_struct -{ - common_header_type h; - ieee_ar_obstack_type *elements; - - unsigned int element_index ; - unsigned int element_count; - -} ieee_ar_data_type; - -#define IEEE_DATA(abfd) ((abfd)->tdata.ieee_data) -#define IEEE_AR_DATA(abfd) ((abfd)->tdata.ieee_ar_data) - -#define ptr(abfd) (ieee_data(abfd)->input_p) diff --git a/contrib/gdb/bfd/libnlm.h b/contrib/gdb/bfd/libnlm.h deleted file mode 100644 index 12d2e4e..0000000 --- a/contrib/gdb/bfd/libnlm.h +++ /dev/null @@ -1,264 +0,0 @@ -/* BFD back-end data structures for NLM (NetWare Loadable Modules) files. - Copyright (C) 1993 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - -#ifndef _LIBNLM_H_ -#define _LIBNLM_H_ 1 - -#ifdef ARCH_SIZE -# define NLM_ARCH_SIZE ARCH_SIZE -#endif -#include "nlm/common.h" -#include "nlm/internal.h" -#include "nlm/external.h" - -/* A reloc for an imported NLM symbol. Normal relocs are associated - with sections, and include a symbol. These relocs are associated - with (undefined) symbols, and include a section. */ - -struct nlm_relent -{ - /* Section of reloc. */ - asection *section; - /* Reloc info (sym_ptr_ptr field set only when canonicalized). */ - arelent reloc; -}; - -/* Information we keep for an NLM symbol. */ - -typedef struct -{ - /* BFD symbol. */ - asymbol symbol; - /* Number of reloc entries for imported symbol. */ - bfd_size_type rcnt; - /* Array of reloc information for imported symbol. */ - struct nlm_relent *relocs; -} nlmNAME(symbol_type); - -extern boolean nlm_mkobject PARAMS ((bfd *)); -extern boolean nlm_set_arch_mach PARAMS ((bfd *, enum bfd_architecture, - unsigned long)); - -extern void nlmNAME(get_symbol_info) - PARAMS ((bfd *, asymbol *, symbol_info *)); -extern long nlmNAME(get_symtab_upper_bound) - PARAMS ((bfd *)); -extern long nlmNAME(get_symtab) - PARAMS ((bfd *, asymbol **)); -extern asymbol *nlmNAME(make_empty_symbol) - PARAMS ((bfd *)); -extern void nlmNAME(print_symbol) - PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type)); -extern long nlmNAME(get_reloc_upper_bound) - PARAMS ((bfd *, asection *)); -extern long nlmNAME(canonicalize_reloc) - PARAMS ((bfd *, asection *, arelent **, asymbol **)); -extern const bfd_target *nlmNAME(object_p) - PARAMS ((bfd *)); -extern boolean nlmNAME(set_arch_mach) - PARAMS ((bfd *, enum bfd_architecture, unsigned long)); -extern boolean nlmNAME(set_section_contents) - PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); -extern boolean nlmNAME(write_object_contents) - PARAMS ((bfd *)); - -/* Some private data is stashed away for future use using the tdata pointer - in the bfd structure. */ - -struct nlm_obj_tdata -{ - /* Actual data, but ref like ptr */ - Nlm_Internal_Fixed_Header nlm_fixed_hdr[1]; - Nlm_Internal_Variable_Header nlm_variable_hdr[1]; - Nlm_Internal_Version_Header nlm_version_hdr[1]; - Nlm_Internal_Copyright_Header nlm_copyright_hdr[1]; - Nlm_Internal_Extended_Header nlm_extended_hdr[1]; - Nlm_Internal_Custom_Header nlm_custom_hdr[1]; - Nlm_Internal_Cygnus_Ext_Header nlm_cygnus_ext_hdr[1]; - /* BFD NLM symbols. */ - nlmNAME(symbol_type) *nlm_symbols; - /* Lowest text and data VMA values. */ - bfd_vma nlm_text_low; - bfd_vma nlm_data_low; - /* Caches for data read from object file. */ - arelent * nlm_reloc_fixups; - asection ** nlm_reloc_fixup_secs; - /* Backend specific information. This should probably be a pointer, - but that would require yet another entry point to initialize the - structure. */ - union - { - struct /* Alpha backend information. */ - { - bfd_vma gp; /* GP value. */ - bfd_vma lita_address; /* .lita section address. */ - bfd_size_type lita_size; /* .lita section size. */ - } - alpha_backend_data; - } - backend_data; -}; - -#define nlm_tdata(bfd) ((bfd) -> tdata.nlm_obj_data) -#define nlm_fixed_header(bfd) (nlm_tdata(bfd) -> nlm_fixed_hdr) -#define nlm_variable_header(bfd) (nlm_tdata(bfd) -> nlm_variable_hdr) -#define nlm_version_header(bfd) (nlm_tdata(bfd) -> nlm_version_hdr) -#define nlm_copyright_header(bfd) (nlm_tdata(bfd) -> nlm_copyright_hdr) -#define nlm_extended_header(bfd) (nlm_tdata(bfd) -> nlm_extended_hdr) -#define nlm_custom_header(bfd) (nlm_tdata(bfd) -> nlm_custom_hdr) -#define nlm_cygnus_ext_header(bfd) (nlm_tdata(bfd) -> nlm_cygnus_ext_hdr) -#define nlm_get_symbols(bfd) (nlm_tdata(bfd) -> nlm_symbols) -#define nlm_set_symbols(bfd, p) (nlm_tdata(bfd) -> nlm_symbols = (p)) -#define nlm_set_text_low(bfd, i) (nlm_tdata(bfd) -> nlm_text_low = (i)) -#define nlm_get_text_low(bfd) (nlm_tdata(bfd) -> nlm_text_low) -#define nlm_set_data_low(bfd, i) (nlm_tdata(bfd) -> nlm_data_low = (i)) -#define nlm_get_data_low(bfd) (nlm_tdata(bfd) -> nlm_data_low) -#define nlm_relocation_fixups(bfd) (nlm_tdata(bfd) -> nlm_reloc_fixups) -#define nlm_relocation_fixup_secs(bfd) (nlm_tdata(bfd)->nlm_reloc_fixup_secs) - -#define nlm_alpha_backend_data(bfd) \ - (&nlm_tdata (bfd)->backend_data.alpha_backend_data) - -/* This is used when writing out the external relocs. */ - -struct reloc_and_sec -{ - arelent *rel; - asection *sec; -}; - -/* We store some function pointer in the backend structure. This lets - different NLM targets share most of the same code, while providing - slightly different code where necessary. */ - -struct nlm_backend_data -{ - /* Signature for this backend. */ - char signature[NLM_SIGNATURE_SIZE]; - /* Size of the fixed header. */ - bfd_size_type fixed_header_size; - /* Size of optional prefix for this backend. Some backend may - require this to be a function, but so far a constant is OK. This - is for a prefix which precedes the standard NLM fixed header. */ - bfd_size_type optional_prefix_size; - /* Architecture. */ - enum bfd_architecture arch; - /* Machine. */ - long mach; - /* Some NLM formats do not use the uninitialized data section, so - all uninitialized data must be put into the regular data section - instead. */ - boolean no_uninitialized_data; - /* Some NLM formats have a prefix on the file. If this function is - not NULL, it will be called by nlm_object_p. It should return - true if this file could match this format, and it should leave - the BFD such that a bfd_read will pick up the fixed header. */ - boolean (*nlm_backend_object_p) PARAMS ((bfd *)); - /* Write out the prefix. This function may be NULL. This must - write out the same number of bytes as is in the field - optional_prefix_size. */ - boolean (*nlm_write_prefix) PARAMS ((bfd *)); - /* Read a relocation fixup from abfd. The reloc information is - machine specific. The second argument is the symbol if this is - an import, or NULL if this is a reloc fixup. This function - should set the third argument to the section which the reloc - belongs in, and the fourth argument to the reloc itself; it does - not need to fill in the sym_ptr_ptr field for a reloc against an - import symbol. */ - boolean (*nlm_read_reloc) PARAMS ((bfd *, nlmNAME(symbol_type) *, - asection **, arelent *)); - /* To make objcopy to an i386 NLM work, the i386 backend needs a - chance to work over the relocs. This is a bit icky. */ - boolean (*nlm_mangle_relocs) PARAMS ((bfd *, asection *, PTR data, - bfd_vma offset, - bfd_size_type count)); - /* Read an import record from abfd. It would be nice if this - were in a machine-dependent format, but it doesn't seem to be. */ - boolean (*nlm_read_import) PARAMS ((bfd *, nlmNAME(symbol_type) *)); - /* Write an import record to abfd. */ - boolean (*nlm_write_import) PARAMS ((bfd *, asection *, arelent *)); - /* Set the section for a public symbol. This may be NULL, in which - case a default method will be used. */ - boolean (*nlm_set_public_section) PARAMS ((bfd *, nlmNAME(symbol_type) *)); - /* Get the offset to write out for a public symbol. This may be - NULL, in which case a default method will be used. */ - bfd_vma (*nlm_get_public_offset) PARAMS ((bfd *, asymbol *)); - /* Swap the fixed header in and out */ - void (*nlm_swap_fhdr_in) PARAMS ((bfd *, - PTR, - Nlm_Internal_Fixed_Header *)); - void (*nlm_swap_fhdr_out) PARAMS ((bfd *, - struct nlm_internal_fixed_header *, - PTR)); - /* Write out an external reference. */ - boolean (*nlm_write_external) PARAMS ((bfd *, bfd_size_type, - asymbol *, - struct reloc_and_sec *)); - boolean (*nlm_write_export) PARAMS ((bfd *, asymbol *, bfd_vma)); -}; - -#define nlm_backend(bfd) \ - ((struct nlm_backend_data *)((bfd) -> xvec -> backend_data)) -#define nlm_signature(bfd) \ - (nlm_backend(bfd) -> signature) -#define nlm_fixed_header_size(bfd) \ - (nlm_backend(bfd) -> fixed_header_size) -#define nlm_optional_prefix_size(bfd) \ - (nlm_backend(bfd) -> optional_prefix_size) -#define nlm_architecture(bfd) \ - (nlm_backend(bfd) -> arch) -#define nlm_machine(bfd) \ - (nlm_backend(bfd) -> mach) -#define nlm_no_uninitialized_data(bfd) \ - (nlm_backend(bfd) -> no_uninitialized_data) -#define nlm_backend_object_p_func(bfd) \ - (nlm_backend(bfd) -> nlm_backend_object_p) -#define nlm_write_prefix_func(bfd) \ - (nlm_backend(bfd) -> nlm_write_prefix) -#define nlm_read_reloc_func(bfd) \ - (nlm_backend(bfd) -> nlm_read_reloc) -#define nlm_mangle_relocs_func(bfd) \ - (nlm_backend(bfd) -> nlm_mangle_relocs) -#define nlm_read_import_func(bfd) \ - (nlm_backend(bfd) -> nlm_read_import) -#define nlm_write_import_func(bfd) \ - (nlm_backend(bfd) -> nlm_write_import) -#define nlm_set_public_section_func(bfd) \ - (nlm_backend(bfd) -> nlm_set_public_section) -#define nlm_get_public_offset_func(bfd) \ - (nlm_backend(bfd) -> nlm_get_public_offset) -#define nlm_swap_fixed_header_in_func(bfd) \ - (nlm_backend(bfd) -> nlm_swap_fhdr_in) -#define nlm_swap_fixed_header_out_func(bfd) \ - (nlm_backend(bfd) -> nlm_swap_fhdr_out) -#define nlm_write_external_func(bfd) \ - (nlm_backend(bfd) -> nlm_write_external) -#define nlm_write_export_func(bfd) \ - (nlm_backend(bfd) -> nlm_write_export) - -/* The NLM code, data, and uninitialized sections have no names defined - in the NLM, but bfd wants to give them names, so use the traditional - UNIX names. */ - -#define NLM_CODE_NAME ".text" -#define NLM_INITIALIZED_DATA_NAME ".data" -#define NLM_UNINITIALIZED_DATA_NAME ".bss" - -#endif /* _LIBNLM_H_ */ diff --git a/contrib/gdb/bfd/liboasys.h b/contrib/gdb/bfd/liboasys.h deleted file mode 100644 index 2d15813..0000000 --- a/contrib/gdb/bfd/liboasys.h +++ /dev/null @@ -1,83 +0,0 @@ -/* BFD internal declarations for Oasys file format handling. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Scrawled by Steve Chamberlain of Cygnus Support. - -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. */ - -typedef struct _oasys_symbol -{ - asymbol symbol; -} oasys_symbol_type; - -typedef struct _oasys_reloc { - arelent relent; - struct _oasys_reloc *next; - unsigned int symbol; -} oasys_reloc_type; - - -#define oasys_symbol(x) ((oasys_symbol_type *)(x)) -#define oasys_per_section(x) ((oasys_per_section_type *)(x->used_by_bfd)) - -typedef struct _oasys_per_section -{ - asection *section; - bfd_byte *data; - bfd_vma offset; - boolean had_vma; - oasys_reloc_type **reloc_tail_ptr; - bfd_vma pc; - - - file_ptr current_pos; - unsigned int current_byte; - boolean initialized; -} oasys_per_section_type; - -#define NSECTIONS 10 - -typedef struct _oasys_ar_obstack { - file_ptr file_offset; - bfd *abfd; -} oasys_ar_obstack_type; - - -typedef struct _oasys_module_info { - file_ptr pos; - unsigned int size; - bfd *abfd; - char *name; -} oasys_module_info_type; - -typedef struct _oasys_ar_data { - oasys_module_info_type *module; - unsigned int module_count; - unsigned int module_index; -} oasys_ar_data_type; - -typedef struct _oasys_data { - struct obstack oasys_obstack; - char *strings; - asymbol *symbols; - unsigned int symbol_string_length; - asection *sections[OASYS_MAX_SEC_COUNT]; - file_ptr first_data_record; -} oasys_data_type; - -#define OASYS_DATA(abfd) ((abfd)->tdata.oasys_obj_data) -#define OASYS_AR_DATA(abfd) ((abfd)->tdata.oasys_ar_data) - diff --git a/contrib/gdb/bfd/lynx-core.c b/contrib/gdb/bfd/lynx-core.c deleted file mode 100644 index 2358177..0000000 --- a/contrib/gdb/bfd/lynx-core.c +++ /dev/null @@ -1,233 +0,0 @@ -/* BFD back end for Lynx core files - Copyright 1993 Free Software Foundation, Inc. - Written by Stu Grossman of Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#ifdef LYNX_CORE - -#include <sys/conf.h> -#include <sys/kernel.h> -/* sys/kernel.h should define this, but doesn't always, sigh. */ -#ifndef __LYNXOS -#define __LYNXOS -#endif -#include <sys/mem.h> -#include <sys/signal.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <sys/itimer.h> -#include <sys/file.h> -#include <sys/proc.h> - -/* These are stored in the bfd's tdata */ - -struct lynx_core_struct -{ - int sig; - char cmd[PNMLEN + 1]; -}; - -#define core_hdr(bfd) ((bfd)->tdata.lynx_core_data) -#define core_signal(bfd) (core_hdr(bfd)->sig) -#define core_command(bfd) (core_hdr(bfd)->cmd) - -/* Handle Lynx core dump file. */ - -static asection * -make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos) - bfd *abfd; - CONST char *name; - flagword flags; - bfd_size_type _raw_size; - bfd_vma vma; - file_ptr filepos; -{ - asection *asect; - char *newname; - - newname = bfd_alloc (abfd, strlen (name) + 1); - if (!newname) - return NULL; - - strcpy (newname, name); - - asect = bfd_make_section (abfd, newname); - if (!asect) - return NULL; - - asect->flags = flags; - asect->_raw_size = _raw_size; - asect->vma = vma; - asect->filepos = filepos; - asect->alignment_power = 2; - - return asect; -} - -/* ARGSUSED */ -const bfd_target * -lynx_core_file_p (abfd) - bfd *abfd; -{ - int val; - int secnum; - struct pssentry pss; - size_t tcontext_size; - core_st_t *threadp; - int pagesize; - asection *newsect; - - pagesize = getpagesize (); /* Serious cross-target issue here... This - really needs to come from a system-specific - header file. */ - - /* Get the pss entry from the core file */ - - if (bfd_seek (abfd, 0, SEEK_SET) != 0) - return NULL; - - val = bfd_read ((void *)&pss, 1, sizeof pss, abfd); - if (val != sizeof pss) - { - /* Too small to be a core file */ - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - core_hdr (abfd) = (struct lynx_core_struct *) - bfd_zalloc (abfd, sizeof (struct lynx_core_struct)); - - if (!core_hdr (abfd)) - return NULL; - - strncpy (core_command (abfd), pss.pname, PNMLEN + 1); - - /* Compute the size of the thread contexts */ - - tcontext_size = pss.threadcnt * sizeof (core_st_t); - - /* Allocate space for the thread contexts */ - - threadp = (core_st_t *)bfd_alloc (abfd, tcontext_size); - if (!threadp) - return NULL; - - /* Save thread contexts */ - - if (bfd_seek (abfd, pagesize, SEEK_SET) != 0) - return NULL; - - val = bfd_read ((void *)threadp, pss.threadcnt, sizeof (core_st_t), abfd); - - if (val != tcontext_size) - { - /* Probably too small to be a core file */ - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - core_signal (abfd) = threadp->currsig; - - newsect = make_bfd_asection (abfd, ".stack", - SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS, - pss.ssize, - pss.slimit, - pagesize + tcontext_size); - if (!newsect) - return NULL; - - newsect = make_bfd_asection (abfd, ".data", - SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS, - pss.data_len + pss.bss_len, - pss.data_start, - pagesize + tcontext_size + pss.ssize -#if defined (SPARC) || defined (__SPARC__) - /* SPARC Lynx seems to start dumping - the .data section at a page - boundary. It's OK to check a - #define like SPARC here because this - file can only be compiled on a Lynx - host. */ - + pss.data_start % pagesize -#endif - ); - if (!newsect) - return NULL; - -/* And, now for the .reg/XXX pseudo sections. Each thread has it's own - .reg/XXX section, where XXX is the thread id (without leading zeros). The - currently running thread (at the time of the core dump) also has an alias - called `.reg' (just to keep GDB happy). Note that we use `.reg/XXX' as - opposed to `.regXXX' because GDB expects that .reg2 will be the floating- - point registers. */ - - newsect = make_bfd_asection (abfd, ".reg", - SEC_HAS_CONTENTS, - sizeof (core_st_t), - 0, - pagesize); - if (!newsect) - return NULL; - - for (secnum = 0; secnum < pss.threadcnt; secnum++) - { - char secname[100]; - - sprintf (secname, ".reg/%d", BUILDPID (0, threadp[secnum].tid)); - newsect = make_bfd_asection (abfd, secname, - SEC_HAS_CONTENTS, - sizeof (core_st_t), - 0, - pagesize + secnum * sizeof (core_st_t)); - if (!newsect) - return NULL; - } - - return abfd->xvec; -} - -char * -lynx_core_file_failing_command (abfd) - bfd *abfd; -{ - return core_command (abfd); -} - -/* ARGSUSED */ -int -lynx_core_file_failing_signal (abfd) - bfd *abfd; -{ - return core_signal (abfd); -} - -/* ARGSUSED */ -boolean -lynx_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - return true; /* FIXME, We have no way of telling at this point */ -} - -#endif /* LYNX_CORE */ diff --git a/contrib/gdb/bfd/m68k4knetbsd.c b/contrib/gdb/bfd/m68k4knetbsd.c deleted file mode 100644 index c1ecb43..0000000 --- a/contrib/gdb/bfd/m68k4knetbsd.c +++ /dev/null @@ -1,35 +0,0 @@ -/* BFD back-end for NetBSD/m68k a.out-ish binaries. - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - -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. */ - -#define BYTES_IN_WORD 4 -#define TARGET_IS_BIG_ENDIAN_P - -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE 4096 - -#define DEFAULT_ARCH bfd_arch_m68k -#define MACHTYPE_OK(mtype) \ - ((mtype) == M_68020 || (mtype) == M_68K_NETBSD || (mtype) == M_68K4K_NETBSD \ - || (mtype) == M_UNKNOWN) - -#define MY(OP) CAT(m68k4knetbsd_,OP) -/* This needs to start with a.out so GDB knows it is an a.out variant. */ -#define TARGETNAME "a.out-m68k4k-netbsd" - -#include "netbsd.h" diff --git a/contrib/gdb/bfd/m68klinux.c b/contrib/gdb/bfd/m68klinux.c deleted file mode 100644 index 062165b..0000000 --- a/contrib/gdb/bfd/m68klinux.c +++ /dev/null @@ -1,767 +0,0 @@ -/* BFD back-end for linux flavored m68k a.out binaries. - Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc. - -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. */ - -#define TARGET_PAGE_SIZE 4096 -#define ZMAGIC_DISK_BLOCK_SIZE 1024 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define TEXT_START_ADDR 0x0 -#define N_SHARED_LIB(x) 0 -#define BYTES_IN_WORD 4 - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "aout/aout64.h" -#include "aout/stab_gnu.h" -#include "aout/ar.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -#define TARGET_IS_BIG_ENDIAN_P -#define DEFAULT_ARCH bfd_arch_m68k -#define MY(OP) CAT(m68klinux_,OP) -#define TARGETNAME "a.out-m68k-linux" - -extern const bfd_target MY(vec); - -/* We always generate QMAGIC files in preference to ZMAGIC files. It - would be possible to make this a linker option, if that ever - becomes important. */ - -static void MY_final_link_callback - PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *)); - -static boolean -m68klinux_bfd_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - obj_aout_subformat (abfd) = q_magic_format; - return NAME(aout,final_link) (abfd, info, MY_final_link_callback); -} - -#define MY_bfd_final_link m68klinux_bfd_final_link - -/* Set the machine type correctly. */ - -static boolean -m68klinux_write_object_contents (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - - N_SET_MACHTYPE (*execp, M_68020); - - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - - WRITE_HEADERS(abfd, execp); - - return true; -} - -#define MY_write_object_contents m68klinux_write_object_contents - -/* Code to link against Linux a.out shared libraries. */ - -/* See if a symbol name is a reference to the global offset table. */ - -#ifndef GOT_REF_PREFIX -#define GOT_REF_PREFIX "__GOT_" -#endif - -#define IS_GOT_SYM(name) \ - (strncmp (name, GOT_REF_PREFIX, sizeof GOT_REF_PREFIX - 1) == 0) - -/* See if a symbol name is a reference to the procedure linkage table. */ - -#ifndef PLT_REF_PREFIX -#define PLT_REF_PREFIX "__PLT_" -#endif - -#define IS_PLT_SYM(name) \ - (strncmp (name, PLT_REF_PREFIX, sizeof PLT_REF_PREFIX - 1) == 0) - -/* This string is used to generate specialized error messages. */ - -#ifndef NEEDS_SHRLIB -#define NEEDS_SHRLIB "__NEEDS_SHRLIB_" -#endif - -/* This special symbol is a set vector that contains a list of - pointers to fixup tables. It will be present in any dynamicly - linked file. The linker generated fixup table should also be added - to the list, and it should always appear in the second slot (the - first one is a dummy with a magic number that is defined in - crt0.o). */ - -#ifndef SHARABLE_CONFLICTS -#define SHARABLE_CONFLICTS "__SHARABLE_CONFLICTS__" -#endif - -/* We keep a list of fixups. The terminology is a bit strange, but - each fixup contains two 32 bit numbers. A regular fixup contains - an address and a pointer, and at runtime we should store the - address at the location pointed to by the pointer. A builtin fixup - contains two pointers, and we should read the address using one - pointer and store it at the location pointed to by the other - pointer. Builtin fixups come into play when we have duplicate - __GOT__ symbols for the same variable. The builtin fixup will copy - the GOT pointer from one over into the other. */ - -struct fixup -{ - struct fixup *next; - struct linux_link_hash_entry *h; - bfd_vma value; - - /* Nonzero if this is a jump instruction that needs to be fixed, - zero if this is just a pointer */ - char jump; - - char builtin; -}; - -/* We don't need a special hash table entry structure, but we do need - to keep some information between linker passes, so we use a special - hash table. */ - -struct linux_link_hash_entry -{ - struct aout_link_hash_entry root; -}; - -struct linux_link_hash_table -{ - struct aout_link_hash_table root; - - /* First dynamic object found in link. */ - bfd *dynobj; - - /* Number of fixups. */ - size_t fixup_count; - - /* Number of builtin fixups. */ - size_t local_builtins; - - /* List of fixups. */ - struct fixup *fixup_list; -}; - -static struct bfd_hash_entry *linux_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static struct bfd_link_hash_table *linux_link_hash_table_create - PARAMS ((bfd *)); -static struct fixup *new_fixup - PARAMS ((struct bfd_link_info *, struct linux_link_hash_entry *, - bfd_vma, int)); -static boolean linux_link_create_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean linux_add_one_symbol - PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *, - bfd_vma, const char *, boolean, boolean, - struct bfd_link_hash_entry **)); -static boolean linux_tally_symbols - PARAMS ((struct linux_link_hash_entry *, PTR)); -static boolean linux_finish_dynamic_link - PARAMS ((bfd *, struct bfd_link_info *)); - -/* Routine to create an entry in an Linux link hash table. */ - -static struct bfd_hash_entry * -linux_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct linux_link_hash_entry *ret = (struct linux_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct linux_link_hash_entry *) NULL) - ret = ((struct linux_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct linux_link_hash_entry))); - if (ret == NULL) - return (struct bfd_hash_entry *) ret; - - /* Call the allocation method of the superclass. */ - ret = ((struct linux_link_hash_entry *) - NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret, - table, string)); - if (ret != NULL) - { - /* Set local fields; there aren't any. */ - } - - return (struct bfd_hash_entry *) ret; -} - -/* Create a Linux link hash table. */ - -static struct bfd_link_hash_table * -linux_link_hash_table_create (abfd) - bfd *abfd; -{ - struct linux_link_hash_table *ret; - - ret = ((struct linux_link_hash_table *) - bfd_alloc (abfd, sizeof (struct linux_link_hash_table))); - if (ret == (struct linux_link_hash_table *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return (struct bfd_link_hash_table *) NULL; - } - if (! NAME(aout,link_hash_table_init) (&ret->root, abfd, - linux_link_hash_newfunc)) - { - free (ret); - return (struct bfd_link_hash_table *) NULL; - } - - ret->dynobj = NULL; - ret->fixup_count = 0; - ret->local_builtins = 0; - ret->fixup_list = NULL; - - return &ret->root.root; -} - -/* Look up an entry in a Linux link hash table. */ - -#define linux_link_hash_lookup(table, string, create, copy, follow) \ - ((struct linux_link_hash_entry *) \ - aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\ - (follow))) - -/* Traverse a Linux link hash table. */ - -#define linux_link_hash_traverse(table, func, info) \ - (aout_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the Linux link hash table from the info structure. This is - just a cast. */ - -#define linux_hash_table(p) ((struct linux_link_hash_table *) ((p)->hash)) - -/* Store the information for a new fixup. */ - -static struct fixup * -new_fixup (info, h, value, builtin) - struct bfd_link_info *info; - struct linux_link_hash_entry *h; - bfd_vma value; - int builtin; -{ - struct fixup *f; - - f = (struct fixup *) bfd_hash_allocate (&info->hash->table, - sizeof (struct fixup)); - if (f == NULL) - return f; - f->next = linux_hash_table (info)->fixup_list; - linux_hash_table (info)->fixup_list = f; - f->h = h; - f->value = value; - f->builtin = builtin; - f->jump = 0; - ++linux_hash_table (info)->fixup_count; - return f; -} - -/* We come here once we realize that we are going to link to a shared - library. We need to create a special section that contains the - fixup table, and we ultimately need to add a pointer to this into - the set vector for SHARABLE_CONFLICTS. At this point we do not - know the size of the section, but that's OK - we just need to - create it for now. */ - -static boolean -linux_link_create_dynamic_sections (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - flagword flags; - register asection *s; - - /* Note that we set the SEC_IN_MEMORY flag. */ - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - - /* We choose to use the name ".linux-dynamic" for the fixup table. - Why not? */ - s = bfd_make_section (abfd, ".linux-dynamic"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - s->_raw_size = 0; - s->contents = 0; - - return true; -} - -/* Function to add a single symbol to the linker hash table. This is - a wrapper around _bfd_generic_link_add_one_symbol which handles the - tweaking needed for dynamic linking support. */ - -static boolean -linux_add_one_symbol (info, abfd, name, flags, section, value, string, - copy, collect, hashp) - struct bfd_link_info *info; - bfd *abfd; - const char *name; - flagword flags; - asection *section; - bfd_vma value; - const char *string; - boolean copy; - boolean collect; - struct bfd_link_hash_entry **hashp; -{ - struct linux_link_hash_entry *h; - boolean insert; - - /* Look up and see if we already have this symbol in the hash table. - If we do, and the defining entry is from a shared library, we - need to create the dynamic sections. - - FIXME: What if abfd->xvec != info->hash->creator? We may want to - be able to link Linux a.out and ELF objects together, but serious - confusion is possible. */ - - insert = false; - - if (! info->relocateable - && linux_hash_table (info)->dynobj == NULL - && strcmp (name, SHARABLE_CONFLICTS) == 0 - && (flags & BSF_CONSTRUCTOR) != 0 - && abfd->xvec == info->hash->creator) - { - if (! linux_link_create_dynamic_sections (abfd, info)) - return false; - linux_hash_table (info)->dynobj = abfd; - insert = true; - } - - if (bfd_is_abs_section (section) - && abfd->xvec == info->hash->creator) - { - h = linux_link_hash_lookup (linux_hash_table (info), name, false, - false, false); - if (h != NULL - && (h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak)) - { - struct fixup *f; - - if (hashp != NULL) - *hashp = (struct bfd_link_hash_entry *) h; - - f = new_fixup (info, h, value, ! IS_PLT_SYM (name)); - if (f == NULL) - return false; - f->jump = IS_PLT_SYM (name); - - return true; - } - } - - /* Do the usual procedure for adding a symbol. */ - if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, - value, string, copy, collect, - hashp)) - return false; - - /* Insert a pointer to our table in the set vector. The dynamic - linker requires this information */ - if (insert) - { - asection *s; - - /* Here we do our special thing to add the pointer to the - dynamic section in the SHARABLE_CONFLICTS set vector. */ - s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, - ".linux-dynamic"); - BFD_ASSERT (s != NULL); - - if (! (_bfd_generic_link_add_one_symbol - (info, linux_hash_table (info)->dynobj, SHARABLE_CONFLICTS, - BSF_GLOBAL | BSF_CONSTRUCTOR, s, 0, NULL, false, false, NULL))) - return false; - } - - return true; -} - -/* We will crawl the hash table and come here for every global symbol. - We will examine each entry and see if there are indications that we - need to add a fixup. There are two possible cases - one is where - you have duplicate definitions of PLT or GOT symbols - these will - have already been caught and added as "builtin" fixups. If we find - that the corresponding non PLT/GOT symbol is also present, we - convert it to a regular fixup instead. - - This function is called via linux_link_hash_traverse. */ - -static boolean -linux_tally_symbols (h, data) - struct linux_link_hash_entry *h; - PTR data; -{ - struct bfd_link_info *info = (struct bfd_link_info *) data; - struct fixup *f, *f1; - int is_plt; - struct linux_link_hash_entry *h1, *h2; - boolean exists; - - if (h->root.root.type == bfd_link_hash_undefined - && strncmp (h->root.root.root.string, NEEDS_SHRLIB, - sizeof NEEDS_SHRLIB - 1) == 0) - { - const char *name; - char *p; - char *alloc = NULL; - - name = h->root.root.root.string + sizeof NEEDS_SHRLIB - 1; - p = strrchr (name, '_'); - if (p != NULL) - alloc = (char *) bfd_malloc (strlen (name) + 1); - - if (p == NULL || alloc == NULL) - (*_bfd_error_handler) ("Output file requires shared library `%s'\n", - name); - else - { - strcpy (alloc, name); - p = strrchr (alloc, '_'); - *p++ = '\0'; - (*_bfd_error_handler) - ("Output file requires shared library `%s.so.%s'\n", - alloc, p); - free (alloc); - } - - abort (); - } - - /* If this symbol is not a PLT/GOT, we do not even need to look at it */ - is_plt = IS_PLT_SYM (h->root.root.root.string); - - if (is_plt || IS_GOT_SYM (h->root.root.root.string)) - { - /* Look up this symbol twice. Once just as a regular lookup, - and then again following all of the indirect links until we - reach a real symbol. */ - h1 = linux_link_hash_lookup (linux_hash_table (info), - (h->root.root.root.string - + sizeof PLT_REF_PREFIX - 1), - false, false, true); - /* h2 does not follow indirect symbols. */ - h2 = linux_link_hash_lookup (linux_hash_table (info), - (h->root.root.root.string - + sizeof PLT_REF_PREFIX - 1), - false, false, false); - - /* The real symbol must exist but if it is also an ABS symbol, - there is no need to have a fixup. This is because they both - came from the same library. If on the other hand, we had to - use an indirect symbol to get to the real symbol, we add the - fixup anyway, since there are cases where these symbols come - from different shared libraries */ - if (h1 != NULL - && (((h1->root.root.type == bfd_link_hash_defined - || h1->root.root.type == bfd_link_hash_defweak) - && ! bfd_is_abs_section (h1->root.root.u.def.section)) - || h2->root.root.type == bfd_link_hash_indirect)) - { - /* See if there is a "builtin" fixup already present - involving this symbol. If so, convert it to a regular - fixup. In the end, this relaxes some of the requirements - about the order of performing fixups. */ - exists = false; - for (f1 = linux_hash_table (info)->fixup_list; - f1 != NULL; - f1 = f1->next) - { - if ((f1->h != h && f1->h != h1) - || (! f1->builtin && ! f1->jump)) - continue; - if (f1->h == h1) - exists = true; - if (! exists - && bfd_is_abs_section (h->root.root.u.def.section)) - { - f = new_fixup (info, h1, f1->h->root.root.u.def.value, 0); - f->jump = is_plt; - } - f1->h = h1; - f1->jump = is_plt; - f1->builtin = 0; - exists = true; - } - if (! exists - && bfd_is_abs_section (h->root.root.u.def.section)) - { - f = new_fixup (info, h1, h->root.root.u.def.value, 0); - if (f == NULL) - { - /* FIXME: No way to return error. */ - abort (); - } - f->jump = is_plt; - } - } - - /* Quick and dirty way of stripping these symbols from the - symtab. */ - if (bfd_is_abs_section (h->root.root.u.def.section)) - h->root.written = true; - } - - return true; -} - -/* This is called to set the size of the .linux-dynamic section is. - It is called by the Linux linker emulation before_allocation - routine. We have finished reading all of the input files, and now - we just scan the hash tables to find out how many additional fixups - are required. */ - -boolean -bfd_m68klinux_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - struct fixup *f; - asection *s; - - if (output_bfd->xvec != &MY(vec)) - return true; - - /* First find the fixups... */ - linux_link_hash_traverse (linux_hash_table (info), - linux_tally_symbols, - (PTR) info); - - /* If there are builtin fixups, leave room for a marker. This is - used by the dynamic linker so that it knows that all that follow - are builtin fixups instead of regular fixups. */ - for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next) - { - if (f->builtin) - { - ++linux_hash_table (info)->fixup_count; - ++linux_hash_table (info)->local_builtins; - break; - } - } - - if (linux_hash_table (info)->dynobj == NULL) - { - if (linux_hash_table (info)->fixup_count > 0) - abort (); - return true; - } - - /* Allocate memory for our fixup table. We will fill it in later. */ - s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, - ".linux-dynamic"); - if (s != NULL) - { - s->_raw_size = 8 + linux_hash_table (info)->fixup_count * 8; - s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); - if (s->contents == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - memset (s->contents, 0, (size_t) s->_raw_size); - } - - return true; -} - -/* We come here once we are ready to actually write the fixup table to - the output file. Scan the fixup tables and so forth and generate - the stuff we need. */ - -static boolean -linux_finish_dynamic_link (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - asection *s, *os, *is; - bfd_byte *fixup_table; - struct linux_link_hash_entry *h; - struct fixup *f; - unsigned int new_addr; - int section_offset; - unsigned int fixups_written; - - if (linux_hash_table (info)->dynobj == NULL) - return true; - - s = bfd_get_section_by_name (linux_hash_table (info)->dynobj, - ".linux-dynamic"); - BFD_ASSERT (s != NULL); - os = s->output_section; - fixups_written = 0; - -#ifdef LINUX_LINK_DEBUG - printf ("Fixup table file offset: %x VMA: %x\n", - os->filepos + s->output_offset, - os->vma + s->output_offset); -#endif - - fixup_table = s->contents; - bfd_put_32 (output_bfd, linux_hash_table (info)->fixup_count, fixup_table); - fixup_table += 4; - - /* Fill in fixup table. */ - for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next) - { - if (f->builtin) - continue; - - if (f->h->root.root.type != bfd_link_hash_defined - && f->h->root.root.type != bfd_link_hash_defweak) - { - (*_bfd_error_handler) - ("Symbol %s not defined for fixups\n", - f->h->root.root.root.string); - continue; - } - - is = f->h->root.root.u.def.section; - section_offset = is->output_section->vma + is->output_offset; - new_addr = f->h->root.root.u.def.value + section_offset; - -#ifdef LINUX_LINK_DEBUG - printf ("Fixup(%d) %s: %x %x\n",f->jump, f->h->root.root.string, - new_addr, f->value); -#endif - - if (f->jump) - { - bfd_put_32 (output_bfd, new_addr, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, f->value + 2, fixup_table); - fixup_table += 4; - } - else - { - bfd_put_32 (output_bfd, new_addr, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, f->value, fixup_table); - fixup_table += 4; - } - ++fixups_written; - } - - if (linux_hash_table (info)->local_builtins != 0) - { - /* Special marker so we know to switch to the other type of fixup */ - bfd_put_32 (output_bfd, 0, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, 0, fixup_table); - fixup_table += 4; - ++fixups_written; - for (f = linux_hash_table (info)->fixup_list; f != NULL; f = f->next) - { - if (! f->builtin) - continue; - - if (f->h->root.root.type != bfd_link_hash_defined - && f->h->root.root.type != bfd_link_hash_defweak) - { - (*_bfd_error_handler) - ("Symbol %s not defined for fixups\n", - f->h->root.root.root.string); - continue; - } - - is = f->h->root.root.u.def.section; - section_offset = is->output_section->vma + is->output_offset; - new_addr = f->h->root.root.u.def.value + section_offset; - -#ifdef LINUX_LINK_DEBUG - printf ("Fixup(B) %s: %x %x\n", f->h->root.root.string, - new_addr, f->value); -#endif - - bfd_put_32 (output_bfd, new_addr, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, f->value, fixup_table); - fixup_table += 4; - ++fixups_written; - } - } - - if (linux_hash_table (info)->fixup_count != fixups_written) - { - (*_bfd_error_handler) ("Warning: fixup count mismatch\n"); - while (linux_hash_table (info)->fixup_count > fixups_written) - { - bfd_put_32 (output_bfd, 0, fixup_table); - fixup_table += 4; - bfd_put_32 (output_bfd, 0, fixup_table); - fixup_table += 4; - ++fixups_written; - } - } - - h = linux_link_hash_lookup (linux_hash_table (info), - "__BUILTIN_FIXUPS__", - false, false, false); - - if (h != NULL - && (h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak)) - { - is = h->root.root.u.def.section; - section_offset = is->output_section->vma + is->output_offset; - new_addr = h->root.root.u.def.value + section_offset; - -#ifdef LINUX_LINK_DEBUG - printf ("Builtin fixup table at %x\n", new_addr); -#endif - - bfd_put_32 (output_bfd, new_addr, fixup_table); - } - else - bfd_put_32 (output_bfd, 0, fixup_table); - - if (bfd_seek (output_bfd, os->filepos + s->output_offset, SEEK_SET) != 0) - return false; - - if (bfd_write ((PTR) s->contents, 1, s->_raw_size, output_bfd) - != s->_raw_size) - return false; - - return true; -} - -#define MY_bfd_link_hash_table_create linux_link_hash_table_create -#define MY_add_one_symbol linux_add_one_symbol -#define MY_finish_dynamic_link linux_finish_dynamic_link - -#define MY_zmagic_contiguous 1 - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/m68klynx.c b/contrib/gdb/bfd/m68klynx.c deleted file mode 100644 index 7acdfbc..0000000 --- a/contrib/gdb/bfd/m68klynx.c +++ /dev/null @@ -1,54 +0,0 @@ -/* BFD back-end for m68k binaries under LynxOS. - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - -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. */ - -#define BYTES_IN_WORD 4 -#define N_SHARED_LIB(x) 0 - -#define TEXT_START_ADDR 0 -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define DEFAULT_ARCH bfd_arch_m68k - -#define MY(OP) CAT(m68klynx_aout_,OP) -#define TARGETNAME "a.out-m68k-lynx" - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#include "libaout.h" -#include "aout/aout64.h" - -#define TARGET_IS_BIG_ENDIAN_P - -#ifdef LYNX_CORE - -char *lynx_core_file_failing_command(); -int lynx_core_file_failing_signal(); -boolean lynx_core_file_matches_executable_p(); -const bfd_target *lynx_core_file_p(); - -#define MY_core_file_failing_command lynx_core_file_failing_command -#define MY_core_file_failing_signal lynx_core_file_failing_signal -#define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p -#define MY_core_file_p lynx_core_file_p - -#endif /* LYNX_CORE */ - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/m68knetbsd.c b/contrib/gdb/bfd/m68knetbsd.c deleted file mode 100644 index 3bff530..0000000 --- a/contrib/gdb/bfd/m68knetbsd.c +++ /dev/null @@ -1,35 +0,0 @@ -/* BFD back-end for NetBSD/m68k a.out-ish binaries. - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - -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. */ - -#define BYTES_IN_WORD 4 -#define TARGET_IS_BIG_ENDIAN_P - -#define TARGET_PAGE_SIZE 8192 -#define SEGMENT_SIZE 8192 - -#define DEFAULT_ARCH bfd_arch_m68k -#define MACHTYPE_OK(mtype) \ - ((mtype) == M_68020 || (mtype) == M_68K_NETBSD || (mtype) == M_68K4K_NETBSD \ - || (mtype) == M_UNKNOWN) - -#define MY(OP) CAT(m68knetbsd_,OP) -/* This needs to start with a.out so GDB knows it is an a.out variant. */ -#define TARGETNAME "a.out-m68k-netbsd" - -#include "netbsd.h" diff --git a/contrib/gdb/bfd/m88kmach3.c b/contrib/gdb/bfd/m88kmach3.c deleted file mode 100644 index 7a56408..0000000 --- a/contrib/gdb/bfd/m88kmach3.c +++ /dev/null @@ -1,38 +0,0 @@ -/* BFD back-end for Motorola m88k a.out (Mach 3) binaries. - Copyright (C) 1990, 1991, 1993, 1994 Free Software Foundation, Inc. - -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. */ - -#define TARGET_PAGE_SIZE (4096*2) -#define SEGMENT_SIZE 0x20000 -#define TEXT_START_ADDR 0 -#define BYTES_IN_WORD 4 -#define N_HEADER_IN_TEXT(x) 1 /* (N_MAGIG(x) == ZMAGIC) */ -#define N_SHARED_LIB(x) 0 - -#define N_TXTSIZE(x) ((x).a_text) - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" - -#define DEFAULT_ARCH bfd_arch_m88k -#define MY(OP) CAT(m88kmach3_,OP) -#define TARGETNAME "a.out-m88k-mach3" - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/makefile.dos b/contrib/gdb/bfd/makefile.dos deleted file mode 100644 index 8a22c6a..0000000 --- a/contrib/gdb/bfd/makefile.dos +++ /dev/null @@ -1,49 +0,0 @@ -CFLAGS=-O2 - -.c.o : - gcc $(CFLAGS) -I. -I../include -c $< - -all : libbfd.a - -targets.o : targets.c - gcc $(CFLAGS) -I. -I../include -DSELECT_VECS=&go32coff_vec,&i386aout_vec -DDEFAULT_VECTOR=go32coff_vec -c $*.c - -archures.o : archures.c - gcc $(CFLAGS) -I. -I../include -DSELECT_ARCHITECTURES=bfd_i386_arch -c $*.c - -OBJS = \ - libbfd.o \ - opncls.o \ - bfd.o \ - archive.o \ - targets.o \ - cache.o \ - archures.o \ - corefile.o \ - section.o \ - format.o \ - syms.o \ - reloc.o \ - init.o \ - coffgen.o \ - srec.o \ - hash.o \ - linker.o \ - ecoff.o \ - ecofflink.o \ - elf.o \ - aout32.o \ - stab-sym.o \ - i386aout.o \ - cpu-i386.o \ - coff-go32.o \ - cofflink.o \ - elf32.o \ - binary.o \ - tekhex.o \ - $E - -libbfd.a : $(OBJS) - -rm libbfd.a - ar rvs libbfd.a $(OBJS) - ranlib libbfd.a diff --git a/contrib/gdb/bfd/mipsbsd.c b/contrib/gdb/bfd/mipsbsd.c deleted file mode 100644 index 801f360..0000000 --- a/contrib/gdb/bfd/mipsbsd.c +++ /dev/null @@ -1,467 +0,0 @@ -/* BFD backend for MIPS BSD (a.out) binaries. - Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. - Written by Ralph Campbell. - -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. */ - -#define BYTES_IN_WORD 4 -/* #define ENTRY_CAN_BE_ZERO */ -#define N_HEADER_IN_TEXT(x) 1 -#define N_SHARED_LIB(x) 0 -#define N_TXTADDR(x) \ - (N_MAGIC(x) != ZMAGIC ? (x).a_entry : /* object file or NMAGIC */\ - TEXT_START_ADDR + EXEC_BYTES_SIZE /* no padding */\ - ) -#define N_DATADDR(x) (N_TXTADDR(x)+N_TXTSIZE(x)) -#define TEXT_START_ADDR 4096 -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define DEFAULT_ARCH bfd_arch_mips -#define MACHTYPE_OK(mtype) ((mtype) == M_UNKNOWN \ - || (mtype) == M_MIPS1 || (mtype) == M_MIPS2) -#define MY_symbol_leading_char '\0' - -#define MY(OP) CAT(mipsbsd_,OP) - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" - -#define SET_ARCH_MACH(ABFD, EXEC) \ - MY(set_arch_mach)(ABFD, N_MACHTYPE (EXEC)); \ - MY(choose_reloc_size)(ABFD); -void MY(set_arch_mach) PARAMS ((bfd *abfd, int machtype)); -static void MY(choose_reloc_size) PARAMS ((bfd *abfd)); - -#define MY_write_object_contents MY(write_object_contents) -static boolean MY(write_object_contents) PARAMS ((bfd *abfd)); - -/* We can't use MY(x) here because it leads to a recursive call to CAT - when expanded inside JUMP_TABLE. */ -#define MY_bfd_reloc_type_lookup mipsbsd_reloc_howto_type_lookup -#define MY_canonicalize_reloc mipsbsd_canonicalize_reloc - -#define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define MY_final_link_callback unused -#define MY_bfd_final_link _bfd_generic_final_link - -#define MY_backend_data &MY(backend_data) -#define MY_BFD_TARGET - -#include "aout-target.h" - -void -MY(set_arch_mach) (abfd, machtype) - bfd *abfd; - int machtype; -{ - enum bfd_architecture arch; - long machine; - - /* Determine the architecture and machine type of the object file. */ - switch (machtype) { - - case M_MIPS1: - arch = bfd_arch_mips; - machine = 3000; - break; - - case M_MIPS2: - arch = bfd_arch_mips; - machine = 4000; - break; - - default: - arch = bfd_arch_obscure; - machine = 0; - break; - } - bfd_set_arch_mach(abfd, arch, machine); -} - -/* Determine the size of a relocation entry, based on the architecture */ -static void -MY(choose_reloc_size) (abfd) - bfd *abfd; -{ - switch (bfd_get_arch(abfd)) { - case bfd_arch_sparc: - case bfd_arch_a29k: - case bfd_arch_mips: - obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE; - break; - default: - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - break; - } -} - -/* Write an object file in BSD a.out format. - Section contents have already been written. We write the - file header, symbols, and relocation. */ - -static boolean -MY(write_object_contents) (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - - /* Magic number, maestro, please! */ - switch (bfd_get_arch(abfd)) { - case bfd_arch_m68k: - switch (bfd_get_mach(abfd)) { - case 68010: - N_SET_MACHTYPE(*execp, M_68010); - break; - default: - case 68020: - N_SET_MACHTYPE(*execp, M_68020); - break; - } - break; - case bfd_arch_sparc: - N_SET_MACHTYPE(*execp, M_SPARC); - break; - case bfd_arch_i386: - N_SET_MACHTYPE(*execp, M_386); - break; - case bfd_arch_a29k: - N_SET_MACHTYPE(*execp, M_29K); - break; - case bfd_arch_mips: - switch (bfd_get_mach(abfd)) { - case 4000: - case 6000: - N_SET_MACHTYPE(*execp, M_MIPS2); - break; - default: - N_SET_MACHTYPE(*execp, M_MIPS1); - break; - } - break; - default: - N_SET_MACHTYPE(*execp, M_UNKNOWN); - } - - MY(choose_reloc_size)(abfd); - - WRITE_HEADERS(abfd, execp); - - return true; -} - -/* - * MIPS relocation types. - */ -#define MIPS_RELOC_32 0 -#define MIPS_RELOC_JMP 1 -#define MIPS_RELOC_WDISP16 2 -#define MIPS_RELOC_HI16 3 -#define MIPS_RELOC_HI16_S 4 -#define MIPS_RELOC_LO16 5 - -/* - * This is only called when performing a BFD_RELOC_MIPS_JMP relocation. - * The jump destination address is formed from the upper 4 bits of the - * "current" program counter concatenated with the jump instruction's - * 26 bit field and two trailing zeros. - * If the destination address is not in the same segment as the "current" - * program counter, then we need to signal an error. - */ -static bfd_reloc_status_type -mips_fix_jmp_addr (abfd,reloc_entry,symbol,data,input_section,output_bfd) - bfd *abfd; - arelent *reloc_entry; - struct symbol_cache_entry *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; -{ - bfd_vma relocation, pc; - - /* If this is a partial relocation, just continue. */ - if (output_bfd != (bfd *)NULL) - return bfd_reloc_continue; - - /* If this is an undefined symbol, return error */ - if (bfd_is_und_section (symbol->section) - && (symbol->flags & BSF_WEAK) == 0) - return bfd_reloc_undefined; - - /* - * Work out which section the relocation is targetted at and the - * initial relocation command value. - */ - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - pc = input_section->output_section->vma + input_section->output_offset + - reloc_entry->address + 4; - - if ((relocation & 0xF0000000) != (pc & 0xF0000000)) - return bfd_reloc_overflow; - - return bfd_reloc_continue; -} - -/* - * This is only called when performing a BFD_RELOC_HI16_S relocation. - * We need to see if bit 15 is set in the result. If it is, we add - * 0x10000 and continue normally. This will compensate for the sign extension - * when the low bits are added at run time. - */ -static bfd_reloc_status_type -mips_fix_hi16_s PARAMS ((bfd *, arelent *, asymbol *, PTR, - asection *, bfd *, char **)); - -static bfd_reloc_status_type -mips_fix_hi16_s (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_vma relocation; - - /* If this is a partial relocation, just continue. */ - if (output_bfd != (bfd *)NULL) - return bfd_reloc_continue; - - /* If this is an undefined symbol, return error */ - if (bfd_is_und_section (symbol->section) - && (symbol->flags & BSF_WEAK) == 0) - return bfd_reloc_undefined; - - /* - * Work out which section the relocation is targetted at and the - * initial relocation command value. - */ - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - - if (relocation & 0x8000) - reloc_entry->addend += 0x10000; - - return bfd_reloc_continue; -} - -static reloc_howto_type mips_howto_table_ext[] = { - {MIPS_RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, - "32", false, 0, 0xffffffff, false}, - {MIPS_RELOC_JMP, 2, 2, 26, false, 0, complain_overflow_dont, - mips_fix_jmp_addr, - "MIPS_JMP", false, 0, 0x03ffffff, false}, - {MIPS_RELOC_WDISP16, 2, 2, 16, true, 0, complain_overflow_signed, 0, - "WDISP16", false, 0, 0x0000ffff, false}, - {MIPS_RELOC_HI16, 16, 2, 16, false, 0, complain_overflow_bitfield, 0, - "HI16", false, 0, 0x0000ffff, false}, - {MIPS_RELOC_HI16_S, 16, 2, 16, false, 0, complain_overflow_bitfield, - mips_fix_hi16_s, - "HI16_S", false, 0, 0x0000ffff, false}, - {MIPS_RELOC_LO16, 0, 2, 16, false, 0, complain_overflow_dont, 0, - "LO16", false, 0, 0x0000ffff, false}, -}; - -static reloc_howto_type * -MY(reloc_howto_type_lookup) (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - - if (bfd_get_arch (abfd) != bfd_arch_mips) - return 0; - - switch (code) - { - case BFD_RELOC_CTOR: - case BFD_RELOC_32: - return (&mips_howto_table_ext[MIPS_RELOC_32]); - case BFD_RELOC_MIPS_JMP: - return (&mips_howto_table_ext[MIPS_RELOC_JMP]); - case BFD_RELOC_16_PCREL_S2: - return (&mips_howto_table_ext[MIPS_RELOC_WDISP16]); - case BFD_RELOC_HI16: - return (&mips_howto_table_ext[MIPS_RELOC_HI16]); - case BFD_RELOC_HI16_S: - return (&mips_howto_table_ext[MIPS_RELOC_HI16_S]); - case BFD_RELOC_LO16: - return (&mips_howto_table_ext[MIPS_RELOC_LO16]); - default: - return 0; - } -} - -/* - * This is just like the standard aoutx.h version but we need to do our - * own mapping of external reloc type values to howto entries. - */ -long -MY(canonicalize_reloc)(abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - arelent *tblptr = section->relocation; - unsigned int count, c; - extern reloc_howto_type NAME(aout,ext_howto_table)[]; - - /* If we have already read in the relocation table, return the values. */ - if (section->flags & SEC_CONSTRUCTOR) { - arelent_chain *chain = section->constructor_chain; - - for (count = 0; count < section->reloc_count; count++) { - *relptr++ = &chain->relent; - chain = chain->next; - } - *relptr = 0; - return section->reloc_count; - } - if (tblptr && section->reloc_count) { - for (count = 0; count++ < section->reloc_count;) - *relptr++ = tblptr++; - *relptr = 0; - return section->reloc_count; - } - - if (!NAME(aout,slurp_reloc_table)(abfd, section, symbols)) - return -1; - tblptr = section->relocation; - - /* fix up howto entries */ - for (count = 0; count++ < section->reloc_count;) - { - c = tblptr->howto - NAME(aout,ext_howto_table); - tblptr->howto = &mips_howto_table_ext[c]; - - *relptr++ = tblptr++; - } - *relptr = 0; - return section->reloc_count; -} - -static CONST struct aout_backend_data MY(backend_data) = { - 0, /* zmagic contiguous */ - 1, /* text incl header */ - 0, /* exec_hdr_flags */ - TARGET_PAGE_SIZE, /* text vma */ - MY_set_sizes, - 0, /* text size includes exec header */ - 0, /* add_dynamic_symbols */ - 0, /* add_one_symbol */ - 0, /* link_dynamic_object */ - 0, /* write_dynamic_symbol */ - 0, /* check_dynamic_reloc */ - 0 /* finish_dynamic_link */ -}; - -const bfd_target aout_mips_little_vec = -{ - "a.out-mips-little", /* name */ - bfd_target_aout_flavour, - BFD_ENDIAN_LITTLE, /* target byte order (little) */ - BFD_ENDIAN_LITTLE, /* target headers byte order (little) */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - MY_symbol_leading_char, - ' ', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - {_bfd_dummy_target, MY_object_p, /* bfd_check_format */ - bfd_generic_archive_p, MY_core_file_p}, - {bfd_false, MY_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, MY_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (MY), - BFD_JUMP_TABLE_COPY (MY), - BFD_JUMP_TABLE_CORE (MY), - BFD_JUMP_TABLE_ARCHIVE (MY), - BFD_JUMP_TABLE_SYMBOLS (MY), - BFD_JUMP_TABLE_RELOCS (MY), - BFD_JUMP_TABLE_WRITE (MY), - BFD_JUMP_TABLE_LINK (MY), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) MY_backend_data, -}; - -const bfd_target aout_mips_big_vec = -{ - "a.out-mips-big", /* name */ - bfd_target_aout_flavour, - BFD_ENDIAN_BIG, /* target byte order (big) */ - BFD_ENDIAN_BIG, /* target headers byte order (big) */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - MY_symbol_leading_char, - ' ', /* ar_pad_char */ - 15, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - {_bfd_dummy_target, MY_object_p, /* bfd_check_format */ - bfd_generic_archive_p, MY_core_file_p}, - {bfd_false, MY_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, MY_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (MY), - BFD_JUMP_TABLE_COPY (MY), - BFD_JUMP_TABLE_CORE (MY), - BFD_JUMP_TABLE_ARCHIVE (MY), - BFD_JUMP_TABLE_SYMBOLS (MY), - BFD_JUMP_TABLE_RELOCS (MY), - BFD_JUMP_TABLE_WRITE (MY), - BFD_JUMP_TABLE_LINK (MY), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) MY_backend_data, -}; diff --git a/contrib/gdb/bfd/mpw-config.in b/contrib/gdb/bfd/mpw-config.in deleted file mode 100644 index 9195d0e..0000000 --- a/contrib/gdb/bfd/mpw-config.in +++ /dev/null @@ -1,73 +0,0 @@ -# Configuration fragment for BFD. - -# This is almost always correct. - -Set selarchs "&bfd_{target_cpu}_arch" -Set defvec "" -Set selvecs "" - -If "{target_canonical}" =~ /m68k-apple-macos/ - Set BFD_BACKENDS '"{o}"coff-m68k.c.o "{o}"cofflink.c.o' - Set defvec m68kcoff_vec - Set selvecs '&m68kcoff_vec' - -Else If "{target_canonical}" =~ /powerpc-apple-macos/ - Set BFD_BACKENDS '"{o}"coff-pmac.c.o "{o}"xcofflink.c.o' - Set defvec pmac_xcoff_vec - Set selvecs '&pmac_xcoff_vec' - Set selarchs "&bfd_powerpc_arch" - -Else If "{target_canonical}" =~ /i386-unknown-go32/ - Set BFD_BACKENDS '"{o}"coff-i386.c.o' - Set defvec i386coff_vec - Set selvecs '&i386coff_vec' - -Else If "{target_canonical}" =~ /mips-\Option-x-\Option-x/ - Set BFD_BACKENDS '"{o}"coff-mips.c.o "{o}"ecoff.c.o "{o}"ecofflink.c.o' - Set defvec ecoff_big_vec - Set selvecs '&ecoff_big_vec,&ecoff_little_vec' - -Else If "{target_canonical}" =~ /sh-hitachi-hms/ - Set BFD_BACKENDS '"{o}"coff-sh.c.o "{o}"cofflink.c.o' - Set defvec shcoff_vec - Set selvecs '&shcoff_vec,&shlcoff_vec' -End If - -Set ta `echo {selarchs} | sed -e 's/&bfd_/{o}cpu-/g' -e 's/_arch/.c.o/g'` - -Set tdefaults "-d DEFAULT_VECTOR={defvec} -d SELECT_VECS={selvecs} -d SELECT_ARCHITECTURES={selarchs}" - -Echo '# From mpw-config.in' > "{o}"mk.tmp -Echo 'WORDSIZE = 32' >> "{o}"mk.tmp -Echo 'BFD_MACHINES = ' {ta} >> "{o}"mk.tmp -Echo 'BFD_BACKENDS = ' {BFD_BACKENDS} >> "{o}"mk.tmp -Echo 'TDEFAULTS = ' {tdefaults} >> "{o}"mk.tmp -Echo 'HDEPFILES = ' >> "{o}"mk.tmp -Echo 'TDEPFILES = ' >> "{o}"mk.tmp -Echo '# End from mpw-config.in' >> "{o}"mk.tmp - -Echo '/* config.h. Generated by mpw-configure. */' > "{o}"config.new -Echo '#include "mpw.h"' >> "{o}"config.new - -MoveIfChange "{o}"config.new "{o}"config.h - -# We can only handle 32-bit targets right now. - -sed -e 's/@WORDSIZE@/32/' \Option-d - -e "s/@VERSION@/`Catenate {srcdir}VERSION`/" \Option-d - -e 's/@BFD_HOST_64BIT_LONG@/0/' \Option-d - "{srcdir}"bfd-in2.h >"{o}"bfd.h-new - -MoveIfChange "{o}"bfd.h-new "{o}"bfd.h - -# Pre-expand some macros in coffswap.h, so MPW C doesn't choke. - -sed -e 's/^ PUT_AOUTHDR_TSIZE (/ bfd_h_put_32 (/' \Option-d - -e 's/^ PUT_AOUTHDR_DSIZE (/ bfd_h_put_32 (/' \Option-d - -e 's/^ PUT_AOUTHDR_BSIZE (/ bfd_h_put_32 (/' \Option-d - -e 's/^ PUT_AOUTHDR_ENTRY (/ bfd_h_put_32 (/' \Option-d - -e 's/^ PUT_AOUTHDR_TEXT_START (/ bfd_h_put_32 (/' \Option-d - -e 's/^ PUT_AOUTHDR_DATA_START (/ bfd_h_put_32 (/' \Option-d - "{srcdir}"coffswap.h >"{o}"coffswap.h-new - -MoveIfChange "{o}"coffswap.h-new "{o}"coffswap.h diff --git a/contrib/gdb/bfd/mpw-make.sed b/contrib/gdb/bfd/mpw-make.sed deleted file mode 100644 index a989ef0..0000000 --- a/contrib/gdb/bfd/mpw-make.sed +++ /dev/null @@ -1,70 +0,0 @@ -# Sed commands to finish translating the Unix BFD Makefile into MPW syntax. - -# Whack out unused host and target define bits. -/HDEFINES/s/@HDEFINES@// -/TDEFINES/s/@TDEFINES@// - -/INCDIR=/s/"{srcdir}":/"{topsrcdir}"/ -/^CSEARCH = .*$/s/$/ -i "{INCDIR}":mpw: -i ::extra-include:/ - -/WORDSIZE/s/^WORDSIZE = /#WORDSIZE = / -/BFD_MACHINES/s/^BFD_MACHINES = /#BFD_MACHINES = / -/BFD_BACKENDS/s/^BFD_BACKENDS = /#BFD_BACKENDS = / -/TDEFAULTS/s/^TDEFAULTS = /#TDEFAULTS = / - -# Remove extra, useless, "all". -/^all \\Option-f _oldest/,/^$/d - -# Remove the Makefile rebuild rule. -/^Makefile /,/--recheck/d - -# Don't do any recursive subdir stuff. -/ subdir_do/s/{MAKE}/null-command/ - -/BFD_H/s/^{BFD_H}/#{BFD_H}/ - -# Point at include files that are always in the objdir. -/bfd/s/"{s}"bfd\.h/"{o}"bfd.h/g -/config/s/"{s}"config\.h/"{o}"config.h/g -/elf32-target/s/"{s}"elf32-target\.h/"{o}"elf32-target.h/g -/elf64-target/s/"{s}"elf64-target\.h/"{o}"elf64-target.h/g - -/"{s}"{INCDIR}/s/"{s}"{INCDIR}/"{INCDIR}"/g - -/dep/s/\.dep/__dep/g - -# Removing duplicates is cool but presently unnecessary, -# so whack this out. -/^ofiles \\Option-f/,/^$/d -/ofiles/s/{OFILES} ofiles/{OFILES}/ -/echo ofiles = /d -/cat ofiles/s/`cat ofiles`/{OFILES}/ - -# No corefile support. -/COREFILE/s/@COREFILE@// -/COREFLAG/s/@COREFLAG@// - -# No PIC foolery in this environment. -/@ALLLIBS@/s/@ALLLIBS@/{TARGETLIB}/ -/@PICLIST@/s/@PICLIST@// -/@PICFLAG@/s/@PICFLAG@// -/^{OFILES} \\Option-f stamp-picdir/,/^$/d - -# Remove the pic trickery from the default build rule. -/^\.c\.o \\Option-f /,/End If/c\ -.c.o \\Option-f .c - -# MPW Make doesn't know about $<. -/"{o}"targets.c.o \\Option-f "{s}"targets.c Makefile/,/^$/c\ -"{o}"targets.c.o \\Option-f "{s}"targets.c Makefile\ - {CC} {ALL_CFLAGS} {TDEFAULTS} "{s}"targets.c -o "{o}"targets.c.o - -/"{o}"archures.c.o \\Option-f "{s}"archures.c Makefile/,/^$/c\ -"{o}"archures.c.o \\Option-f "{s}"archures.c Makefile\ - {CC} {ALL_CFLAGS} {TDEFAULTS} "{s}"archures.c -o "{o}"archures.c.o - -# Remove the .h rebuilding rules, we don't currently have a doc subdir, -# or a way to build the prototype-hacking tool that's in it. -/^"{srcdir}"bfd-in2.h \\Option-f /,/^$/d -/^"{srcdir}"libbfd.h \\Option-f /,/^$/d -/^"{srcdir}"libcoff.h \\Option-f /,/^$/d diff --git a/contrib/gdb/bfd/netbsd-core.c b/contrib/gdb/bfd/netbsd-core.c deleted file mode 100644 index 4e82867..0000000 --- a/contrib/gdb/bfd/netbsd-core.c +++ /dev/null @@ -1,310 +0,0 @@ -/* BFD back end for NetBSD style core files - Copyright 1988, 1989, 1991, 1992, 1993, 1996 Free Software Foundation, Inc. - Written by Paul Kranenburg, EUR - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -#include <stdio.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/dir.h> -#include <signal.h> -#include <sys/core.h> -#include <errno.h> - -/* - * FIXME: On NetBSD/sparc CORE_FPU_OFFSET should be (sizeof(struct trapframe)) - */ - -struct netbsd_core_struct { - struct core core; -} *rawptr; - -/* forward declarations */ - -static const bfd_target * netbsd_core_core_file_p PARAMS ((bfd *abfd)); -static char * netbsd_core_core_file_failing_command PARAMS ((bfd *abfd)); -static int netbsd_core_core_file_failing_signal PARAMS ((bfd *abfd)); -static boolean netbsd_core_core_file_matches_executable_p - PARAMS ((bfd *core_bfd, bfd *exec_bfd)); - -/* Handle NetBSD-style core dump file. */ - -/* ARGSUSED */ -static const bfd_target * -netbsd_core_core_file_p (abfd) - bfd *abfd; - -{ - int i, val, offset; - asection *asect, *asect2; - struct core core; - struct coreseg coreseg; - - val = bfd_read ((void *)&core, 1, sizeof core, abfd); - if (val != sizeof core) { - /* Too small to be a core file */ - bfd_set_error(bfd_error_wrong_format); - return 0; - } - - if (CORE_GETMAGIC(core) != COREMAGIC) { - bfd_set_error(bfd_error_wrong_format); - return 0; - } - - rawptr = (struct netbsd_core_struct *) - bfd_zalloc (abfd, sizeof (struct netbsd_core_struct)); - if (rawptr == NULL) { - bfd_set_error(bfd_error_no_memory); - return 0; - } - - rawptr->core = core; - abfd->tdata.netbsd_core_data = rawptr; - - offset = core.c_hdrsize; - for (i = 0; i < core.c_nseg; i++) { - - if (bfd_seek (abfd, offset, SEEK_SET) != 0) - goto punt; - - val = bfd_read ((void *)&coreseg, 1, sizeof coreseg, abfd); - if (val != sizeof coreseg) { - bfd_set_error(bfd_error_file_truncated); - goto punt; - } - if (CORE_GETMAGIC(coreseg) != CORESEGMAGIC) { - bfd_set_error(bfd_error_wrong_format); - goto punt; - } - - offset += core.c_seghdrsize; - - asect = (asection *) bfd_zalloc (abfd, sizeof(asection)); - if (asect == NULL) { - bfd_set_error(bfd_error_no_memory); - } - - asect->_raw_size = coreseg.c_size; - asect->vma = coreseg.c_addr; - asect->filepos = offset; - asect->alignment_power = 2; - asect->next = abfd->sections; - abfd->sections = asect; - abfd->section_count++; - offset += coreseg.c_size; - - switch (CORE_GETFLAG(coreseg)) { - case CORE_CPU: - asect->name = ".reg"; - asect->flags = SEC_ALLOC + SEC_HAS_CONTENTS; -#ifdef CORE_FPU_OFFSET - /* Hackish... */ - asect->_raw_size = CORE_FPU_OFFSET; - asect2 = (asection *)bfd_zalloc (abfd, - sizeof (asection)); - if (asect2 == NULL) { - bfd_set_error(bfd_error_no_memory); - goto punt; - } - asect2->_raw_size = coreseg.c_size - CORE_FPU_OFFSET; - asect2->vma = 0; - asect2->filepos = asect->filepos + CORE_FPU_OFFSET; - asect2->alignment_power = 2; - asect2->next = abfd->sections; - asect2->name = ".reg2"; - asect2->flags = SEC_ALLOC + SEC_HAS_CONTENTS; - abfd->sections = asect2; - abfd->section_count++; -#endif - - break; - case CORE_DATA: - asect->name = ".data"; - asect->flags = SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS; - break; - case CORE_STACK: - asect->name = ".stack"; - asect->flags = SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS; - break; - } - } - - /* OK, we believe you. You're a core file (sure, sure). */ - return abfd->xvec; - -punt: { - asection *anext; - for (asect = abfd->sections; asect; asect = anext) { - anext = asect->next; - free((void *)asect); - } - } - free ((void *)rawptr); - abfd->tdata.netbsd_core_data = NULL; - abfd->sections = NULL; - abfd->section_count = 0; - return 0; -} - -static char* -netbsd_core_core_file_failing_command (abfd) - bfd *abfd; -{ - /*return core_command (abfd);*/ - return abfd->tdata.netbsd_core_data->core.c_name; -} - -/* ARGSUSED */ -static int -netbsd_core_core_file_failing_signal (abfd) - bfd *abfd; -{ - /*return core_signal (abfd);*/ - return abfd->tdata.netbsd_core_data->core.c_signo; -} - -/* ARGSUSED */ -static boolean -netbsd_core_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - return true; /* FIXME, We have no way of telling at this point */ -} - -/* No archive file support via this BFD */ -#define netbsd_openr_next_archived_file bfd_generic_openr_next_archived_file -#define netbsd_generic_stat_arch_elt bfd_generic_stat_arch_elt -#define netbsd_slurp_armap bfd_false -#define netbsd_slurp_extended_name_table bfd_true -#define netbsd_write_armap (boolean (*) PARAMS \ - ((bfd *arch, unsigned int elength, struct orl *map, \ - unsigned int orl_count, int stridx))) bfd_false -#define netbsd_truncate_arname bfd_dont_truncate_arname -#define aout_32_openr_next_archived_file bfd_generic_openr_next_archived_file - -#define netbsd_close_and_cleanup bfd_generic_close_and_cleanup -#define netbsd_set_section_contents (boolean (*) PARAMS \ - ((bfd *abfd, asection *section, PTR data, file_ptr offset, \ - bfd_size_type count))) bfd_false -#define netbsd_get_section_contents bfd_generic_get_section_contents -#define netbsd_new_section_hook (boolean (*) PARAMS \ - ((bfd *, sec_ptr))) bfd_true -#define netbsd_get_symtab_upper_bound bfd_0u -#define netbsd_get_symtab (unsigned int (*) PARAMS \ - ((bfd *, struct symbol_cache_entry **))) bfd_0u -#define netbsd_get_reloc_upper_bound (unsigned int (*) PARAMS \ - ((bfd *, sec_ptr))) bfd_0u -#define netbsd_canonicalize_reloc (unsigned int (*) PARAMS \ - ((bfd *, sec_ptr, arelent **, struct symbol_cache_entry**))) bfd_0u -#define netbsd_make_empty_symbol (struct symbol_cache_entry * \ - (*) PARAMS ((bfd *))) bfd_false -#define netbsd_print_symbol (void (*) PARAMS \ - ((bfd *, PTR, struct symbol_cache_entry *, \ - bfd_print_symbol_type))) bfd_false -#define netbsd_get_symbol_info (void (*) PARAMS \ - ((bfd *, struct symbol_cache_entry *, \ - symbol_info *))) bfd_false -#define netbsd_get_lineno (alent * (*) PARAMS \ - ((bfd *, struct symbol_cache_entry *))) bfd_nullvoidptr -#define netbsd_set_arch_mach (boolean (*) PARAMS \ - ((bfd *, enum bfd_architecture, unsigned long))) bfd_false -#define netbsd_find_nearest_line (boolean (*) PARAMS \ - ((bfd *abfd, struct sec *section, \ - struct symbol_cache_entry **symbols,bfd_vma offset, \ - CONST char **file, CONST char **func, unsigned int *line))) bfd_false -#define netbsd_sizeof_headers (int (*) PARAMS \ - ((bfd *, boolean))) bfd_0 - -#define netbsd_bfd_debug_info_start bfd_void -#define netbsd_bfd_debug_info_end bfd_void -#define netbsd_bfd_debug_info_accumulate (void (*) PARAMS \ - ((bfd *, struct sec *))) bfd_void -#define netbsd_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents -#define netbsd_bfd_relax_section bfd_generic_relax_section -#define netbsd_bfd_seclet_link \ - ((boolean (*) PARAMS ((bfd *, PTR, boolean))) bfd_false) -#define netbsd_bfd_reloc_type_lookup \ - ((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr) -#define netbsd_bfd_make_debug_symbol \ - ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr) - -/* If somebody calls any byte-swapping routines, shoot them. */ -static void -swap_abort() -{ - abort(); /* This way doesn't require any declaration for ANSI to fuck up */ -} -#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort ) -#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort ) -#define NO_SIGNED_GET \ - ((bfd_signed_vma (*) PARAMS (( const bfd_byte *))) swap_abort ) - -const bfd_target netbsd_core_vec = - { - "netbsd-core", - bfd_target_unknown_flavour, - true, /* target byte order */ - true, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* symbol prefix */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - 3, /* minimum alignment power */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */ - - { /* bfd_check_format */ - _bfd_dummy_target, /* unknown format */ - _bfd_dummy_target, /* object file */ - _bfd_dummy_target, /* archive */ - netbsd_core_core_file_p /* a core file */ - }, - { /* bfd_set_format */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - { /* bfd_write_contents */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (netbsd_core), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (_bfd_generic), - BFD_JUMP_TABLE_LINK (_bfd_nolink), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 /* backend_data */ -}; diff --git a/contrib/gdb/bfd/netbsd.h b/contrib/gdb/bfd/netbsd.h deleted file mode 100644 index dd73d37..0000000 --- a/contrib/gdb/bfd/netbsd.h +++ /dev/null @@ -1,108 +0,0 @@ -/* BFD back-end definitions used by all NetBSD targets. - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - -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. -*/ - -/* NetBSD fits its header into the start of its text segment */ -#define N_HEADER_IN_TEXT(x) 1 -#define TEXT_START_ADDR TARGET_PAGE_SIZE - -#define N_MACHTYPE(exec) \ - ((enum machine_type)(((exec).a_info >> 16) & 0x03ff)) -#define N_FLAGS(exec) \ - (((exec).a_info >> 26) & 0x3f) - -#define N_SET_INFO(exec, magic, type, flags) \ - ((exec).a_info = ((magic) & 0xffff) \ - | (((int)(type) & 0x3ff) << 16) \ - | (((flags) & 0x3f) << 24)) -#define N_SET_MACHTYPE(exec, machtype) \ - ((exec).a_info = \ - ((exec).a_info & 0xfb00ffff) | ((((int)(machtype))&0x3ff) << 16)) -#define N_SET_FLAGS(exec, flags) \ - ((exec).a_info = \ - ((exec).a_info & 0x03ffffff) | ((flags & 0x03f) << 26)) - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" - -/* On NetBSD, the magic number is always in ntohl's "network" (big-endian) - format. */ -#define SWAP_MAGIC(ext) bfd_getb32 (ext) - - -#define MY_write_object_contents MY(write_object_contents) -static boolean MY(write_object_contents) PARAMS ((bfd *abfd)); -#define MY_text_includes_header 1 - -#include "aout-target.h" - -/* Write an object file. - Section contents have already been written. We write the - file header, symbols, and relocation. */ - -static boolean -MY(write_object_contents) (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - -#if CHOOSE_RELOC_SIZE - CHOOSE_RELOC_SIZE(abfd); -#else - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; -#endif - - /* Magic number, maestro, please! */ - switch (bfd_get_arch(abfd)) { - case bfd_arch_m68k: - if (strcmp (abfd->xvec->name, "a.out-m68k4k-netbsd") == 0) - N_SET_MACHTYPE(*execp, M_68K4K_NETBSD); - else - N_SET_MACHTYPE(*execp, M_68K_NETBSD); - break; - case bfd_arch_sparc: - N_SET_MACHTYPE(*execp, M_SPARC_NETBSD); - break; - case bfd_arch_i386: - N_SET_MACHTYPE(*execp, M_386_NETBSD); - break; - case bfd_arch_ns32k: - N_SET_MACHTYPE(*execp, M_532_NETBSD); - break; - default: - N_SET_MACHTYPE(*execp, M_UNKNOWN); - break; - } - - /* The NetBSD magic number is always big-endian */ -#ifndef TARGET_IS_BIG_ENDIAN_P - /* XXX aren't there any macro to change byteorder of a word independent of - the host's or target's endianesses? */ - execp->a_info - = (execp->a_info & 0xff) << 24 | (execp->a_info & 0xff00) << 8 - | (execp->a_info & 0xff0000) >> 8 | (execp->a_info & 0xff000000) >> 24; -#endif - - WRITE_HEADERS(abfd, execp); - - return true; -} diff --git a/contrib/gdb/bfd/newsos3.c b/contrib/gdb/bfd/newsos3.c deleted file mode 100644 index 7ec7a75..0000000 --- a/contrib/gdb/bfd/newsos3.c +++ /dev/null @@ -1,40 +0,0 @@ -/* BFD back-end for NewsOS3 (Sony, 68k) binaries. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - -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. */ - -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define TEXT_START_ADDR 0 -#define BYTES_IN_WORD 4 -#define MY(OP) CAT(newsos3_,OP) -#define TARGETNAME "a.out-newsos3" -#define ENTRY_CAN_BE_ZERO -#define N_SHARED_LIB(x) 0 /* Avoids warning when compiled with -Wall. */ -#define DEFAULT_ARCH bfd_arch_m68k -#define TARGET_IS_BIG_ENDIAN_P -#define N_HEADER_IN_TEXT(x) 0 - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "aout/aout64.h" -#include "aout/stab_gnu.h" -#include "aout/ar.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/nlm-target.h b/contrib/gdb/bfd/nlm-target.h deleted file mode 100644 index cdd3fa8..0000000 --- a/contrib/gdb/bfd/nlm-target.h +++ /dev/null @@ -1,228 +0,0 @@ -/* Target definitions for 32/64-bit NLM (NetWare Loadable Module) - Copyright (C) 1993, 1994 Free Software Foundation, Inc. - -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. */ - -#define nlm_core_file_p _bfd_dummy_target - -#define nlm_get_symtab_upper_bound nlmNAME(get_symtab_upper_bound) -#define nlm_get_symtab nlmNAME(get_symtab) -#define nlm_make_empty_symbol nlmNAME(make_empty_symbol) -#define nlm_print_symbol nlmNAME(print_symbol) -#define nlm_get_symbol_info nlmNAME(get_symbol_info) -#define nlm_bfd_is_local_label bfd_generic_is_local_label -#define nlm_get_lineno _bfd_nosymbols_get_lineno -#define nlm_find_nearest_line _bfd_nosymbols_find_nearest_line -#define nlm_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define nlm_read_minisymbols _bfd_generic_read_minisymbols -#define nlm_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol - -#define nlm_get_reloc_upper_bound nlmNAME(get_reloc_upper_bound) -#define nlm_canonicalize_reloc nlmNAME(canonicalize_reloc) -#define nlm_bfd_reloc_type_lookup bfd_default_reloc_type_lookup - -#define nlm_set_section_contents nlmNAME(set_section_contents) - -#define nlm_sizeof_headers _bfd_nolink_sizeof_headers -#define nlm_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define nlm_bfd_relax_section bfd_generic_relax_section -#define nlm_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define nlm_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define nlm_bfd_final_link _bfd_generic_final_link -#define nlm_bfd_link_split_section _bfd_generic_link_split_section - -/* This structure contains everything that BFD knows about a target. - It includes things like its byte order, name, what routines to call - to do various operations, etc. Every BFD points to a target structure - with its "xvec" member. - - There are two such structures here: one for big-endian machines and - one for little-endian machines. */ - - -#ifdef TARGET_BIG_SYM -const bfd_target TARGET_BIG_SYM = -{ - /* name: identify kind of target */ - TARGET_BIG_NAME, - - /* flavour: general indication about file */ - bfd_target_nlm_flavour, - - /* byteorder: data is big endian */ - BFD_ENDIAN_BIG, - - /* header_byteorder: header is also big endian */ - BFD_ENDIAN_BIG, - - /* object_flags: mask of all file flags */ - (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS - | WP_TEXT), - - /* section_flags: mask of all section flags */ - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | - SEC_CODE | SEC_DATA), - - /* leading_symbol_char: is the first char of a user symbol - predictable, and if so what is it */ - 0, - - /* ar_pad_char: pad character for filenames within an archive header - FIXME: this really has nothing to do with NLM, this is a characteristic - of the archiver and/or os and should be independently tunable */ - '/', - - /* ar_max_namelen: maximum number of characters in an archive header - FIXME: this really has nothing to do with NLM, this is a characteristic - of the archiver and should be independently tunable. This value is - a WAG (wild a** guess) */ - 15, - - /* Routines to byte-swap various sized integers from the data sections */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - - /* Routines to byte-swap various sized integers from the file headers */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - - /* bfd_check_format: check the format of a file being read */ - { _bfd_dummy_target, /* unknown format */ - nlmNAME(object_p), /* assembler/linker output (object file) */ - bfd_generic_archive_p, /* an archive */ - nlm_core_file_p /* a core file */ - }, - - /* bfd_set_format: set the format of a file being written */ - { bfd_false, - nlm_mkobject, - _bfd_generic_mkarchive, - bfd_false - }, - - /* bfd_write_contents: write cached information into a file being written */ - { bfd_false, - nlmNAME(write_object_contents), - _bfd_write_archive_contents, - bfd_false - }, - - /* Initialize a jump table with the standard macro. All names start with - "nlm" */ - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (nlm), - BFD_JUMP_TABLE_RELOCS (nlm), - BFD_JUMP_TABLE_WRITE (nlm), - BFD_JUMP_TABLE_LINK (nlm), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - /* backend_data: */ - (PTR) TARGET_BACKEND_DATA -}; -#endif - -#ifdef TARGET_LITTLE_SYM -const bfd_target TARGET_LITTLE_SYM = -{ - /* name: identify kind of target */ - TARGET_LITTLE_NAME, - - /* flavour: general indication about file */ - bfd_target_nlm_flavour, - - /* byteorder: data is little endian */ - BFD_ENDIAN_LITTLE, - - /* header_byteorder: header is also little endian */ - BFD_ENDIAN_LITTLE, - - /* object_flags: mask of all file flags */ - (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS - | WP_TEXT), - - /* section_flags: mask of all section flags */ - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | - SEC_DATA), - - /* leading_symbol_char: is the first char of a user symbol - predictable, and if so what is it */ - 0, - - /* ar_pad_char: pad character for filenames within an archive header - FIXME: this really has nothing to do with NLM, this is a characteristic - of the archiver and/or os and should be independently tunable */ - '/', - - /* ar_max_namelen: maximum number of characters in an archive header - FIXME: this really has nothing to do with NLM, this is a characteristic - of the archiver and should be independently tunable. This value is - a WAG (wild a** guess) */ - 15, - - /* Routines to byte-swap various sized integers from the data sections */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, - - /* Routines to byte-swap various sized integers from the file headers */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, - - /* bfd_check_format: check the format of a file being read */ - { _bfd_dummy_target, /* unknown format */ - nlmNAME(object_p), /* assembler/linker output (object file) */ - bfd_generic_archive_p, /* an archive */ - nlm_core_file_p /* a core file */ - }, - - /* bfd_set_format: set the format of a file being written */ - { bfd_false, - nlm_mkobject, - _bfd_generic_mkarchive, - bfd_false - }, - - /* bfd_write_contents: write cached information into a file being written */ - { bfd_false, - nlmNAME(write_object_contents), - _bfd_write_archive_contents, - bfd_false - }, - - /* Initialize a jump table with the standard macro. All names start with - "nlm" */ - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (nlm), - BFD_JUMP_TABLE_RELOCS (nlm), - BFD_JUMP_TABLE_WRITE (nlm), - BFD_JUMP_TABLE_LINK (nlm), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - /* backend_data: */ - (PTR) TARGET_BACKEND_DATA -}; -#endif diff --git a/contrib/gdb/bfd/nlm.c b/contrib/gdb/bfd/nlm.c deleted file mode 100644 index 89c6baa..0000000 --- a/contrib/gdb/bfd/nlm.c +++ /dev/null @@ -1,55 +0,0 @@ -/* NLM (NetWare Loadable Module) executable support for BFD. - Copyright (C) 1993 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libnlm.h" - -/* Make an NLM object. We just need to allocate the backend - information. */ - -boolean -nlm_mkobject (abfd) - bfd * abfd; -{ - nlm_tdata (abfd) = - (struct nlm_obj_tdata *) bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata)); - if (nlm_tdata (abfd) == NULL) - return (false); - - if (nlm_architecture (abfd) != bfd_arch_unknown) - bfd_default_set_arch_mach (abfd, nlm_architecture (abfd), - nlm_machine (abfd)); - - /* since everything is done at close time, do we need any initialization? */ - return (true); -} - -/* Set the architecture and machine for an NLM object. */ - -boolean -nlm_set_arch_mach (abfd, arch, machine) - bfd * abfd; - enum bfd_architecture arch; - unsigned long machine; -{ - bfd_default_set_arch_mach (abfd, arch, machine); - return arch == nlm_architecture (abfd); -} diff --git a/contrib/gdb/bfd/nlm32-alpha.c b/contrib/gdb/bfd/nlm32-alpha.c deleted file mode 100644 index 24c8e51..0000000 --- a/contrib/gdb/bfd/nlm32-alpha.c +++ /dev/null @@ -1,892 +0,0 @@ -/* Support for 32-bit Alpha NLM (NetWare Loadable Module) - Copyright (C) 1993 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Cygnus Support. - -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 describes the 32 bit Alpha NLM format. You might think - that an Alpha chip would use a 64 bit format, but, for some reason, - it doesn't. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#define ARCH_SIZE 32 - -#include "nlm/alpha-ext.h" -#define Nlm_External_Fixed_Header Nlm32_alpha_External_Fixed_Header - -#include "libnlm.h" - -static boolean nlm_alpha_backend_object_p - PARAMS ((bfd *)); -static boolean nlm_alpha_write_prefix - PARAMS ((bfd *)); -static boolean nlm_alpha_read_reloc - PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *)); -static boolean nlm_alpha_mangle_relocs - PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type)); -static boolean nlm_alpha_read_import - PARAMS ((bfd *, nlmNAME(symbol_type) *)); -static boolean nlm_alpha_write_import - PARAMS ((bfd *, asection *, arelent *)); -static boolean nlm_alpha_set_public_section - PARAMS ((bfd *, nlmNAME(symbol_type) *)); -static bfd_vma nlm_alpha_get_public_offset - PARAMS ((bfd *, asymbol *)); -static boolean nlm_alpha_write_external - PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *)); - -/* Alpha NLM's have a prefix header before the standard NLM. This - function reads it in, verifies the version, and seeks the bfd to - the location before the regular NLM header. */ - -static boolean -nlm_alpha_backend_object_p (abfd) - bfd *abfd; -{ - struct nlm32_alpha_external_prefix_header s; - bfd_size_type size; - - if (bfd_read ((PTR) &s, sizeof s, 1, abfd) != sizeof s) - return false; - - if (bfd_h_get_32 (abfd, s.magic) != NLM32_ALPHA_MAGIC) - return false; - - /* FIXME: Should we check the format number? */ - - /* Skip to the end of the header. */ - size = bfd_h_get_32 (abfd, s.size); - if (bfd_seek (abfd, size, SEEK_SET) != 0) - return false; - - return true; -} - -/* Write out the prefix. */ - -static boolean -nlm_alpha_write_prefix (abfd) - bfd *abfd; -{ - struct nlm32_alpha_external_prefix_header s; - - memset (&s, 0, sizeof s); - bfd_h_put_32 (abfd, (bfd_vma) NLM32_ALPHA_MAGIC, s.magic); - bfd_h_put_32 (abfd, (bfd_vma) 2, s.format); - bfd_h_put_32 (abfd, (bfd_vma) sizeof s, s.size); - if (bfd_write ((PTR) &s, sizeof s, 1, abfd) != sizeof s) - return false; - return true; -} - -/* How to process the various reloc types. */ - -static reloc_howto_type nlm32_alpha_howto_table[] = -{ - /* Reloc type 0 is ignored by itself. However, it appears after a - GPDISP reloc to identify the location where the low order 16 bits - of the gp register are loaded. */ - HOWTO (ALPHA_R_IGNORE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "IGNORE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 32 bit reference to a symbol. */ - HOWTO (ALPHA_R_REFLONG, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "REFLONG", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 64 bit reference to a symbol. */ - HOWTO (ALPHA_R_REFQUAD, /* type */ - 0, /* rightshift */ - 4, /* size (0 = byte, 1 = short, 2 = long) */ - 64, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "REFQUAD", /* name */ - true, /* partial_inplace */ - 0xffffffffffffffff, /* src_mask */ - 0xffffffffffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 32 bit GP relative offset. This is just like REFLONG except - that when the value is used the value of the gp register will be - added in. */ - HOWTO (ALPHA_R_GPREL32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "GPREL32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Used for an instruction that refers to memory off the GP - register. The offset is 16 bits of the 32 bit instruction. This - reloc always seems to be against the .lita section. */ - HOWTO (ALPHA_R_LITERAL, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "LITERAL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* This reloc only appears immediately following a LITERAL reloc. - It identifies a use of the literal. It seems that the linker can - use this to eliminate a portion of the .lita section. The symbol - index is special: 1 means the literal address is in the base - register of a memory format instruction; 2 means the literal - address is in the byte offset register of a byte-manipulation - instruction; 3 means the literal address is in the target - register of a jsr instruction. This does not actually do any - relocation. */ - HOWTO (ALPHA_R_LITUSE, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "LITUSE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Load the gp register. This is always used for a ldah instruction - which loads the upper 16 bits of the gp register. The next reloc - will be an IGNORE reloc which identifies the location of the lda - instruction which loads the lower 16 bits. The symbol index of - the GPDISP instruction appears to actually be the number of bytes - between the ldah and lda instructions. This gives two different - ways to determine where the lda instruction is; I don't know why - both are used. The value to use for the relocation is the - difference between the GP value and the current location; the - load will always be done against a register holding the current - address. */ - HOWTO (ALPHA_R_GPDISP, /* type */ - 16, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "GPDISP", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - true), /* pcrel_offset */ - - /* A 21 bit branch. The native assembler generates these for - branches within the text segment, and also fills in the PC - relative offset in the instruction. It seems to me that this - reloc, unlike the others, is not partial_inplace. */ - HOWTO (ALPHA_R_BRADDR, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 21, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "BRADDR", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0x1fffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A hint for a jump to a register. */ - HOWTO (ALPHA_R_HINT, /* type */ - 2, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 14, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "HINT", /* name */ - true, /* partial_inplace */ - 0x3fff, /* src_mask */ - 0x3fff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit PC relative offset. */ - HOWTO (ALPHA_R_SREL16, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "SREL16", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32 bit PC relative offset. */ - HOWTO (ALPHA_R_SREL32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "SREL32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* A 64 bit PC relative offset. */ - HOWTO (ALPHA_R_SREL64, /* type */ - 0, /* rightshift */ - 4, /* size (0 = byte, 1 = short, 2 = long) */ - 64, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "SREL64", /* name */ - true, /* partial_inplace */ - 0xffffffffffffffff, /* src_mask */ - 0xffffffffffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Push a value on the reloc evaluation stack. */ - HOWTO (ALPHA_R_OP_PUSH, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "OP_PUSH", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Store the value from the stack at the given address. Store it in - a bitfield of size r_size starting at bit position r_offset. */ - HOWTO (ALPHA_R_OP_STORE, /* type */ - 0, /* rightshift */ - 4, /* size (0 = byte, 1 = short, 2 = long) */ - 64, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "OP_STORE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0xffffffffffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Subtract the reloc address from the value on the top of the - relocation stack. */ - HOWTO (ALPHA_R_OP_PSUB, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "OP_PSUB", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Shift the value on the top of the relocation stack right by the - given value. */ - HOWTO (ALPHA_R_OP_PRSHIFT, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "OP_PRSHIFT", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - /* Adjust the GP value for a new range in the object file. */ - HOWTO (ALPHA_R_GPVALUE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "GPVALUE", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false) /* pcrel_offset */ -}; - -static reloc_howto_type nlm32_alpha_nw_howto = - HOWTO (ALPHA_R_NW_RELOC, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 0, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ - "NW_RELOC", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false); /* pcrel_offset */ - -/* Read an Alpha NLM reloc. This routine keeps some static data which - it uses when handling local relocs. This only works correctly - because all the local relocs are read at once. */ - -static boolean -nlm_alpha_read_reloc (abfd, sym, secp, rel) - bfd *abfd; - nlmNAME(symbol_type) *sym; - asection **secp; - arelent *rel; -{ - static bfd_vma gp_value; - static bfd_vma lita_address; - struct nlm32_alpha_external_reloc ext; - bfd_vma r_vaddr; - long r_symndx; - int r_type, r_extern, r_offset, r_size; - asection *code_sec, *data_sec; - - /* Read the reloc from the file. */ - if (bfd_read (&ext, sizeof ext, 1, abfd) != sizeof ext) - return false; - - /* Swap in the reloc information. */ - r_vaddr = bfd_h_get_64 (abfd, (bfd_byte *) ext.r_vaddr); - r_symndx = bfd_h_get_32 (abfd, (bfd_byte *) ext.r_symndx); - - BFD_ASSERT (bfd_little_endian (abfd)); - - r_type = ((ext.r_bits[0] & RELOC_BITS0_TYPE_LITTLE) - >> RELOC_BITS0_TYPE_SH_LITTLE); - r_extern = (ext.r_bits[1] & RELOC_BITS1_EXTERN_LITTLE) != 0; - r_offset = ((ext.r_bits[1] & RELOC_BITS1_OFFSET_LITTLE) - >> RELOC_BITS1_OFFSET_SH_LITTLE); - /* Ignore the reserved bits. */ - r_size = ((ext.r_bits[3] & RELOC_BITS3_SIZE_LITTLE) - >> RELOC_BITS3_SIZE_SH_LITTLE); - - /* Fill in the BFD arelent structure. */ - code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME); - data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - if (r_extern) - { - /* External relocations are only used for imports. */ - BFD_ASSERT (sym != NULL); - /* We don't need to set sym_ptr_ptr for this case. It is set in - nlm_canonicalize_reloc. */ - rel->sym_ptr_ptr = NULL; - rel->addend = 0; - } - else - { - /* Internal relocations are only used for local relocation - fixups. If they are not NW_RELOC or GPDISP or IGNORE, they - must be against .text or .data. */ - BFD_ASSERT (r_type == ALPHA_R_NW_RELOC || sym == NULL); - if (r_type == ALPHA_R_NW_RELOC - || r_type == ALPHA_R_GPDISP - || r_type == ALPHA_R_IGNORE) - { - rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - rel->addend = 0; - } - else if (r_symndx == ALPHA_RELOC_SECTION_TEXT) - { - rel->sym_ptr_ptr = code_sec->symbol_ptr_ptr; - BFD_ASSERT (bfd_get_section_vma (abfd, code_sec) == 0); - rel->addend = 0; - } - else if (r_symndx == ALPHA_RELOC_SECTION_DATA) - { - rel->sym_ptr_ptr = data_sec->symbol_ptr_ptr; - rel->addend = - bfd_get_section_vma (abfd, data_sec); - } - else - { - BFD_ASSERT (0); - rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - rel->addend = 0; - } - } - - /* We use the address to determine whether the reloc is in the .text - or .data section. R_NW_RELOC relocs don't really have a section, - so we put them in .text. */ - if (r_type == ALPHA_R_NW_RELOC - || r_vaddr < bfd_section_size (abfd, code_sec)) - { - *secp = code_sec; - rel->address = r_vaddr; - } - else - { - *secp = data_sec; - rel->address = r_vaddr - bfd_section_size (abfd, code_sec); - } - - /* We must adjust the addend based on the type. */ - BFD_ASSERT ((r_type >= 0 && r_type <= ALPHA_R_GPVALUE) - || r_type == ALPHA_R_NW_RELOC); - - switch (r_type) - { - case ALPHA_R_BRADDR: - case ALPHA_R_SREL16: - case ALPHA_R_SREL32: - case ALPHA_R_SREL64: - /* The PC relative relocs do not seem to use the section VMA as - a negative addend. */ - rel->addend = 0; - break; - - case ALPHA_R_GPREL32: - /* Copy the gp value for this object file into the addend, to - ensure that we are not confused by the linker. */ - if (! r_extern) - rel->addend += gp_value; - break; - - case ALPHA_R_LITERAL: - BFD_ASSERT (! r_extern); - rel->addend += lita_address; - break; - - case ALPHA_R_LITUSE: - case ALPHA_R_GPDISP: - /* The LITUSE and GPDISP relocs do not use a symbol, or an - addend, but they do use a special code. Put this code in the - addend field. */ - rel->addend = r_symndx; - rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - break; - - case ALPHA_R_OP_STORE: - /* The STORE reloc needs the size and offset fields. We store - them in the addend. */ - BFD_ASSERT (r_offset < 256 && r_size < 256); - rel->addend = (r_offset << 8) + r_size; - break; - - case ALPHA_R_OP_PUSH: - case ALPHA_R_OP_PSUB: - case ALPHA_R_OP_PRSHIFT: - /* The PUSH, PSUB and PRSHIFT relocs do not actually use an - address. I believe that the address supplied is really an - addend. */ - rel->addend = r_vaddr; - break; - - case ALPHA_R_GPVALUE: - /* Record the new gp value. */ - gp_value += r_symndx; - rel->addend = gp_value; - break; - - case ALPHA_R_IGNORE: - /* If the type is ALPHA_R_IGNORE, make sure this is a reference - to the absolute section so that the reloc is ignored. For - some reason the address of this reloc type is not adjusted by - the section vma. We record the gp value for this object file - here, for convenience when doing the GPDISP relocation. */ - rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - rel->address = r_vaddr; - rel->addend = gp_value; - break; - - case ALPHA_R_NW_RELOC: - /* If this is SETGP, we set the addend to 0. Otherwise we set - the addend to the size of the .lita section (this is - r_symndx) plus 1. We have already set the address of the - reloc to r_vaddr. */ - if (r_size == ALPHA_R_NW_RELOC_SETGP) - { - gp_value = r_vaddr; - rel->addend = 0; - } - else if (r_size == ALPHA_R_NW_RELOC_LITA) - { - lita_address = r_vaddr; - rel->addend = r_symndx + 1; - } - else - BFD_ASSERT (0); - rel->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - break; - - default: - break; - } - - if (r_type == ALPHA_R_NW_RELOC) - rel->howto = &nlm32_alpha_nw_howto; - else - rel->howto = &nlm32_alpha_howto_table[r_type]; - - return true; -} - -/* Mangle Alpha NLM relocs for output. */ - -static boolean -nlm_alpha_mangle_relocs (abfd, sec, data, offset, count) - bfd *abfd; - asection *sec; - PTR data; - bfd_vma offset; - bfd_size_type count; -{ - return true; -} - -/* Read an ALPHA NLM import record */ - -static boolean -nlm_alpha_read_import (abfd, sym) - bfd *abfd; - nlmNAME(symbol_type) *sym; -{ - struct nlm_relent *nlm_relocs; /* relocation records for symbol */ - bfd_size_type rcount; /* number of relocs */ - bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */ - unsigned char symlength; /* length of symbol name */ - char *name; - - if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd) - != sizeof (symlength)) - return false; - sym -> symbol.the_bfd = abfd; - name = bfd_alloc (abfd, symlength + 1); - if (name == NULL) - return false; - if (bfd_read (name, symlength, 1, abfd) != symlength) - return false; - name[symlength] = '\0'; - sym -> symbol.name = name; - sym -> symbol.flags = 0; - sym -> symbol.value = 0; - sym -> symbol.section = bfd_und_section_ptr; - if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return false; - rcount = bfd_h_get_32 (abfd, temp); - nlm_relocs = ((struct nlm_relent *) - bfd_alloc (abfd, rcount * sizeof (struct nlm_relent))); - if (!nlm_relocs) - return false; - sym -> relocs = nlm_relocs; - sym -> rcnt = 0; - while (sym -> rcnt < rcount) - { - asection *section; - - if (nlm_alpha_read_reloc (abfd, sym, §ion, - &nlm_relocs -> reloc) - == false) - return false; - nlm_relocs -> section = section; - nlm_relocs++; - sym -> rcnt++; - } - - return true; -} - -/* Write an Alpha NLM reloc. */ - -static boolean -nlm_alpha_write_import (abfd, sec, rel) - bfd *abfd; - asection *sec; - arelent *rel; -{ - asymbol *sym; - bfd_vma r_vaddr; - long r_symndx; - int r_type, r_extern, r_offset, r_size; - struct nlm32_alpha_external_reloc ext; - - sym = *rel->sym_ptr_ptr; - - /* Get values for the relocation fields. */ - r_type = rel->howto->type; - if (r_type != ALPHA_R_NW_RELOC) - { - r_vaddr = bfd_get_section_vma (abfd, sec) + rel->address; - if ((sec->flags & SEC_CODE) == 0) - r_vaddr += bfd_section_size (abfd, - bfd_get_section_by_name (abfd, - NLM_CODE_NAME)); - if (bfd_is_und_section (bfd_get_section (sym))) - { - r_extern = 1; - r_symndx = 0; - } - else - { - r_extern = 0; - if (bfd_get_section_flags (abfd, bfd_get_section (sym)) & SEC_CODE) - r_symndx = ALPHA_RELOC_SECTION_TEXT; - else - r_symndx = ALPHA_RELOC_SECTION_DATA; - } - r_offset = 0; - r_size = 0; - - switch (r_type) - { - case ALPHA_R_LITUSE: - case ALPHA_R_GPDISP: - r_symndx = rel->addend; - break; - - case ALPHA_R_OP_STORE: - r_size = rel->addend & 0xff; - r_offset = (rel->addend >> 8) & 0xff; - break; - - case ALPHA_R_OP_PUSH: - case ALPHA_R_OP_PSUB: - case ALPHA_R_OP_PRSHIFT: - r_vaddr = rel->addend; - break; - - case ALPHA_R_IGNORE: - r_vaddr = rel->address; - break; - - default: - break; - } - } - else - { - /* r_type == ALPHA_R_NW_RELOC */ - r_vaddr = rel->address; - if (rel->addend == 0) - { - r_symndx = 0; - r_size = ALPHA_R_NW_RELOC_SETGP; - } - else - { - r_symndx = rel->addend - 1; - r_size = ALPHA_R_NW_RELOC_LITA; - } - r_extern = 0; - r_offset = 0; - } - - /* Swap out the relocation fields. */ - bfd_h_put_64 (abfd, r_vaddr, (bfd_byte *) ext.r_vaddr); - bfd_h_put_32 (abfd, r_symndx, (bfd_byte *) ext.r_symndx); - - BFD_ASSERT (bfd_little_endian (abfd)); - - ext.r_bits[0] = ((r_type << RELOC_BITS0_TYPE_SH_LITTLE) - & RELOC_BITS0_TYPE_LITTLE); - ext.r_bits[1] = ((r_extern ? RELOC_BITS1_EXTERN_LITTLE : 0) - | ((r_offset << RELOC_BITS1_OFFSET_SH_LITTLE) - & RELOC_BITS1_OFFSET_LITTLE)); - ext.r_bits[2] = 0; - ext.r_bits[3] = ((r_size << RELOC_BITS3_SIZE_SH_LITTLE) - & RELOC_BITS3_SIZE_LITTLE); - - /* Write out the relocation. */ - if (bfd_write (&ext, sizeof ext, 1, abfd) != sizeof ext) - return false; - - return true; -} - -/* Alpha NetWare does not use the high bit to determine whether a - public symbol is in the code segment or the data segment. Instead, - it just uses the address. The set_public_section and - get_public_offset routines override the default code which uses the - high bit. */ - -/* Set the section for a public symbol. */ - -static boolean -nlm_alpha_set_public_section (abfd, sym) - bfd *abfd; - nlmNAME(symbol_type) *sym; -{ - asection *code_sec, *data_sec; - - code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME); - data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - if (sym->symbol.value < bfd_section_size (abfd, code_sec)) - { - sym->symbol.section = code_sec; - sym->symbol.flags |= BSF_FUNCTION; - } - else - { - sym->symbol.section = data_sec; - sym->symbol.value -= bfd_section_size (abfd, code_sec); - /* The data segment had better be aligned. */ - BFD_ASSERT ((bfd_section_size (abfd, code_sec) & 0xf) == 0); - } - return true; -} - -/* Get the offset to write out for a public symbol. */ - -static bfd_vma -nlm_alpha_get_public_offset (abfd, sym) - bfd *abfd; - asymbol *sym; -{ - return bfd_asymbol_value (sym); -} - -/* Write an Alpha NLM external symbol. */ - -static boolean -nlm_alpha_write_external (abfd, count, sym, relocs) - bfd *abfd; - bfd_size_type count; - asymbol *sym; - struct reloc_and_sec *relocs; -{ - int i; - bfd_byte len; - unsigned char temp[NLM_TARGET_LONG_SIZE]; - arelent r; - - len = strlen (sym->name); - if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte)) - || bfd_write (sym->name, len, 1, abfd) != len) - return false; - - bfd_put_32 (abfd, count + 2, temp); - if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return false; - - /* The first two relocs for each external symbol are the .lita - address and the GP value. */ - r.sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - r.howto = &nlm32_alpha_nw_howto; - - r.address = nlm_alpha_backend_data (abfd)->lita_address; - r.addend = nlm_alpha_backend_data (abfd)->lita_size + 1; - if (nlm_alpha_write_import (abfd, (asection *) NULL, &r) == false) - return false; - - r.address = nlm_alpha_backend_data (abfd)->gp; - r.addend = 0; - if (nlm_alpha_write_import (abfd, (asection *) NULL, &r) == false) - return false; - - for (i = 0; i < count; i++) - { - if (nlm_alpha_write_import (abfd, relocs[i].sec, - relocs[i].rel) == false) - return false; - } - - return true; -} - -#include "nlmswap.h" - -static const struct nlm_backend_data nlm32_alpha_backend = -{ - "NetWare Alpha Module \032", - sizeof (Nlm32_alpha_External_Fixed_Header), - sizeof (struct nlm32_alpha_external_prefix_header), - bfd_arch_alpha, - 0, - true, /* no uninitialized data permitted by Alpha NetWare. */ - nlm_alpha_backend_object_p, - nlm_alpha_write_prefix, - nlm_alpha_read_reloc, - nlm_alpha_mangle_relocs, - nlm_alpha_read_import, - nlm_alpha_write_import, - nlm_alpha_set_public_section, - nlm_alpha_get_public_offset, - nlm_swap_fixed_header_in, - nlm_swap_fixed_header_out, - nlm_alpha_write_external, - 0, /* write_export */ -}; - -#define TARGET_LITTLE_NAME "nlm32-alpha" -#define TARGET_LITTLE_SYM nlmNAME(alpha_vec) -#define TARGET_BACKEND_DATA &nlm32_alpha_backend - -#include "nlm-target.h" diff --git a/contrib/gdb/bfd/nlm32-i386.c b/contrib/gdb/bfd/nlm32-i386.c deleted file mode 100644 index f16c74d..0000000 --- a/contrib/gdb/bfd/nlm32-i386.c +++ /dev/null @@ -1,451 +0,0 @@ -/* Support for 32-bit i386 NLM (NetWare Loadable Module) - Copyright (C) 1993 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#define ARCH_SIZE 32 - -#include "nlm/i386-ext.h" -#define Nlm_External_Fixed_Header Nlm32_i386_External_Fixed_Header - -#include "libnlm.h" - -static boolean nlm_i386_read_reloc - PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *)); -static boolean nlm_i386_write_import - PARAMS ((bfd *, asection *, arelent *)); -static boolean nlm_i386_mangle_relocs - PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type)); -static boolean nlm_i386_read_import - PARAMS ((bfd *, nlmNAME(symbol_type) *)); -static boolean nlm_i386_write_external - PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *)); - -/* Adjust the reloc location by an absolute value. */ - -static reloc_howto_type nlm_i386_abs_howto = - HOWTO (0, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false); /* pcrel_offset */ - -/* Adjust the reloc location by a PC relative displacement. */ - -static reloc_howto_type nlm_i386_pcrel_howto = - HOWTO (1, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "DISP32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - true); /* pcrel_offset */ - -/* Read a NetWare i386 reloc. */ - -static boolean -nlm_i386_read_reloc (abfd, sym, secp, rel) - bfd *abfd; - nlmNAME(symbol_type) *sym; - asection **secp; - arelent *rel; -{ - bfd_byte temp[4]; - bfd_vma val; - const char *name; - - if (bfd_read (temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return false; - - val = bfd_get_32 (abfd, temp); - - /* The value is an offset into either the code or data segment. - This is the location which needs to be adjusted. - - If this is a relocation fixup rather than an imported symbol (the - sym argument is NULL) then the high bit is 0 if the location - needs to be adjusted by the address of the data segment, or 1 if - the location needs to be adjusted by the address of the code - segment. If this is an imported symbol, then the high bit is 0 - if the location is 0 if the location should be adjusted by the - offset to the symbol, or 1 if the location should adjusted by the - absolute value of the symbol. - - The second most significant bit is 0 if the value is an offset - into the data segment, or 1 if the value is an offset into the - code segment. - - All this translates fairly easily into a BFD reloc. */ - - if (sym == NULL) - { - if ((val & NLM_HIBIT) == 0) - name = NLM_INITIALIZED_DATA_NAME; - else - { - name = NLM_CODE_NAME; - val &=~ NLM_HIBIT; - } - rel->sym_ptr_ptr = bfd_get_section_by_name (abfd, name)->symbol_ptr_ptr; - rel->howto = &nlm_i386_abs_howto; - } - else - { - /* In this case we do not need to set the sym_ptr_ptr field. */ - rel->sym_ptr_ptr = NULL; - if ((val & NLM_HIBIT) == 0) - rel->howto = &nlm_i386_pcrel_howto; - else - { - rel->howto = &nlm_i386_abs_howto; - val &=~ NLM_HIBIT; - } - } - - if ((val & (NLM_HIBIT >> 1)) == 0) - *secp = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - else - { - *secp = bfd_get_section_by_name (abfd, NLM_CODE_NAME); - val &=~ (NLM_HIBIT >> 1); - } - - rel->address = val; - rel->addend = 0; - - return true; -} - -/* Write a NetWare i386 reloc. */ - -static boolean -nlm_i386_write_import (abfd, sec, rel) - bfd *abfd; - asection *sec; - arelent *rel; -{ - asymbol *sym; - bfd_vma val; - bfd_byte temp[4]; - - /* NetWare only supports two kinds of relocs. We should check - special_function here, as well, but at the moment coff-i386 - relocs uses a special_function which does not affect what we do - here. */ - if (rel->addend != 0 - || rel->howto == NULL - || rel->howto->rightshift != 0 - || rel->howto->size != 2 - || rel->howto->bitsize != 32 - || rel->howto->bitpos != 0 - || rel->howto->src_mask != 0xffffffff - || rel->howto->dst_mask != 0xffffffff) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - sym = *rel->sym_ptr_ptr; - - /* The value we write out is the offset into the appropriate - segment. This offset is the section vma, adjusted by the vma of - the lowest section in that segment, plus the address of the - relocation. */ - val = bfd_get_section_vma (abfd, sec) + rel->address; - - /* The second most significant bit is 0 if the value is an offset - into the data segment, or 1 if the value is an offset into the - code segment. */ - if (bfd_get_section_flags (abfd, sec) & SEC_CODE) - { - val -= nlm_get_text_low (abfd); - val |= NLM_HIBIT >> 1; - } - else - val -= nlm_get_data_low (abfd); - - if (! bfd_is_und_section (bfd_get_section (sym))) - { - /* NetWare only supports absolute internal relocs. */ - if (rel->howto->pc_relative) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - /* The high bit is 1 if the reloc is against the code section, 0 - if against the data section. */ - if (bfd_get_section_flags (abfd, bfd_get_section (sym)) & SEC_CODE) - val |= NLM_HIBIT; - } - else - { - /* The high bit is 1 if this is an absolute reloc, 0 if it is PC - relative. */ - if (! rel->howto->pc_relative) - val |= NLM_HIBIT; - else - { - /* PC relative relocs on NetWare must be pcrel_offset. */ - if (! rel->howto->pcrel_offset) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - } - } - - bfd_put_32 (abfd, val, temp); - if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return false; - - return true; -} - -/* I want to be able to use objcopy to turn a i386 a.out or COFF file - into a NetWare i386 module. That means that the relocs from the - source file have to be mapped into relocs that apply to the target - file. This function is called by nlm_set_section_contents to give - it a chance to rework the relocs. - - This is actually a fairly general concept. However, this is not a - general implementation. */ - -static boolean -nlm_i386_mangle_relocs (abfd, sec, data, offset, count) - bfd *abfd; - asection *sec; - PTR data; - bfd_vma offset; - bfd_size_type count; -{ - arelent **rel_ptr_ptr, **rel_end; - - rel_ptr_ptr = sec->orelocation; - rel_end = rel_ptr_ptr + sec->reloc_count; - for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++) - { - arelent *rel; - asymbol *sym; - bfd_vma addend; - - rel = *rel_ptr_ptr; - sym = *rel->sym_ptr_ptr; - - /* Note that no serious harm will ensue if we fail to change a - reloc. We will wind up failing in nlm_i386_write_import. */ - - /* Make sure this reloc is within the data we have. We only 4 - byte relocs here, so we insist on having 4 bytes. */ - if (rel->address < offset - || rel->address + 4 > offset + count) - continue; - - /* NetWare doesn't support reloc addends, so we get rid of them - here by simply adding them into the object data. We handle - the symbol value, if any, the same way. */ - addend = rel->addend + sym->value; - - /* The value of a symbol is the offset into the section. If the - symbol is in the .bss segment, we need to include the size of - the data segment in the offset as well. Fortunately, we know - that at this point the size of the data section is in the NLM - header. */ - if (((bfd_get_section_flags (abfd, bfd_get_section (sym)) - & SEC_LOAD) == 0) - && ((bfd_get_section_flags (abfd, bfd_get_section (sym)) - & SEC_ALLOC) != 0)) - addend += nlm_fixed_header (abfd)->dataImageSize; - - if (addend != 0 - && rel->howto != NULL - && rel->howto->rightshift == 0 - && rel->howto->size == 2 - && rel->howto->bitsize == 32 - && rel->howto->bitpos == 0 - && rel->howto->src_mask == 0xffffffff - && rel->howto->dst_mask == 0xffffffff) - { - bfd_vma val; - - val = bfd_get_32 (abfd, (bfd_byte *) data + rel->address - offset); - val += addend; - bfd_put_32 (abfd, val, (bfd_byte *) data + rel->address - offset); - rel->addend = 0; - } - - /* NetWare uses a reloc with pcrel_offset set. We adjust - pc_relative relocs accordingly. We are going to change the - howto field, so we can only do this if the current one is - compatible. We should check special_function here, but at - the moment coff-i386 uses a special_function which does not - affect what we are doing here. */ - if (rel->howto != NULL - && rel->howto->pc_relative - && ! rel->howto->pcrel_offset - && rel->howto->rightshift == 0 - && rel->howto->size == 2 - && rel->howto->bitsize == 32 - && rel->howto->bitpos == 0 - && rel->howto->src_mask == 0xffffffff - && rel->howto->dst_mask == 0xffffffff) - { - bfd_vma val; - - /* When pcrel_offset is not set, it means that the negative - of the address of the memory location is stored in the - memory location. We must add it back in. */ - val = bfd_get_32 (abfd, (bfd_byte *) data + rel->address - offset); - val += rel->address; - bfd_put_32 (abfd, val, (bfd_byte *) data + rel->address - offset); - - rel->howto = &nlm_i386_pcrel_howto; - } - } - - return true; -} - -/* Read a NetWare i386 import record */ -static boolean -nlm_i386_read_import (abfd, sym) - bfd *abfd; - nlmNAME(symbol_type) *sym; -{ - struct nlm_relent *nlm_relocs; /* relocation records for symbol */ - bfd_size_type rcount; /* number of relocs */ - bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */ - unsigned char symlength; /* length of symbol name */ - char *name; - - if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd) - != sizeof (symlength)) - return false; - sym -> symbol.the_bfd = abfd; - name = bfd_alloc (abfd, symlength + 1); - if (name == NULL) - return false; - if (bfd_read (name, symlength, 1, abfd) != symlength) - return false; - name[symlength] = '\0'; - sym -> symbol.name = name; - sym -> symbol.flags = 0; - sym -> symbol.value = 0; - sym -> symbol.section = bfd_und_section_ptr; - if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return false; - rcount = bfd_h_get_32 (abfd, temp); - nlm_relocs = ((struct nlm_relent *) - bfd_alloc (abfd, rcount * sizeof (struct nlm_relent))); - if (!nlm_relocs) - return false; - sym -> relocs = nlm_relocs; - sym -> rcnt = 0; - while (sym -> rcnt < rcount) - { - asection *section; - - if (nlm_i386_read_reloc (abfd, sym, §ion, - &nlm_relocs -> reloc) - == false) - return false; - nlm_relocs -> section = section; - nlm_relocs++; - sym -> rcnt++; - } - return true; -} - -/* Write out an external reference. */ - -static boolean -nlm_i386_write_external (abfd, count, sym, relocs) - bfd *abfd; - bfd_size_type count; - asymbol *sym; - struct reloc_and_sec *relocs; -{ - unsigned int i; - bfd_byte len; - unsigned char temp[NLM_TARGET_LONG_SIZE]; - - len = strlen (sym->name); - if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte)) - || bfd_write (sym->name, len, 1, abfd) != len) - return false; - - bfd_put_32 (abfd, count, temp); - if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp)) - return false; - - for (i = 0; i < count; i++) - { - if (nlm_i386_write_import (abfd, relocs[i].sec, - relocs[i].rel) == false) - return false; - } - - return true; -} - -#include "nlmswap.h" - -static const struct nlm_backend_data nlm32_i386_backend = -{ - "NetWare Loadable Module\032", - sizeof (Nlm32_i386_External_Fixed_Header), - 0, /* optional_prefix_size */ - bfd_arch_i386, - 0, - false, - 0, /* backend_object_p */ - 0, /* write_prefix_func */ - nlm_i386_read_reloc, - nlm_i386_mangle_relocs, - nlm_i386_read_import, - nlm_i386_write_import, - 0, /* set_public_section */ - 0, /* get_public_offset */ - nlm_swap_fixed_header_in, - nlm_swap_fixed_header_out, - nlm_i386_write_external, - 0, /* write_export */ -}; - -#define TARGET_LITTLE_NAME "nlm32-i386" -#define TARGET_LITTLE_SYM nlmNAME(i386_vec) -#define TARGET_BACKEND_DATA &nlm32_i386_backend - -#include "nlm-target.h" diff --git a/contrib/gdb/bfd/nlm32-ppc.c b/contrib/gdb/bfd/nlm32-ppc.c deleted file mode 100644 index ecf2de8..0000000 --- a/contrib/gdb/bfd/nlm32-ppc.c +++ /dev/null @@ -1,1045 +0,0 @@ -/* Support for 32-bit PowerPC NLM (NetWare Loadable Module) - Copyright (C) 1994, 1995 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -/* The format of a PowerPC NLM changed. Define OLDFORMAT to get the - old format. */ - -#define ARCH_SIZE 32 - -#include "nlm/ppc-ext.h" -#define Nlm_External_Fixed_Header Nlm32_powerpc_External_Fixed_Header - -#include "libnlm.h" - -#ifdef OLDFORMAT -static boolean nlm_powerpc_backend_object_p - PARAMS ((bfd *)); -static boolean nlm_powerpc_write_prefix - PARAMS ((bfd *)); -#endif - -static boolean nlm_powerpc_read_reloc - PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *)); -static boolean nlm_powerpc_mangle_relocs - PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type)); -static boolean nlm_powerpc_read_import - PARAMS ((bfd *, nlmNAME(symbol_type) *)); - -#ifdef OLDFORMAT -static boolean nlm_powerpc_write_reloc - PARAMS ((bfd *, asection *, arelent *, int)); -#endif - -static boolean nlm_powerpc_write_import - PARAMS ((bfd *, asection *, arelent *)); -static boolean nlm_powerpc_write_external - PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *)); - -#ifndef OLDFORMAT -static boolean nlm_powerpc_set_public_section - PARAMS ((bfd *, nlmNAME(symbol_type) *)); -static bfd_vma nlm_powerpc_get_public_offset - PARAMS ((bfd *, asymbol *)); -#endif - -#ifdef OLDFORMAT - -/* The prefix header is only used in the old format. */ - -/* PowerPC NLM's have a prefix header before the standard NLM. This - function reads it in, verifies the version, and seeks the bfd to - the location before the regular NLM header. */ - -static boolean -nlm_powerpc_backend_object_p (abfd) - bfd *abfd; -{ - struct nlm32_powerpc_external_prefix_header s; - - if (bfd_read ((PTR) &s, sizeof s, 1, abfd) != sizeof s) - return false; - - if (memcmp (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature) != 0 - || bfd_h_get_32 (abfd, s.headerVersion) != NLM32_POWERPC_HEADER_VERSION) - return false; - - return true; -} - -/* Write out the prefix. */ - -static boolean -nlm_powerpc_write_prefix (abfd) - bfd *abfd; -{ - struct nlm32_powerpc_external_prefix_header s; - - memset (&s, 0, sizeof s); - memcpy (s.signature, NLM32_POWERPC_SIGNATURE, sizeof s.signature); - bfd_h_put_32 (abfd, (bfd_vma) NLM32_POWERPC_HEADER_VERSION, s.headerVersion); - bfd_h_put_32 (abfd, (bfd_vma) 0, s.origins); - - /* FIXME: What should we do about the date? */ - - if (bfd_write ((PTR) &s, sizeof s, 1, abfd) != sizeof s) - return false; - - return true; -} - -#endif /* OLDFORMAT */ - -#ifndef OLDFORMAT - -/* There is only one type of reloc in a PowerPC NLM. */ - -static reloc_howto_type nlm_powerpc_howto = - HOWTO (0, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false); /* pcrel_offset */ - -/* Read a PowerPC NLM reloc. */ - -static boolean -nlm_powerpc_read_reloc (abfd, sym, secp, rel) - bfd *abfd; - nlmNAME(symbol_type) *sym; - asection **secp; - arelent *rel; -{ - bfd_byte temp[4]; - bfd_vma val; - const char *name; - - if (bfd_read (temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return false; - - val = bfd_get_32 (abfd, temp); - - /* The value is a word offset into either the code or data segment. - This is the location which needs to be adjusted. - - The high bit is 0 if the value is an offset into the data - segment, or 1 if the value is an offset into the text segment. - - If this is a relocation fixup rather than an imported symbol (the - sym argument is NULL), then the second most significant bit is 0 - if the address of the data segment should be added to the - location addressed by the value, or 1 if the address of the text - segment should be added. - - If this is an imported symbol, the second most significant bit is - not used and must be 0. */ - - if ((val & NLM_HIBIT) == 0) - name = NLM_INITIALIZED_DATA_NAME; - else - { - name = NLM_CODE_NAME; - val &=~ NLM_HIBIT; - } - *secp = bfd_get_section_by_name (abfd, name); - - if (sym == NULL) - { - if ((val & (NLM_HIBIT >> 1)) == 0) - name = NLM_INITIALIZED_DATA_NAME; - else - { - name = NLM_CODE_NAME; - val &=~ (NLM_HIBIT >> 1); - } - rel->sym_ptr_ptr = bfd_get_section_by_name (abfd, name)->symbol_ptr_ptr; - } - - rel->howto = &nlm_powerpc_howto; - - rel->address = val << 2; - rel->addend = 0; - - return true; -} - -#else /* OLDFORMAT */ - -/* This reloc handling is only applicable to the old format. */ - -/* How to process the various reloc types. PowerPC NLMs use XCOFF - reloc types, and I have just copied the XCOFF reloc table here. */ - -static reloc_howto_type nlm_powerpc_howto_table[] = -{ - /* Standard 32 bit relocation. */ - HOWTO (0, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_POS", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32 bit relocation, but store negative value. */ - HOWTO (1, /* type */ - 0, /* rightshift */ - -2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_NEG", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 32 bit PC relative relocation. */ - HOWTO (2, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "R_REL", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* 16 bit TOC relative relocation. */ - HOWTO (3, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "R_TOC", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* I don't really know what this is. */ - HOWTO (4, /* type */ - 1, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RTB", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* External TOC relative symbol. */ - HOWTO (5, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_GL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Local TOC relative symbol. */ - HOWTO (6, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_TCL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - { 7 }, - - /* Non modifiable absolute branch. */ - HOWTO (8, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_BA", /* name */ - true, /* partial_inplace */ - 0x3fffffc, /* src_mask */ - 0x3fffffc, /* dst_mask */ - false), /* pcrel_offset */ - - { 9 }, - - /* Non modifiable relative branch. */ - HOWTO (0xa, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "R_BR", /* name */ - true, /* partial_inplace */ - 0x3fffffc, /* src_mask */ - 0x3fffffc, /* dst_mask */ - false), /* pcrel_offset */ - - { 0xb }, - - /* Indirect load. */ - HOWTO (0xc, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Load address. */ - HOWTO (0xd, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RLA", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - { 0xe }, - - /* Non-relocating reference. */ - HOWTO (0xf, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_REF", /* name */ - false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - false), /* pcrel_offset */ - - { 0x10 }, - { 0x11 }, - - /* TOC relative indirect load. */ - HOWTO (0x12, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_TRL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* TOC relative load address. */ - HOWTO (0x13, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_TRLA", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable relative branch. */ - HOWTO (0x14, /* type */ - 1, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RRTBI", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable absolute branch. */ - HOWTO (0x15, /* type */ - 1, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RRTBA", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable call absolute indirect. */ - HOWTO (0x16, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_CAI", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable call relative. */ - HOWTO (0x17, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_REL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable branch absolute. */ - HOWTO (0x18, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RBA", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable branch absolute. */ - HOWTO (0x19, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_RBAC", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable branch relative. */ - HOWTO (0x1a, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 26, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ - "R_REL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false), /* pcrel_offset */ - - /* Modifiable branch absolute. */ - HOWTO (0x1b, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ - "R_REL", /* name */ - true, /* partial_inplace */ - 0xffff, /* src_mask */ - 0xffff, /* dst_mask */ - false) /* pcrel_offset */ -}; - -#define HOWTO_COUNT (sizeof nlm_powerpc_howto_table \ - / sizeof nlm_powerpc_howto_table[0]) - -/* Read a PowerPC NLM reloc. */ - -static boolean -nlm_powerpc_read_reloc (abfd, sym, secp, rel) - bfd *abfd; - nlmNAME(symbol_type) *sym; - asection **secp; - arelent *rel; -{ - struct nlm32_powerpc_external_reloc ext; - bfd_vma l_vaddr; - unsigned long l_symndx; - int l_rtype; - int l_rsecnm; - asection *code_sec, *data_sec, *bss_sec; - - /* Read the reloc from the file. */ - if (bfd_read (&ext, sizeof ext, 1, abfd) != sizeof ext) - return false; - - /* Swap in the fields. */ - l_vaddr = bfd_h_get_32 (abfd, ext.l_vaddr); - l_symndx = bfd_h_get_32 (abfd, ext.l_symndx); - l_rtype = bfd_h_get_16 (abfd, ext.l_rtype); - l_rsecnm = bfd_h_get_16 (abfd, ext.l_rsecnm); - - /* Get the sections now, for convenience. */ - code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME); - data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME); - - /* Work out the arelent fields. */ - if (sym != NULL) - { - /* This is an import. sym_ptr_ptr is filled in by - nlm_canonicalize_reloc. */ - rel->sym_ptr_ptr = NULL; - } - else - { - asection *sec; - - if (l_symndx == 0) - sec = code_sec; - else if (l_symndx == 1) - sec = data_sec; - else if (l_symndx == 2) - sec = bss_sec; - else - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - rel->sym_ptr_ptr = sec->symbol_ptr_ptr; - } - - rel->addend = 0; - - BFD_ASSERT ((l_rtype & 0xff) < HOWTO_COUNT); - - rel->howto = nlm_powerpc_howto_table + (l_rtype & 0xff); - - BFD_ASSERT (rel->howto->name != NULL - && ((l_rtype & 0x8000) != 0 - ? (rel->howto->complain_on_overflow - == complain_overflow_signed) - : (rel->howto->complain_on_overflow - == complain_overflow_bitfield)) - && ((l_rtype >> 8) & 0x1f) == rel->howto->bitsize - 1); - - if (l_rsecnm == 0) - *secp = code_sec; - else if (l_rsecnm == 1) - { - *secp = data_sec; - l_vaddr -= bfd_section_size (abfd, code_sec); - } - else - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - rel->address = l_vaddr; - - return true; -} - -#endif /* OLDFORMAT */ - -/* Mangle PowerPC NLM relocs for output. */ - -static boolean -nlm_powerpc_mangle_relocs (abfd, sec, data, offset, count) - bfd *abfd; - asection *sec; - PTR data; - bfd_vma offset; - bfd_size_type count; -{ - return true; -} - -/* Read a PowerPC NLM import record */ - -static boolean -nlm_powerpc_read_import (abfd, sym) - bfd *abfd; - nlmNAME(symbol_type) *sym; -{ - struct nlm_relent *nlm_relocs; /* relocation records for symbol */ - bfd_size_type rcount; /* number of relocs */ - bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */ - unsigned char symlength; /* length of symbol name */ - char *name; - - if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd) - != sizeof (symlength)) - return (false); - sym -> symbol.the_bfd = abfd; - name = bfd_alloc (abfd, symlength + 1); - if (name == NULL) - return false; - if (bfd_read (name, symlength, 1, abfd) != symlength) - return (false); - name[symlength] = '\0'; - sym -> symbol.name = name; - sym -> symbol.flags = 0; - sym -> symbol.value = 0; - sym -> symbol.section = bfd_und_section_ptr; - if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return (false); - rcount = bfd_h_get_32 (abfd, temp); - nlm_relocs = ((struct nlm_relent *) - bfd_alloc (abfd, rcount * sizeof (struct nlm_relent))); - if (nlm_relocs == (struct nlm_relent *) NULL) - return false; - sym -> relocs = nlm_relocs; - sym -> rcnt = 0; - while (sym -> rcnt < rcount) - { - asection *section; - - if (nlm_powerpc_read_reloc (abfd, sym, §ion, - &nlm_relocs -> reloc) - == false) - return false; - nlm_relocs -> section = section; - nlm_relocs++; - sym -> rcnt++; - } - return true; -} - -#ifndef OLDFORMAT - -/* Write a PowerPC NLM reloc. */ - -static boolean -nlm_powerpc_write_import (abfd, sec, rel) - bfd *abfd; - asection *sec; - arelent *rel; -{ - asymbol *sym; - bfd_vma val; - bfd_byte temp[4]; - - /* PowerPC NetWare only supports one kind of reloc. */ - if (rel->addend != 0 - || rel->howto == NULL - || rel->howto->rightshift != 0 - || rel->howto->size != 2 - || rel->howto->bitsize != 32 - || rel->howto->bitpos != 0 - || rel->howto->pc_relative - || (rel->howto->src_mask != 0xffffffff && rel->addend != 0) - || rel->howto->dst_mask != 0xffffffff) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - sym = *rel->sym_ptr_ptr; - - /* The value we write out is the offset into the appropriate - segment, rightshifted by two. This offset is the section vma, - adjusted by the vma of the lowest section in that segment, plus - the address of the relocation. */ - val = bfd_get_section_vma (abfd, sec) + rel->address; - if ((val & 3) != 0) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - val >>= 2; - - /* The high bit is 0 if the reloc is in the data section, or 1 if - the reloc is in the code section. */ - if (bfd_get_section_flags (abfd, sec) & SEC_DATA) - val -= nlm_get_data_low (abfd); - else - { - val -= nlm_get_text_low (abfd); - val |= NLM_HIBIT; - } - - if (! bfd_is_und_section (bfd_get_section (sym))) - { - /* This is an internal relocation fixup. The second most - significant bit is 0 if this is a reloc against the data - segment, or 1 if it is a reloc against the text segment. */ - if (bfd_get_section_flags (abfd, bfd_get_section (sym)) & SEC_CODE) - val |= NLM_HIBIT >> 1; - } - - bfd_put_32 (abfd, val, temp); - if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return false; - - return true; -} - -#else /* OLDFORMAT */ - -/* This is used for the reloc handling in the old format. */ - -/* Write a PowerPC NLM reloc. */ - -static boolean -nlm_powerpc_write_reloc (abfd, sec, rel, indx) - bfd *abfd; - asection *sec; - arelent *rel; - int indx; -{ - struct nlm32_powerpc_external_reloc ext; - asection *code_sec, *data_sec, *bss_sec; - asymbol *sym; - asection *symsec; - unsigned long l_symndx; - int l_rtype; - int l_rsecnm; - reloc_howto_type *howto; - bfd_size_type address; - - /* Get the sections now, for convenience. */ - code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME); - data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME); - - sym = *rel->sym_ptr_ptr; - symsec = bfd_get_section (sym); - if (indx != -1) - { - BFD_ASSERT (bfd_is_und_section (symsec)); - l_symndx = indx + 3; - } - else - { - if (symsec == code_sec) - l_symndx = 0; - else if (symsec == data_sec) - l_symndx = 1; - else if (symsec == bss_sec) - l_symndx = 2; - else - { - bfd_set_error (bfd_error_bad_value); - return false; - } - } - - bfd_h_put_32 (abfd, (bfd_vma) l_symndx, ext.l_symndx); - - for (howto = nlm_powerpc_howto_table; - howto < nlm_powerpc_howto_table + HOWTO_COUNT; - howto++) - { - if (howto->rightshift == rel->howto->rightshift - && howto->size == rel->howto->size - && howto->bitsize == rel->howto->bitsize - && howto->pc_relative == rel->howto->pc_relative - && howto->bitpos == rel->howto->bitpos - && (howto->partial_inplace == rel->howto->partial_inplace - || (! rel->howto->partial_inplace - && rel->addend == 0)) - && (howto->src_mask == rel->howto->src_mask - || (rel->howto->src_mask == 0 - && rel->addend == 0)) - && howto->dst_mask == rel->howto->dst_mask - && howto->pcrel_offset == rel->howto->pcrel_offset) - break; - } - if (howto >= nlm_powerpc_howto_table + HOWTO_COUNT) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - l_rtype = howto->type; - if (howto->complain_on_overflow == complain_overflow_signed) - l_rtype |= 0x8000; - l_rtype |= (howto->bitsize - 1) << 8; - bfd_h_put_16 (abfd, (bfd_vma) l_rtype, ext.l_rtype); - - address = rel->address; - - if (sec == code_sec) - l_rsecnm = 0; - else if (sec == data_sec) - { - l_rsecnm = 1; - address += bfd_section_size (abfd, code_sec); - } - else - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - bfd_h_put_16 (abfd, (bfd_vma) l_rsecnm, ext.l_rsecnm); - bfd_h_put_32 (abfd, (bfd_vma) address, ext.l_vaddr); - - if (bfd_write (&ext, sizeof ext, 1, abfd) != sizeof ext) - return false; - - return true; -} - -/* Write a PowerPC NLM import. */ - -static boolean -nlm_powerpc_write_import (abfd, sec, rel) - bfd *abfd; - asection *sec; - arelent *rel; -{ - return nlm_powerpc_write_reloc (abfd, sec, rel, -1); -} - -#endif /* OLDFORMAT */ - -/* Write a PowerPC NLM external symbol. This routine keeps a static - count of the symbol index. FIXME: I don't know if this is - necessary, and the index never gets reset. */ - -static boolean -nlm_powerpc_write_external (abfd, count, sym, relocs) - bfd *abfd; - bfd_size_type count; - asymbol *sym; - struct reloc_and_sec *relocs; -{ - unsigned int i; - bfd_byte len; - unsigned char temp[NLM_TARGET_LONG_SIZE]; -#ifdef OLDFORMAT - static int indx; -#endif - - len = strlen (sym->name); - if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte)) - || bfd_write (sym->name, len, 1, abfd) != len) - return false; - - bfd_put_32 (abfd, count, temp); - if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp)) - return false; - - for (i = 0; i < count; i++) - { -#ifndef OLDFORMAT - if (! nlm_powerpc_write_import (abfd, relocs[i].sec, relocs[i].rel)) - return false; -#else - if (! nlm_powerpc_write_reloc (abfd, relocs[i].sec, - relocs[i].rel, indx)) - return false; -#endif - } - -#ifdef OLDFORMAT - ++indx; -#endif - - return true; -} - -#ifndef OLDFORMAT - -/* PowerPC Netware uses a word offset, not a byte offset, for public - symbols. */ - -/* Set the section for a public symbol. */ - -static boolean -nlm_powerpc_set_public_section (abfd, sym) - bfd *abfd; - nlmNAME(symbol_type) *sym; -{ - if (sym->symbol.value & NLM_HIBIT) - { - sym->symbol.value &= ~NLM_HIBIT; - sym->symbol.flags |= BSF_FUNCTION; - sym->symbol.section = - bfd_get_section_by_name (abfd, NLM_CODE_NAME); - } - else - { - sym->symbol.section = - bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - } - - sym->symbol.value <<= 2; - - return true; -} - -/* Get the offset to write out for a public symbol. */ - -static bfd_vma -nlm_powerpc_get_public_offset (abfd, sym) - bfd *abfd; - asymbol *sym; -{ - bfd_vma offset; - asection *sec; - - offset = bfd_asymbol_value (sym); - sec = bfd_get_section (sym); - if (sec->flags & SEC_CODE) - { - offset -= nlm_get_text_low (abfd); - offset |= NLM_HIBIT; - } - else if (sec->flags & (SEC_DATA | SEC_ALLOC)) - { - /* SEC_ALLOC is for the .bss section. */ - offset -= nlm_get_data_low (abfd); - } - else - { - /* We can't handle an exported symbol that is not in the code or - data segment. */ - bfd_set_error (bfd_error_invalid_operation); - /* FIXME: No way to return error. */ - abort (); - } - - return offset; -} - -#endif /* ! defined (OLDFORMAT) */ - -#include "nlmswap.h" - -static const struct nlm_backend_data nlm32_powerpc_backend = -{ - "NetWare PowerPC Module \032", - sizeof (Nlm32_powerpc_External_Fixed_Header), -#ifndef OLDFORMAT - 0, /* optional_prefix_size */ -#else - sizeof (struct nlm32_powerpc_external_prefix_header), -#endif - bfd_arch_powerpc, - 0, - false, -#ifndef OLDFORMAT - 0, /* backend_object_p */ - 0, /* write_prefix */ -#else - nlm_powerpc_backend_object_p, - nlm_powerpc_write_prefix, -#endif - nlm_powerpc_read_reloc, - nlm_powerpc_mangle_relocs, - nlm_powerpc_read_import, - nlm_powerpc_write_import, -#ifndef OLDFORMAT - nlm_powerpc_set_public_section, - nlm_powerpc_get_public_offset, -#else - 0, /* set_public_section */ - 0, /* get_public_offset */ -#endif - nlm_swap_fixed_header_in, - nlm_swap_fixed_header_out, - nlm_powerpc_write_external, - 0, /* write_export */ -}; - -#define TARGET_BIG_NAME "nlm32-powerpc" -#define TARGET_BIG_SYM nlmNAME(powerpc_vec) -#define TARGET_BACKEND_DATA &nlm32_powerpc_backend - -#include "nlm-target.h" diff --git a/contrib/gdb/bfd/nlm32-sparc.c b/contrib/gdb/bfd/nlm32-sparc.c deleted file mode 100644 index 5963adb..0000000 --- a/contrib/gdb/bfd/nlm32-sparc.c +++ /dev/null @@ -1,440 +0,0 @@ -/* Support for 32-bit SPARC NLM (NetWare Loadable Module) - Copyright (C) 1993 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#define ARCH_SIZE 32 - -#include "nlm/sparc32-ext.h" -#define Nlm_External_Fixed_Header Nlm32_sparc_External_Fixed_Header - -#include "libnlm.h" - -static boolean nlm_sparc_read_reloc - PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *)); -static boolean nlm_sparc_write_reloc - PARAMS ((bfd *, asection *, arelent *)); -static boolean nlm_sparc_mangle_relocs - PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type)); -static boolean nlm_sparc_read_import - PARAMS ((bfd *, nlmNAME(symbol_type) *)); -static boolean nlm_sparc_write_import - PARAMS ((bfd *, asection *, arelent *)); -static boolean nlm_sparc_write_external - PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *)); - -enum reloc_type - { - R_SPARC_NONE = 0, - R_SPARC_8, R_SPARC_16, R_SPARC_32, - R_SPARC_DISP8, R_SPARC_DISP16, R_SPARC_DISP32, - R_SPARC_WDISP30, R_SPARC_WDISP22, - R_SPARC_HI22, R_SPARC_22, - R_SPARC_13, R_SPARC_LO10, - R_SPARC_GOT10, R_SPARC_GOT13, R_SPARC_GOT22, - R_SPARC_PC10, R_SPARC_PC22, - R_SPARC_WPLT30, - R_SPARC_COPY, - R_SPARC_GLOB_DAT, R_SPARC_JMP_SLOT, - R_SPARC_RELATIVE, - R_SPARC_UA32, - R_SPARC_max - }; - -#if 0 -static CONST char *CONST reloc_type_names[] = -{ - "R_SPARC_NONE", - "R_SPARC_8", "R_SPARC_16", "R_SPARC_32", - "R_SPARC_DISP8", "R_SPARC_DISP16", "R_SPARC_DISP32", - "R_SPARC_WDISP30", "R_SPARC_WDISP22", - "R_SPARC_HI22", "R_SPARC_22", - "R_SPARC_13", "R_SPARC_LO10", - "R_SPARC_GOT10", "R_SPARC_GOT13", "R_SPARC_GOT22", - "R_SPARC_PC10", "R_SPARC_PC22", - "R_SPARC_WPLT30", - "R_SPARC_COPY", - "R_SPARC_GLOB_DAT", "R_SPARC_JMP_SLOT", - "R_SPARC_RELATIVE", - "R_SPARC_UA32", -}; -#endif - -static reloc_howto_type nlm32_sparc_howto_table[] = -{ - HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, 0,"R_SPARC_NONE", false,0,0x00000000,true), - HOWTO(R_SPARC_8, 0,0, 8,false,0,complain_overflow_bitfield,0,"R_SPARC_8", false,0,0x000000ff,true), - HOWTO(R_SPARC_16, 0,1,16,false,0,complain_overflow_bitfield,0,"R_SPARC_16", false,0,0x0000ffff,true), - HOWTO(R_SPARC_32, 0,2,32,false,0,complain_overflow_bitfield,0,"R_SPARC_32", false,0,0xffffffff,true), - HOWTO(R_SPARC_DISP8, 0,0, 8,true, 0,complain_overflow_signed, 0,"R_SPARC_DISP8", false,0,0x000000ff,true), - HOWTO(R_SPARC_DISP16, 0,1,16,true, 0,complain_overflow_signed, 0,"R_SPARC_DISP16", false,0,0x0000ffff,true), - HOWTO(R_SPARC_DISP32, 0,2,32,true, 0,complain_overflow_signed, 0,"R_SPARC_DISP32", false,0,0x00ffffff,true), - HOWTO(R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed, 0,"R_SPARC_WDISP30", false,0,0x3fffffff,true), - HOWTO(R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed, 0,"R_SPARC_WDISP22", false,0,0x003fffff,true), - HOWTO(R_SPARC_HI22, 10,2,22,false,0,complain_overflow_dont, 0,"R_SPARC_HI22", false,0,0x003fffff,true), - HOWTO(R_SPARC_22, 0,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_22", false,0,0x003fffff,true), - HOWTO(R_SPARC_13, 0,2,13,false,0,complain_overflow_bitfield,0,"R_SPARC_13", false,0,0x00001fff,true), - HOWTO(R_SPARC_LO10, 0,2,10,false,0,complain_overflow_dont, 0,"R_SPARC_LO10", false,0,0x000003ff,true), - HOWTO(R_SPARC_GOT10, 0,2,10,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT10", false,0,0x000003ff,true), - HOWTO(R_SPARC_GOT13, 0,2,13,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT13", false,0,0x00001fff,true), - HOWTO(R_SPARC_GOT22, 10,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT22", false,0,0x003fffff,true), - HOWTO(R_SPARC_PC10, 0,2,10,false,0,complain_overflow_bitfield,0,"R_SPARC_PC10", false,0,0x000003ff,true), - HOWTO(R_SPARC_PC22, 0,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_PC22", false,0,0x003fffff,true), - HOWTO(R_SPARC_WPLT30, 0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_WPLT30", false,0,0x00000000,true), - HOWTO(R_SPARC_COPY, 0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_COPY", false,0,0x00000000,true), - HOWTO(R_SPARC_GLOB_DAT,0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_GLOB_DAT",false,0,0x00000000,true), - HOWTO(R_SPARC_JMP_SLOT,0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_JMP_SLOT",false,0,0x00000000,true), - HOWTO(R_SPARC_RELATIVE,0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_RELATIVE",false,0,0x00000000,true), - HOWTO(R_SPARC_UA32, 0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_UA32", false,0,0x00000000,true), -}; - -/* Read a NetWare sparc reloc. */ - -struct nlm32_sparc_reloc_ext { - unsigned char offset[4]; - unsigned char addend[4]; - unsigned char type[1]; - unsigned char pad1[3]; -}; - -static boolean -nlm_sparc_read_reloc (abfd, sym, secp, rel) - bfd *abfd; - nlmNAME(symbol_type) *sym; - asection **secp; - arelent *rel; -{ - bfd_vma val, addend; - unsigned int index; - unsigned int type; - struct nlm32_sparc_reloc_ext tmp_reloc; - asection *code_sec, *data_sec; - - if (bfd_read (&tmp_reloc, 12, 1, abfd) != 12) - return false; - - code_sec = bfd_get_section_by_name (abfd, NLM_CODE_NAME); - data_sec = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - - *secp = code_sec; - - val = bfd_get_32 (abfd, tmp_reloc.offset); - addend = bfd_get_32 (abfd, tmp_reloc.addend); - type = bfd_get_8 (abfd, tmp_reloc.type); - - rel->address = val; - rel->addend = addend; - rel->howto = NULL; - - for (index = 0; - index < sizeof(nlm32_sparc_howto_table) / sizeof(reloc_howto_type); - index++) - if (nlm32_sparc_howto_table[index].type == type) { - rel->howto = &nlm32_sparc_howto_table[index]; - break; - } - -#ifdef DEBUG - fprintf (stderr, "%s: address = %08lx, addend = %08lx, type = %d, howto = %08lx\n", - __FUNCTION__, rel->address, rel->addend, type, rel->howto); -#endif - return true; - -} - -/* Write a NetWare sparc reloc. */ - -static boolean -nlm_sparc_write_reloc (abfd, sec, rel) - bfd *abfd; - asection *sec; - arelent *rel; -{ - bfd_vma val; - struct nlm32_sparc_reloc_ext tmp_reloc; - unsigned int index; - int type = -1; - reloc_howto_type *tmp; - - - for (index = 0; - index < sizeof (nlm32_sparc_howto_table) / sizeof(reloc_howto_type); - index++) { - tmp = &nlm32_sparc_howto_table[index]; - - if (tmp->rightshift == rel->howto->rightshift - && tmp->size == rel->howto->size - && tmp->bitsize == rel->howto->bitsize - && tmp->pc_relative == rel->howto->pc_relative - && tmp->bitpos == rel->howto->bitpos - && tmp->src_mask == rel->howto->src_mask - && tmp->dst_mask == rel->howto->dst_mask) { - type = tmp->type; - break; - } - } - if (type == -1) - abort(); - - /* - * Netware wants a list of relocs for each address. - * Format is: - * long offset - * long addend - * char type - * That should be it. - */ - - /* The value we write out is the offset into the appropriate - segment. This offset is the section vma, adjusted by the vma of - the lowest section in that segment, plus the address of the - relocation. */ -#if 0 - val = bfd_get_section_vma (abfd, (*rel->sym_ptr_ptr)->section) + rel->address; -#else - val = bfd_get_section_vma (abfd, sec) + rel->address; -#endif - -#ifdef DEBUG - fprintf (stderr, "%s: val = %08lx, addend = %08lx, type = %d\n", - __FUNCTION__, val, rel->addend, rel->howto->type); -#endif - bfd_put_32 (abfd, val, tmp_reloc.offset); - bfd_put_32 (abfd, rel->addend, tmp_reloc.addend); - bfd_put_8 (abfd, (short)(rel->howto->type), tmp_reloc.type); - - if (bfd_write (&tmp_reloc, 12, 1, abfd) != 12) - return false; - - return true; -} - -/* Mangle relocs for SPARC NetWare. We can just use the standard - SPARC relocs. */ - -static boolean -nlm_sparc_mangle_relocs (abfd, sec, data, offset, count) - bfd *abfd; - asection *sec; - PTR data; - bfd_vma offset; - bfd_size_type count; -{ - return true; -} - -/* Read a NetWare sparc import record */ -static boolean -nlm_sparc_read_import (abfd, sym) - bfd *abfd; - nlmNAME(symbol_type) *sym; -{ - struct nlm_relent *nlm_relocs; /* relocation records for symbol */ - bfd_size_type rcount; /* number of relocs */ - bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */ - unsigned char symlength; /* length of symbol name */ - char *name; - - /* - * First, read in the number of relocation - * entries for this symbol - */ - if (bfd_read ((PTR) temp, 4, 1, abfd) != 4) - return false; - - rcount = bfd_get_32 (abfd, temp); - - /* - * Next, read in the length of the symbol - */ - - if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd) - != sizeof (symlength)) - return false; - sym -> symbol.the_bfd = abfd; - name = bfd_alloc (abfd, symlength + 1); - if (name == NULL) - return false; - - /* - * Then read in the symbol - */ - - if (bfd_read (name, symlength, 1, abfd) != symlength) - return false; - name[symlength] = '\0'; - sym -> symbol.name = name; - sym -> symbol.flags = 0; - sym -> symbol.value = 0; - sym -> symbol.section = bfd_und_section_ptr; - - /* - * Next, start reading in the relocs. - */ - - nlm_relocs = ((struct nlm_relent *) - bfd_alloc (abfd, rcount * sizeof (struct nlm_relent))); - if (!nlm_relocs) - return false; - sym -> relocs = nlm_relocs; - sym -> rcnt = 0; - while (sym -> rcnt < rcount) - { - asection *section; - - if (nlm_sparc_read_reloc (abfd, sym, §ion, - &nlm_relocs -> reloc) - == false) - return false; - nlm_relocs -> section = section; - nlm_relocs++; - sym -> rcnt++; - } - return true; -} - -static boolean -nlm_sparc_write_import (abfd, sec, rel) - bfd *abfd; - asection *sec; - arelent *rel; -{ - char temp[4]; - asection *code, *data, *bss, *symsec; - bfd_vma base; - - code = bfd_get_section_by_name (abfd, NLM_CODE_NAME); - data = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - bss = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME); - symsec = (*rel->sym_ptr_ptr)->section; - - if (symsec == code) { - base = 0; - } else if (symsec == data) { - base = bfd_section_size (abfd, code); - } else if (symsec == bss) { - base = bfd_section_size (abfd, code) + bfd_section_size (abfd, data); - } else - base = 0; - -#ifdef DEBUG - fprintf (stderr, "%s: <%x, 1>\n\t", - __FUNCTION__, base + (*rel->sym_ptr_ptr)->value); -#endif - bfd_put_32 (abfd, base + (*rel->sym_ptr_ptr)->value, temp); - if (bfd_write ((PTR)temp, 4, 1, abfd) != 4) - return false; - bfd_put_32 (abfd, 1, temp); - if (bfd_write ((PTR)temp, 4, 1, abfd) != 4) - return false; - if (nlm_sparc_write_reloc (abfd, sec, rel) == false) - return false; - return true; -} - -/* Write out an external reference. */ - -static boolean -nlm_sparc_write_external (abfd, count, sym, relocs) - bfd *abfd; - bfd_size_type count; - asymbol *sym; - struct reloc_and_sec *relocs; -{ - unsigned int i; - bfd_byte len; - unsigned char temp[NLM_TARGET_LONG_SIZE]; - - bfd_put_32 (abfd, count, temp); - if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp)) - return false; - - len = strlen (sym->name); - if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte)) - || bfd_write (sym->name, len, 1, abfd) != len) - return false; - - for (i = 0; i < count; i++) - { - if (nlm_sparc_write_reloc (abfd, relocs[i].sec, - relocs[i].rel) == false) - return false; - } - - return true; -} - -static boolean -nlm_sparc_write_export (abfd, sym, value) - bfd *abfd; - asymbol *sym; - bfd_vma value; -{ - bfd_byte len; - bfd_byte temp[4]; - -#ifdef DEBUG - fprintf (stderr, "%s: <%x, %d, %s>\n", - __FUNCTION__, value, strlen (sym->name), sym->name); -#endif - bfd_put_32 (abfd, value, temp); - len = strlen (sym->name); - - if (bfd_write (temp, 4, 1, abfd) != 4 - || bfd_write (&len, 1, 1, abfd) != 1 - || bfd_write (sym->name, len, 1, abfd) != len) - return false; - - return true; -} - -#undef nlm_swap_fixed_header_in -#undef nlm_swap_fixed_header_out - -#include "nlmswap.h" - -static const struct nlm_backend_data nlm32_sparc_backend = -{ - "NetWare SPARC Module \032", - sizeof (Nlm32_sparc_External_Fixed_Header), - 0, /* optional_prefix_size */ - bfd_arch_sparc, - 0, - false, - 0, /* backend_object_p */ - 0, /* write_prefix_func */ - nlm_sparc_read_reloc, - nlm_sparc_mangle_relocs, - nlm_sparc_read_import, - nlm_sparc_write_import, - 0, /* set_public_section */ - 0, /* get_public_offset */ - nlm_swap_fixed_header_in, - nlm_swap_fixed_header_out, - nlm_sparc_write_external, - nlm_sparc_write_export -}; - -#define TARGET_BIG_NAME "nlm32-sparc" -#define TARGET_BIG_SYM nlmNAME(sparc_vec) -#define TARGET_BACKEND_DATA &nlm32_sparc_backend - -#include "nlm-target.h" diff --git a/contrib/gdb/bfd/nlm32.c b/contrib/gdb/bfd/nlm32.c deleted file mode 100644 index 4730e4f..0000000 --- a/contrib/gdb/bfd/nlm32.c +++ /dev/null @@ -1,21 +0,0 @@ -/* NLM (NetWare Loadable Module) 32-bit executable support for BFD. - Copyright (C) 1993 Free Software Foundation, Inc. - -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. */ - -#define ARCH_SIZE 32 -#include "nlmcode.h" diff --git a/contrib/gdb/bfd/nlm64.c b/contrib/gdb/bfd/nlm64.c deleted file mode 100644 index 5dcd96a..0000000 --- a/contrib/gdb/bfd/nlm64.c +++ /dev/null @@ -1,21 +0,0 @@ -/* NLM (NetWare Loadable Module) 64-bit executable support for BFD. - Copyright (C) 1993 Free Software Foundation, Inc. - -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. */ - -#define ARCH_SIZE 64 -#include "nlmcode.h" diff --git a/contrib/gdb/bfd/nlmcode.h b/contrib/gdb/bfd/nlmcode.h deleted file mode 100644 index 7f828b4..0000000 --- a/contrib/gdb/bfd/nlmcode.h +++ /dev/null @@ -1,2057 +0,0 @@ -/* NLM (NetWare Loadable Module) executable support for BFD. - Copyright (C) 1993 Free Software Foundation, Inc. - - Written by Fred Fish @ Cygnus Support, using ELF support as the - template. - -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. */ - -#include <string.h> /* For strrchr and friends */ -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libnlm.h" - -/* The functions in this file do not use the names they appear to use. - This file is actually compiled multiple times, once for each size - of NLM target we are using. At each size we use a different name, - constructed by the macro nlmNAME. For example, the function which - is named nlm_symbol_type below is actually named nlm32_symbol_type - in the final executable. */ - -#define Nlm_External_Fixed_Header NlmNAME(External_Fixed_Header) -#define Nlm_External_Version_Header NlmNAME(External_Version_Header) -#define Nlm_External_Copyright_Header NlmNAME(External_Copyright_Header) -#define Nlm_External_Extended_Header NlmNAME(External_Extended_Header) -#define Nlm_External_Custom_Header NlmNAME(External_Custom_Header) -#define Nlm_External_Cygnus_Ext_Header NlmNAME(External_Cygnus_Ext_Header) - -#define nlm_symbol_type nlmNAME(symbol_type) -#define nlm_get_symtab_upper_bound nlmNAME(get_symtab_upper_bound) -#define nlm_get_symtab nlmNAME(get_symtab) -#define nlm_make_empty_symbol nlmNAME(make_empty_symbol) -#define nlm_print_symbol nlmNAME(print_symbol) -#define nlm_get_symbol_info nlmNAME(get_symbol_info) -#define nlm_get_reloc_upper_bound nlmNAME(get_reloc_upper_bound) -#define nlm_canonicalize_reloc nlmNAME(canonicalize_reloc) -#define nlm_object_p nlmNAME(object_p) -#define nlm_set_section_contents nlmNAME(set_section_contents) -#define nlm_write_object_contents nlmNAME(write_object_contents) - -#define nlm_swap_fixed_header_in(abfd,src,dst) \ - (nlm_swap_fixed_header_in_func(abfd))(abfd,src,dst) -#define nlm_swap_fixed_header_out(abfd,src,dst) \ - (nlm_swap_fixed_header_out_func(abfd))(abfd,src,dst) - -/* Forward declarations of static functions */ - -static boolean add_bfd_section - PARAMS ((bfd *, char *, file_ptr, bfd_size_type, flagword)); -static boolean nlm_swap_variable_header_in - PARAMS ((bfd *)); -static boolean nlm_swap_variable_header_out - PARAMS ((bfd *)); -static boolean find_nonzero - PARAMS ((PTR, size_t)); -static boolean nlm_swap_auxiliary_headers_in - PARAMS ((bfd *)); -static boolean nlm_swap_auxiliary_headers_out - PARAMS ((bfd *)); -static boolean nlm_slurp_symbol_table - PARAMS ((bfd *)); -static boolean nlm_slurp_reloc_fixups - PARAMS ((bfd *)); -static boolean nlm_compute_section_file_positions - PARAMS ((bfd *)); -static int nlm_external_reloc_compare - PARAMS ((const void *, const void *)); - -/* Should perhaps use put_offset, put_word, etc. For now, the two versions - can be handled by explicitly specifying 32 bits or "the long type". */ -#if ARCH_SIZE == 64 -#define put_word bfd_h_put_64 -#define get_word bfd_h_get_64 -#endif -#if ARCH_SIZE == 32 -#define put_word bfd_h_put_32 -#define get_word bfd_h_get_32 -#endif - -const bfd_target * -nlm_object_p (abfd) - bfd *abfd; -{ - struct nlm_obj_tdata *preserved_tdata = nlm_tdata (abfd); - boolean (*backend_object_p) PARAMS ((bfd *)); - PTR x_fxdhdr = NULL; - Nlm_Internal_Fixed_Header *i_fxdhdrp; - struct nlm_obj_tdata *new_tdata = NULL; - const char *signature; - enum bfd_architecture arch; - - /* Some NLM formats have a prefix before the standard NLM fixed - header. */ - backend_object_p = nlm_backend_object_p_func (abfd); - if (backend_object_p) - { - if (!(*backend_object_p) (abfd)) - goto got_wrong_format_error; - } - - /* Read in the fixed length portion of the NLM header in external format. */ - - x_fxdhdr = (PTR) bfd_malloc ((size_t) nlm_fixed_header_size (abfd)); - if (x_fxdhdr == NULL) - goto got_no_match; - - if (bfd_read ((PTR) x_fxdhdr, nlm_fixed_header_size (abfd), 1, abfd) != - nlm_fixed_header_size (abfd)) - { - if (bfd_get_error () != bfd_error_system_call) - goto got_wrong_format_error; - else - goto got_no_match; - } - - /* Allocate an instance of the nlm_obj_tdata structure and hook it up to - the tdata pointer in the bfd. */ - - new_tdata = ((struct nlm_obj_tdata *) - bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata))); - if (new_tdata == NULL) - goto got_no_match; - - nlm_tdata (abfd) = new_tdata; - - i_fxdhdrp = nlm_fixed_header (abfd); - nlm_swap_fixed_header_in (abfd, x_fxdhdr, i_fxdhdrp); - free (x_fxdhdr); - x_fxdhdr = NULL; - - /* Check to see if we have an NLM file for this backend by matching - the NLM signature. */ - - signature = nlm_signature (abfd); - if (signature != NULL - && *signature != '\0' - && strncmp ((char *) i_fxdhdrp->signature, signature, - NLM_SIGNATURE_SIZE) != 0) - goto got_wrong_format_error; - - /* There's no supported way to discover the endianess of an NLM, so test for - a sane version number after doing byte swapping appropriate for this - XVEC. (Hack alert!) */ - - if (i_fxdhdrp->version > 0xFFFF) - goto got_wrong_format_error; - - /* There's no supported way to check for 32 bit versus 64 bit addresses, - so ignore this distinction for now. (FIXME) */ - - /* Swap in the rest of the required header. */ - if (!nlm_swap_variable_header_in (abfd)) - { - if (bfd_get_error () != bfd_error_system_call) - goto got_wrong_format_error; - else - goto got_no_match; - } - - /* Add the sections supplied by all NLM's, and then read in the - auxiliary headers. Reading the auxiliary headers may create - additional sections described in the cygnus_ext header. - From this point on we assume that we have an NLM, and do not - treat errors as indicating the wrong format. */ - - if (!add_bfd_section (abfd, NLM_CODE_NAME, - i_fxdhdrp->codeImageOffset, - i_fxdhdrp->codeImageSize, - (SEC_CODE | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS - | SEC_RELOC)) - || !add_bfd_section (abfd, NLM_INITIALIZED_DATA_NAME, - i_fxdhdrp->dataImageOffset, - i_fxdhdrp->dataImageSize, - (SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS - | SEC_RELOC)) - || !add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME, - (file_ptr) 0, - i_fxdhdrp->uninitializedDataSize, - SEC_ALLOC)) - goto got_no_match; - - if (!nlm_swap_auxiliary_headers_in (abfd)) - goto got_no_match; - - if (nlm_fixed_header (abfd)->numberOfRelocationFixups != 0 - || nlm_fixed_header (abfd)->numberOfExternalReferences != 0) - abfd->flags |= HAS_RELOC; - if (nlm_fixed_header (abfd)->numberOfPublics != 0 - || nlm_fixed_header (abfd)->numberOfDebugRecords != 0 - || nlm_fixed_header (abfd)->numberOfExternalReferences != 0) - abfd->flags |= HAS_SYMS; - - arch = nlm_architecture (abfd); - if (arch != bfd_arch_unknown) - bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0); - - abfd->flags |= EXEC_P; - bfd_get_start_address (abfd) = nlm_fixed_header (abfd)->codeStartOffset; - - return (abfd->xvec); - -got_wrong_format_error: - bfd_set_error (bfd_error_wrong_format); -got_no_match: - nlm_tdata (abfd) = preserved_tdata; - if (new_tdata != NULL) - bfd_release (abfd, new_tdata); - if (x_fxdhdr != NULL) - free (x_fxdhdr); - return (NULL); -} - -/* Add a section to the bfd. */ - -static boolean -add_bfd_section (abfd, name, offset, size, flags) - bfd *abfd; - char *name; - file_ptr offset; - bfd_size_type size; - flagword flags; -{ - asection *newsect; - - newsect = bfd_make_section (abfd, name); - if (newsect == NULL) - { - return (false); - } - newsect->vma = 0; /* NLM's are relocatable. */ - newsect->_raw_size = size; - newsect->filepos = offset; - newsect->flags = flags; - newsect->alignment_power = bfd_log2 (0); /* FIXME */ - return (true); -} - -/* Read and swap in the variable length header. All the fields must - exist in the NLM, and must exist in the order they are read here. */ - -static boolean -nlm_swap_variable_header_in (abfd) - bfd *abfd; -{ - unsigned char temp[NLM_TARGET_LONG_SIZE]; - - /* Read the description length and text members. */ - - if (bfd_read ((PTR) & nlm_variable_header (abfd)->descriptionLength, - sizeof (nlm_variable_header (abfd)->descriptionLength), - 1, abfd) != - sizeof (nlm_variable_header (abfd)->descriptionLength)) - return (false); - if (bfd_read ((PTR) nlm_variable_header (abfd)->descriptionText, - nlm_variable_header (abfd)->descriptionLength + 1, - 1, abfd) != - (bfd_size_type) nlm_variable_header (abfd)->descriptionLength + 1) - return (false); - - /* Read and convert the stackSize field. */ - - if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return (false); - nlm_variable_header (abfd)->stackSize = get_word (abfd, (bfd_byte *) temp); - - /* Read and convert the reserved field. */ - - if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return (false); - nlm_variable_header (abfd)->reserved = get_word (abfd, (bfd_byte *) temp); - - /* Read the oldThreadName field. This field is a fixed length string. */ - - if (bfd_read ((PTR) nlm_variable_header (abfd)->oldThreadName, - sizeof (nlm_variable_header (abfd)->oldThreadName), - 1, abfd) != - sizeof (nlm_variable_header (abfd)->oldThreadName)) - return (false); - - /* Read the screen name length and text members. */ - - if (bfd_read ((PTR) & nlm_variable_header (abfd)->screenNameLength, - sizeof (nlm_variable_header (abfd)->screenNameLength), - 1, abfd) != - sizeof (nlm_variable_header (abfd)->screenNameLength)) - return (false); - if (bfd_read ((PTR) nlm_variable_header (abfd)->screenName, - nlm_variable_header (abfd)->screenNameLength + 1, - 1, abfd) != - (bfd_size_type) nlm_variable_header (abfd)->screenNameLength + 1) - return (false); - - /* Read the thread name length and text members. */ - - if (bfd_read ((PTR) & nlm_variable_header (abfd)->threadNameLength, - sizeof (nlm_variable_header (abfd)->threadNameLength), - 1, abfd) != - sizeof (nlm_variable_header (abfd)->threadNameLength)) - return (false); - if (bfd_read ((PTR) nlm_variable_header (abfd)->threadName, - nlm_variable_header (abfd)->threadNameLength + 1, - 1, abfd) != - (bfd_size_type) nlm_variable_header (abfd)->threadNameLength + 1) - return (false); - return (true); -} - -/* Swap and write out the variable length header. All the fields must - exist in the NLM, and must exist in this order. */ - -static boolean -nlm_swap_variable_header_out (abfd) - bfd *abfd; -{ - unsigned char temp[NLM_TARGET_LONG_SIZE]; - - /* Write the description length and text members. */ - - if (bfd_write ((PTR) & nlm_variable_header (abfd)->descriptionLength, - sizeof (nlm_variable_header (abfd)->descriptionLength), - 1, abfd) != - sizeof (nlm_variable_header (abfd)->descriptionLength)) - return (false); - if (bfd_write ((PTR) nlm_variable_header (abfd)->descriptionText, - nlm_variable_header (abfd)->descriptionLength + 1, - 1, abfd) != - (bfd_size_type) nlm_variable_header (abfd)->descriptionLength + 1) - return (false); - - /* Convert and write the stackSize field. */ - - put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->stackSize, - (bfd_byte *) temp); - if (bfd_write ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return (false); - - /* Convert and write the reserved field. */ - - put_word (abfd, (bfd_vma) nlm_variable_header (abfd)->reserved, - (bfd_byte *) temp); - if (bfd_write ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return (false); - - /* Write the oldThreadName field. This field is a fixed length string. */ - - if (bfd_write ((PTR) nlm_variable_header (abfd)->oldThreadName, - sizeof (nlm_variable_header (abfd)->oldThreadName), - 1, abfd) != - sizeof (nlm_variable_header (abfd)->oldThreadName)) - return (false); - - /* Write the screen name length and text members. */ - - if (bfd_write ((PTR) & nlm_variable_header (abfd)->screenNameLength, - sizeof (nlm_variable_header (abfd)->screenNameLength), - 1, abfd) != - sizeof (nlm_variable_header (abfd)->screenNameLength)) - return (false); - if (bfd_write ((PTR) nlm_variable_header (abfd)->screenName, - nlm_variable_header (abfd)->screenNameLength + 1, - 1, abfd) != - (bfd_size_type) nlm_variable_header (abfd)->screenNameLength + 1) - return (false); - - /* Write the thread name length and text members. */ - - if (bfd_write ((PTR) & nlm_variable_header (abfd)->threadNameLength, - sizeof (nlm_variable_header (abfd)->threadNameLength), - 1, abfd) != - sizeof (nlm_variable_header (abfd)->threadNameLength)) - return (false); - if (bfd_write ((PTR) nlm_variable_header (abfd)->threadName, - nlm_variable_header (abfd)->threadNameLength + 1, - 1, abfd) != - (bfd_size_type) nlm_variable_header (abfd)->threadNameLength + 1) - return (false); - return (true); -} - -/* Read and swap in the contents of all the auxiliary headers. Because of - the braindead design, we have to do strcmps on strings of indeterminate - length to figure out what each auxiliary header is. Even worse, we have - no way of knowing how many auxiliary headers there are or where the end - of the auxiliary headers are, except by finding something that doesn't - look like a known auxiliary header. This means that the first new type - of auxiliary header added will break all existing tools that don't - recognize it. */ - -static boolean -nlm_swap_auxiliary_headers_in (abfd) - bfd *abfd; -{ - char tempstr[16]; - long position; - - for (;;) - { - position = bfd_tell (abfd); - if (bfd_read ((PTR) tempstr, sizeof (tempstr), 1, abfd) != - sizeof (tempstr)) - return (false); - if (bfd_seek (abfd, position, SEEK_SET) == -1) - return (false); - if (strncmp (tempstr, "VeRsIoN#", 8) == 0) - { - Nlm_External_Version_Header thdr; - if (bfd_read ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr)) - return (false); - memcpy (nlm_version_header (abfd)->stamp, thdr.stamp, - sizeof (thdr.stamp)); - nlm_version_header (abfd)->majorVersion = - get_word (abfd, (bfd_byte *) thdr.majorVersion); - nlm_version_header (abfd)->minorVersion = - get_word (abfd, (bfd_byte *) thdr.minorVersion); - nlm_version_header (abfd)->revision = - get_word (abfd, (bfd_byte *) thdr.revision); - nlm_version_header (abfd)->year = - get_word (abfd, (bfd_byte *) thdr.year); - nlm_version_header (abfd)->month = - get_word (abfd, (bfd_byte *) thdr.month); - nlm_version_header (abfd)->day = - get_word (abfd, (bfd_byte *) thdr.day); - } - else if (strncmp (tempstr, "MeSsAgEs", 8) == 0) - { - Nlm_External_Extended_Header thdr; - if (bfd_read ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr)) - return (false); - memcpy (nlm_extended_header (abfd)->stamp, thdr.stamp, - sizeof (thdr.stamp)); - nlm_extended_header (abfd)->languageID = - get_word (abfd, (bfd_byte *) thdr.languageID); - nlm_extended_header (abfd)->messageFileOffset = - get_word (abfd, (bfd_byte *) thdr.messageFileOffset); - nlm_extended_header (abfd)->messageFileLength = - get_word (abfd, (bfd_byte *) thdr.messageFileLength); - nlm_extended_header (abfd)->messageCount = - get_word (abfd, (bfd_byte *) thdr.messageCount); - nlm_extended_header (abfd)->helpFileOffset = - get_word (abfd, (bfd_byte *) thdr.helpFileOffset); - nlm_extended_header (abfd)->helpFileLength = - get_word (abfd, (bfd_byte *) thdr.helpFileLength); - nlm_extended_header (abfd)->RPCDataOffset = - get_word (abfd, (bfd_byte *) thdr.RPCDataOffset); - nlm_extended_header (abfd)->RPCDataLength = - get_word (abfd, (bfd_byte *) thdr.RPCDataLength); - nlm_extended_header (abfd)->sharedCodeOffset = - get_word (abfd, (bfd_byte *) thdr.sharedCodeOffset); - nlm_extended_header (abfd)->sharedCodeLength = - get_word (abfd, (bfd_byte *) thdr.sharedCodeLength); - nlm_extended_header (abfd)->sharedDataOffset = - get_word (abfd, (bfd_byte *) thdr.sharedDataOffset); - nlm_extended_header (abfd)->sharedDataLength = - get_word (abfd, (bfd_byte *) thdr.sharedDataLength); - nlm_extended_header (abfd)->sharedRelocationFixupOffset = - get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupOffset); - nlm_extended_header (abfd)->sharedRelocationFixupCount = - get_word (abfd, (bfd_byte *) thdr.sharedRelocationFixupCount); - nlm_extended_header (abfd)->sharedExternalReferenceOffset = - get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceOffset); - nlm_extended_header (abfd)->sharedExternalReferenceCount = - get_word (abfd, (bfd_byte *) thdr.sharedExternalReferenceCount); - nlm_extended_header (abfd)->sharedPublicsOffset = - get_word (abfd, (bfd_byte *) thdr.sharedPublicsOffset); - nlm_extended_header (abfd)->sharedPublicsCount = - get_word (abfd, (bfd_byte *) thdr.sharedPublicsCount); - nlm_extended_header (abfd)->sharedDebugRecordOffset = - get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordOffset); - nlm_extended_header (abfd)->sharedDebugRecordCount = - get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordCount); - nlm_extended_header (abfd)->SharedInitializationOffset = - get_word (abfd, (bfd_byte *) thdr.sharedInitializationOffset); - nlm_extended_header (abfd)->SharedExitProcedureOffset = - get_word (abfd, (bfd_byte *) thdr.SharedExitProcedureOffset); - nlm_extended_header (abfd)->productID = - get_word (abfd, (bfd_byte *) thdr.productID); - nlm_extended_header (abfd)->reserved0 = - get_word (abfd, (bfd_byte *) thdr.reserved0); - nlm_extended_header (abfd)->reserved1 = - get_word (abfd, (bfd_byte *) thdr.reserved1); - nlm_extended_header (abfd)->reserved2 = - get_word (abfd, (bfd_byte *) thdr.reserved2); - nlm_extended_header (abfd)->reserved3 = - get_word (abfd, (bfd_byte *) thdr.reserved3); - nlm_extended_header (abfd)->reserved4 = - get_word (abfd, (bfd_byte *) thdr.reserved4); - nlm_extended_header (abfd)->reserved5 = - get_word (abfd, (bfd_byte *) thdr.reserved5); - } - else if (strncmp (tempstr, "CoPyRiGhT=", 10) == 0) - { - if (bfd_read ((PTR) nlm_copyright_header (abfd)->stamp, - sizeof (nlm_copyright_header (abfd)->stamp), - 1, abfd) - != sizeof (nlm_copyright_header (abfd)->stamp)) - return (false); - if (bfd_read ((PTR) & (nlm_copyright_header (abfd) - ->copyrightMessageLength), - 1, 1, abfd) != 1) - return (false); - /* The copyright message is a variable length string. */ - if (bfd_read ((PTR) nlm_copyright_header (abfd)->copyrightMessage, - nlm_copyright_header (abfd)->copyrightMessageLength + 1, - 1, abfd) != - ((bfd_size_type) - nlm_copyright_header (abfd)->copyrightMessageLength + 1)) - return (false); - } - else if (strncmp (tempstr, "CuStHeAd", 8) == 0) - { - Nlm_External_Custom_Header thdr; - bfd_size_type hdrLength; - file_ptr dataOffset; - bfd_size_type dataLength; - char dataStamp[8]; - PTR hdr; - - /* Read the stamp ("CuStHeAd"). */ - if (bfd_read ((PTR) thdr.stamp, 1, sizeof (thdr.stamp), abfd) - != sizeof (thdr.stamp)) - return false; - /* Read the length of this custom header. */ - if (bfd_read ((PTR) thdr.length, 1, sizeof (thdr.length), abfd) - != sizeof (thdr.length)) - return false; - hdrLength = get_word (abfd, (bfd_byte *) thdr.length); - /* Read further fields if we have them. */ - if (hdrLength < NLM_TARGET_LONG_SIZE) - dataOffset = 0; - else - { - if (bfd_read ((PTR) thdr.dataOffset, 1, - sizeof (thdr.dataOffset), abfd) - != sizeof (thdr.dataOffset)) - return false; - dataOffset = get_word (abfd, (bfd_byte *) thdr.dataOffset); - } - if (hdrLength < 2 * NLM_TARGET_LONG_SIZE) - dataLength = 0; - else - { - if (bfd_read ((PTR) thdr.dataLength, 1, - sizeof (thdr.dataLength), abfd) - != sizeof (thdr.dataLength)) - return false; - dataLength = get_word (abfd, (bfd_byte *) thdr.dataLength); - } - if (hdrLength < 2 * NLM_TARGET_LONG_SIZE + 8) - memset (dataStamp, 0, sizeof (dataStamp)); - else - { - if (bfd_read ((PTR) dataStamp, 1, sizeof (dataStamp), abfd) - != sizeof (dataStamp)) - return false; - } - - /* Read the rest of the header, if any. */ - if (hdrLength <= 2 * NLM_TARGET_LONG_SIZE + 8) - { - hdr = NULL; - hdrLength = 0; - } - else - { - hdrLength -= 2 * NLM_TARGET_LONG_SIZE + 8; - hdr = bfd_alloc (abfd, hdrLength); - if (hdr == NULL) - return false; - if (bfd_read (hdr, 1, hdrLength, abfd) != hdrLength) - return false; - } - - /* If we have found a Cygnus header, process it. Otherwise, - just save the associated data without trying to interpret - it. */ - if (strncmp (dataStamp, "CyGnUsEx", 8) == 0) - { - file_ptr pos; - bfd_byte *contents; - bfd_byte *p, *pend; - - BFD_ASSERT (hdrLength == 0 && hdr == NULL); - - pos = bfd_tell (abfd); - if (bfd_seek (abfd, dataOffset, SEEK_SET) != 0) - return false; - contents = (bfd_byte *) bfd_alloc (abfd, dataLength); - if (contents == NULL) - return false; - if (bfd_read (contents, 1, dataLength, abfd) != dataLength) - return false; - if (bfd_seek (abfd, pos, SEEK_SET) != 0) - return false; - - memcpy (nlm_cygnus_ext_header (abfd), "CyGnUsEx", 8); - nlm_cygnus_ext_header (abfd)->offset = dataOffset; - nlm_cygnus_ext_header (abfd)->length = dataLength; - - /* This data this header points to provides a list of - the sections which were in the original object file - which was converted to become an NLM. We locate - those sections and add them to the BFD. Note that - this is likely to create a second .text, .data and - .bss section; retrieving the sections by name will - get the actual NLM sections, which is what we want to - happen. The sections from the original file, which - may be subsets of the NLM section, can only be found - using bfd_map_over_sections. */ - p = contents; - pend = p + dataLength; - while (p < pend) - { - char *name; - size_t l; - file_ptr filepos; - bfd_size_type size; - asection *newsec; - - /* The format of this information is - null terminated section name - zeroes to adjust to 4 byte boundary - 4 byte section data file pointer - 4 byte section size - */ - - name = (char *) p; - l = strlen (name) + 1; - l = (l + 3) &~ 3; - p += l; - filepos = bfd_h_get_32 (abfd, p); - p += 4; - size = bfd_h_get_32 (abfd, p); - p += 4; - - newsec = bfd_make_section_anyway (abfd, name); - if (newsec == (asection *) NULL) - return false; - newsec->_raw_size = size; - if (filepos != 0) - { - newsec->filepos = filepos; - newsec->flags |= SEC_HAS_CONTENTS; - } - } - } - else - { - memcpy (nlm_custom_header (abfd)->stamp, thdr.stamp, - sizeof (thdr.stamp)); - nlm_custom_header (abfd)->hdrLength = hdrLength; - nlm_custom_header (abfd)->dataOffset = dataOffset; - nlm_custom_header (abfd)->dataLength = dataLength; - memcpy (nlm_custom_header (abfd)->dataStamp, dataStamp, - sizeof (dataStamp)); - nlm_custom_header (abfd)->hdr = hdr; - } - } - else - { - break; - } - } - return (true); -} - -/* Return whether there is a non-zero byte in a memory block. */ - -static boolean -find_nonzero (buf, size) - PTR buf; - size_t size; -{ - char *p = (char *) buf; - - while (size-- != 0) - if (*p++ != 0) - return true; - return false; -} - -/* Swap out the contents of the auxiliary headers. We create those - auxiliary headers which have been set non-zero. We do not require - the caller to set up the stamp fields. */ - -static boolean -nlm_swap_auxiliary_headers_out (abfd) - bfd *abfd; -{ - /* Write out the version header if there is one. */ - if (find_nonzero ((PTR) nlm_version_header (abfd), - sizeof (Nlm_Internal_Version_Header))) - { - Nlm_External_Version_Header thdr; - - memcpy (thdr.stamp, "VeRsIoN#", 8); - put_word (abfd, (bfd_vma) nlm_version_header (abfd)->majorVersion, - (bfd_byte *) thdr.majorVersion); - put_word (abfd, (bfd_vma) nlm_version_header (abfd)->minorVersion, - (bfd_byte *) thdr.minorVersion); - put_word (abfd, (bfd_vma) nlm_version_header (abfd)->revision, - (bfd_byte *) thdr.revision); - put_word (abfd, (bfd_vma) nlm_version_header (abfd)->year, - (bfd_byte *) thdr.year); - put_word (abfd, (bfd_vma) nlm_version_header (abfd)->month, - (bfd_byte *) thdr.month); - put_word (abfd, (bfd_vma) nlm_version_header (abfd)->day, - (bfd_byte *) thdr.day); - if (bfd_write ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr)) - return false; - } - - /* Write out the extended header if there is one. */ - if (find_nonzero ((PTR) nlm_extended_header (abfd), - sizeof (Nlm_Internal_Extended_Header))) - { - Nlm_External_Extended_Header thdr; - - memcpy (thdr.stamp, "MeSsAgEs", 8); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->languageID, - (bfd_byte *) thdr.languageID); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->messageFileOffset, - (bfd_byte *) thdr.messageFileOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->messageFileLength, - (bfd_byte *) thdr.messageFileLength); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->messageCount, - (bfd_byte *) thdr.messageCount); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->helpFileOffset, - (bfd_byte *) thdr.helpFileOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->helpFileLength, - (bfd_byte *) thdr.helpFileLength); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->RPCDataOffset, - (bfd_byte *) thdr.RPCDataOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->RPCDataLength, - (bfd_byte *) thdr.RPCDataLength); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedCodeOffset, - (bfd_byte *) thdr.sharedCodeOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedCodeLength, - (bfd_byte *) thdr.sharedCodeLength); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedDataOffset, - (bfd_byte *) thdr.sharedDataOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedDataLength, - (bfd_byte *) thdr.sharedDataLength); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupOffset, - (bfd_byte *) thdr.sharedRelocationFixupOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedRelocationFixupCount, - (bfd_byte *) thdr.sharedRelocationFixupCount); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceOffset, - (bfd_byte *) thdr.sharedExternalReferenceOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedExternalReferenceCount, - (bfd_byte *) thdr.sharedExternalReferenceCount); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedPublicsOffset, - (bfd_byte *) thdr.sharedPublicsOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedPublicsCount, - (bfd_byte *) thdr.sharedPublicsCount); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordOffset, - (bfd_byte *) thdr.sharedDebugRecordOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->sharedDebugRecordCount, - (bfd_byte *) thdr.sharedDebugRecordCount); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->SharedInitializationOffset, - (bfd_byte *) thdr.sharedInitializationOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->SharedExitProcedureOffset, - (bfd_byte *) thdr.SharedExitProcedureOffset); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->productID, - (bfd_byte *) thdr.productID); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->reserved0, - (bfd_byte *) thdr.reserved0); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->reserved1, - (bfd_byte *) thdr.reserved1); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->reserved2, - (bfd_byte *) thdr.reserved2); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->reserved3, - (bfd_byte *) thdr.reserved3); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->reserved4, - (bfd_byte *) thdr.reserved4); - put_word (abfd, - (bfd_vma) nlm_extended_header (abfd)->reserved5, - (bfd_byte *) thdr.reserved5); - if (bfd_write ((PTR) & thdr, sizeof (thdr), 1, abfd) != sizeof (thdr)) - return false; - } - - - /* Write out the copyright header if there is one. */ - if (find_nonzero ((PTR) nlm_copyright_header (abfd), - sizeof (Nlm_Internal_Copyright_Header))) - { - Nlm_External_Copyright_Header thdr; - - memcpy (thdr.stamp, "CoPyRiGhT=", 10); - if (bfd_write ((PTR) thdr.stamp, sizeof (thdr.stamp), 1, abfd) - != sizeof (thdr.stamp)) - return false; - thdr.copyrightMessageLength[0] = - nlm_copyright_header (abfd)->copyrightMessageLength; - if (bfd_write ((PTR) thdr.copyrightMessageLength, 1, 1, abfd) != 1) - return false; - /* The copyright message is a variable length string. */ - if (bfd_write ((PTR) nlm_copyright_header (abfd)->copyrightMessage, - nlm_copyright_header (abfd)->copyrightMessageLength + 1, - 1, abfd) != - ((bfd_size_type) - nlm_copyright_header (abfd)->copyrightMessageLength + 1)) - return false; - } - - /* Write out the custom header if there is one. */ - if (find_nonzero ((PTR) nlm_custom_header (abfd), - sizeof (Nlm_Internal_Custom_Header))) - { - Nlm_External_Custom_Header thdr; - boolean ds; - bfd_size_type hdrLength; - - ds = find_nonzero ((PTR) nlm_custom_header (abfd)->dataStamp, - sizeof (nlm_custom_header (abfd)->dataStamp)); - memcpy (thdr.stamp, "CuStHeAd", 8); - hdrLength = (2 * NLM_TARGET_LONG_SIZE + (ds ? 8 : 0) - + nlm_custom_header (abfd)->hdrLength); - put_word (abfd, hdrLength, thdr.length); - put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataOffset, - thdr.dataOffset); - put_word (abfd, (bfd_vma) nlm_custom_header (abfd)->dataLength, - thdr.dataLength); - if (! ds) - { - BFD_ASSERT (nlm_custom_header (abfd)->hdrLength == 0); - if (bfd_write ((PTR) &thdr, 1, - sizeof (thdr) - sizeof (thdr.dataStamp), abfd) - != sizeof (thdr) - sizeof (thdr.dataStamp)) - return false; - } - else - { - memcpy (thdr.dataStamp, nlm_custom_header (abfd)->dataStamp, - sizeof (thdr.dataStamp)); - if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr)) - return false; - if (bfd_write (nlm_custom_header (abfd)->hdr, 1, - nlm_custom_header (abfd)->hdrLength, abfd) - != nlm_custom_header (abfd)->hdrLength) - return false; - } - } - - /* Write out the Cygnus debugging header if there is one. */ - if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd), - sizeof (Nlm_Internal_Cygnus_Ext_Header))) - { - Nlm_External_Custom_Header thdr; - - memcpy (thdr.stamp, "CuStHeAd", 8); - put_word (abfd, (bfd_vma) 2 * NLM_TARGET_LONG_SIZE + 8, - (bfd_byte *) thdr.length); - put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->offset, - (bfd_byte *) thdr.dataOffset); - put_word (abfd, (bfd_vma) nlm_cygnus_ext_header (abfd)->length, - (bfd_byte *) thdr.dataLength); - memcpy (thdr.dataStamp, "CyGnUsEx", 8); - if (bfd_write ((PTR) &thdr, sizeof (thdr), 1, abfd) != sizeof (thdr)) - return false; - } - - return true; -} - -/* We read the NLM's public symbols and use it to generate a bfd symbol - table (hey, it's better than nothing) on a one-for-one basis. Thus - use the number of public symbols as the number of bfd symbols we will - have once we actually get around to reading them in. - - Return the number of bytes required to hold the symtab vector, based on - the count plus 1, since we will NULL terminate the vector allocated based - on this size. */ - -long -nlm_get_symtab_upper_bound (abfd) - bfd *abfd; -{ - Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */ - long symcount; - long symtab_size = 0; - - i_fxdhdrp = nlm_fixed_header (abfd); - symcount = (i_fxdhdrp->numberOfPublics - + i_fxdhdrp->numberOfDebugRecords - + i_fxdhdrp->numberOfExternalReferences); - symtab_size = (symcount + 1) * (sizeof (asymbol)); - return (symtab_size); -} - -/* Note that bfd_get_symcount is guaranteed to be zero if slurping the - symbol table fails. */ - -long -nlm_get_symtab (abfd, alocation) - bfd *abfd; - asymbol **alocation; -{ - nlm_symbol_type *symbase; - bfd_size_type counter = 0; - - if (nlm_slurp_symbol_table (abfd) == false) - return -1; - symbase = nlm_get_symbols (abfd); - while (counter < bfd_get_symcount (abfd)) - { - *alocation++ = &symbase->symbol; - symbase++; - counter++; - } - *alocation = (asymbol *) NULL; - return bfd_get_symcount (abfd); -} - -/* Make an NLM symbol. There is nothing special to do here. */ - -asymbol * -nlm_make_empty_symbol (abfd) - bfd *abfd; -{ - nlm_symbol_type *new; - - new = (nlm_symbol_type *) bfd_zalloc (abfd, sizeof (nlm_symbol_type)); - if (new) - new->symbol.the_bfd = abfd; - return &new->symbol; -} - -/* Get symbol information. */ - -void -nlm_get_symbol_info (ignore_abfd, symbol, ret) - bfd *ignore_abfd; - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); -} - -/* Print symbol information. */ - -void -nlm_print_symbol (abfd, afile, symbol, how) - bfd *abfd; - PTR afile; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *) afile; - - switch (how) - { - case bfd_print_symbol_name: - case bfd_print_symbol_more: - if (symbol->name) - fprintf (file, "%s", symbol->name); - break; - case bfd_print_symbol_all: - bfd_print_symbol_vandf ((PTR) file, symbol); - fprintf (file, " %-5s", symbol->section->name); - if (symbol->name) - fprintf (file, " %s", symbol->name); - break; - } -} - -/* Slurp in nlm symbol table. - - In the external (in-file) form, NLM export records are variable length, - with the following form: - - 1 byte length of the symbol name (N) - N bytes the symbol name - 4 bytes the symbol offset from start of it's section - - We also read in the debugging symbols and import records. Import - records are treated as undefined symbols. As we read the import - records we also read in the associated reloc information, which is - attached to the symbol. - - The bfd symbols are copied to SYMPTRS. - - When we return, the bfd symcount is either zero or contains the correct - number of symbols. -*/ - -static boolean -nlm_slurp_symbol_table (abfd) - bfd *abfd; -{ - Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */ - bfd_size_type totsymcount; /* Number of NLM symbols */ - bfd_size_type symcount; /* Counter of NLM symbols */ - nlm_symbol_type *sym; /* Pointer to current bfd symbol */ - unsigned char symlength; /* Symbol length read into here */ - unsigned char symtype; /* Type of debugging symbol */ - bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* Symbol offsets read into here */ - boolean (*read_import_func) PARAMS ((bfd *, nlm_symbol_type *)); - boolean (*set_public_section_func) PARAMS ((bfd *, nlm_symbol_type *)); - - if (nlm_get_symbols (abfd) != NULL) - return (true); - - /* Read each raw NLM symbol, using the information to create a canonical bfd - symbol table entry. - - Note that we allocate the initial bfd canonical symbol buffer based on a - one-to-one mapping of the NLM symbols to canonical symbols. We actually - use all the NLM symbols, so there will be no space left over at the end. - When we have all the symbols, we build the caller's pointer vector. */ - - abfd->symcount = 0; - i_fxdhdrp = nlm_fixed_header (abfd); - totsymcount = (i_fxdhdrp->numberOfPublics - + i_fxdhdrp->numberOfDebugRecords - + i_fxdhdrp->numberOfExternalReferences); - if (totsymcount == 0) - { - return (true); - } - - if (bfd_seek (abfd, i_fxdhdrp->publicsOffset, SEEK_SET) == -1) - return (false); - - sym = ((nlm_symbol_type *) - bfd_zalloc (abfd, totsymcount * sizeof (nlm_symbol_type))); - if (!sym) - return false; - nlm_set_symbols (abfd, sym); - - /* We use the bfd's symcount directly as the control count, so that early - termination of the loop leaves the symcount correct for the symbols that - were read. */ - - set_public_section_func = nlm_set_public_section_func (abfd); - symcount = i_fxdhdrp->numberOfPublics; - while (abfd->symcount < symcount) - { - if (bfd_read ((PTR) & symlength, sizeof (symlength), 1, abfd) - != sizeof (symlength)) - return (false); - sym->symbol.the_bfd = abfd; - sym->symbol.name = bfd_alloc (abfd, symlength + 1); - if (!sym->symbol.name) - return false; - if (bfd_read ((PTR) sym->symbol.name, symlength, 1, abfd) - != symlength) - return (false); - /* Cast away const. */ - ((char *) (sym->symbol.name))[symlength] = '\0'; - if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp)) - return (false); - sym->symbol.flags = BSF_GLOBAL | BSF_EXPORT; - sym->symbol.value = get_word (abfd, temp); - if (set_public_section_func) - { - /* Most backends can use the code below, but unfortunately - some use a different scheme. */ - if ((*set_public_section_func) (abfd, sym) == false) - return false; - } - else - { - if (sym->symbol.value & NLM_HIBIT) - { - sym->symbol.value &= ~NLM_HIBIT; - sym->symbol.flags |= BSF_FUNCTION; - sym->symbol.section = - bfd_get_section_by_name (abfd, NLM_CODE_NAME); - } - else - { - sym->symbol.section = - bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - } - } - sym->rcnt = 0; - abfd->symcount++; - sym++; - } - - /* Read the debugging records. */ - - if (i_fxdhdrp->numberOfDebugRecords > 0) - { - if (bfd_seek (abfd, i_fxdhdrp->debugInfoOffset, SEEK_SET) == -1) - return (false); - - symcount += i_fxdhdrp->numberOfDebugRecords; - while (abfd->symcount < symcount) - { - if ((bfd_read ((PTR) & symtype, sizeof (symtype), 1, abfd) - != sizeof (symtype)) - || bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp) - || (bfd_read ((PTR) & symlength, sizeof (symlength), 1, abfd) - != sizeof (symlength))) - return false; - sym->symbol.the_bfd = abfd; - sym->symbol.name = bfd_alloc (abfd, symlength + 1); - if (!sym->symbol.name) - return false; - if (bfd_read ((PTR) sym->symbol.name, symlength, 1, abfd) - != symlength) - return (false); - /* Cast away const. */ - ((char *) (sym->symbol.name))[symlength] = '\0'; - sym->symbol.flags = BSF_LOCAL; - sym->symbol.value = get_word (abfd, temp); - if (symtype == 0) - { - sym->symbol.section = - bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME); - } - else if (symtype == 1) - { - sym->symbol.flags |= BSF_FUNCTION; - sym->symbol.section = - bfd_get_section_by_name (abfd, NLM_CODE_NAME); - } - else - { - sym->symbol.section = bfd_abs_section_ptr; - } - sym->rcnt = 0; - abfd->symcount++; - sym++; - } - } - - /* Read in the import records. We can only do this if we know how - to read relocs for this target. */ - - read_import_func = nlm_read_import_func (abfd); - if (read_import_func != NULL) - { - if (bfd_seek (abfd, i_fxdhdrp->externalReferencesOffset, SEEK_SET) - == -1) - return (false); - - symcount += i_fxdhdrp->numberOfExternalReferences; - while (abfd->symcount < symcount) - { - if ((*read_import_func) (abfd, sym) == false) - return false; - sym++; - abfd->symcount++; - } - } - - return (true); -} - -/* Get the relocs for an NLM file. There are two types of relocs. - Imports are relocs against symbols defined in other NLM files. We - treat these as relocs against global symbols. Relocation fixups - are internal relocs. - - The actual format used to store the relocs is machine specific. */ - -/* Read in the relocation fixup information. This is stored in - nlm_relocation_fixups, an array of arelent structures, and - nlm_relocation_fixup_secs, an array of section pointers. The - section pointers are needed because the relocs are not sorted by - section. */ - -static boolean -nlm_slurp_reloc_fixups (abfd) - bfd *abfd; -{ - boolean (*read_func) PARAMS ((bfd *, nlm_symbol_type *, asection **, - arelent *)); - bfd_size_type count; - arelent *rels; - asection **secs; - - if (nlm_relocation_fixups (abfd) != NULL) - return true; - read_func = nlm_read_reloc_func (abfd); - if (read_func == NULL) - return true; - - if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset, - SEEK_SET) != 0) - return false; - - count = nlm_fixed_header (abfd)->numberOfRelocationFixups; - rels = (arelent *) bfd_alloc (abfd, count * sizeof (arelent)); - secs = (asection **) bfd_alloc (abfd, count * sizeof (asection *)); - if ((rels == NULL || secs == NULL) && count != 0) - return false; - nlm_relocation_fixups (abfd) = rels; - nlm_relocation_fixup_secs (abfd) = secs; - - /* We have to read piece by piece, because we don't know how large - the machine specific reloc information is. */ - while (count-- != 0) - { - if ((*read_func) (abfd, (nlm_symbol_type *) NULL, secs, rels) == false) - { - nlm_relocation_fixups (abfd) = NULL; - nlm_relocation_fixup_secs (abfd) = NULL; - return false; - } - ++secs; - ++rels; - } - - return true; -} - -/* Get the number of relocs. This really just returns an upper bound, - since it does not attempt to distinguish them based on the section. - That will be handled when they are actually read. */ - -long -nlm_get_reloc_upper_bound (abfd, sec) - bfd *abfd; - asection *sec; -{ - nlm_symbol_type *syms; - bfd_size_type count; - unsigned int ret; - - /* If we don't know how to read relocs, just return 0. */ - if (nlm_read_reloc_func (abfd) == NULL) - return -1; - /* Make sure we have either the code or the data section. */ - if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0) - return 0; - - syms = nlm_get_symbols (abfd); - if (syms == NULL) - { - if (nlm_slurp_symbol_table (abfd) == false) - return -1; - syms = nlm_get_symbols (abfd); - } - - ret = nlm_fixed_header (abfd)->numberOfRelocationFixups; - - count = bfd_get_symcount (abfd); - while (count-- != 0) - { - ret += syms->rcnt; - ++syms; - } - - return (ret + 1) * sizeof (arelent *); -} - -/* Get the relocs themselves. */ - -long -nlm_canonicalize_reloc (abfd, sec, relptr, symbols) - bfd *abfd; - asection *sec; - arelent **relptr; - asymbol **symbols; -{ - arelent *rels; - asection **secs; - bfd_size_type count, i; - unsigned int ret; - - /* Get the relocation fixups. */ - rels = nlm_relocation_fixups (abfd); - if (rels == NULL) - { - if (nlm_slurp_reloc_fixups (abfd) == false) - return -1; - rels = nlm_relocation_fixups (abfd); - } - secs = nlm_relocation_fixup_secs (abfd); - - ret = 0; - count = nlm_fixed_header (abfd)->numberOfRelocationFixups; - for (i = 0; i < count; i++, rels++, secs++) - { - if (*secs == sec) - { - *relptr++ = rels; - ++ret; - } - } - - /* Get the import symbols. */ - count = bfd_get_symcount (abfd); - for (i = 0; i < count; i++, symbols++) - { - asymbol *sym; - - sym = *symbols; - if (bfd_asymbol_flavour (sym) == bfd_target_nlm_flavour) - { - nlm_symbol_type *nlm_sym; - bfd_size_type j; - - nlm_sym = (nlm_symbol_type *) sym; - for (j = 0; j < nlm_sym->rcnt; j++) - { - if (nlm_sym->relocs[j].section == sec) - { - *relptr = &nlm_sym->relocs[j].reloc; - (*relptr)->sym_ptr_ptr = symbols; - ++relptr; - ++ret; - } - } - } - } - - *relptr = NULL; - - return ret; -} - -/* Compute the section file positions for an NLM file. All variable - length data in the file headers must be set before this function is - called. If the variable length data is changed later, the - resulting object file will be incorrect. Unfortunately, there is - no way to check this. - - This routine also sets the Size and Offset fields in the fixed - header. - - It also looks over the symbols and moves any common symbols into - the .bss section; NLM has no way to represent a common symbol. - This approach means that either the symbols must already have been - set at this point, or there must be no common symbols. We need to - move the symbols at this point so that mangle_relocs can see the - final values. */ - -static boolean -nlm_compute_section_file_positions (abfd) - bfd *abfd; -{ - file_ptr sofar; - asection *sec; - bfd_vma text, data, bss; - bfd_vma text_low, data_low; - unsigned int text_align, data_align, other_align; - file_ptr text_ptr, data_ptr, other_ptr; - asection *bss_sec; - asymbol **sym_ptr_ptr; - - if (abfd->output_has_begun == true) - return true; - - /* Make sure we have a section to hold uninitialized data. */ - bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME); - if (bss_sec == NULL) - { - if (!add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME, - (file_ptr) 0, (bfd_size_type) 0, - SEC_ALLOC)) - return false; - bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME); - } - - abfd->output_has_begun = true; - - /* The fixed header. */ - sofar = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd); - - /* The variable header. */ - sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength) - + nlm_variable_header (abfd)->descriptionLength + 1 - + NLM_TARGET_LONG_SIZE /* stackSize */ - + NLM_TARGET_LONG_SIZE /* reserved */ - + sizeof (nlm_variable_header (abfd)->oldThreadName) - + sizeof (nlm_variable_header (abfd)->screenNameLength) - + nlm_variable_header (abfd)->screenNameLength + 1 - + sizeof (nlm_variable_header (abfd)->threadNameLength) - + nlm_variable_header (abfd)->threadNameLength + 1); - - /* The auxiliary headers. */ - if (find_nonzero ((PTR) nlm_version_header (abfd), - sizeof (Nlm_Internal_Version_Header))) - sofar += sizeof (Nlm_External_Version_Header); - if (find_nonzero ((PTR) nlm_extended_header (abfd), - sizeof (Nlm_Internal_Extended_Header))) - sofar += sizeof (Nlm_External_Extended_Header); - if (find_nonzero ((PTR) nlm_copyright_header (abfd), - sizeof (Nlm_Internal_Copyright_Header))) - sofar += (sizeof (Nlm_External_Copyright_Header) - + nlm_copyright_header (abfd)->copyrightMessageLength + 1); - if (find_nonzero ((PTR) nlm_custom_header (abfd), - sizeof (Nlm_Internal_Custom_Header))) - sofar += (sizeof (Nlm_External_Custom_Header) - + nlm_custom_header (abfd)->hdrLength); - if (find_nonzero ((PTR) nlm_cygnus_ext_header (abfd), - sizeof (Nlm_Internal_Cygnus_Ext_Header))) - sofar += sizeof (Nlm_External_Custom_Header); - - /* Compute the section file positions in two passes. First get the - sizes of the text and data sections, and then set the file - positions. This code aligns the sections in the file using the - same alignment restrictions that apply to the sections in memory; - this may not be necessary. */ - text = 0; - text_low = (bfd_vma) - 1; - text_align = 0; - data = 0; - data_low = (bfd_vma) - 1; - data_align = 0; - bss = 0; - other_align = 0; - for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next) - { - flagword f; - - sec->_raw_size = BFD_ALIGN (sec->_raw_size, 1 << sec->alignment_power); - - f = bfd_get_section_flags (abfd, sec); - if (f & SEC_CODE) - { - text += sec->_raw_size; - if (bfd_get_section_vma (abfd, sec) < text_low) - text_low = bfd_get_section_vma (abfd, sec); - if (sec->alignment_power > text_align) - text_align = sec->alignment_power; - } - else if (f & SEC_DATA) - { - data += sec->_raw_size; - if (bfd_get_section_vma (abfd, sec) < data_low) - data_low = bfd_get_section_vma (abfd, sec); - if (sec->alignment_power > data_align) - data_align = sec->alignment_power; - } - else if (f & SEC_HAS_CONTENTS) - { - if (sec->alignment_power > other_align) - other_align = sec->alignment_power; - } - else if (f & SEC_ALLOC) - bss += sec->_raw_size; - } - - nlm_set_text_low (abfd, text_low); - nlm_set_data_low (abfd, data_low); - - if (nlm_no_uninitialized_data (abfd)) - { - /* This NetWare format does not use uninitialized data. We must - increase the size of the data section. We will never wind up - writing those file locations, so they will remain zero. */ - data += bss; - bss = 0; - } - - text_ptr = BFD_ALIGN (sofar, 1 << text_align); - data_ptr = BFD_ALIGN (text_ptr + text, 1 << data_align); - other_ptr = BFD_ALIGN (data_ptr + data, 1 << other_align); - - /* Fill in some fields in the header for which we now have the - information. */ - nlm_fixed_header (abfd)->codeImageOffset = text_ptr; - nlm_fixed_header (abfd)->codeImageSize = text; - nlm_fixed_header (abfd)->dataImageOffset = data_ptr; - nlm_fixed_header (abfd)->dataImageSize = data; - nlm_fixed_header (abfd)->uninitializedDataSize = bss; - - for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next) - { - flagword f; - - f = bfd_get_section_flags (abfd, sec); - - if (f & SEC_CODE) - { - sec->filepos = text_ptr; - text_ptr += sec->_raw_size; - } - else if (f & SEC_DATA) - { - sec->filepos = data_ptr; - data_ptr += sec->_raw_size; - } - else if (f & SEC_HAS_CONTENTS) - { - sec->filepos = other_ptr; - other_ptr += sec->_raw_size; - } - } - - nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr; - - /* Move all common symbols into the .bss section. */ - - sym_ptr_ptr = bfd_get_outsymbols (abfd); - if (sym_ptr_ptr != NULL) - { - asymbol **sym_end; - bfd_vma add; - - sym_end = sym_ptr_ptr + bfd_get_symcount (abfd); - add = 0; - for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++) - { - asymbol *sym; - bfd_vma size; - - sym = *sym_ptr_ptr; - - if (!bfd_is_com_section (bfd_get_section (sym))) - continue; - - /* Put the common symbol in the .bss section, and increase - the size of the .bss section by the size of the common - symbol (which is the old value of the symbol). */ - sym->section = bss_sec; - size = sym->value; - sym->value = bss_sec->_raw_size + add; - add += size; - add = BFD_ALIGN (add, 1 << bss_sec->alignment_power); - } - if (add != 0) - { - if (nlm_no_uninitialized_data (abfd)) - { - /* We could handle this case, but so far it hasn't been - necessary. */ - abort (); - } - nlm_fixed_header (abfd)->uninitializedDataSize += add; - bss_sec->_raw_size += add; - } - } - - return true; -} - -/* Set the contents of a section. To do this we need to know where - the section is going to be located in the output file. That means - that the sizes of all the sections must be set, and all the - variable size header information must be known. */ - -boolean -nlm_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - asection *section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if (abfd->output_has_begun == false - && nlm_compute_section_file_positions (abfd) == false) - return false; - - if (count == 0) - return true; - - /* i386 NetWare has a very restricted set of relocs. In order for - objcopy to work, the NLM i386 backend needs a chance to rework - the section contents so that its set of relocs will work. If all - the relocs are already acceptable, this will not do anything. */ - if (section->reloc_count != 0) - { - boolean (*mangle_relocs_func) PARAMS ((bfd *, asection *, PTR, - bfd_vma, bfd_size_type)); - - mangle_relocs_func = nlm_mangle_relocs_func (abfd); - if (mangle_relocs_func != NULL) - { - if (!(*mangle_relocs_func) (abfd, section, location, - (bfd_vma) offset, count)) - return false; - } - } - - if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0 - || bfd_write (location, 1, count, abfd) != count) - return false; - - return true; -} - -/* We need to sort a list of relocs associated with sections when we - write out the external relocs. */ - -static int -nlm_external_reloc_compare (p1, p2) - const void *p1; - const void *p2; -{ - const struct reloc_and_sec *r1 = (const struct reloc_and_sec *) p1; - const struct reloc_and_sec *r2 = (const struct reloc_and_sec *) p2; - int cmp; - - cmp = strcmp ((*r1->rel->sym_ptr_ptr)->name, - (*r2->rel->sym_ptr_ptr)->name); - if (cmp != 0) - return cmp; - - /* We sort by address within symbol to make the sort more stable and - increase the chances that different hosts will generate bit for - bit equivalent results. */ - return (int) (r1->rel->address - r2->rel->address); -} - -/* Write out an NLM file. We write out the information in this order: - fixed header - variable header - auxiliary headers - code sections - data sections - other sections (custom data, messages, help, shared NLM, RPC, - module dependencies) - relocation fixups - external references (imports) - public symbols (exports) - debugging records - This is similar to the order used by the NetWare tools; the - difference is that NetWare puts the sections other than code, data - and custom data at the end of the NLM. It is convenient for us to - know where the sections are going to be before worrying about the - size of the other information. - - By the time this function is called, all the section data should - have been output using set_section_contents. Note that custom - data, the message file, the help file, the shared NLM file, the RPC - data, and the module dependencies are all considered to be - sections; the caller is responsible for filling in the offset and - length fields in the NLM headers. The relocation fixups and - imports are both obtained from the list of relocs attached to each - section. The exports and debugging records are obtained from the - list of outsymbols. */ - -boolean -nlm_write_object_contents (abfd) - bfd *abfd; -{ - asection *sec; - boolean (*write_import_func) PARAMS ((bfd *, asection *, arelent *)); - bfd_size_type external_reloc_count, internal_reloc_count, i, c; - struct reloc_and_sec *external_relocs; - asymbol **sym_ptr_ptr; - file_ptr last; - boolean (*write_prefix_func) PARAMS ((bfd *)); - unsigned char *fixed_header = NULL; - - fixed_header = ((unsigned char *) - bfd_malloc ((size_t) nlm_fixed_header_size (abfd))); - if (fixed_header == NULL) - goto error_return; - - if (abfd->output_has_begun == false - && nlm_compute_section_file_positions (abfd) == false) - goto error_return; - - /* Write out the variable length headers. */ - if (bfd_seek (abfd, - nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd), - SEEK_SET) != 0) - goto error_return; - if (nlm_swap_variable_header_out (abfd) == false - || nlm_swap_auxiliary_headers_out (abfd) == false) - { - bfd_set_error (bfd_error_system_call); - goto error_return; - } - - /* A weak check on whether the section file positions were - reasonable. */ - if (bfd_tell (abfd) > nlm_fixed_header (abfd)->codeImageOffset) - { - bfd_set_error (bfd_error_invalid_operation); - goto error_return; - } - - /* Advance to the relocs. */ - if (bfd_seek (abfd, nlm_fixed_header (abfd)->relocationFixupOffset, - SEEK_SET) != 0) - goto error_return; - - /* The format of the relocation entries is dependent upon the - particular target. We use an external routine to write the reloc - out. */ - write_import_func = nlm_write_import_func (abfd); - - /* Write out the internal relocation fixups. While we're looping - over the relocs, we also count the external relocs, which is - needed when they are written out below. */ - internal_reloc_count = 0; - external_reloc_count = 0; - for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next) - { - arelent **rel_ptr_ptr, **rel_end; - - if (sec->reloc_count == 0) - continue; - - /* We can only represent relocs within a code or data - section. We ignore them for a debugging section. */ - if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0) - continue; - - /* We need to know how to write out imports */ - if (write_import_func == NULL) - { - bfd_set_error (bfd_error_invalid_operation); - goto error_return; - } - - rel_ptr_ptr = sec->orelocation; - rel_end = rel_ptr_ptr + sec->reloc_count; - for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++) - { - arelent *rel; - asymbol *sym; - - rel = *rel_ptr_ptr; - sym = *rel->sym_ptr_ptr; - - if (! bfd_is_und_section (bfd_get_section (sym))) - { - ++internal_reloc_count; - if ((*write_import_func) (abfd, sec, rel) == false) - goto error_return; - } - else - ++external_reloc_count; - } - } - nlm_fixed_header (abfd)->numberOfRelocationFixups = internal_reloc_count; - - /* Write out the imports (relocs against external symbols). These - are output as a symbol name followed by all the relocs for that - symbol, so we must first gather together all the relocs against - external symbols and sort them. */ - external_relocs = - (struct reloc_and_sec *) bfd_alloc (abfd, - (external_reloc_count - * sizeof (struct reloc_and_sec))); - if (external_relocs == (struct reloc_and_sec *) NULL) - goto error_return; - i = 0; - for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next) - { - arelent **rel_ptr_ptr, **rel_end; - - if (sec->reloc_count == 0) - continue; - - rel_ptr_ptr = sec->orelocation; - rel_end = rel_ptr_ptr + sec->reloc_count; - for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++) - { - arelent *rel; - asymbol *sym; - - rel = *rel_ptr_ptr; - sym = *rel->sym_ptr_ptr; - - if (! bfd_is_und_section (bfd_get_section (sym))) - continue; - - external_relocs[i].rel = rel; - external_relocs[i].sec = sec; - ++i; - } - } - - BFD_ASSERT (i == external_reloc_count); - - /* Sort the external relocs by name. */ - qsort ((PTR) external_relocs, (size_t) external_reloc_count, - sizeof (struct reloc_and_sec), nlm_external_reloc_compare); - - /* Write out the external relocs. */ - nlm_fixed_header (abfd)->externalReferencesOffset = bfd_tell (abfd); - c = 0; - i = 0; - while (i < external_reloc_count) - { - arelent *rel; - asymbol *sym; - bfd_size_type j, cnt; - - ++c; - - rel = external_relocs[i].rel; - sym = *rel->sym_ptr_ptr; - - cnt = 0; - for (j = i; - (j < external_reloc_count - && *external_relocs[j].rel->sym_ptr_ptr == sym); - j++) - ++cnt; - - if ((*nlm_write_external_func (abfd)) (abfd, cnt, sym, - &external_relocs[i]) - == false) - goto error_return; - - i += cnt; - } - - nlm_fixed_header (abfd)->numberOfExternalReferences = c; - - /* Write out the public symbols (exports). */ - sym_ptr_ptr = bfd_get_outsymbols (abfd); - if (sym_ptr_ptr != (asymbol **) NULL) - { - bfd_vma (*get_public_offset_func) PARAMS ((bfd *, asymbol *)); - boolean (*write_export_func) PARAMS ((bfd *, asymbol *, bfd_vma)); - - asymbol **sym_end; - - nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd); - get_public_offset_func = nlm_get_public_offset_func (abfd); - write_export_func = nlm_write_export_func (abfd); - c = 0; - sym_end = sym_ptr_ptr + bfd_get_symcount (abfd); - for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++) - { - asymbol *sym; - bfd_byte len; - bfd_vma offset; - bfd_byte temp[NLM_TARGET_LONG_SIZE]; - - sym = *sym_ptr_ptr; - - if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0 - || bfd_is_und_section (bfd_get_section (sym))) - continue; - - ++c; - - if (get_public_offset_func) - { - /* Most backends can use the code below, but - unfortunately some use a different scheme. */ - offset = (*get_public_offset_func) (abfd, sym); - } - else - { - offset = bfd_asymbol_value (sym); - sec = sym->section; - if (sec->flags & SEC_CODE) - { - offset -= nlm_get_text_low (abfd); - offset |= NLM_HIBIT; - } - else if (sec->flags & (SEC_DATA | SEC_ALLOC)) - { - /* SEC_ALLOC is for the .bss section. */ - offset -= nlm_get_data_low (abfd); - } - else - { - /* We can't handle an exported symbol that is not in - the code or data segment. */ - bfd_set_error (bfd_error_invalid_operation); - goto error_return; - } - } - - if (write_export_func) - { - if ((*write_export_func) (abfd, sym, offset) == false) - goto error_return; - } - else - { - len = strlen (sym->name); - if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) - != sizeof (bfd_byte)) - || bfd_write (sym->name, len, 1, abfd) != len) - goto error_return; - - put_word (abfd, offset, temp); - if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp)) - goto error_return; - } - } - nlm_fixed_header (abfd)->numberOfPublics = c; - - /* Write out the debugging records. The NLM conversion program - wants to be able to inhibit this, so as a special hack if - debugInfoOffset is set to -1 we don't write any debugging - information. This can not be handled by fiddling with the - symbol table, because exported symbols appear in both the - exported symbol list and the debugging information. */ - if (nlm_fixed_header (abfd)->debugInfoOffset == (file_ptr) - 1) - { - nlm_fixed_header (abfd)->debugInfoOffset = 0; - nlm_fixed_header (abfd)->numberOfDebugRecords = 0; - } - else - { - nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd); - c = 0; - sym_ptr_ptr = bfd_get_outsymbols (abfd); - sym_end = sym_ptr_ptr + bfd_get_symcount (abfd); - for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++) - { - asymbol *sym; - bfd_byte type, len; - bfd_vma offset; - bfd_byte temp[NLM_TARGET_LONG_SIZE]; - - sym = *sym_ptr_ptr; - - /* The NLM notion of a debugging symbol is actually what - BFD calls a local or global symbol. What BFD calls a - debugging symbol NLM does not understand at all. */ - if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0 - || (sym->flags & BSF_DEBUGGING) != 0 - || bfd_is_und_section (bfd_get_section (sym))) - continue; - - ++c; - - offset = bfd_asymbol_value (sym); - sec = sym->section; - if (sec->flags & SEC_CODE) - { - offset -= nlm_get_text_low (abfd); - type = 1; - } - else if (sec->flags & (SEC_DATA | SEC_ALLOC)) - { - /* SEC_ALLOC is for the .bss section. */ - offset -= nlm_get_data_low (abfd); - type = 0; - } - else - type = 2; - - /* The type is 0 for data, 1 for code, 2 for absolute. */ - if (bfd_write (&type, sizeof (bfd_byte), 1, abfd) - != sizeof (bfd_byte)) - goto error_return; - - put_word (abfd, offset, temp); - if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp)) - goto error_return; - - len = strlen (sym->name); - if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) - != sizeof (bfd_byte)) - || bfd_write (sym->name, len, 1, abfd) != len) - goto error_return; - } - nlm_fixed_header (abfd)->numberOfDebugRecords = c; - } - } - - /* NLMLINK fills in offset values even if there is no data, so we do - the same. */ - last = bfd_tell (abfd); - if (nlm_fixed_header (abfd)->codeImageOffset == 0) - nlm_fixed_header (abfd)->codeImageOffset = last; - if (nlm_fixed_header (abfd)->dataImageOffset == 0) - nlm_fixed_header (abfd)->dataImageOffset = last; - if (nlm_fixed_header (abfd)->customDataOffset == 0) - nlm_fixed_header (abfd)->customDataOffset = last; - if (nlm_fixed_header (abfd)->moduleDependencyOffset == 0) - nlm_fixed_header (abfd)->moduleDependencyOffset = last; - if (nlm_fixed_header (abfd)->relocationFixupOffset == 0) - nlm_fixed_header (abfd)->relocationFixupOffset = last; - if (nlm_fixed_header (abfd)->externalReferencesOffset == 0) - nlm_fixed_header (abfd)->externalReferencesOffset = last; - if (nlm_fixed_header (abfd)->publicsOffset == 0) - nlm_fixed_header (abfd)->publicsOffset = last; - if (nlm_fixed_header (abfd)->debugInfoOffset == 0) - nlm_fixed_header (abfd)->debugInfoOffset = last; - - /* At this point everything has been written out except the fixed - header. */ - memcpy (nlm_fixed_header (abfd)->signature, nlm_signature (abfd), - NLM_SIGNATURE_SIZE); - nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION; - nlm_fixed_header (abfd)->codeStartOffset = - (bfd_get_start_address (abfd) - - nlm_get_text_low (abfd)); - - /* We have no convenient way for the caller to pass in the exit - procedure or the check unload procedure, so the caller must set - the values in the header to the values of the symbols. */ - nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd); - if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0) - nlm_fixed_header (abfd)->checkUnloadProcedureOffset -= - nlm_get_text_low (abfd); - - if (bfd_seek (abfd, 0, SEEK_SET) != 0) - goto error_return; - - write_prefix_func = nlm_write_prefix_func (abfd); - if (write_prefix_func) - { - if ((*write_prefix_func) (abfd) == false) - goto error_return; - } - - BFD_ASSERT ((bfd_size_type) bfd_tell (abfd) - == nlm_optional_prefix_size (abfd)); - - nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), fixed_header); - if (bfd_write (fixed_header, nlm_fixed_header_size (abfd), 1, abfd) - != nlm_fixed_header_size (abfd)) - goto error_return; - - if (fixed_header != NULL) - free (fixed_header); - return true; - -error_return: - if (fixed_header != NULL) - free (fixed_header); - return false; -} diff --git a/contrib/gdb/bfd/nlmswap.h b/contrib/gdb/bfd/nlmswap.h deleted file mode 100644 index 5a9ce72..0000000 --- a/contrib/gdb/bfd/nlmswap.h +++ /dev/null @@ -1,157 +0,0 @@ -/* NLM (NetWare Loadable Module) swapping routines for BFD. - Copyright (C) 1993 Free Software Foundation, Inc. - - Written by Fred Fish @ Cygnus Support, using ELF support as the - template. - -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. */ - -/* Although this is a header file, it defines functions. It is - included by NLM backends to define swapping functions that vary - from one NLM to another. The backend code must arrange for - Nlm_External_xxxx to be defined appropriately, and can then include - this file to get the swapping routines. - - At the moment this is only needed for one structure, the fixed NLM - file header. */ - -static void nlm_swap_fixed_header_in PARAMS ((bfd *, PTR, - Nlm_Internal_Fixed_Header *)); -static void nlm_swap_fixed_header_out PARAMS ((bfd *, - Nlm_Internal_Fixed_Header *, - PTR)); - -/* Translate an NLM fixed length file header in external format into an NLM - file header in internal format. */ - -static void -nlm_swap_fixed_header_in (abfd, realsrc, dst) - bfd *abfd; - PTR realsrc; - Nlm_Internal_Fixed_Header *dst; -{ - Nlm_External_Fixed_Header *src = (Nlm_External_Fixed_Header *) realsrc; - memcpy (dst->signature, src->signature, NLM_SIGNATURE_SIZE); - memcpy (dst->moduleName, src->moduleName, NLM_MODULE_NAME_SIZE); - dst->version = - bfd_h_get_32 (abfd, (bfd_byte *) src->version); - dst->codeImageOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->codeImageOffset); - dst->codeImageSize = - bfd_h_get_32 (abfd, (bfd_byte *) src->codeImageSize); - dst->dataImageOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->dataImageOffset); - dst->dataImageSize = - bfd_h_get_32 (abfd, (bfd_byte *) src->dataImageSize); - dst->uninitializedDataSize = - bfd_h_get_32 (abfd, (bfd_byte *) src->uninitializedDataSize); - dst->customDataOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->customDataOffset); - dst->customDataSize = - bfd_h_get_32 (abfd, (bfd_byte *) src->customDataSize); - dst->moduleDependencyOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->moduleDependencyOffset); - dst->numberOfModuleDependencies = - bfd_h_get_32 (abfd, (bfd_byte *) src->numberOfModuleDependencies); - dst->relocationFixupOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->relocationFixupOffset); - dst->numberOfRelocationFixups = - bfd_h_get_32 (abfd, (bfd_byte *) src->numberOfRelocationFixups); - dst->externalReferencesOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->externalReferencesOffset); - dst->numberOfExternalReferences = - bfd_h_get_32 (abfd, (bfd_byte *) src->numberOfExternalReferences); - dst->publicsOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->publicsOffset); - dst->numberOfPublics = - bfd_h_get_32 (abfd, (bfd_byte *) src->numberOfPublics); - dst->debugInfoOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->debugInfoOffset); - dst->numberOfDebugRecords = - bfd_h_get_32 (abfd, (bfd_byte *) src->numberOfDebugRecords); - dst->codeStartOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->codeStartOffset); - dst->exitProcedureOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->exitProcedureOffset); - dst->checkUnloadProcedureOffset = - bfd_h_get_32 (abfd, (bfd_byte *) src->checkUnloadProcedureOffset); - dst->moduleType = - bfd_h_get_32 (abfd, (bfd_byte *) src->moduleType); - dst->flags = - bfd_h_get_32 (abfd, (bfd_byte *) src->flags); -} - -/* Translate an NLM fixed length file header in internal format into - an NLM file header in external format. */ - -static void -nlm_swap_fixed_header_out (abfd, src, realdst) - bfd *abfd; - Nlm_Internal_Fixed_Header *src; - PTR realdst; -{ - Nlm_External_Fixed_Header *dst = (Nlm_External_Fixed_Header *) realdst; - memset (dst, 0, sizeof *dst); - memcpy (dst->signature, src->signature, NLM_SIGNATURE_SIZE); - memcpy (dst->moduleName, src->moduleName, NLM_MODULE_NAME_SIZE); - bfd_h_put_32 (abfd, (bfd_vma) src->version, - (bfd_byte *) dst->version); - bfd_h_put_32 (abfd, (bfd_vma) src->codeImageOffset, - (bfd_byte *) dst->codeImageOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->codeImageSize, - (bfd_byte *) dst->codeImageSize); - bfd_h_put_32 (abfd, (bfd_vma) src->dataImageOffset, - (bfd_byte *) dst->dataImageOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->dataImageSize, - (bfd_byte *) dst->dataImageSize); - bfd_h_put_32 (abfd, (bfd_vma) src->uninitializedDataSize, - (bfd_byte *) dst->uninitializedDataSize); - bfd_h_put_32 (abfd, (bfd_vma) src->customDataOffset, - (bfd_byte *) dst->customDataOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->customDataSize, - (bfd_byte *) dst->customDataSize); - bfd_h_put_32 (abfd, (bfd_vma) src->moduleDependencyOffset, - (bfd_byte *) dst->moduleDependencyOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->numberOfModuleDependencies, - (bfd_byte *) dst->numberOfModuleDependencies); - bfd_h_put_32 (abfd, (bfd_vma) src->relocationFixupOffset, - (bfd_byte *) dst->relocationFixupOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->numberOfRelocationFixups, - (bfd_byte *) dst->numberOfRelocationFixups); - bfd_h_put_32 (abfd, (bfd_vma) src->externalReferencesOffset, - (bfd_byte *) dst->externalReferencesOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->numberOfExternalReferences, - (bfd_byte *) dst->numberOfExternalReferences); - bfd_h_put_32 (abfd, (bfd_vma) src->publicsOffset, - (bfd_byte *) dst->publicsOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->numberOfPublics, - (bfd_byte *) dst->numberOfPublics); - bfd_h_put_32 (abfd, (bfd_vma) src->debugInfoOffset, - (bfd_byte *) dst->debugInfoOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->numberOfDebugRecords, - (bfd_byte *) dst->numberOfDebugRecords); - bfd_h_put_32 (abfd, (bfd_vma) src->codeStartOffset, - (bfd_byte *) dst->codeStartOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->exitProcedureOffset, - (bfd_byte *) dst->exitProcedureOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->checkUnloadProcedureOffset, - (bfd_byte *) dst->checkUnloadProcedureOffset); - bfd_h_put_32 (abfd, (bfd_vma) src->moduleType, - (bfd_byte *) dst->moduleType); - bfd_h_put_32 (abfd, (bfd_vma) src->flags, - (bfd_byte *) dst->flags); -} diff --git a/contrib/gdb/bfd/ns32knetbsd.c b/contrib/gdb/bfd/ns32knetbsd.c deleted file mode 100644 index 3e3f08a..0000000 --- a/contrib/gdb/bfd/ns32knetbsd.c +++ /dev/null @@ -1,53 +0,0 @@ -/* BFD back-end for NetBSD/ns32k a.out-ish binaries. - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - -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. */ - -#define BYTES_IN_WORD 4 -#undef TARGET_IS_BIG_ENDIAN_P - -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE 4096 - -#define DEFAULT_ARCH bfd_arch_ns32k -#define MACHTYPE_OK(mtype) ((mtype) == M_532_NETBSD || (mtype) == M_UNKNOWN) - -#define MY(OP) CAT(pc532netbsd_,OP) - -#define NAME(x,y) CAT3(ns32kaout,_32_,y) - -/* This needs to start with a.out so GDB knows it is an a.out variant. */ -#define TARGETNAME "a.out-ns32k-netbsd" - -#define ns32kaout_32_get_section_contents aout_32_get_section_contents - -#define MY_text_includes_header 1 - -/* We can`t use the MYNS macro here for cpp reasons too subtle - * for me -- IWD - */ -#define MY_bfd_reloc_type_lookup ns32kaout_bfd_reloc_type_lookup - -#include "bfd.h" /* To ensure following declaration is OK */ - -CONST struct reloc_howto_struct * -MY_bfd_reloc_type_lookup - PARAMS((bfd *abfd AND - bfd_reloc_code_real_type code)); - - -#include "netbsd.h" diff --git a/contrib/gdb/bfd/oasys.c b/contrib/gdb/bfd/oasys.c deleted file mode 100644 index c721472..0000000 --- a/contrib/gdb/bfd/oasys.c +++ /dev/null @@ -1,1533 +0,0 @@ -/* BFD back-end for oasys objects. - Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support, <sac@cygnus.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. */ - -#define UNDERSCORE_HACK 1 -#include "bfd.h" -#include "sysdep.h" -#include <ctype.h> -#include "libbfd.h" -#include "oasys.h" -#include "liboasys.h" - -/* XXX - FIXME. offsetof belongs in the system-specific files in - ../include/sys. */ -/* Define offsetof for those systems which lack it */ - -#ifndef offsetof -#define offsetof(type, identifier) (size_t) &(((type *) 0)->identifier) -#endif - -static boolean oasys_read_record PARAMS ((bfd *, - oasys_record_union_type *)); -static boolean oasys_write_sections PARAMS ((bfd *)); -static boolean oasys_write_record PARAMS ((bfd *, - oasys_record_enum_type, - oasys_record_union_type *, - size_t)); -static boolean oasys_write_syms PARAMS ((bfd *)); -static boolean oasys_write_header PARAMS ((bfd *)); -static boolean oasys_write_end PARAMS ((bfd *)); -static boolean oasys_write_data PARAMS ((bfd *)); - -/* Read in all the section data and relocation stuff too */ -PROTO (static boolean, oasys_slurp_section_data, (bfd * CONST abfd)); - -static boolean -oasys_read_record (abfd, record) - bfd *abfd; - oasys_record_union_type *record; -{ - if (bfd_read ((PTR) record, 1, sizeof (record->header), abfd) - != sizeof (record->header)) - return false; - - if ((size_t) record->header.length <= (size_t) sizeof (record->header)) - return true; - if (bfd_read ((PTR) (((char *) record) + sizeof (record->header)), - 1, record->header.length - sizeof (record->header), - abfd) - != record->header.length - sizeof (record->header)) - return false; - return true; -} -static size_t -oasys_string_length (record) - oasys_record_union_type *record; -{ - return record->header.length - - ((char *) record->symbol.name - (char *) record); -} - -/*****************************************************************************/ - -/* - -Slurp the symbol table by reading in all the records at the start file -till we get to the first section record. - -We'll sort the symbolss into two lists, defined and undefined. The -undefined symbols will be placed into the table according to their -refno. - -We do this by placing all undefined symbols at the front of the table -moving in, and the defined symbols at the end of the table moving back. - -*/ - -static boolean -oasys_slurp_symbol_table (abfd) - bfd *CONST abfd; -{ - oasys_record_union_type record; - oasys_data_type *data = OASYS_DATA (abfd); - boolean loop = true; - asymbol *dest_defined; - asymbol *dest; - char *string_ptr; - - - if (data->symbols != (asymbol *) NULL) - { - return true; - } - /* Buy enough memory for all the symbols and all the names */ - data->symbols = - (asymbol *) bfd_alloc (abfd, sizeof (asymbol) * abfd->symcount); -#ifdef UNDERSCORE_HACK - /* buy 1 more char for each symbol to keep the underscore in*/ - data->strings = bfd_alloc (abfd, data->symbol_string_length + - abfd->symcount); -#else - data->strings = bfd_alloc (abfd, data->symbol_string_length); -#endif - if (!data->symbols || !data->strings) - return false; - - dest_defined = data->symbols + abfd->symcount - 1; - - string_ptr = data->strings; - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - return false; - while (loop) - { - - if (! oasys_read_record (abfd, &record)) - return false; - switch (record.header.type) - { - case oasys_record_is_header_enum: - break; - case oasys_record_is_local_enum: - case oasys_record_is_symbol_enum: - { - int flag = record.header.type == (int) oasys_record_is_local_enum ? - (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT); - - - size_t length = oasys_string_length (&record); - switch (record.symbol.relb & RELOCATION_TYPE_BITS) - { - case RELOCATION_TYPE_ABS: - dest = dest_defined--; - dest->section = bfd_abs_section_ptr; - dest->flags = 0; - - break; - case RELOCATION_TYPE_REL: - dest = dest_defined--; - dest->section = - OASYS_DATA (abfd)->sections[record.symbol.relb & - RELOCATION_SECT_BITS]; - if (record.header.type == (int) oasys_record_is_local_enum) - { - dest->flags = BSF_LOCAL; - if (dest->section == (asection *) (~0)) - { - /* It seems that sometimes internal symbols are tied up, but - still get output, even though there is no - section */ - dest->section = 0; - } - } - else - { - - dest->flags = flag; - } - break; - case RELOCATION_TYPE_UND: - dest = data->symbols + bfd_h_get_16 (abfd, record.symbol.refno); - dest->section = bfd_und_section_ptr; - break; - case RELOCATION_TYPE_COM: - dest = dest_defined--; - dest->name = string_ptr; - dest->the_bfd = abfd; - - dest->section = bfd_com_section_ptr; - - break; - default: - dest = dest_defined--; - BFD_ASSERT (0); - break; - } - dest->name = string_ptr; - dest->the_bfd = abfd; - dest->udata.p = (PTR) NULL; - dest->value = bfd_h_get_32 (abfd, record.symbol.value); - -#ifdef UNDERSCORE_HACK - if (record.symbol.name[0] != '_') - { - string_ptr[0] = '_'; - string_ptr++; - } -#endif - memcpy (string_ptr, record.symbol.name, length); - - - string_ptr[length] = 0; - string_ptr += length + 1; - } - break; - default: - loop = false; - } - } - return true; -} - -static long -oasys_get_symtab_upper_bound (abfd) - bfd *CONST abfd; -{ - if (! oasys_slurp_symbol_table (abfd)) - return -1; - - return (abfd->symcount + 1) * (sizeof (oasys_symbol_type *)); -} - -/* -*/ - -extern const bfd_target oasys_vec; - -long -oasys_get_symtab (abfd, location) - bfd *abfd; - asymbol **location; -{ - asymbol *symbase; - unsigned int counter; - if (oasys_slurp_symbol_table (abfd) == false) - { - return -1; - } - symbase = OASYS_DATA (abfd)->symbols; - for (counter = 0; counter < abfd->symcount; counter++) - { - *(location++) = symbase++; - } - *location = 0; - return abfd->symcount; -} - -/*********************************************************************** -* archive stuff -*/ - -static const bfd_target * -oasys_archive_p (abfd) - bfd *abfd; -{ - oasys_archive_header_type header; - oasys_extarchive_header_type header_ext; - unsigned int i; - file_ptr filepos; - - if (bfd_seek (abfd, (file_ptr) 0, false) != 0 - || (bfd_read ((PTR) & header_ext, 1, sizeof (header_ext), abfd) - != sizeof (header_ext))) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - header.version = bfd_h_get_32 (abfd, header_ext.version); - header.mod_count = bfd_h_get_32 (abfd, header_ext.mod_count); - header.mod_tbl_offset = bfd_h_get_32 (abfd, header_ext.mod_tbl_offset); - header.sym_tbl_size = bfd_h_get_32 (abfd, header_ext.sym_tbl_size); - header.sym_count = bfd_h_get_32 (abfd, header_ext.sym_count); - header.sym_tbl_offset = bfd_h_get_32 (abfd, header_ext.sym_tbl_offset); - header.xref_count = bfd_h_get_32 (abfd, header_ext.xref_count); - header.xref_lst_offset = bfd_h_get_32 (abfd, header_ext.xref_lst_offset); - - /* - There isn't a magic number in an Oasys archive, so the best we - can do to verify reasnableness is to make sure that the values in - the header are too weird - */ - - if (header.version > 10000 || - header.mod_count > 10000 || - header.sym_count > 100000 || - header.xref_count > 100000) - return (const bfd_target *) NULL; - - /* - That all worked, let's buy the space for the header and read in - the headers. - */ - { - oasys_ar_data_type *ar = - (oasys_ar_data_type *) bfd_alloc (abfd, sizeof (oasys_ar_data_type)); - - oasys_module_info_type *module = - (oasys_module_info_type *) - bfd_alloc (abfd, sizeof (oasys_module_info_type) * header.mod_count); - oasys_module_table_type record; - - if (!ar || !module) - return NULL; - - abfd->tdata.oasys_ar_data = ar; - ar->module = module; - ar->module_count = header.mod_count; - - filepos = header.mod_tbl_offset; - for (i = 0; i < header.mod_count; i++) - { - if (bfd_seek (abfd, filepos, SEEK_SET) != 0) - return NULL; - - /* There are two ways of specifying the archive header */ - - if (0) - { - oasys_extmodule_table_type_a_type record_ext; - if (bfd_read ((PTR) & record_ext, 1, sizeof (record_ext), abfd) - != sizeof (record_ext)) - return NULL; - - record.mod_size = bfd_h_get_32 (abfd, record_ext.mod_size); - record.file_offset = bfd_h_get_32 (abfd, record_ext.file_offset); - - record.dep_count = bfd_h_get_32 (abfd, record_ext.dep_count); - record.depee_count = bfd_h_get_32 (abfd, record_ext.depee_count); - record.sect_count = bfd_h_get_32 (abfd, record_ext.sect_count); - - module[i].name = bfd_alloc (abfd, 33); - if (!module[i].name) - return NULL; - - memcpy (module[i].name, record_ext.mod_name, 33); - filepos += - sizeof (record_ext) + - record.dep_count * 4 + - record.depee_count * 4 + - record.sect_count * 8 + 187; - } - else - { - oasys_extmodule_table_type_b_type record_ext; - if (bfd_read ((PTR) & record_ext, 1, sizeof (record_ext), abfd) - != sizeof (record_ext)) - return NULL; - - record.mod_size = bfd_h_get_32 (abfd, record_ext.mod_size); - record.file_offset = bfd_h_get_32 (abfd, record_ext.file_offset); - - record.dep_count = bfd_h_get_32 (abfd, record_ext.dep_count); - record.depee_count = bfd_h_get_32 (abfd, record_ext.depee_count); - record.sect_count = bfd_h_get_32 (abfd, record_ext.sect_count); - record.module_name_size = bfd_h_get_32 (abfd, record_ext.mod_name_length); - - module[i].name = bfd_alloc (abfd, record.module_name_size + 1); - if (!module[i].name) - return NULL; - if (bfd_read ((PTR) module[i].name, 1, record.module_name_size, - abfd) - != record.module_name_size) - return NULL; - module[i].name[record.module_name_size] = 0; - filepos += - sizeof (record_ext) + - record.dep_count * 4 + - record.module_name_size + 1; - - } - - - module[i].size = record.mod_size; - module[i].pos = record.file_offset; - module[i].abfd = 0; - } - - } - return abfd->xvec; -} - -static boolean -oasys_mkobject (abfd) - bfd *abfd; -{ - - abfd->tdata.oasys_obj_data = (oasys_data_type *) bfd_alloc (abfd, sizeof (oasys_data_type)); - return abfd->tdata.oasys_obj_data ? true : false; -} - -#define MAX_SECS 16 -static const bfd_target * -oasys_object_p (abfd) - bfd *abfd; -{ - oasys_data_type *oasys; - oasys_data_type *save = OASYS_DATA (abfd); - boolean loop = true; - boolean had_usefull = false; - - abfd->tdata.oasys_obj_data = 0; - oasys_mkobject (abfd); - oasys = OASYS_DATA (abfd); - memset ((PTR) oasys->sections, 0xff, sizeof (oasys->sections)); - - /* Point to the start of the file */ - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - goto fail; - oasys->symbol_string_length = 0; - /* Inspect the records, but only keep the section info - - remember the size of the symbols - */ - oasys->first_data_record = 0; - while (loop) - { - oasys_record_union_type record; - if (! oasys_read_record (abfd, &record)) - goto fail; - if ((size_t) record.header.length < (size_t) sizeof (record.header)) - goto fail; - - - switch ((oasys_record_enum_type) (record.header.type)) - { - case oasys_record_is_header_enum: - had_usefull = true; - break; - case oasys_record_is_symbol_enum: - case oasys_record_is_local_enum: - /* Count symbols and remember their size for a future malloc */ - abfd->symcount++; - oasys->symbol_string_length += 1 + oasys_string_length (&record); - had_usefull = true; - break; - case oasys_record_is_section_enum: - { - asection *s; - char *buffer; - unsigned int section_number; - if (record.section.header.length != sizeof (record.section)) - { - goto fail; - } - buffer = bfd_alloc (abfd, 3); - if (!buffer) - goto fail; - section_number = record.section.relb & RELOCATION_SECT_BITS; - sprintf (buffer, "%u", section_number); - s = bfd_make_section (abfd, buffer); - oasys->sections[section_number] = s; - switch (record.section.relb & RELOCATION_TYPE_BITS) - { - case RELOCATION_TYPE_ABS: - case RELOCATION_TYPE_REL: - break; - case RELOCATION_TYPE_UND: - case RELOCATION_TYPE_COM: - BFD_FAIL (); - } - - s->_raw_size = bfd_h_get_32 (abfd, record.section.value); - s->vma = bfd_h_get_32 (abfd, record.section.vma); - s->flags = 0; - had_usefull = true; - } - break; - case oasys_record_is_data_enum: - oasys->first_data_record = bfd_tell (abfd) - record.header.length; - case oasys_record_is_debug_enum: - case oasys_record_is_module_enum: - case oasys_record_is_named_section_enum: - case oasys_record_is_end_enum: - if (had_usefull == false) - goto fail; - loop = false; - break; - default: - goto fail; - } - } - oasys->symbols = (asymbol *) NULL; - /* - Oasys support several architectures, but I can't see a simple way - to discover which one is in a particular file - we'll guess - */ - bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0); - if (abfd->symcount != 0) - { - abfd->flags |= HAS_SYMS; - } - - /* - We don't know if a section has data until we've read it.. - */ - - oasys_slurp_section_data (abfd); - - - return abfd->xvec; - -fail: - (void) bfd_release (abfd, oasys); - abfd->tdata.oasys_obj_data = save; - return (const bfd_target *) NULL; -} - - -static void -oasys_get_symbol_info (ignore_abfd, symbol, ret) - bfd *ignore_abfd; - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); - if (!symbol->section) - ret->type = (symbol->flags & BSF_LOCAL) ? 'a' : 'A'; -} - -static void -oasys_print_symbol (ignore_abfd, afile, symbol, how) - bfd *ignore_abfd; - PTR afile; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *) afile; - - switch (how) - { - case bfd_print_symbol_name: - case bfd_print_symbol_more: - fprintf (file, "%s", symbol->name); - break; - case bfd_print_symbol_all: - { - CONST char *section_name = symbol->section == (asection *) NULL ? - (CONST char *) "*abs" : symbol->section->name; - - bfd_print_symbol_vandf ((PTR) file, symbol); - - fprintf (file, " %-5s %s", - section_name, - symbol->name); - } - break; - } -} -/* - The howto table is build using the top two bits of a reloc byte to - index into it. The bits are PCREL,WORD/LONG -*/ -static reloc_howto_type howto_table[] = -{ - - HOWTO (0, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "abs16", true, 0x0000ffff, 0x0000ffff, false), - HOWTO (0, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "abs32", true, 0xffffffff, 0xffffffff, false), - HOWTO (0, 0, 1, 16, true, 0, complain_overflow_signed, 0, "pcrel16", true, 0x0000ffff, 0x0000ffff, false), - HOWTO (0, 0, 2, 32, true, 0, complain_overflow_signed, 0, "pcrel32", true, 0xffffffff, 0xffffffff, false) -}; - -/* Read in all the section data and relocation stuff too */ -static boolean -oasys_slurp_section_data (abfd) - bfd *CONST abfd; -{ - oasys_record_union_type record; - oasys_data_type *data = OASYS_DATA (abfd); - boolean loop = true; - - oasys_per_section_type *per; - - asection *s; - - /* See if the data has been slurped already .. */ - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - per = oasys_per_section (s); - if (per->initialized == true) - return true; - } - - if (data->first_data_record == 0) - return true; - - if (bfd_seek (abfd, data->first_data_record, SEEK_SET) != 0) - return false; - while (loop) - { - if (! oasys_read_record (abfd, &record)) - return false; - switch (record.header.type) - { - case oasys_record_is_header_enum: - break; - case oasys_record_is_data_enum: - { - - bfd_byte *src = record.data.data; - bfd_byte *end_src = ((bfd_byte *) & record) + record.header.length; - bfd_byte *dst_ptr; - bfd_byte *dst_base_ptr; - unsigned int relbit; - unsigned int count; - asection *section = - data->sections[record.data.relb & RELOCATION_SECT_BITS]; - bfd_vma dst_offset; - - per = oasys_per_section (section); - - if (per->initialized == false) - { - per->data = (bfd_byte *) bfd_zalloc (abfd, section->_raw_size); - if (!per->data) - return false; - per->reloc_tail_ptr = (oasys_reloc_type **) & (section->relocation); - per->had_vma = false; - per->initialized = true; - section->reloc_count = 0; - section->flags = SEC_ALLOC; - } - - dst_offset = bfd_h_get_32 (abfd, record.data.addr); - if (per->had_vma == false) - { - /* Take the first vma we see as the base */ - section->vma = dst_offset; - per->had_vma = true; - } - - dst_offset -= section->vma; - - dst_base_ptr = oasys_per_section (section)->data; - dst_ptr = oasys_per_section (section)->data + - dst_offset; - - if (src < end_src) - { - section->flags |= SEC_LOAD | SEC_HAS_CONTENTS; - } - while (src < end_src) - { - unsigned char mod_byte = *src++; - size_t gap = end_src - src; - - count = 8; - if (mod_byte == 0 && gap >= 8) - { - dst_ptr[0] = src[0]; - dst_ptr[1] = src[1]; - dst_ptr[2] = src[2]; - dst_ptr[3] = src[3]; - dst_ptr[4] = src[4]; - dst_ptr[5] = src[5]; - dst_ptr[6] = src[6]; - dst_ptr[7] = src[7]; - dst_ptr += 8; - src += 8; - } - else - { - for (relbit = 1; count-- != 0 && src < end_src; relbit <<= 1) - { - if (relbit & mod_byte) - { - unsigned char reloc = *src; - /* This item needs to be relocated */ - switch (reloc & RELOCATION_TYPE_BITS) - { - case RELOCATION_TYPE_ABS: - - break; - - case RELOCATION_TYPE_REL: - { - /* Relocate the item relative to the section */ - oasys_reloc_type *r = - (oasys_reloc_type *) - bfd_alloc (abfd, - sizeof (oasys_reloc_type)); - if (!r) - return false; - *(per->reloc_tail_ptr) = r; - per->reloc_tail_ptr = &r->next; - r->next = (oasys_reloc_type *) NULL; - /* Reference to undefined symbol */ - src++; - /* There is no symbol */ - r->symbol = 0; - /* Work out the howto */ - abort (); -#if 0 - r->relent.section = - data->sections[reloc & - RELOCATION_SECT_BITS]; - - r->relent.addend = - - r->relent.section->vma; -#endif - r->relent.address = dst_ptr - dst_base_ptr; - r->relent.howto = &howto_table[reloc >> 6]; - r->relent.sym_ptr_ptr = (asymbol **) NULL; - section->reloc_count++; - - /* Fake up the data to look like it's got the -ve pc in it, this makes - it much easier to convert into other formats. This is done by - hitting the addend. - */ - if (r->relent.howto->pc_relative == true) - { - r->relent.addend -= dst_ptr - dst_base_ptr; - } - - - } - break; - - - case RELOCATION_TYPE_UND: - { - oasys_reloc_type *r = - (oasys_reloc_type *) - bfd_alloc (abfd, - sizeof (oasys_reloc_type)); - if (!r) - return false; - *(per->reloc_tail_ptr) = r; - per->reloc_tail_ptr = &r->next; - r->next = (oasys_reloc_type *) NULL; - /* Reference to undefined symbol */ - src++; - /* Get symbol number */ - r->symbol = (src[0] << 8) | src[1]; - /* Work out the howto */ - abort (); - -#if 0 - r->relent.section = (asection - *) NULL; -#endif - r->relent.addend = 0; - r->relent.address = dst_ptr - dst_base_ptr; - r->relent.howto = &howto_table[reloc >> 6]; - r->relent.sym_ptr_ptr = (asymbol **) NULL; - section->reloc_count++; - - src += 2; - /* Fake up the data to look like it's got the -ve pc in it, this makes - it much easier to convert into other formats. This is done by - hitting the addend. - */ - if (r->relent.howto->pc_relative == true) - { - r->relent.addend -= dst_ptr - dst_base_ptr; - } - - - - } - break; - case RELOCATION_TYPE_COM: - BFD_FAIL (); - } - } - *dst_ptr++ = *src++; - } - } - } - } - break; - case oasys_record_is_local_enum: - case oasys_record_is_symbol_enum: - case oasys_record_is_section_enum: - break; - default: - loop = false; - } - } - - return true; - -} - -static boolean -oasys_new_section_hook (abfd, newsect) - bfd *abfd; - asection *newsect; -{ - newsect->used_by_bfd = (PTR) - bfd_alloc (abfd, sizeof (oasys_per_section_type)); - if (!newsect->used_by_bfd) - return false; - oasys_per_section (newsect)->data = (bfd_byte *) NULL; - oasys_per_section (newsect)->section = newsect; - oasys_per_section (newsect)->offset = 0; - oasys_per_section (newsect)->initialized = false; - newsect->alignment_power = 1; - /* Turn the section string into an index */ - - sscanf (newsect->name, "%u", &newsect->target_index); - - return true; -} - - -static long -oasys_get_reloc_upper_bound (abfd, asect) - bfd *abfd; - sec_ptr asect; -{ - if (! oasys_slurp_section_data (abfd)) - return -1; - return (asect->reloc_count + 1) * sizeof (arelent *); -} - -static boolean -oasys_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd; - oasys_slurp_section_data (abfd); - if (p->initialized == false) - { - (void) memset (location, 0, (int) count); - } - else - { - (void) memcpy (location, (PTR) (p->data + offset), (int) count); - } - return true; -} - - -long -oasys_canonicalize_reloc (ignore_abfd, section, relptr, symbols) - bfd *ignore_abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - unsigned int reloc_count = 0; - oasys_reloc_type *src = (oasys_reloc_type *) (section->relocation); - while (src != (oasys_reloc_type *) NULL) - { - abort (); - -#if 0 - if (src->relent.section == (asection *) NULL) - { - src->relent.sym_ptr_ptr = symbols + src->symbol; - } -#endif - - *relptr++ = &src->relent; - src = src->next; - reloc_count++; - } - *relptr = (arelent *) NULL; - return section->reloc_count = reloc_count; -} - - - - -/* Writing */ - - -/* Calculate the checksum and write one record */ -static boolean -oasys_write_record (abfd, type, record, size) - bfd *abfd; - oasys_record_enum_type type; - oasys_record_union_type *record; - size_t size; -{ - int checksum; - size_t i; - unsigned char *ptr; - - record->header.length = size; - record->header.type = (int) type; - record->header.check_sum = 0; - record->header.fill = 0; - ptr = (unsigned char *) &record->pad[0]; - checksum = 0; - for (i = 0; i < size; i++) - { - checksum += *ptr++; - } - record->header.check_sum = 0xff & (-checksum); - if (bfd_write ((PTR) record, 1, size, abfd) != size) - return false; - return true; -} - - -/* Write out all the symbols */ -static boolean -oasys_write_syms (abfd) - bfd *abfd; -{ - unsigned int count; - asymbol **generic = bfd_get_outsymbols (abfd); - unsigned int index = 0; - for (count = 0; count < bfd_get_symcount (abfd); count++) - { - - oasys_symbol_record_type symbol; - asymbol *CONST g = generic[count]; - - CONST char *src = g->name; - char *dst = symbol.name; - unsigned int l = 0; - - if (bfd_is_com_section (g->section)) - { - symbol.relb = RELOCATION_TYPE_COM; - bfd_h_put_16 (abfd, index, symbol.refno); - index++; - } - else if (bfd_is_abs_section (g->section)) - { - symbol.relb = RELOCATION_TYPE_ABS; - bfd_h_put_16 (abfd, 0, symbol.refno); - - } - else if (bfd_is_und_section (g->section)) - { - symbol.relb = RELOCATION_TYPE_UND; - bfd_h_put_16 (abfd, index, symbol.refno); - /* Overload the value field with the output index number */ - index++; - } - else if (g->flags & BSF_DEBUGGING) - { - /* throw it away */ - continue; - } - else - { - if (g->section == (asection *) NULL) - { - /* Sometime, the oasys tools give out a symbol with illegal - bits in it, we'll output it in the same broken way */ - - symbol.relb = RELOCATION_TYPE_REL | 0; - } - else - { - symbol.relb = RELOCATION_TYPE_REL | g->section->output_section->target_index; - } - bfd_h_put_16 (abfd, 0, symbol.refno); - } -#ifdef UNDERSCORE_HACK - if (src[l] == '_') - dst[l++] = '.'; -#endif - while (src[l]) - { - dst[l] = src[l]; - l++; - } - - bfd_h_put_32 (abfd, g->value, symbol.value); - - - if (g->flags & BSF_LOCAL) - { - if (! oasys_write_record (abfd, - oasys_record_is_local_enum, - (oasys_record_union_type *) & symbol, - offsetof (oasys_symbol_record_type, - name[0]) + l)) - return false; - } - else - { - if (! oasys_write_record (abfd, - oasys_record_is_symbol_enum, - (oasys_record_union_type *) & symbol, - offsetof (oasys_symbol_record_type, - name[0]) + l)) - return false; - } - g->value = index - 1; - } - - return true; -} - - - /* Write a section header for each section */ -static boolean -oasys_write_sections (abfd) - bfd *abfd; -{ - asection *s; - static oasys_section_record_type out; - - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - if (!isdigit (s->name[0])) - { - (*_bfd_error_handler) - ("%s: can not represent section `%s' in oasys", - bfd_get_filename (abfd), s->name); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; - } - out.relb = RELOCATION_TYPE_REL | s->target_index; - bfd_h_put_32 (abfd, s->_cooked_size, out.value); - bfd_h_put_32 (abfd, s->vma, out.vma); - - if (! oasys_write_record (abfd, - oasys_record_is_section_enum, - (oasys_record_union_type *) & out, - sizeof (out))) - return false; - } - return true; -} - -static boolean -oasys_write_header (abfd) - bfd *abfd; -{ - /* Create and write the header */ - oasys_header_record_type r; - size_t length = strlen (abfd->filename); - if (length > (size_t) sizeof (r.module_name)) - { - length = sizeof (r.module_name); - } - - (void) memcpy (r.module_name, - abfd->filename, - length); - (void) memset (r.module_name + length, - ' ', - sizeof (r.module_name) - length); - - r.version_number = OASYS_VERSION_NUMBER; - r.rev_number = OASYS_REV_NUMBER; - if (! oasys_write_record (abfd, - oasys_record_is_header_enum, - (oasys_record_union_type *) & r, - offsetof (oasys_header_record_type, - description[0]))) - return false; - - return true; -} - -static boolean -oasys_write_end (abfd) - bfd *abfd; -{ - oasys_end_record_type end; - unsigned char null = 0; - end.relb = RELOCATION_TYPE_ABS; - bfd_h_put_32 (abfd, abfd->start_address, end.entry); - bfd_h_put_16 (abfd, 0, end.fill); - end.zero = 0; - if (! oasys_write_record (abfd, - oasys_record_is_end_enum, - (oasys_record_union_type *) & end, - sizeof (end))) - return false; - if (bfd_write ((PTR) & null, 1, 1, abfd) != 1) - return false; - return true; -} - -static int -comp (ap, bp) - CONST PTR ap; - CONST PTR bp; -{ - arelent *a = *((arelent **) ap); - arelent *b = *((arelent **) bp); - return a->address - b->address; -} - -/* - Writing data.. - -*/ -static boolean -oasys_write_data (abfd) - bfd *abfd; -{ - asection *s; - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - if (s->flags & SEC_LOAD) - { - bfd_byte *raw_data = oasys_per_section (s)->data; - oasys_data_record_type processed_data; - bfd_size_type current_byte_index = 0; - unsigned int relocs_to_go = s->reloc_count; - arelent **p = s->orelocation; - if (s->reloc_count != 0) - { -/* Sort the reloc records so it's easy to insert the relocs into the - data */ - - qsort (s->orelocation, - s->reloc_count, - sizeof (arelent **), - comp); - } - current_byte_index = 0; - processed_data.relb = s->target_index | RELOCATION_TYPE_REL; - - while (current_byte_index < s->_cooked_size) - { - /* Scan forwards by eight bytes or however much is left and see if - there are any relocations going on */ - bfd_byte *mod = &processed_data.data[0]; - bfd_byte *dst = &processed_data.data[1]; - - unsigned int i = 0; - *mod = 0; - - - bfd_h_put_32 (abfd, s->vma + current_byte_index, - processed_data.addr); - - /* Don't start a relocation unless you're sure you can finish it - within the same data record. The worst case relocation is a - 4-byte relocatable value which is split across two modification - bytes (1 relocation byte + 2 symbol reference bytes + 2 data + - 1 modification byte + 2 data = 8 bytes total). That's where - the magic number 8 comes from. - */ - while (current_byte_index < s->_raw_size && dst <= - &processed_data.data[sizeof (processed_data.data) - 8]) - { - - - if (relocs_to_go != 0) - { - arelent *r = *p; - reloc_howto_type *const how = r->howto; - /* There is a relocation, is it for this byte ? */ - if (r->address == current_byte_index) - { - unsigned char rel_byte; - - p++; - relocs_to_go--; - - *mod |= (1 << i); - if (how->pc_relative) - { - rel_byte = RELOCATION_PCREL_BIT; - - /* Also patch the raw data so that it doesn't have - the -ve stuff any more */ - if (how->size != 2) - { - bfd_put_16 (abfd, - bfd_get_16 (abfd, raw_data) + - current_byte_index, raw_data); - } - - else - { - bfd_put_32 (abfd, - bfd_get_32 (abfd, raw_data) + - current_byte_index, raw_data); - } - } - else - { - rel_byte = 0; - } - if (how->size == 2) - { - rel_byte |= RELOCATION_32BIT_BIT; - } - - /* Is this a section relative relocation, or a symbol - relative relocation ? */ - abort (); - -#if 0 - if (r->section != (asection *) NULL) - { - /* The relent has a section attached, so it must be section - relative */ - rel_byte |= RELOCATION_TYPE_REL; - rel_byte |= r->section->output_section->target_index; - *dst++ = rel_byte; - } - else -#endif - { - asymbol *p = *(r->sym_ptr_ptr); - - /* If this symbol has a section attached, then it - has already been resolved. Change from a symbol - ref to a section ref */ - if (p->section != (asection *) NULL) - { - rel_byte |= RELOCATION_TYPE_REL; - rel_byte |= - p->section->output_section->target_index; - *dst++ = rel_byte; - } - else - { - rel_byte |= RELOCATION_TYPE_UND; - *dst++ = rel_byte; - /* Next two bytes are a symbol index - we can get - this from the symbol value which has been zapped - into the symbol index in the table when the - symbol table was written - */ - *dst++ = p->value >> 8; - *dst++ = p->value; - } - } -#define ADVANCE { if (++i >= 8) { i = 0; mod = dst++; *mod = 0; } current_byte_index++; } - /* relocations never occur from an unloadable section, - so we can assume that raw_data is not NULL - */ - *dst++ = *raw_data++; - ADVANCE - * dst++ = *raw_data++; - ADVANCE - if (how->size == 2) - { - *dst++ = *raw_data++; - ADVANCE - * dst++ = *raw_data++; - ADVANCE - } - continue; - } - } - /* If this is coming from an unloadable section then copy - zeros */ - if (raw_data == NULL) - { - *dst++ = 0; - } - else - { - *dst++ = *raw_data++; - } - ADVANCE - } - - /* Don't write a useless null modification byte */ - if (dst == mod + 1) - { - --dst; - } - - if (! oasys_write_record (abfd, - oasys_record_is_data_enum, - ((oasys_record_union_type *) - & processed_data), - dst - (bfd_byte *) & processed_data)) - return false; - } - } - } - - return true; -} - -static boolean -oasys_write_object_contents (abfd) - bfd *abfd; -{ - if (! oasys_write_header (abfd)) - return false; - if (! oasys_write_syms (abfd)) - return false; - if (! oasys_write_sections (abfd)) - return false; - if (! oasys_write_data (abfd)) - return false; - if (! oasys_write_end (abfd)) - return false; - return true; -} - - - - -/** exec and core file sections */ - -/* set section contents is complicated with OASYS since the format is -* not a byte image, but a record stream. -*/ -static boolean -oasys_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if (count != 0) - { - if (oasys_per_section (section)->data == (bfd_byte *) NULL) - { - oasys_per_section (section)->data = - (bfd_byte *) (bfd_alloc (abfd, section->_cooked_size)); - if (!oasys_per_section (section)->data) - return false; - } - (void) memcpy ((PTR) (oasys_per_section (section)->data + offset), - location, - (size_t) count); - } - return true; -} - - - -/* Native-level interface to symbols. */ - -/* We read the symbols into a buffer, which is discarded when this -function exits. We read the strings into a buffer large enough to -hold them all plus all the cached symbol entries. */ - -static asymbol * -oasys_make_empty_symbol (abfd) - bfd *abfd; -{ - - oasys_symbol_type *new = - (oasys_symbol_type *) bfd_zalloc (abfd, sizeof (oasys_symbol_type)); - if (!new) - return NULL; - new->symbol.the_bfd = abfd; - return &new->symbol; -} - - - - -/* User should have checked the file flags; perhaps we should return -BFD_NO_MORE_SYMBOLS if there are none? */ - -static bfd * -oasys_openr_next_archived_file (arch, prev) - bfd *arch; - bfd *prev; -{ - oasys_ar_data_type *ar = OASYS_AR_DATA (arch); - oasys_module_info_type *p; - /* take the next one from the arch state, or reset */ - if (prev == (bfd *) NULL) - { - /* Reset the index - the first two entries are bogus*/ - ar->module_index = 0; - } - - p = ar->module + ar->module_index; - ar->module_index++; - - if (ar->module_index <= ar->module_count) - { - if (p->abfd == (bfd *) NULL) - { - p->abfd = _bfd_create_empty_archive_element_shell (arch); - p->abfd->origin = p->pos; - p->abfd->filename = p->name; - - /* Fixup a pointer to this element for the member */ - p->abfd->arelt_data = (PTR) p; - } - return p->abfd; - } - else - { - bfd_set_error (bfd_error_no_more_archived_files); - return (bfd *) NULL; - } -} - -static boolean -oasys_find_nearest_line (abfd, - section, - symbols, - offset, - filename_ptr, - functionname_ptr, - line_ptr) - bfd *abfd; - asection *section; - asymbol **symbols; - bfd_vma offset; - char **filename_ptr; - char **functionname_ptr; - unsigned int *line_ptr; -{ - return false; - -} - -static int -oasys_generic_stat_arch_elt (abfd, buf) - bfd *abfd; - struct stat *buf; -{ - oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data; - if (mod == (oasys_module_info_type *) NULL) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - else - { - buf->st_size = mod->size; - buf->st_mode = 0666; - return 0; - } -} - -static int -oasys_sizeof_headers (abfd, exec) - bfd *abfd; - boolean exec; -{ - return 0; -} - -#define oasys_close_and_cleanup _bfd_generic_close_and_cleanup -#define oasys_bfd_free_cached_info _bfd_generic_bfd_free_cached_info - -#define oasys_slurp_armap bfd_true -#define oasys_slurp_extended_name_table bfd_true -#define oasys_construct_extended_name_table \ - ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \ - bfd_true) -#define oasys_truncate_arname bfd_dont_truncate_arname -#define oasys_write_armap \ - ((boolean (*) \ - PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \ - bfd_true) -#define oasys_read_ar_hdr bfd_nullvoidptr -#define oasys_get_elt_at_index _bfd_generic_get_elt_at_index -#define oasys_update_armap_timestamp bfd_true - -#define oasys_bfd_is_local_label bfd_generic_is_local_label -#define oasys_get_lineno _bfd_nosymbols_get_lineno -#define oasys_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define oasys_read_minisymbols _bfd_generic_read_minisymbols -#define oasys_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol - -#define oasys_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup - -#define oasys_set_arch_mach bfd_default_set_arch_mach - -#define oasys_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -#define oasys_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define oasys_bfd_relax_section bfd_generic_relax_section -#define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define oasys_bfd_final_link _bfd_generic_final_link -#define oasys_bfd_link_split_section _bfd_generic_link_split_section - -/*SUPPRESS 460 */ -const bfd_target oasys_vec = -{ - "oasys", /* name */ - bfd_target_oasys_flavour, - BFD_ENDIAN_BIG, /* target byte order */ - BFD_ENDIAN_BIG, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - {_bfd_dummy_target, - oasys_object_p, /* bfd_check_format */ - oasys_archive_p, - _bfd_dummy_target, - }, - { /* bfd_set_format */ - bfd_false, - oasys_mkobject, - _bfd_generic_mkarchive, - bfd_false - }, - { /* bfd_write_contents */ - bfd_false, - oasys_write_object_contents, - _bfd_write_archive_contents, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (oasys), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (oasys), - BFD_JUMP_TABLE_SYMBOLS (oasys), - BFD_JUMP_TABLE_RELOCS (oasys), - BFD_JUMP_TABLE_WRITE (oasys), - BFD_JUMP_TABLE_LINK (oasys), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; diff --git a/contrib/gdb/bfd/osf-core.c b/contrib/gdb/bfd/osf-core.c deleted file mode 100644 index 6d1df9b..0000000 --- a/contrib/gdb/bfd/osf-core.c +++ /dev/null @@ -1,256 +0,0 @@ -/* BFD back-end for OSF/1 core files. - Copyright 1993, 1994 Free Software Foundation, Inc. - -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 can only be compiled on systems which use OSF/1 style - core files. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#include <stdio.h> -#include <string.h> -#include <sys/user.h> -#include <sys/core.h> - -/* forward declarations */ - -static asection * -make_bfd_asection PARAMS ((bfd *, CONST char *, flagword, bfd_size_type, - bfd_vma, file_ptr)); -static asymbol * -osf_core_make_empty_symbol PARAMS ((bfd *)); -static const bfd_target * -osf_core_core_file_p PARAMS ((bfd *)); -static char * -osf_core_core_file_failing_command PARAMS ((bfd *)); -static int -osf_core_core_file_failing_signal PARAMS ((bfd *)); -static boolean -osf_core_core_file_matches_executable_p PARAMS ((bfd *, bfd *)); -static void -swap_abort PARAMS ((void)); - -/* These are stored in the bfd's tdata */ - -struct osf_core_struct -{ - int sig; - char cmd[MAXCOMLEN + 1]; -}; - -#define core_hdr(bfd) ((bfd)->tdata.osf_core_data) -#define core_signal(bfd) (core_hdr(bfd)->sig) -#define core_command(bfd) (core_hdr(bfd)->cmd) - -static asection * -make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos) - bfd *abfd; - CONST char *name; - flagword flags; - bfd_size_type _raw_size; - bfd_vma vma; - file_ptr filepos; -{ - asection *asect; - - asect = bfd_make_section_anyway (abfd, name); - if (!asect) - return NULL; - - asect->flags = flags; - asect->_raw_size = _raw_size; - asect->vma = vma; - asect->filepos = filepos; - asect->alignment_power = 8; - - return asect; -} - -static asymbol * -osf_core_make_empty_symbol (abfd) - bfd *abfd; -{ - asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol)); - if (new) - new->the_bfd = abfd; - return new; -} - -static const bfd_target * -osf_core_core_file_p (abfd) - bfd *abfd; -{ - int val; - int i; - char *secname; - struct core_filehdr core_header; - - val = bfd_read ((PTR)&core_header, 1, sizeof core_header, abfd); - if (val != sizeof core_header) - return NULL; - - if (strncmp (core_header.magic, "Core", 4) != 0) - return NULL; - - core_hdr (abfd) = (struct osf_core_struct *) - bfd_zalloc (abfd, sizeof (struct osf_core_struct)); - if (!core_hdr (abfd)) - return NULL; - - strncpy (core_command (abfd), core_header.name, MAXCOMLEN + 1); - core_signal (abfd) = core_header.signo; - - for (i = 0; i < core_header.nscns; i++) - { - struct core_scnhdr core_scnhdr; - flagword flags; - - val = bfd_read ((PTR)&core_scnhdr, 1, sizeof core_scnhdr, abfd); - if (val != sizeof core_scnhdr) - break; - - /* Skip empty sections. */ - if (core_scnhdr.size == 0 || core_scnhdr.scnptr == 0) - continue; - - switch (core_scnhdr.scntype) - { - case SCNRGN: - secname = ".data"; - flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - break; - case SCNSTACK: - secname = ".stack"; - flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - break; - case SCNREGS: - secname = ".reg"; - flags = SEC_HAS_CONTENTS; - break; - default: - (*_bfd_error_handler) ("Unhandled OSF/1 core file section type %d\n", - core_scnhdr.scntype); - continue; - } - - if (!make_bfd_asection (abfd, secname, flags, - (bfd_size_type) core_scnhdr.size, - (bfd_vma) core_scnhdr.vaddr, - (file_ptr) core_scnhdr.scnptr)) - return NULL; - } - - /* OK, we believe you. You're a core file (sure, sure). */ - - return abfd->xvec; -} - -static char * -osf_core_core_file_failing_command (abfd) - bfd *abfd; -{ - return core_command (abfd); -} - -/* ARGSUSED */ -static int -osf_core_core_file_failing_signal (abfd) - bfd *abfd; -{ - return core_signal (abfd); -} - -/* ARGSUSED */ -static boolean -osf_core_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - return true; /* FIXME, We have no way of telling at this point */ -} - -#define osf_core_get_symtab_upper_bound _bfd_nosymbols_get_symtab_upper_bound -#define osf_core_get_symtab _bfd_nosymbols_get_symtab -#define osf_core_print_symbol _bfd_nosymbols_print_symbol -#define osf_core_get_symbol_info _bfd_nosymbols_get_symbol_info -#define osf_core_bfd_is_local_label _bfd_nosymbols_bfd_is_local_label -#define osf_core_get_lineno _bfd_nosymbols_get_lineno -#define osf_core_find_nearest_line _bfd_nosymbols_find_nearest_line -#define osf_core_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define osf_core_read_minisymbols _bfd_nosymbols_read_minisymbols -#define osf_core_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol - -/* If somebody calls any byte-swapping routines, shoot them. */ -static void -swap_abort() -{ - abort(); /* This way doesn't require any declaration for ANSI to fuck up */ -} -#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort ) -#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort ) -#define NO_SIGNED_GET \ - ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort ) - -const bfd_target osf_core_vec = - { - "osf-core", - bfd_target_unknown_flavour, - BFD_ENDIAN_BIG, /* target byte order */ - BFD_ENDIAN_BIG, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* symbol prefix */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */ - - { /* bfd_check_format */ - _bfd_dummy_target, /* unknown format */ - _bfd_dummy_target, /* object file */ - _bfd_dummy_target, /* archive */ - osf_core_core_file_p /* a core file */ - }, - { /* bfd_set_format */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - { /* bfd_write_contents */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (osf_core), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (osf_core), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (_bfd_generic), - BFD_JUMP_TABLE_LINK (_bfd_nolink), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 /* backend_data */ -}; diff --git a/contrib/gdb/bfd/pc532-mach.c b/contrib/gdb/bfd/pc532-mach.c deleted file mode 100644 index 73f4ac4..0000000 --- a/contrib/gdb/bfd/pc532-mach.c +++ /dev/null @@ -1,121 +0,0 @@ -/* BFD back-end for Mach3/532 a.out-ish binaries. - Copyright (C) 1990, 1991, 1992, 1994 Free Software Foundation, Inc. - -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. */ - -/* Written by Ian Dall - * 19-Apr-94 - * - * Formerly part of aout-pc532-mach.c. Split out to allow more - * flexibility with multiple formats. - * - */ -/* This architecture has N_TXTOFF and N_TXTADDR defined as if - * N_HEADER_IN_TEXT, but the a_text entry (text size) does not include the - * space for the header. So we have N_HEADER_IN_TEXT defined to - * 1 and specially define our own N_TXTSIZE - */ - -#define N_HEADER_IN_TEXT(x) 1 -#define N_TXTSIZE(x) ((x).a_text) - - -#define TEXT_START_ADDR 0x10000 /* from old ld */ -#define TARGET_PAGE_SIZE 0x1000 /* from old ld, 032 & 532 are really 512/4k */ - -/* Use a_entry of 0 to distinguish object files from OMAGIC executables */ -#define N_TXTADDR(x) \ - (N_MAGIC(x) == OMAGIC ? \ - ((x).a_entry < TEXT_START_ADDR? 0: TEXT_START_ADDR): \ - (N_MAGIC(x) == NMAGIC? TEXT_START_ADDR: \ - TEXT_START_ADDR + EXEC_BYTES_SIZE)) - -#define SEGMENT_SIZE TARGET_PAGE_SIZE - -#define N_SHARED_LIB(x) 0 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define DEFAULT_ARCH bfd_arch_ns32k - -#define MY(OP) CAT(pc532machaout_,OP) - -/* Must be the same as aout-ns32k.c */ -#define NAME(x,y) CAT3(ns32kaout,_32_,y) - -#define TARGETNAME "a.out-pc532-mach" - -#include "bfd.h" -#include "sysdep.h" -#include "libaout.h" -#include "libbfd.h" -#include "aout/aout64.h" - -/* We can`t use the MYNS macro here for cpp reasons too subtle for me -- IWD */ - -#define MY_bfd_reloc_type_lookup ns32kaout_bfd_reloc_type_lookup - -/* libaout doesn't use NAME for these ... */ - -#define MY_get_section_contents aout_32_get_section_contents - -#define MY_text_includes_header 1 - -#define MY_exec_header_not_counted 1 - -#define MYNSX(OP) CAT(ns32kaout_,OP) -reloc_howto_type * -MYNSX(bfd_reloc_type_lookup) - PARAMS((bfd *abfd AND - bfd_reloc_code_real_type code)); - -boolean -MYNSX(write_object_contents) - PARAMS((bfd *abfd)); - -static boolean -MY(write_object_contents) (abfd) -bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - -#if CHOOSE_RELOC_SIZE - CHOOSE_RELOC_SIZE(abfd); -#else - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; -#endif - - BFD_ASSERT (bfd_get_arch (abfd) == bfd_arch_ns32k); - switch (bfd_get_mach (abfd)) - { - case 32032: - N_SET_MACHTYPE (*execp, M_NS32032); - break; - case 32532: - default: - N_SET_MACHTYPE (*execp, M_NS32532); - break; - } - N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags); - - WRITE_HEADERS(abfd, execp); - - return true; -} - -#define MY_write_object_contents MY(write_object_contents) - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/pe-arm.c b/contrib/gdb/bfd/pe-arm.c deleted file mode 100644 index fa97e2e..0000000 --- a/contrib/gdb/bfd/pe-arm.c +++ /dev/null @@ -1,32 +0,0 @@ -/* BFD back-end for ARM PECOFF files. - Copyright 1995 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" - -#define TARGET_LITTLE_SYM armpe_little_vec -#define TARGET_LITTLE_NAME "pe-arm-little" -#define TARGET_BIG_SYM armpe_big_vec -#define TARGET_BIG_NAME "pe-arm-big" - -#define COFF_OBJ_WITH_PE -#define COFF_WITH_PE -#define PCRELOFFSET true - -#include "coff-arm.c" diff --git a/contrib/gdb/bfd/pe-i386.c b/contrib/gdb/bfd/pe-i386.c deleted file mode 100644 index 878993e..0000000 --- a/contrib/gdb/bfd/pe-i386.c +++ /dev/null @@ -1,30 +0,0 @@ -/* BFD back-end for Intel 386 PECOFF files. - Copyright 1995 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" - - -#define TARGET_SYM i386pe_vec -#define TARGET_NAME "pe-i386" -#define COFF_OBJ_WITH_PE -#define COFF_WITH_PE -#define PCRELOFFSET true -#define TARGET_UNDERSCORE '_' -#include "coff-i386.c" diff --git a/contrib/gdb/bfd/pe-ppc.c b/contrib/gdb/bfd/pe-ppc.c deleted file mode 100644 index 67fdda0..0000000 --- a/contrib/gdb/bfd/pe-ppc.c +++ /dev/null @@ -1,39 +0,0 @@ -/* BFD back-end for Intel 386 PECOFF files. - Copyright 1995 Free Software Foundation, Inc. - -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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "bfd.h" -#include "sysdep.h" - - -#define E_FILENMLEN 18 - -#define PPC - -#define TARGET_LITTLE_SYM bfd_powerpcle_pe_vec -#define TARGET_LITTLE_NAME "pe-powerpcle" - -#define TARGET_BIG_SYM bfd_powerpc_pe_vec -#define TARGET_BIG_NAME "pe-powerpc" - -#define COFF_OBJ_WITH_PE -#define COFF_WITH_PE - -/* FIXME: verify PCRELOFFSET is always false */ - -#include "coff-ppc.c" diff --git a/contrib/gdb/bfd/pei-arm.c b/contrib/gdb/bfd/pei-arm.c deleted file mode 100644 index fd9d398..0000000 --- a/contrib/gdb/bfd/pei-arm.c +++ /dev/null @@ -1,33 +0,0 @@ -/* BFD back-end for arm PE IMAGE COFF files. - Copyright 1995 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" - -#define TARGET_LITTLE_SYM armpei_little_vec -#define TARGET_LITTLE_NAME "pei-arm-little" -#define TARGET_BIG_SYM armpei_big_vec -#define TARGET_BIG_NAME "pei-arm-big" - -#define IMAGE_BASE NT_IMAGE_BASE -#define COFF_IMAGE_WITH_PE -#define COFF_WITH_PE -#define PCRELOFFSET true - -#include "coff-arm.c" diff --git a/contrib/gdb/bfd/pei-i386.c b/contrib/gdb/bfd/pei-i386.c deleted file mode 100644 index 8754e7c..0000000 --- a/contrib/gdb/bfd/pei-i386.c +++ /dev/null @@ -1,33 +0,0 @@ -/* BFD back-end for Intel 386 PE IMAGE COFF files. - Copyright 1995 Free Software Foundation, Inc. - -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. */ - -#include "bfd.h" -#include "sysdep.h" - -#define TARGET_SYM i386pei_vec -#define TARGET_NAME "pei-i386" -#define IMAGE_BASE NT_IMAGE_BASE -#define COFF_IMAGE_WITH_PE -#define COFF_WITH_PE -#define PCRELOFFSET true -#define TARGET_UNDERSCORE '_' -#include "coff-i386.c" - - - diff --git a/contrib/gdb/bfd/pei-ppc.c b/contrib/gdb/bfd/pei-ppc.c deleted file mode 100644 index fc8f89f..0000000 --- a/contrib/gdb/bfd/pei-ppc.c +++ /dev/null @@ -1,44 +0,0 @@ -/* BFD back-end for Intel 386 PE IMAGE COFF files. - Copyright 1995 Free Software Foundation, Inc. - -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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "bfd.h" -#include "sysdep.h" - -/* setting up for a PE environment stolen directly from the i386 structure */ -#define E_FILNMLEN 18 /* # characters in a file name */ - -#define PPC - -#define TARGET_LITTLE_SYM bfd_powerpcle_pei_vec -#define TARGET_LITTLE_NAME "pei-powerpcle" - -#define TARGET_BIG_SYM bfd_powerpc_pei_vec -#define TARGET_BIG_NAME "pei-powerpc" - -#define IMAGE_BASE NT_IMAGE_BASE - -#define COFF_IMAGE_WITH_PE -#define COFF_WITH_PE - -/* FIXME: Verify PCRELOFFSET is always false */ - -#include "coff-ppc.c" - - - diff --git a/contrib/gdb/bfd/peicode.h b/contrib/gdb/bfd/peicode.h deleted file mode 100644 index a7a4746..0000000 --- a/contrib/gdb/bfd/peicode.h +++ /dev/null @@ -1,1861 +0,0 @@ -/* Support for the generic parts of most COFF variants, for BFD. - Copyright 1995 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - -/* -Most of this hacked by Steve Chamberlain, - sac@cygnus.com -*/ - - - -#define coff_bfd_print_private_bfd_data pe_print_private_bfd_data -#define coff_mkobject pe_mkobject -#define coff_mkobject_hook pe_mkobject_hook - -#ifndef GET_FCN_LNNOPTR -#define GET_FCN_LNNOPTR(abfd, ext) \ - bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr) -#endif - -#ifndef GET_FCN_ENDNDX -#define GET_FCN_ENDNDX(abfd, ext) \ - bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx) -#endif - -#ifndef PUT_FCN_LNNOPTR -#define PUT_FCN_LNNOPTR(abfd, in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr) -#endif -#ifndef PUT_FCN_ENDNDX -#define PUT_FCN_ENDNDX(abfd, in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx) -#endif -#ifndef GET_LNSZ_LNNO -#define GET_LNSZ_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_lnno) -#endif -#ifndef GET_LNSZ_SIZE -#define GET_LNSZ_SIZE(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_size) -#endif -#ifndef PUT_LNSZ_LNNO -#define PUT_LNSZ_LNNO(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_sym.x_misc.x_lnsz.x_lnno) -#endif -#ifndef PUT_LNSZ_SIZE -#define PUT_LNSZ_SIZE(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte*) ext->x_sym.x_misc.x_lnsz.x_size) -#endif -#ifndef GET_SCN_SCNLEN -#define GET_SCN_SCNLEN(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_scnlen) -#endif -#ifndef GET_SCN_NRELOC -#define GET_SCN_NRELOC(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nreloc) -#endif -#ifndef GET_SCN_NLINNO -#define GET_SCN_NLINNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nlinno) -#endif -#ifndef PUT_SCN_SCNLEN -#define PUT_SCN_SCNLEN(abfd,in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_scn.x_scnlen) -#endif -#ifndef PUT_SCN_NRELOC -#define PUT_SCN_NRELOC(abfd,in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_scn.x_nreloc) -#endif -#ifndef PUT_SCN_NLINNO -#define PUT_SCN_NLINNO(abfd,in, ext) bfd_h_put_16(abfd,in, (bfd_byte *) ext->x_scn.x_nlinno) -#endif -#ifndef GET_LINENO_LNNO -#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) (ext->l_lnno)); -#endif -#ifndef PUT_LINENO_LNNO -#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_16(abfd,val, (bfd_byte *) (ext->l_lnno)); -#endif - -/* The f_symptr field in the filehdr is sometimes 64 bits. */ -#ifndef GET_FILEHDR_SYMPTR -#define GET_FILEHDR_SYMPTR bfd_h_get_32 -#endif -#ifndef PUT_FILEHDR_SYMPTR -#define PUT_FILEHDR_SYMPTR bfd_h_put_32 -#endif - -/* Some fields in the aouthdr are sometimes 64 bits. */ -#ifndef GET_AOUTHDR_TSIZE -#define GET_AOUTHDR_TSIZE bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_TSIZE -#define PUT_AOUTHDR_TSIZE bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_DSIZE -#define GET_AOUTHDR_DSIZE bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_DSIZE -#define PUT_AOUTHDR_DSIZE bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_BSIZE -#define GET_AOUTHDR_BSIZE bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_BSIZE -#define PUT_AOUTHDR_BSIZE bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_ENTRY -#define GET_AOUTHDR_ENTRY bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_ENTRY -#define PUT_AOUTHDR_ENTRY bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_TEXT_START -#define GET_AOUTHDR_TEXT_START bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_TEXT_START -#define PUT_AOUTHDR_TEXT_START bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_DATA_START -#define GET_AOUTHDR_DATA_START bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_DATA_START -#define PUT_AOUTHDR_DATA_START bfd_h_put_32 -#endif - -/* Some fields in the scnhdr are sometimes 64 bits. */ -#ifndef GET_SCNHDR_PADDR -#define GET_SCNHDR_PADDR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_PADDR -#define PUT_SCNHDR_PADDR bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_VADDR -#define GET_SCNHDR_VADDR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_VADDR -#define PUT_SCNHDR_VADDR bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_SIZE -#define GET_SCNHDR_SIZE bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_SIZE -#define PUT_SCNHDR_SIZE bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_SCNPTR -#define GET_SCNHDR_SCNPTR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_SCNPTR -#define PUT_SCNHDR_SCNPTR bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_RELPTR -#define GET_SCNHDR_RELPTR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_RELPTR -#define PUT_SCNHDR_RELPTR bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_LNNOPTR -#define GET_SCNHDR_LNNOPTR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_LNNOPTR -#define PUT_SCNHDR_LNNOPTR bfd_h_put_32 -#endif - - - -/**********************************************************************/ - -static void -coff_swap_reloc_in (abfd, src, dst) - bfd *abfd; - PTR src; - PTR dst; -{ - RELOC *reloc_src = (RELOC *) src; - struct internal_reloc *reloc_dst = (struct internal_reloc *) dst; - - reloc_dst->r_vaddr = bfd_h_get_32(abfd, (bfd_byte *)reloc_src->r_vaddr); - reloc_dst->r_symndx = bfd_h_get_signed_32(abfd, (bfd_byte *) reloc_src->r_symndx); - - reloc_dst->r_type = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_type); - -#ifdef SWAP_IN_RELOC_OFFSET - reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET(abfd, - (bfd_byte *) reloc_src->r_offset); -#endif -} - - -static unsigned int -coff_swap_reloc_out (abfd, src, dst) - bfd *abfd; - PTR src; - PTR dst; -{ - struct internal_reloc *reloc_src = (struct internal_reloc *)src; - struct external_reloc *reloc_dst = (struct external_reloc *)dst; - bfd_h_put_32(abfd, reloc_src->r_vaddr, (bfd_byte *) reloc_dst->r_vaddr); - bfd_h_put_32(abfd, reloc_src->r_symndx, (bfd_byte *) reloc_dst->r_symndx); - - bfd_h_put_16(abfd, reloc_src->r_type, (bfd_byte *) - reloc_dst->r_type); - -#ifdef SWAP_OUT_RELOC_OFFSET - SWAP_OUT_RELOC_OFFSET(abfd, - reloc_src->r_offset, - (bfd_byte *) reloc_dst->r_offset); -#endif -#ifdef SWAP_OUT_RELOC_EXTRA - SWAP_OUT_RELOC_EXTRA(abfd,reloc_src, reloc_dst); -#endif - return sizeof(struct external_reloc); -} - - -static void -coff_swap_filehdr_in (abfd, src, dst) - bfd *abfd; - PTR src; - PTR dst; -{ - FILHDR *filehdr_src = (FILHDR *) src; - struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst; - filehdr_dst->f_magic = bfd_h_get_16(abfd, (bfd_byte *) filehdr_src->f_magic); - filehdr_dst->f_nscns = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_nscns); - filehdr_dst->f_timdat = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_timdat); - - filehdr_dst->f_nsyms = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_nsyms); - filehdr_dst->f_flags = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_flags); - filehdr_dst->f_symptr = bfd_h_get_32 (abfd, (bfd_byte *) filehdr_src->f_symptr); - - /* Other people's tools sometimes generate headers - with an nsyms but a zero symptr. */ - if (filehdr_dst->f_nsyms && filehdr_dst->f_symptr) - { - filehdr_dst->f_flags |= HAS_SYMS; - } - else - { - filehdr_dst->f_symptr = 0; - filehdr_dst->f_nsyms = 0; - filehdr_dst->f_flags &= ~HAS_SYMS; - } - - filehdr_dst->f_opthdr = bfd_h_get_16(abfd, - (bfd_byte *)filehdr_src-> f_opthdr); -} - -#ifdef COFF_IMAGE_WITH_PE - -static unsigned int -coff_swap_filehdr_out (abfd, in, out) - bfd *abfd; - PTR in; - PTR out; -{ - int idx; - struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in; - FILHDR *filehdr_out = (FILHDR *)out; - - if (pe_data (abfd)->has_reloc_section) - filehdr_in->f_flags &= ~F_RELFLG; - - if (pe_data (abfd)->dll) - filehdr_in->f_flags |= F_DLL; - - filehdr_in->pe.e_magic = DOSMAGIC; - filehdr_in->pe.e_cblp = 0x90; - filehdr_in->pe.e_cp = 0x3; - filehdr_in->pe.e_crlc = 0x0; - filehdr_in->pe.e_cparhdr = 0x4; - filehdr_in->pe.e_minalloc = 0x0; - filehdr_in->pe.e_maxalloc = 0xffff; - filehdr_in->pe.e_ss = 0x0; - filehdr_in->pe.e_sp = 0xb8; - filehdr_in->pe.e_csum = 0x0; - filehdr_in->pe.e_ip = 0x0; - filehdr_in->pe.e_cs = 0x0; - filehdr_in->pe.e_lfarlc = 0x40; - filehdr_in->pe.e_ovno = 0x0; - - for (idx=0; idx < 4; idx++) - filehdr_in->pe.e_res[idx] = 0x0; - - filehdr_in->pe.e_oemid = 0x0; - filehdr_in->pe.e_oeminfo = 0x0; - - for (idx=0; idx < 10; idx++) - filehdr_in->pe.e_res2[idx] = 0x0; - - filehdr_in->pe.e_lfanew = 0x80; - - /* this next collection of data are mostly just characters. It appears - to be constant within the headers put on NT exes */ - filehdr_in->pe.dos_message[0] = 0x0eba1f0e; - filehdr_in->pe.dos_message[1] = 0xcd09b400; - filehdr_in->pe.dos_message[2] = 0x4c01b821; - filehdr_in->pe.dos_message[3] = 0x685421cd; - filehdr_in->pe.dos_message[4] = 0x70207369; - filehdr_in->pe.dos_message[5] = 0x72676f72; - filehdr_in->pe.dos_message[6] = 0x63206d61; - filehdr_in->pe.dos_message[7] = 0x6f6e6e61; - filehdr_in->pe.dos_message[8] = 0x65622074; - filehdr_in->pe.dos_message[9] = 0x6e757220; - filehdr_in->pe.dos_message[10] = 0x206e6920; - filehdr_in->pe.dos_message[11] = 0x20534f44; - filehdr_in->pe.dos_message[12] = 0x65646f6d; - filehdr_in->pe.dos_message[13] = 0x0a0d0d2e; - filehdr_in->pe.dos_message[14] = 0x24; - filehdr_in->pe.dos_message[15] = 0x0; - filehdr_in->pe.nt_signature = NT_SIGNATURE; - - - - bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic); - bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns); - - bfd_h_put_32(abfd, time (0), (bfd_byte *) filehdr_out->f_timdat); - PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr, - (bfd_byte *) filehdr_out->f_symptr); - bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms); - bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr); - bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags); - - /* put in extra dos header stuff. This data remains essentially - constant, it just has to be tacked on to the beginning of all exes - for NT */ - bfd_h_put_16(abfd, filehdr_in->pe.e_magic, (bfd_byte *) filehdr_out->e_magic); - bfd_h_put_16(abfd, filehdr_in->pe.e_cblp, (bfd_byte *) filehdr_out->e_cblp); - bfd_h_put_16(abfd, filehdr_in->pe.e_cp, (bfd_byte *) filehdr_out->e_cp); - bfd_h_put_16(abfd, filehdr_in->pe.e_crlc, (bfd_byte *) filehdr_out->e_crlc); - bfd_h_put_16(abfd, filehdr_in->pe.e_cparhdr, - (bfd_byte *) filehdr_out->e_cparhdr); - bfd_h_put_16(abfd, filehdr_in->pe.e_minalloc, - (bfd_byte *) filehdr_out->e_minalloc); - bfd_h_put_16(abfd, filehdr_in->pe.e_maxalloc, - (bfd_byte *) filehdr_out->e_maxalloc); - bfd_h_put_16(abfd, filehdr_in->pe.e_ss, (bfd_byte *) filehdr_out->e_ss); - bfd_h_put_16(abfd, filehdr_in->pe.e_sp, (bfd_byte *) filehdr_out->e_sp); - bfd_h_put_16(abfd, filehdr_in->pe.e_csum, (bfd_byte *) filehdr_out->e_csum); - bfd_h_put_16(abfd, filehdr_in->pe.e_ip, (bfd_byte *) filehdr_out->e_ip); - bfd_h_put_16(abfd, filehdr_in->pe.e_cs, (bfd_byte *) filehdr_out->e_cs); - bfd_h_put_16(abfd, filehdr_in->pe.e_lfarlc, (bfd_byte *) filehdr_out->e_lfarlc); - bfd_h_put_16(abfd, filehdr_in->pe.e_ovno, (bfd_byte *) filehdr_out->e_ovno); - { - int idx; - for (idx=0; idx < 4; idx++) - bfd_h_put_16(abfd, filehdr_in->pe.e_res[idx], - (bfd_byte *) filehdr_out->e_res[idx]); - } - bfd_h_put_16(abfd, filehdr_in->pe.e_oemid, (bfd_byte *) filehdr_out->e_oemid); - bfd_h_put_16(abfd, filehdr_in->pe.e_oeminfo, - (bfd_byte *) filehdr_out->e_oeminfo); - { - int idx; - for (idx=0; idx < 10; idx++) - bfd_h_put_16(abfd, filehdr_in->pe.e_res2[idx], - (bfd_byte *) filehdr_out->e_res2[idx]); - } - bfd_h_put_32(abfd, filehdr_in->pe.e_lfanew, (bfd_byte *) filehdr_out->e_lfanew); - - { - int idx; - for (idx=0; idx < 16; idx++) - bfd_h_put_32(abfd, filehdr_in->pe.dos_message[idx], - (bfd_byte *) filehdr_out->dos_message[idx]); - } - - /* also put in the NT signature */ - bfd_h_put_32(abfd, filehdr_in->pe.nt_signature, - (bfd_byte *) filehdr_out->nt_signature); - - - - - return sizeof(FILHDR); -} -#else - -static unsigned int -coff_swap_filehdr_out (abfd, in, out) - bfd *abfd; - PTR in; - PTR out; -{ - struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in; - FILHDR *filehdr_out = (FILHDR *)out; - - bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic); - bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns); - bfd_h_put_32(abfd, filehdr_in->f_timdat, (bfd_byte *) filehdr_out->f_timdat); - PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr, - (bfd_byte *) filehdr_out->f_symptr); - bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms); - bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr); - bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags); - - return sizeof(FILHDR); -} - -#endif - - -static void -coff_swap_sym_in (abfd, ext1, in1) - bfd *abfd; - PTR ext1; - PTR in1; -{ - SYMENT *ext = (SYMENT *)ext1; - struct internal_syment *in = (struct internal_syment *)in1; - - if( ext->e.e_name[0] == 0) { - in->_n._n_n._n_zeroes = 0; - in->_n._n_n._n_offset = bfd_h_get_32(abfd, (bfd_byte *) ext->e.e.e_offset); - } - else { -#if SYMNMLEN != E_SYMNMLEN - -> Error, we need to cope with truncating or extending SYMNMLEN!; -#else - memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN); -#endif - } - - in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value); - in->n_scnum = bfd_h_get_16(abfd, (bfd_byte *) ext->e_scnum); - if (sizeof(ext->e_type) == 2){ - in->n_type = bfd_h_get_16(abfd, (bfd_byte *) ext->e_type); - } - else { - in->n_type = bfd_h_get_32(abfd, (bfd_byte *) ext->e_type); - } - in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass); - in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux); - - /* The section symbols for the .idata$ sections have class 68, which MS - documentation indicates is a section symbol. The problem is that the - value field in the symbol is simply a copy of the .idata section's flags - rather than something useful. When these symbols are encountered, change - the value to 0 and the section number to 1 so that they will be handled - somewhat correctly in the bfd code. */ - if (in->n_sclass == 0x68) { - in->n_value = 0x0; - in->n_scnum = 1; - /* I have tried setting the class to 3 and using the following to set - the section number. This will put the address of the pointer to the - string kernel32.dll at addresses 0 and 0x10 off start of idata section - which is not correct */ - /* if (strcmp (in->_n._n_name, ".idata$4") == 0) */ - /* in->n_scnum = 3; */ - /* else */ - /* in->n_scnum = 2; */ - } - -#ifdef coff_swap_sym_in_hook - coff_swap_sym_in_hook(abfd, ext1, in1); -#endif -} - -static unsigned int -coff_swap_sym_out (abfd, inp, extp) - bfd *abfd; - PTR inp; - PTR extp; -{ - struct internal_syment *in = (struct internal_syment *)inp; - SYMENT *ext =(SYMENT *)extp; - if(in->_n._n_name[0] == 0) { - bfd_h_put_32(abfd, 0, (bfd_byte *) ext->e.e.e_zeroes); - bfd_h_put_32(abfd, in->_n._n_n._n_offset, (bfd_byte *) ext->e.e.e_offset); - } - else { -#if SYMNMLEN != E_SYMNMLEN - -> Error, we need to cope with truncating or extending SYMNMLEN!; -#else - memcpy(ext->e.e_name, in->_n._n_name, SYMNMLEN); -#endif - } - - bfd_h_put_32(abfd, in->n_value , (bfd_byte *) ext->e_value); - bfd_h_put_16(abfd, in->n_scnum , (bfd_byte *) ext->e_scnum); - if (sizeof(ext->e_type) == 2) - { - bfd_h_put_16(abfd, in->n_type , (bfd_byte *) ext->e_type); - } - else - { - bfd_h_put_32(abfd, in->n_type , (bfd_byte *) ext->e_type); - } - bfd_h_put_8(abfd, in->n_sclass , ext->e_sclass); - bfd_h_put_8(abfd, in->n_numaux , ext->e_numaux); - - return sizeof(SYMENT); -} - -static void -coff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1) - bfd *abfd; - PTR ext1; - int type; - int class; - int indx; - int numaux; - PTR in1; -{ - AUXENT *ext = (AUXENT *)ext1; - union internal_auxent *in = (union internal_auxent *)in1; - - switch (class) { - case C_FILE: - if (ext->x_file.x_fname[0] == 0) { - in->x_file.x_n.x_zeroes = 0; - in->x_file.x_n.x_offset = - bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset); - } else { -#if FILNMLEN != E_FILNMLEN - -> Error, we need to cope with truncating or extending FILNMLEN!; -#else - memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN); -#endif - } - return; - - - case C_STAT: -#ifdef C_LEAFSTAT - case C_LEAFSTAT: -#endif - case C_HIDDEN: - if (type == T_NULL) { - in->x_scn.x_scnlen = GET_SCN_SCNLEN(abfd, ext); - in->x_scn.x_nreloc = GET_SCN_NRELOC(abfd, ext); - in->x_scn.x_nlinno = GET_SCN_NLINNO(abfd, ext); - return; - } - break; - } - - in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_tagndx); -#ifndef NO_TVNDX - in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx); -#endif - - if (class == C_BLOCK || ISFCN (type) || ISTAG (class)) - { - in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext); - in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX (abfd, ext); - } - else - { -#if DIMNUM != E_DIMNUM - #error we need to cope with truncating or extending DIMNUM -#endif - in->x_sym.x_fcnary.x_ary.x_dimen[0] = - bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]); - in->x_sym.x_fcnary.x_ary.x_dimen[1] = - bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]); - in->x_sym.x_fcnary.x_ary.x_dimen[2] = - bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]); - in->x_sym.x_fcnary.x_ary.x_dimen[3] = - bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]); - } - - if (ISFCN(type)) { - in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize); - } - else { - in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO(abfd, ext); - in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE(abfd, ext); - } -} - -static unsigned int -coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp) - bfd *abfd; - PTR inp; - int type; - int class; - int indx; - int numaux; - PTR extp; -{ - union internal_auxent *in = (union internal_auxent *)inp; - AUXENT *ext = (AUXENT *)extp; - - memset((PTR)ext, 0, AUXESZ); - switch (class) { - case C_FILE: - if (in->x_file.x_fname[0] == 0) { - bfd_h_put_32(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes); - bfd_h_put_32(abfd, - in->x_file.x_n.x_offset, - (bfd_byte *) ext->x_file.x_n.x_offset); - } - else { -#if FILNMLEN != E_FILNMLEN - -> Error, we need to cope with truncating or extending FILNMLEN!; -#else - memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN); -#endif - } - return sizeof (AUXENT); - - - case C_STAT: -#ifdef C_LEAFSTAT - case C_LEAFSTAT: -#endif - case C_HIDDEN: - if (type == T_NULL) { - PUT_SCN_SCNLEN(abfd, in->x_scn.x_scnlen, ext); - PUT_SCN_NRELOC(abfd, in->x_scn.x_nreloc, ext); - PUT_SCN_NLINNO(abfd, in->x_scn.x_nlinno, ext); - return sizeof (AUXENT); - } - break; - } - - bfd_h_put_32(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx); -#ifndef NO_TVNDX - bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx); -#endif - - if (class == C_BLOCK || ISFCN (type) || ISTAG (class)) - { - PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext); - PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext); - } - else - { -#if DIMNUM != E_DIMNUM - #error we need to cope with truncating or extending DIMNUM -#endif - bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0], - (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]); - bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1], - (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]); - bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2], - (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]); - bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3], - (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]); - } - - if (ISFCN (type)) - bfd_h_put_32 (abfd, in->x_sym.x_misc.x_fsize, - (bfd_byte *) ext->x_sym.x_misc.x_fsize); - else - { - PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext); - PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext); - } - - return sizeof(AUXENT); -} - - -static void -coff_swap_lineno_in (abfd, ext1, in1) - bfd *abfd; - PTR ext1; - PTR in1; -{ - LINENO *ext = (LINENO *)ext1; - struct internal_lineno *in = (struct internal_lineno *)in1; - - in->l_addr.l_symndx = bfd_h_get_32(abfd, (bfd_byte *) ext->l_addr.l_symndx); - in->l_lnno = GET_LINENO_LNNO(abfd, ext); -} - -static unsigned int -coff_swap_lineno_out (abfd, inp, outp) - bfd *abfd; - PTR inp; - PTR outp; -{ - struct internal_lineno *in = (struct internal_lineno *)inp; - struct external_lineno *ext = (struct external_lineno *)outp; - bfd_h_put_32(abfd, in->l_addr.l_symndx, (bfd_byte *) - ext->l_addr.l_symndx); - - PUT_LINENO_LNNO (abfd, in->l_lnno, ext); - return sizeof(struct external_lineno); -} - - - -static void -coff_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1) - bfd *abfd; - PTR aouthdr_ext1; - PTR aouthdr_int1; -{ - struct internal_extra_pe_aouthdr *a; - PEAOUTHDR *src = (PEAOUTHDR *)(aouthdr_ext1); - AOUTHDR *aouthdr_ext = (AOUTHDR *) aouthdr_ext1; - struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1; - - aouthdr_int->magic = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->magic); - aouthdr_int->vstamp = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->vstamp); - aouthdr_int->tsize = - GET_AOUTHDR_TSIZE (abfd, (bfd_byte *) aouthdr_ext->tsize); - aouthdr_int->dsize = - GET_AOUTHDR_DSIZE (abfd, (bfd_byte *) aouthdr_ext->dsize); - aouthdr_int->bsize = - GET_AOUTHDR_BSIZE (abfd, (bfd_byte *) aouthdr_ext->bsize); - aouthdr_int->entry = - GET_AOUTHDR_ENTRY (abfd, (bfd_byte *) aouthdr_ext->entry); - aouthdr_int->text_start = - GET_AOUTHDR_TEXT_START (abfd, (bfd_byte *) aouthdr_ext->text_start); - aouthdr_int->data_start = - GET_AOUTHDR_DATA_START (abfd, (bfd_byte *) aouthdr_ext->data_start); - - a = &aouthdr_int->pe; - a->ImageBase = bfd_h_get_32 (abfd, src->ImageBase); - a->SectionAlignment = bfd_h_get_32 (abfd, src->SectionAlignment); - a->FileAlignment = bfd_h_get_32 (abfd, src->FileAlignment); - a->MajorOperatingSystemVersion = - bfd_h_get_16 (abfd, src->MajorOperatingSystemVersion); - a->MinorOperatingSystemVersion = - bfd_h_get_16 (abfd, src->MinorOperatingSystemVersion); - a->MajorImageVersion = bfd_h_get_16 (abfd, src->MajorImageVersion); - a->MinorImageVersion = bfd_h_get_16 (abfd, src->MinorImageVersion); - a->MajorSubsystemVersion = bfd_h_get_16 (abfd, src->MajorSubsystemVersion); - a->MinorSubsystemVersion = bfd_h_get_16 (abfd, src->MinorSubsystemVersion); - a->Reserved1 = bfd_h_get_32 (abfd, src->Reserved1); - a->SizeOfImage = bfd_h_get_32 (abfd, src->SizeOfImage); - a->SizeOfHeaders = bfd_h_get_32 (abfd, src->SizeOfHeaders); - a->CheckSum = bfd_h_get_32 (abfd, src->CheckSum); - a->Subsystem = bfd_h_get_16 (abfd, src->Subsystem); - a->DllCharacteristics = bfd_h_get_16 (abfd, src->DllCharacteristics); - a->SizeOfStackReserve = bfd_h_get_32 (abfd, src->SizeOfStackReserve); - a->SizeOfStackCommit = bfd_h_get_32 (abfd, src->SizeOfStackCommit); - a->SizeOfHeapReserve = bfd_h_get_32 (abfd, src->SizeOfHeapReserve); - a->SizeOfHeapCommit = bfd_h_get_32 (abfd, src->SizeOfHeapCommit); - a->LoaderFlags = bfd_h_get_32 (abfd, src->LoaderFlags); - a->NumberOfRvaAndSizes = bfd_h_get_32 (abfd, src->NumberOfRvaAndSizes); - - { - int idx; - for (idx=0; idx < 16; idx++) - { - a->DataDirectory[idx].VirtualAddress = - bfd_h_get_32 (abfd, src->DataDirectory[idx][0]); - a->DataDirectory[idx].Size = - bfd_h_get_32 (abfd, src->DataDirectory[idx][1]); - } - } - - if (aouthdr_int->entry) - aouthdr_int->entry += a->ImageBase; - if (aouthdr_int->tsize) - aouthdr_int->text_start += a->ImageBase; - if (aouthdr_int->dsize) - aouthdr_int->data_start += a->ImageBase; -} - - -static void add_data_entry (abfd, aout, idx, name, base) - bfd *abfd; - struct internal_extra_pe_aouthdr *aout; - int idx; - char *name; - bfd_vma base; -{ - asection *sec = bfd_get_section_by_name (abfd, name); - - /* add import directory information if it exists */ - if (sec != NULL) - { - aout->DataDirectory[idx].VirtualAddress = sec->vma - base; - aout->DataDirectory[idx].Size = sec->_cooked_size; - sec->flags |= SEC_DATA; - } -} - -static unsigned int -coff_swap_aouthdr_out (abfd, in, out) - bfd *abfd; - PTR in; - PTR out; -{ - struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *)in; - struct internal_extra_pe_aouthdr *extra = &pe_data (abfd)->pe_opthdr; - PEAOUTHDR *aouthdr_out = (PEAOUTHDR *)out; - - bfd_vma sa = extra->SectionAlignment; - bfd_vma fa = extra->FileAlignment; - bfd_vma ib = extra->ImageBase ; - - if (aouthdr_in->tsize) - aouthdr_in->text_start -= ib; - if (aouthdr_in->dsize) - aouthdr_in->data_start -= ib; - if (aouthdr_in->entry) - aouthdr_in->entry -= ib; - -#define FA(x) (((x) + fa -1 ) & (- fa)) -#define SA(x) (((x) + sa -1 ) & (- sa)) - - /* We like to have the sizes aligned */ - - aouthdr_in->bsize = FA (aouthdr_in->bsize); - - - extra->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES; - - /* first null out all data directory entries .. */ - memset (extra->DataDirectory, sizeof (extra->DataDirectory), 0); - - add_data_entry (abfd, extra, 0, ".edata", ib); - add_data_entry (abfd, extra, 1, ".idata", ib); - add_data_entry (abfd, extra, 2, ".rsrc" ,ib); - -#ifdef POWERPC_LE_PE - /* FIXME: do other PE platforms use this? */ - add_data_entry (abfd, extra, 3, ".pdata" ,ib); -#endif - - add_data_entry (abfd, extra, 5, ".reloc", ib); - -#ifdef POWERPC_LE_PE - /* On the PPC NT system, this field is set up as follows. It is - not an "officially" reserved field, so it currently has no title. - first_thunk_address is idata$5, and the thunk_size is the size - of the idata$5 chunk of the idata section. - */ - extra->DataDirectory[12].VirtualAddress = first_thunk_address; - extra->DataDirectory[12].Size = thunk_size; - - /* On the PPC NT system, the size of the directory entry is not the - size of the entire section. It's actually offset to the end of - the idata$3 component of the idata section. This is the size of - the entire import table. (also known as the start of idata$4) - */ - extra->DataDirectory[1].Size = import_table_size; -#endif - - { - asection *sec; - bfd_vma dsize= 0; - bfd_vma isize = SA(abfd->sections->filepos); - bfd_vma tsize= 0; - - for (sec = abfd->sections; sec; sec = sec->next) - { - int rounded = FA(sec->_raw_size); - - if (strcmp(sec->name,".junk") == 0) - { - continue; - } - - if (sec->flags & SEC_DATA) - dsize += rounded; - if (sec->flags & SEC_CODE) - tsize += rounded; - isize += SA(rounded); - } - - aouthdr_in->dsize = dsize; - aouthdr_in->tsize = tsize; - extra->SizeOfImage = isize; - } - - extra->SizeOfHeaders = abfd->sections->filepos; - bfd_h_put_16(abfd, aouthdr_in->magic, (bfd_byte *) aouthdr_out->standard.magic); - -#ifdef POWERPC_LE_PE - /* this little piece of magic sets the "linker version" field to 2.60 */ - bfd_h_put_16(abfd, 2 + 60 * 256, (bfd_byte *) aouthdr_out->standard.vstamp); -#else - /* this little piece of magic sets the "linker version" field to 2.55 */ - bfd_h_put_16(abfd, 2 + 55 * 256, (bfd_byte *) aouthdr_out->standard.vstamp); -#endif - - PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, (bfd_byte *) aouthdr_out->standard.tsize); - PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, (bfd_byte *) aouthdr_out->standard.dsize); - PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, (bfd_byte *) aouthdr_out->standard.bsize); - PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, (bfd_byte *) aouthdr_out->standard.entry); - PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start, - (bfd_byte *) aouthdr_out->standard.text_start); - - PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start, - (bfd_byte *) aouthdr_out->standard.data_start); - - - bfd_h_put_32 (abfd, extra->ImageBase, - (bfd_byte *) aouthdr_out->ImageBase); - bfd_h_put_32 (abfd, extra->SectionAlignment, - (bfd_byte *) aouthdr_out->SectionAlignment); - bfd_h_put_32 (abfd, extra->FileAlignment, - (bfd_byte *) aouthdr_out->FileAlignment); - bfd_h_put_16 (abfd, extra->MajorOperatingSystemVersion, - (bfd_byte *) aouthdr_out->MajorOperatingSystemVersion); - bfd_h_put_16 (abfd, extra->MinorOperatingSystemVersion, - (bfd_byte *) aouthdr_out->MinorOperatingSystemVersion); - bfd_h_put_16 (abfd, extra->MajorImageVersion, - (bfd_byte *) aouthdr_out->MajorImageVersion); - bfd_h_put_16 (abfd, extra->MinorImageVersion, - (bfd_byte *) aouthdr_out->MinorImageVersion); - bfd_h_put_16 (abfd, extra->MajorSubsystemVersion, - (bfd_byte *) aouthdr_out->MajorSubsystemVersion); - bfd_h_put_16 (abfd, extra->MinorSubsystemVersion, - (bfd_byte *) aouthdr_out->MinorSubsystemVersion); - bfd_h_put_32 (abfd, extra->Reserved1, - (bfd_byte *) aouthdr_out->Reserved1); - bfd_h_put_32 (abfd, extra->SizeOfImage, - (bfd_byte *) aouthdr_out->SizeOfImage); - bfd_h_put_32 (abfd, extra->SizeOfHeaders, - (bfd_byte *) aouthdr_out->SizeOfHeaders); - bfd_h_put_32 (abfd, extra->CheckSum, - (bfd_byte *) aouthdr_out->CheckSum); - bfd_h_put_16 (abfd, extra->Subsystem, - (bfd_byte *) aouthdr_out->Subsystem); - bfd_h_put_16 (abfd, extra->DllCharacteristics, - (bfd_byte *) aouthdr_out->DllCharacteristics); - bfd_h_put_32 (abfd, extra->SizeOfStackReserve, - (bfd_byte *) aouthdr_out->SizeOfStackReserve); - bfd_h_put_32 (abfd, extra->SizeOfStackCommit, - (bfd_byte *) aouthdr_out->SizeOfStackCommit); - bfd_h_put_32 (abfd, extra->SizeOfHeapReserve, - (bfd_byte *) aouthdr_out->SizeOfHeapReserve); - bfd_h_put_32 (abfd, extra->SizeOfHeapCommit, - (bfd_byte *) aouthdr_out->SizeOfHeapCommit); - bfd_h_put_32 (abfd, extra->LoaderFlags, - (bfd_byte *) aouthdr_out->LoaderFlags); - bfd_h_put_32 (abfd, extra->NumberOfRvaAndSizes, - (bfd_byte *) aouthdr_out->NumberOfRvaAndSizes); - { - int idx; - for (idx=0; idx < 16; idx++) - { - bfd_h_put_32 (abfd, extra->DataDirectory[idx].VirtualAddress, - (bfd_byte *) aouthdr_out->DataDirectory[idx][0]); - bfd_h_put_32 (abfd, extra->DataDirectory[idx].Size, - (bfd_byte *) aouthdr_out->DataDirectory[idx][1]); - } - } - - return sizeof(AOUTHDR); -} - -static void - coff_swap_scnhdr_in (abfd, ext, in) - bfd *abfd; - PTR ext; - PTR in; -{ - SCNHDR *scnhdr_ext = (SCNHDR *) ext; - struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in; - - memcpy(scnhdr_int->s_name, scnhdr_ext->s_name, sizeof(scnhdr_int->s_name)); - scnhdr_int->s_vaddr = - GET_SCNHDR_VADDR (abfd, (bfd_byte *) scnhdr_ext->s_vaddr); - scnhdr_int->s_paddr = - GET_SCNHDR_PADDR (abfd, (bfd_byte *) scnhdr_ext->s_paddr); - scnhdr_int->s_size = - GET_SCNHDR_SIZE (abfd, (bfd_byte *) scnhdr_ext->s_size); - scnhdr_int->s_scnptr = - GET_SCNHDR_SCNPTR (abfd, (bfd_byte *) scnhdr_ext->s_scnptr); - scnhdr_int->s_relptr = - GET_SCNHDR_RELPTR (abfd, (bfd_byte *) scnhdr_ext->s_relptr); - scnhdr_int->s_lnnoptr = - GET_SCNHDR_LNNOPTR (abfd, (bfd_byte *) scnhdr_ext->s_lnnoptr); - scnhdr_int->s_flags = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_flags); - - scnhdr_int->s_nreloc = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nreloc); - scnhdr_int->s_nlnno = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nlnno); - - if (scnhdr_int->s_vaddr != 0) - { - scnhdr_int->s_vaddr += pe_data (abfd)->pe_opthdr.ImageBase; - } - if (strcmp (scnhdr_int->s_name, _BSS) == 0) - { - scnhdr_int->s_size = scnhdr_int->s_paddr; - scnhdr_int->s_paddr = 0; - } -} - -static unsigned int -coff_swap_scnhdr_out (abfd, in, out) - bfd *abfd; - PTR in; - PTR out; -{ - struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in; - SCNHDR *scnhdr_ext = (SCNHDR *)out; - unsigned int ret = sizeof (SCNHDR); - bfd_vma ps; - bfd_vma ss; - - memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name)); - - PUT_SCNHDR_VADDR (abfd, - (scnhdr_int->s_vaddr - - pe_data(abfd)->pe_opthdr.ImageBase), - (bfd_byte *) scnhdr_ext->s_vaddr); - - /* NT wants the size data to be rounded up to the next NT_FILE_ALIGNMENT - value except for the BSS section, its s_size should be 0 */ - - - if (strcmp (scnhdr_int->s_name, _BSS) == 0) - { - ps = scnhdr_int->s_size; - ss = 0; - } - else - { - ps = scnhdr_int->s_paddr; - ss = scnhdr_int->s_size; - } - - PUT_SCNHDR_SIZE (abfd, ss, - (bfd_byte *) scnhdr_ext->s_size); - - - PUT_SCNHDR_PADDR (abfd, ps, (bfd_byte *) scnhdr_ext->s_paddr); - - PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr, - (bfd_byte *) scnhdr_ext->s_scnptr); - PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr, - (bfd_byte *) scnhdr_ext->s_relptr); - PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr, - (bfd_byte *) scnhdr_ext->s_lnnoptr); - - /* Extra flags must be set when dealing with NT. All sections should also - have the IMAGE_SCN_MEM_READ (0x40000000) flag set. In addition, the - .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data - sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set - (this is especially important when dealing with the .idata section since - the addresses for routines from .dlls must be overwritten). If .reloc - section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE - (0x02000000). Also, the resource data should also be read and - writable. */ - - /* FIXME: alignment is also encoded in this field, at least on ppc (krk) */ - /* FIXME: even worse, I don't see how to get the original alignment field*/ - /* back... */ - - { - int flags = scnhdr_int->s_flags; - if (strcmp (scnhdr_int->s_name, ".data") == 0 || - strcmp (scnhdr_int->s_name, ".CRT") == 0 || - strcmp (scnhdr_int->s_name, ".rsrc") == 0 || - strcmp (scnhdr_int->s_name, ".bss") == 0) - flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE; - else if (strcmp (scnhdr_int->s_name, ".text") == 0) - flags |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE; - else if (strcmp (scnhdr_int->s_name, ".reloc") == 0) - flags = SEC_DATA| IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE; - else if (strcmp (scnhdr_int->s_name, ".idata") == 0) - flags = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | SEC_DATA; - else if (strcmp (scnhdr_int->s_name, ".rdata") == 0 - || strcmp (scnhdr_int->s_name, ".edata") == 0) - flags = IMAGE_SCN_MEM_READ | SEC_DATA; - /* ppc-nt additions */ - else if (strcmp (scnhdr_int->s_name, ".pdata") == 0) - flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | - IMAGE_SCN_MEM_READ ; - /* Remember this field is a max of 8 chars, so the null is _not_ there - for an 8 character name like ".reldata". (yep. Stupid bug) */ - else if (strncmp (scnhdr_int->s_name, ".reldata", strlen(".reldata")) == 0) - flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES | - IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ; - else if (strcmp (scnhdr_int->s_name, ".ydata") == 0) - flags = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_8BYTES | - IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE ; - else if (strcmp (scnhdr_int->s_name, ".drectve") == 0) - flags = IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE ; - /* end of ppc-nt additions */ -#ifdef POWERPC_LE_PE - else if (strncmp (scnhdr_int->s_name, ".stabstr", strlen(".stabstr")) == 0) - { - flags = IMAGE_SCN_LNK_INFO; - } - else if (strcmp (scnhdr_int->s_name, ".stab") == 0) - { - flags = IMAGE_SCN_LNK_INFO; - } -#endif - - bfd_h_put_32(abfd, flags, (bfd_byte *) scnhdr_ext->s_flags); - } - - if (scnhdr_int->s_nlnno <= 0xffff) - bfd_h_put_16(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno); - else - { - (*_bfd_error_handler) ("%s: line number overflow: 0x%lx > 0xffff", - bfd_get_filename (abfd), - scnhdr_int->s_nlnno); - bfd_set_error (bfd_error_file_truncated); - bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nlnno); - ret = 0; - } - if (scnhdr_int->s_nreloc <= 0xffff) - bfd_h_put_16(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc); - else - { - (*_bfd_error_handler) ("%s: reloc overflow: 0x%lx > 0xffff", - bfd_get_filename (abfd), - scnhdr_int->s_nreloc); - bfd_set_error (bfd_error_file_truncated); - bfd_h_put_16 (abfd, 0xffff, (bfd_byte *) scnhdr_ext->s_nreloc); - ret = 0; - } - return ret; -} - -static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] = -{ - "Export Directory [.edata]", - "Import Directory [parts of .idata]", - "Resource Directory [.rsrc]", - "Exception Directory [.pdata]", - "Security Directory", - "Base Relocation Directory [.reloc]", - "Debug Directory", - "Description Directory", - "Special Directory", - "Thread Storage Directory [.tls]", - "Load Configuration Directory", - "Bound Import Directory", - "Import Address Table Directory", - "Reserved", - "Reserved", - "Reserved" -}; - -/**********************************************************************/ -static boolean -pe_print_idata(abfd, vfile) - bfd*abfd; - void *vfile; -{ - FILE *file = vfile; - bfd_byte *data = 0; - asection *section = bfd_get_section_by_name (abfd, ".idata"); - -#ifdef POWERPC_LE_PE - asection *rel_section = bfd_get_section_by_name (abfd, ".reldata"); -#endif - - bfd_size_type datasize = 0; - bfd_size_type i; - bfd_size_type start, stop; - int onaline = 20; - bfd_vma addr_value; - bfd_vma loadable_toc_address; - bfd_vma toc_address; - bfd_vma start_address; - - pe_data_type *pe = pe_data (abfd); - struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr; - - if (section == 0) - return true; - -#ifdef POWERPC_LE_PE - if (rel_section != 0 && bfd_section_size (abfd, rel_section) != 0) - { - /* The toc address can be found by taking the starting address, - which on the PPC locates a function descriptor. The descriptor - consists of the function code starting address followed by the - address of the toc. The starting address we get from the bfd, - and the descriptor is supposed to be in the .reldata section. - */ - - bfd_byte *data = 0; - int offset; - data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, - rel_section)); - if (data == NULL && bfd_section_size (abfd, rel_section) != 0) - return false; - - datasize = bfd_section_size (abfd, rel_section); - - bfd_get_section_contents (abfd, - rel_section, - (PTR) data, 0, - bfd_section_size (abfd, rel_section)); - - offset = abfd->start_address - rel_section->vma; - - start_address = bfd_get_32(abfd, data+offset); - loadable_toc_address = bfd_get_32(abfd, data+offset+4); - toc_address = loadable_toc_address - 32768; - - fprintf(file, - "\nFunction descriptor located at the start address: %04lx\n", - (unsigned long int) (abfd->start_address)); - fprintf (file, - "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n", - start_address, loadable_toc_address, toc_address); - } - else - { - loadable_toc_address = 0; - toc_address = 0; - start_address = 0; - } -#endif - - fprintf(file, - "\nThe Import Tables (interpreted .idata section contents)\n"); - fprintf(file, - " vma: Hint Time Forward DLL First\n"); - fprintf(file, - " Table Stamp Chain Name Thunk\n"); - - if (bfd_section_size (abfd, section) == 0) - return true; - - data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section)); - datasize = bfd_section_size (abfd, section); - if (data == NULL && datasize != 0) - return false; - - bfd_get_section_contents (abfd, - section, - (PTR) data, 0, - bfd_section_size (abfd, section)); - - start = 0; - - stop = bfd_section_size (abfd, section); - - for (i = start; i < stop; i += onaline) - { - bfd_vma hint_addr; - bfd_vma time_stamp; - bfd_vma forward_chain; - bfd_vma dll_name; - bfd_vma first_thunk; - int idx; - int j; - char *dll; - int adj = extra->ImageBase - section->vma; - - fprintf (file, - " %04lx\t", - (unsigned long int) (i + section->vma)); - - if (i+20 > stop) - { - /* check stuff */ - ; - } - - hint_addr = bfd_get_32(abfd, data+i); - time_stamp = bfd_get_32(abfd, data+i+4); - forward_chain = bfd_get_32(abfd, data+i+8); - dll_name = bfd_get_32(abfd, data+i+12); - first_thunk = bfd_get_32(abfd, data+i+16); - - fprintf(file, "%08lx %08lx %08lx %08lx %08lx\n", - hint_addr, - time_stamp, - forward_chain, - dll_name, - first_thunk); - - if (hint_addr ==0) - { - break; - } - - /* the image base is present in the section->vma */ - dll = data + dll_name + adj; - fprintf(file, "\n\tDLL Name: %s\n", dll); - fprintf(file, "\tvma: Ordinal Member-Name\n"); - - idx = hint_addr + adj; - - for (j=0;j<stop;j+=4) - { - int ordinal; - char *member_name; - bfd_vma member = bfd_get_32(abfd, data + idx + j); - if (member == 0) - break; - ordinal = bfd_get_16(abfd, - data + member + adj); - member_name = data + member + adj + 2; - fprintf(file, "\t%04lx\t %4d %s\n", - member, ordinal, member_name); - } - - if (hint_addr != first_thunk) - { - int differ = 0; - int idx2; - - idx2 = first_thunk + adj; - - for (j=0;j<stop;j+=4) - { - int ordinal; - char *member_name; - bfd_vma hint_member = bfd_get_32(abfd, data + idx + j); - bfd_vma iat_member = bfd_get_32(abfd, data + idx2 + j); - if (hint_member != iat_member) - { - if (differ == 0) - { - fprintf(file, - "\tThe Import Address Table (difference found)\n"); - fprintf(file, "\tvma: Ordinal Member-Name\n"); - differ = 1; - } - if (iat_member == 0) - { - fprintf(file, - "\t>>> Ran out of IAT members!\n"); - } - else - { - ordinal = bfd_get_16(abfd, - data + iat_member + adj); - member_name = data + iat_member + adj + 2; - fprintf(file, "\t%04lx\t %4d %s\n", - iat_member, ordinal, member_name); - } - break; - } - if (hint_member == 0) - break; - } - if (differ == 0) - { - fprintf(file, - "\tThe Import Address Table is identical\n"); - } - } - - fprintf(file, "\n"); - - } - - free (data); -} - -static boolean -pe_print_edata(abfd, vfile) - bfd*abfd; - void *vfile; -{ - FILE *file = vfile; - bfd_byte *data = 0; - asection *section = bfd_get_section_by_name (abfd, ".edata"); - - bfd_size_type datasize = 0; - bfd_size_type i; - - int adj; - struct EDT_type - { - long export_flags; /* reserved - should be zero */ - long time_stamp; - short major_ver; - short minor_ver; - bfd_vma name; /* rva - relative to image base */ - long base; /* ordinal base */ - long num_functions; /* Number in the export address table */ - long num_names; /* Number in the name pointer table */ - bfd_vma eat_addr; /* rva to the export address table */ - bfd_vma npt_addr; /* rva to the Export Name Pointer Table */ - bfd_vma ot_addr; /* rva to the Ordinal Table */ - } edt; - - pe_data_type *pe = pe_data (abfd); - struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr; - - if (section == 0) - return true; - - data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, - section)); - datasize = bfd_section_size (abfd, section); - - if (data == NULL && datasize != 0) - return false; - - bfd_get_section_contents (abfd, - section, - (PTR) data, 0, - bfd_section_size (abfd, section)); - - /* Go get Export Directory Table */ - edt.export_flags = bfd_get_32(abfd, data+0); - edt.time_stamp = bfd_get_32(abfd, data+4); - edt.major_ver = bfd_get_16(abfd, data+8); - edt.minor_ver = bfd_get_16(abfd, data+10); - edt.name = bfd_get_32(abfd, data+12); - edt.base = bfd_get_32(abfd, data+16); - edt.num_functions = bfd_get_32(abfd, data+20); - edt.num_names = bfd_get_32(abfd, data+24); - edt.eat_addr = bfd_get_32(abfd, data+28); - edt.npt_addr = bfd_get_32(abfd, data+32); - edt.ot_addr = bfd_get_32(abfd, data+36); - - adj = extra->ImageBase - section->vma; - - - /* Dump the EDT first first */ - fprintf(file, - "\nThe Export Tables (interpreted .edata section contents)\n\n"); - - fprintf(file, - "Export Flags \t\t\t%x\n",edt.export_flags); - - fprintf(file, - "Time/Date stamp \t\t%x\n",edt.time_stamp); - - fprintf(file, - "Major/Minor \t\t\t%d/%d\n", edt.major_ver, edt.minor_ver); - - fprintf(file, - "Name \t\t\t\t%x %s\n", edt.name, data + edt.name + adj); - - fprintf(file, - "Ordinal Base \t\t\t%d\n", edt.base); - - fprintf(file, - "Number in:\n"); - - fprintf(file, - "\tExport Address Table \t\t%x\n", edt.num_functions); - - fprintf(file, - "\t[Name Pointer/Ordinal] Table\t%d\n", edt.num_names); - - fprintf(file, - "Table Addresses\n"); - - fprintf(file, - "\tExport Address Table \t\t%x\n", - edt.eat_addr); - - fprintf(file, - "\tName Pointer Table \t\t%x\n", - edt.npt_addr); - - fprintf(file, - "\tOrdinal Table \t\t\t%x\n", - edt.ot_addr); - - - /* The next table to find si the Export Address Table. It's basically - a list of pointers that either locate a function in this dll, or - forward the call to another dll. Something like: - typedef union - { - long export_rva; - long forwarder_rva; - } export_address_table_entry; - */ - - fprintf(file, - "\nExport Address Table -- Ordinal Base %d\n", - edt.base); - - for (i = 0; i < edt.num_functions; ++i) - { - bfd_vma eat_member = bfd_get_32(abfd, - data + edt.eat_addr + (i*4) + adj); - bfd_vma eat_actual = extra->ImageBase + eat_member; - bfd_vma edata_start = bfd_get_section_vma(abfd,section); - bfd_vma edata_end = edata_start + bfd_section_size (abfd, section); - - - if (eat_member == 0) - continue; - - if (edata_start < eat_actual && eat_actual < edata_end) - { - /* this rva is to a name (forwarding function) in our section */ - /* Should locate a function descriptor */ - fprintf(file, - "\t[%4d] +base[%4d] %04lx %s -- %s\n", - i, i+edt.base, eat_member, "Forwarder RVA", - data + eat_member + adj); - } - else - { - /* Should locate a function descriptor in the reldata section */ - fprintf(file, - "\t[%4d] +base[%4d] %04lx %s\n", - i, i+edt.base, eat_member, "Export RVA"); - } - } - - /* The Export Name Pointer Table is paired with the Export Ordinal Table */ - /* Dump them in parallel for clarity */ - fprintf(file, - "\n[Ordinal/Name Pointer] Table\n"); - - for (i = 0; i < edt.num_names; ++i) - { - bfd_vma name_ptr = bfd_get_32(abfd, - data + - edt.npt_addr - + (i*4) + adj); - - char *name = data + name_ptr + adj; - - bfd_vma ord = bfd_get_16(abfd, - data + - edt.ot_addr - + (i*2) + adj); - fprintf(file, - "\t[%4d] %s\n", ord, name); - - } - - free (data); -} - -static boolean -pe_print_pdata(abfd, vfile) - bfd*abfd; - void *vfile; -{ - FILE *file = vfile; - bfd_byte *data = 0; - asection *section = bfd_get_section_by_name (abfd, ".pdata"); - bfd_size_type datasize = 0; - bfd_size_type i; - bfd_size_type start, stop; - int onaline = 20; - bfd_vma addr_value; - - if (section == 0) - return true; - - fprintf(file, - "\nThe Function Table (interpreted .pdata section contents)\n"); - fprintf(file, - " vma:\t\tBegin End EH EH PrologEnd\n"); - fprintf(file, - " \t\tAddress Address Handler Data Address\n"); - - if (bfd_section_size (abfd, section) == 0) - return true; - - data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section)); - datasize = bfd_section_size (abfd, section); - if (data == NULL && datasize != 0) - return false; - - bfd_get_section_contents (abfd, - section, - (PTR) data, 0, - bfd_section_size (abfd, section)); - - start = 0; - - stop = bfd_section_size (abfd, section); - - for (i = start; i < stop; i += onaline) - { - bfd_vma begin_addr; - bfd_vma end_addr; - bfd_vma eh_handler; - bfd_vma eh_data; - bfd_vma prolog_end_addr; - - if (i+20 > stop) - break; - - begin_addr = bfd_get_32(abfd, data+i); - end_addr = bfd_get_32(abfd, data+i+4); - eh_handler = bfd_get_32(abfd, data+i+8); - eh_data = bfd_get_32(abfd, data+i+12); - prolog_end_addr = bfd_get_32(abfd, data+i+16); - - if (begin_addr == 0 && end_addr == 0 && eh_handler == 0 - && eh_data == 0 && prolog_end_addr == 0) - { - /* We are probably into the padding of the - section now */ - break; - } - - fprintf (file, - " %08lx\t", - (unsigned long int) (i + section->vma)); - - fprintf(file, "%08lx %08lx %08lx %08lx %08lx", - begin_addr, - end_addr, - eh_handler, - eh_data, - prolog_end_addr); - -#ifdef POWERPC_LE_PE - if (eh_handler == 0 && eh_data != 0) - { - /* Special bits here, although the meaning may */ - /* be a little mysterious. The only one I know */ - /* for sure is 0x03. */ - /* Code Significance */ - /* 0x00 None */ - /* 0x01 Register Save Millicode */ - /* 0x02 Register Restore Millicode */ - /* 0x03 Glue Code Sequence */ - switch (eh_data) - { - case 0x01: - fprintf(file, " Register save millicode"); - break; - case 0x02: - fprintf(file, " Register restore millicode"); - break; - case 0x03: - fprintf(file, " Glue code sequence"); - break; - default: - break; - } - } -#endif - fprintf(file, "\n"); - } - - free (data); -} - -static const char *tbl[6] = -{ -"ABSOLUTE", -"HIGH", -"LOW", -"HIGHLOW", -"HIGHADJ", -"unknown" -}; - -static boolean -pe_print_reloc(abfd, vfile) - bfd*abfd; - void *vfile; -{ - FILE *file = vfile; - bfd_byte *data = 0; - asection *section = bfd_get_section_by_name (abfd, ".reloc"); - bfd_size_type datasize = 0; - bfd_size_type i; - bfd_size_type start, stop; - int onaline = 20; - bfd_vma addr_value; - - if (section == 0) - return true; - - if (bfd_section_size (abfd, section) == 0) - return true; - - fprintf(file, - "\n\nPE File Base Relocations (interpreted .reloc" - " section contents)\n"); - - data = (bfd_byte *) bfd_malloc ((size_t) bfd_section_size (abfd, section)); - datasize = bfd_section_size (abfd, section); - if (data == NULL && datasize != 0) - return false; - - bfd_get_section_contents (abfd, - section, - (PTR) data, 0, - bfd_section_size (abfd, section)); - - start = 0; - - stop = bfd_section_size (abfd, section); - - for (i = start; i < stop;) - { - int j; - bfd_vma virtual_address; - long number, size; - - /* The .reloc section is a sequence of blocks, with a header consisting - of two 32 bit quantities, followed by a number of 16 bit entries */ - - virtual_address = bfd_get_32(abfd, data+i); - size = bfd_get_32(abfd, data+i+4); - number = (size - 8) / 2; - - if (size == 0) - { - break; - } - - fprintf (file, - "\nVirtual Address: %08lx Chunk size %d (0x%x) " - "Number of fixups %d\n", - virtual_address, size, size, number); - - for (j = 0; j < number; ++j) - { - unsigned short e = bfd_get_16(abfd, data + i + 8 + j*2); - int t = (e & 0xF000) >> 12; - int off = e & 0x0FFF; - - if (t > 5) - abort(); - - fprintf(file, - "\treloc %4d offset %4x [%4x] %s\n", - j, off, off+virtual_address, tbl[t]); - - } - i += size; - } - - free (data); -} - -static boolean -pe_print_private_bfd_data (abfd, vfile) - bfd *abfd; - PTR vfile; -{ - FILE *file = (FILE *) vfile; - int j; - pe_data_type *pe = pe_data (abfd); - struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr; - - fprintf (file,"\nImageBase\t\t"); - fprintf_vma (file, i->ImageBase); - fprintf (file,"\nSectionAlignment\t"); - fprintf_vma (file, i->SectionAlignment); - fprintf (file,"\nFileAlignment\t\t"); - fprintf_vma (file, i->FileAlignment); - fprintf (file,"\nMajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion); - fprintf (file,"MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion); - fprintf (file,"MajorImageVersion\t%d\n", i->MajorImageVersion); - fprintf (file,"MinorImageVersion\t%d\n", i->MinorImageVersion); - fprintf (file,"MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion); - fprintf (file,"MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion); - fprintf (file,"Reserved1\t\t%08lx\n", i->Reserved1); - fprintf (file,"SizeOfImage\t\t%08lx\n", i->SizeOfImage); - fprintf (file,"SizeOfHeaders\t\t%08lx\n", i->SizeOfHeaders); - fprintf (file,"CheckSum\t\t%08lx\n", i->CheckSum); - fprintf (file,"Subsystem\t\t%08x\n", i->Subsystem); - fprintf (file,"DllCharacteristics\t%08x\n", i->DllCharacteristics); - fprintf (file,"SizeOfStackReserve\t"); - fprintf_vma (file, i->SizeOfStackReserve); - fprintf (file,"\nSizeOfStackCommit\t"); - fprintf_vma (file, i->SizeOfStackCommit); - fprintf (file,"\nSizeOfHeapReserve\t"); - fprintf_vma (file, i->SizeOfHeapReserve); - fprintf (file,"\nSizeOfHeapCommit\t"); - fprintf_vma (file, i->SizeOfHeapCommit); - fprintf (file,"\nLoaderFlags\t\t%08lx\n", i->LoaderFlags); - fprintf (file,"NumberOfRvaAndSizes\t%08lx\n", i->NumberOfRvaAndSizes); - - fprintf (file,"\nThe Data Directory\n"); - for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++) - { - fprintf (file, "Entry %1x ", j); - fprintf_vma (file, i->DataDirectory[j].VirtualAddress); - fprintf (file, " %08lx ", i->DataDirectory[j].Size); - fprintf (file, "%s\n", dir_names[j]); - } - - pe_print_idata(abfd, vfile); - pe_print_edata(abfd, vfile); - pe_print_pdata(abfd, vfile); - pe_print_reloc(abfd, vfile); - - return true; -} - -static boolean -pe_mkobject (abfd) - bfd * abfd; -{ - pe_data_type *pe; - abfd->tdata.pe_obj_data = - (struct pe_tdata *) bfd_zalloc (abfd, sizeof (pe_data_type)); - - if (abfd->tdata.pe_obj_data == 0) - return false; - - pe = pe_data (abfd); - - pe->coff.pe = 1; - pe->in_reloc_p = in_reloc_p; - return true; -} - -/* Create the COFF backend specific information. */ -static PTR -pe_mkobject_hook (abfd, filehdr, aouthdr) - bfd * abfd; - PTR filehdr; - PTR aouthdr; -{ - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; - pe_data_type *pe; - - if (pe_mkobject (abfd) == false) - return NULL; - - pe = pe_data (abfd); - pe->coff.sym_filepos = internal_f->f_symptr; - /* These members communicate important constants about the symbol - table to GDB's symbol-reading code. These `constants' - unfortunately vary among coff implementations... */ - pe->coff.local_n_btmask = N_BTMASK; - pe->coff.local_n_btshft = N_BTSHFT; - pe->coff.local_n_tmask = N_TMASK; - pe->coff.local_n_tshift = N_TSHIFT; - pe->coff.local_symesz = SYMESZ; - pe->coff.local_auxesz = AUXESZ; - pe->coff.local_linesz = LINESZ; - - obj_raw_syment_count (abfd) = - obj_conv_table_size (abfd) = - internal_f->f_nsyms; - - pe->real_flags = internal_f->f_flags; - -#ifdef COFF_IMAGE_WITH_PE - if (aouthdr) - { - pe->pe_opthdr = ((struct internal_aouthdr *)aouthdr)->pe; - } -#endif - - return (PTR) pe; -} - - - -/* Copy any private info we understand from the input bfd - to the output bfd. */ - -#define coff_bfd_copy_private_bfd_data pe_bfd_copy_private_bfd_data - -static boolean -pe_bfd_copy_private_bfd_data (ibfd, obfd) - bfd *ibfd, *obfd; -{ - /* One day we may try to grok other private data. */ - if (ibfd->xvec->flavour != bfd_target_coff_flavour - || obfd->xvec->flavour != bfd_target_coff_flavour) - return true; - - pe_data(obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr; - - return true; -} diff --git a/contrib/gdb/bfd/ptrace-core.c b/contrib/gdb/bfd/ptrace-core.c deleted file mode 100644 index e356457..0000000 --- a/contrib/gdb/bfd/ptrace-core.c +++ /dev/null @@ -1,233 +0,0 @@ -/* BFD backend for core files which use the ptrace_user structure - Copyright 1993, 1994 Free Software Foundation, Inc. - The structure of this file is based on trad-core.c written by John Gilmore - of Cygnus Support. - Modified to work with the ptrace_user structure by Kevin A. Buettner. - (Longterm it may be better to merge this file with trad-core.c) - -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. */ - -#ifdef PTRACE_CORE - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#include <stdio.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/dir.h> -#include <signal.h> -#include <errno.h> -#include <unistd.h> -#include <sys/ptrace.h> - - -struct trad_core_struct - { - asection *data_section; - asection *stack_section; - asection *reg_section; - struct ptrace_user u; - }; - -#define core_upage(bfd) (&((bfd)->tdata.trad_core_data->u)) -#define core_datasec(bfd) ((bfd)->tdata.trad_core_data->data_section) -#define core_stacksec(bfd) ((bfd)->tdata.trad_core_data->stack_section) -#define core_regsec(bfd) ((bfd)->tdata.trad_core_data->reg_section) - -/* forward declarations */ - -const bfd_target *ptrace_unix_core_file_p PARAMS ((bfd *abfd)); -char * ptrace_unix_core_file_failing_command PARAMS ((bfd *abfd)); -int ptrace_unix_core_file_failing_signal PARAMS ((bfd *abfd)); -boolean ptrace_unix_core_file_matches_executable_p - PARAMS ((bfd *core_bfd, bfd *exec_bfd)); - -/* ARGSUSED */ -const bfd_target * -ptrace_unix_core_file_p (abfd) - bfd *abfd; - -{ - int val; - struct ptrace_user u; - struct trad_core_struct *rawptr; - - val = bfd_read ((void *)&u, 1, sizeof u, abfd); - if (val != sizeof u || u.pt_magic != _BCS_PTRACE_MAGIC - || u.pt_rev != _BCS_PTRACE_REV) - { - /* Too small to be a core file */ - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - /* OK, we believe you. You're a core file (sure, sure). */ - - /* Allocate both the upage and the struct core_data at once, so - a single free() will free them both. */ - rawptr = (struct trad_core_struct *) - bfd_zalloc (abfd, sizeof (struct trad_core_struct)); - - if (rawptr == NULL) - return 0; - - abfd->tdata.trad_core_data = rawptr; - - rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */ - - /* Create the sections. This is raunchy, but bfd_close wants to free - them separately. */ - - core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_stacksec (abfd) == NULL) - return NULL; - core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_datasec (abfd) == NULL) - return NULL; - core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (core_regsec (abfd) == NULL) - return NULL; - - core_stacksec (abfd)->name = ".stack"; - core_datasec (abfd)->name = ".data"; - core_regsec (abfd)->name = ".reg"; - - /* FIXME: Need to worry about shared memory, library data, and library - text. I don't think that any of these things are supported on the - system on which I am developing this for though. */ - - - core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - core_regsec (abfd)->flags = SEC_HAS_CONTENTS; - - core_datasec (abfd)->_raw_size = u.pt_dsize; - core_stacksec (abfd)->_raw_size = u.pt_ssize; - core_regsec (abfd)->_raw_size = sizeof(u); - - core_datasec (abfd)->vma = u.pt_o_data_start; - core_stacksec (abfd)->vma = USRSTACK - u.pt_ssize; - core_regsec (abfd)->vma = 0 - sizeof(u); /* see trad-core.c */ - - core_datasec (abfd)->filepos = (int) u.pt_dataptr; - core_stacksec (abfd)->filepos = (int) (u.pt_dataptr + u.pt_dsize); - core_regsec (abfd)->filepos = 0; /* Register segment is ptrace_user */ - - /* Align to word at least */ - core_stacksec (abfd)->alignment_power = 2; - core_datasec (abfd)->alignment_power = 2; - core_regsec (abfd)->alignment_power = 2; - - abfd->sections = core_stacksec (abfd); - core_stacksec (abfd)->next = core_datasec (abfd); - core_datasec (abfd)->next = core_regsec (abfd); - abfd->section_count = 3; - - return abfd->xvec; -} - -char * -ptrace_unix_core_file_failing_command (abfd) - bfd *abfd; -{ - char *com = abfd->tdata.trad_core_data->u.pt_comm; - if (*com) - return com; - else - return 0; -} - -/* ARGSUSED */ -int -ptrace_unix_core_file_failing_signal (abfd) - bfd *abfd; -{ - return abfd->tdata.trad_core_data->u.pt_sigframe.sig_num; -} - -/* ARGSUSED */ -boolean -ptrace_unix_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - /* FIXME: Use pt_timdat field of the ptrace_user structure to match - the date of the executable */ - return true; -} - -/* If somebody calls any byte-swapping routines, shoot them. */ -void -swap_abort() -{ - abort(); /* This way doesn't require any declaration for ANSI to fuck up */ -} -#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort ) -#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort ) -#define NO_SIGNED_GET \ - ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort ) - -const bfd_target ptrace_core_vec = - { - "trad-core", - bfd_target_unknown_flavour, - BFD_ENDIAN_UNKNOWN, /* target byte order */ - BFD_ENDIAN_UNKNOWN, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* symbol prefix */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */ - - { /* bfd_check_format */ - _bfd_dummy_target, /* unknown format */ - _bfd_dummy_target, /* object file */ - _bfd_dummy_target, /* archive */ - ptrace_unix_core_file_p /* a core file */ - }, - { /* bfd_set_format */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - { /* bfd_write_contents */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (ptrace_unix), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (_bfd_generic), - BFD_JUMP_TABLE_LINK (_bfd_nolink), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 /* backend_data */ -}; - -#endif /* PTRACE_CORE */ diff --git a/contrib/gdb/bfd/reloc16.c b/contrib/gdb/bfd/reloc16.c deleted file mode 100644 index e88d50f..0000000 --- a/contrib/gdb/bfd/reloc16.c +++ /dev/null @@ -1,289 +0,0 @@ -/* 8 and 16 bit COFF relocation functions, for BFD. - Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - -/* -Most of this hacked by Steve Chamberlain, - sac@cygnus.com -*/ - -/* These routines are used by coff-h8300 and coff-z8k to do - relocation. - - FIXME: This code should be rewritten to support the new COFF - linker. Basically, they need to deal with COFF relocs rather than - BFD generic relocs. They should store the relocs in some location - where coff_link_input_bfd can find them (and coff_link_input_bfd - should be changed to use this location rather than rereading the - file) (unless info->keep_memory is false, in which case they should - free up the relocs after dealing with them). */ - -#include "bfd.h" -#include "sysdep.h" -#include "obstack.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "genlink.h" -#include "coff/internal.h" -#include "libcoff.h" - -bfd_vma -bfd_coff_reloc16_get_value (reloc, link_info, input_section) - arelent *reloc; - struct bfd_link_info *link_info; - asection *input_section; -{ - bfd_vma value; - asymbol *symbol = *(reloc->sym_ptr_ptr); - /* A symbol holds a pointer to a section, and an offset from the - base of the section. To relocate, we find where the section will - live in the output and add that in */ - - if (bfd_is_und_section (symbol->section)) - { - struct bfd_link_hash_entry *h; - - /* The symbol is undefined in this BFD. Look it up in the - global linker hash table. FIXME: This should be changed when - we convert this stuff to use a specific final_link function - and change the interface to bfd_relax_section to not require - the generic symbols. */ - h = bfd_wrapped_link_hash_lookup (input_section->owner, link_info, - bfd_asymbol_name (symbol), - false, false, true); - if (h != (struct bfd_link_hash_entry *) NULL - && (h->type == bfd_link_hash_defined - || h->type == bfd_link_hash_defweak)) - value = (h->u.def.value - + h->u.def.section->output_section->vma - + h->u.def.section->output_offset); - else if (h != (struct bfd_link_hash_entry *) NULL - && h->type == bfd_link_hash_common) - value = h->u.c.size; - else - { - if (! ((*link_info->callbacks->undefined_symbol) - (link_info, bfd_asymbol_name (symbol), - input_section->owner, input_section, reloc->address))) - abort (); - value = 0; - } - } - else - { - value = symbol->value + - symbol->section->output_offset + - symbol->section->output_section->vma; - } - - /* Add the value contained in the relocation */ - value += reloc->addend; - - return value; -} - -void -bfd_perform_slip(abfd, slip, input_section, value) - bfd *abfd; - unsigned int slip; - asection *input_section; - bfd_vma value; -{ - asymbol **s; - - s = _bfd_generic_link_get_symbols (abfd); - BFD_ASSERT (s != (asymbol **) NULL); - - /* Find all symbols past this point, and make them know - what's happened */ - while (*s) - { - asymbol *p = *s; - if (p->section == input_section) - { - /* This was pointing into this section, so mangle it */ - if (p->value > value) - { - p->value -= slip; - if (p->udata.p != NULL) - { - struct generic_link_hash_entry *h; - - h = (struct generic_link_hash_entry *) p->udata.p; - BFD_ASSERT (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak); - h->root.u.def.value -= slip; - BFD_ASSERT (h->root.u.def.value == p->value); - } - } - } - s++; - } -} - -boolean -bfd_coff_reloc16_relax_section (abfd, i, link_info, again) - bfd *abfd; - asection *i; - struct bfd_link_info *link_info; - boolean *again; -{ - /* Get enough memory to hold the stuff */ - bfd *input_bfd = i->owner; - asection *input_section = i; - int shrink = 0 ; - long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); - arelent **reloc_vector = NULL; - long reloc_count; - - /* We only run this relaxation once. It might work to run it more - often, but it hasn't been tested. */ - *again = false; - - if (reloc_size < 0) - return false; - - reloc_vector = (arelent **) bfd_malloc (reloc_size); - if (!reloc_vector && reloc_size > 0) - return false; - - /* Get the relocs and think about them */ - reloc_count = - bfd_canonicalize_reloc (input_bfd, input_section, reloc_vector, - _bfd_generic_link_get_symbols (input_bfd)); - if (reloc_count < 0) - { - free (reloc_vector); - return false; - } - - if (reloc_count > 0) - { - arelent **parent; - for (parent = reloc_vector; *parent; parent++) - { - shrink = bfd_coff_reloc16_estimate (abfd, input_section, - *parent, shrink, link_info); - } - } - - input_section->_cooked_size -= shrink; - free((char *)reloc_vector); - return true; -} - -bfd_byte * -bfd_coff_reloc16_get_relocated_section_contents(in_abfd, - link_info, - link_order, - data, - relocateable, - symbols) - bfd *in_abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - bfd_byte *data; - boolean relocateable; - asymbol **symbols; -{ - /* Get enough memory to hold the stuff */ - bfd *input_bfd = link_order->u.indirect.section->owner; - asection *input_section = link_order->u.indirect.section; - long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); - arelent **reloc_vector; - long reloc_count; - - if (reloc_size < 0) - return NULL; - - /* If producing relocateable output, don't bother to relax. */ - if (relocateable) - return bfd_generic_get_relocated_section_contents (in_abfd, link_info, - link_order, - data, relocateable, - symbols); - - /* read in the section */ - if (! bfd_get_section_contents(input_bfd, - input_section, - data, - 0, - input_section->_raw_size)) - return NULL; - - - reloc_vector = (arelent **) bfd_malloc((size_t) reloc_size); - if (!reloc_vector && reloc_size != 0) - return NULL; - - reloc_count = bfd_canonicalize_reloc (input_bfd, - input_section, - reloc_vector, - symbols); - if (reloc_count < 0) - { - free (reloc_vector); - return NULL; - } - - if (reloc_count > 0) - { - arelent **parent = reloc_vector; - arelent *reloc ; - unsigned int dst_address = 0; - unsigned int src_address = 0; - unsigned int run; - unsigned int idx; - - /* Find how long a run we can do */ - while (dst_address < link_order->size) - { - reloc = *parent; - if (reloc) - { - /* Note that the relaxing didn't tie up the addresses in the - relocation, so we use the original address to work out the - run of non-relocated data */ - run = reloc->address - src_address; - parent++; - } - else - { - run = link_order->size - dst_address; - } - /* Copy the bytes */ - for (idx = 0; idx < run; idx++) - { - data[dst_address++] = data[src_address++]; - } - - /* Now do the relocation */ - - if (reloc) - { - bfd_coff_reloc16_extra_cases (input_bfd, link_info, link_order, - reloc, data, &src_address, - &dst_address); - } - } - } - free((char *)reloc_vector); - return data; -} - diff --git a/contrib/gdb/bfd/riscix.c b/contrib/gdb/bfd/riscix.c deleted file mode 100644 index 21a86d5..0000000 --- a/contrib/gdb/bfd/riscix.c +++ /dev/null @@ -1,644 +0,0 @@ -/* BFD back-end for RISC iX (Acorn, arm) binaries. - Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. - Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org) - -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. */ - - -/* RISC iX overloads the MAGIC field to indicate more than just the usual - [ZNO]MAGIC values. Also included are squeezing information and - shared library usage. */ - -/* The following come from the man page. */ -#define SHLIBLEN 60 - -#define MF_IMPURE 00200 -#define MF_SQUEEZED 01000 -#define MF_USES_SL 02000 -#define MF_IS_SL 04000 - -/* Common combinations. */ -#define IMAGIC (MF_IMPURE|ZMAGIC) /* Demand load (impure text) */ -#define SPOMAGIC (MF_USES_SL|OMAGIC) /* OMAGIC with large header */ - /* -- may contain a ref to a */ - /* shared lib required by the */ - /* object. */ -#define SLOMAGIC (MF_IS_SL|OMAGIC) /* A reference to a shared library */ - /* The text portion of the object */ - /* contains "overflow text" from */ - /* the shared library to be linked */ - /* in with an object */ -#define QMAGIC (MF_SQUEEZED|ZMAGIC) /* Sqeezed demand paged. */ - /* NOTE: This interpretation of */ - /* QMAGIC seems to be at variance */ - /* With that used on other */ - /* architectures. */ -#define SPZMAGIC (MF_USES_SL|ZMAGIC) /* program which uses sl */ -#define SPQMAGIC (MF_USES_SL|QMAGIC) /* sqeezed ditto */ -#define SLZMAGIC (MF_IS_SL|ZMAGIC) /* shared lib part of prog */ -#define SLPZMAGIC (MF_USES_SL|SLZMAGIC) /* sl which uses another */ - -#define N_SHARED_LIB(x) ((x).a_info & MF_USES_SL) - -/* Only a pure OMAGIC file has the minimal header */ -#define N_TXTOFF(x) \ - ((x).a_info == OMAGIC ? 32 \ - : (N_MAGIC(x) == ZMAGIC) ? TARGET_PAGE_SIZE \ - : 999) - -#define N_TXTADDR(x) \ - (N_MAGIC(x) != ZMAGIC ? 0 /* object file or NMAGIC */ \ - /* Programs with shared libs are loaded at the first page after all the \ - text segments of the shared library programs. Without looking this \ - up we can't know exactly what the address will be. A reasonable guess \ - is that a_entry will be in the first page of the executable. */ \ - : N_SHARED_LIB(x) ? ((x).a_entry & ~(TARGET_PAGE_SIZE - 1)) \ - : TEXT_START_ADDR) - -#define N_SYMOFF(x) \ - (N_TXTOFF (x) + (x).a_text + (x).a_data + (x).a_trsize + (x).a_drsize) - -#define N_STROFF(x) (N_SYMOFF (x) + (x).a_syms) - -#define TEXT_START_ADDR 32768 -#define TARGET_PAGE_SIZE 32768 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define DEFAULT_ARCH bfd_arch_arm - -#define MY(OP) CAT(riscix_,OP) -#define TARGETNAME "a.out-riscix" -#define N_BADMAG(x) ((((x).a_info & ~007200) != ZMAGIC) && \ - (((x).a_info & ~006000) != OMAGIC) && \ - ((x).a_info != NMAGIC)) -#define N_MAGIC(x) ((x).a_info & ~07200) - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "assert.h" - -#define WRITE_HEADERS(abfd, execp) \ - { \ - bfd_size_type text_size; /* dummy vars */ \ - file_ptr text_end; \ - if (adata(abfd).magic == undecided_magic) \ - NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \ - \ - execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \ - execp->a_entry = bfd_get_start_address (abfd); \ - \ - execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * \ - obj_reloc_entry_size (abfd)); \ - execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * \ - obj_reloc_entry_size (abfd)); \ - NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \ - \ - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) return false; \ - if (bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) \ - != EXEC_BYTES_SIZE) \ - return false; \ - /* Now write out reloc info, followed by syms and strings */ \ - \ - if (bfd_get_outsymbols (abfd) != (asymbol **) NULL \ - && bfd_get_symcount (abfd) != 0) \ - { \ - if (bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET) != 0) \ - return false; \ - \ - if (! NAME(aout,write_syms)(abfd)) return false; \ - \ - if (bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET) != 0) \ - return false; \ - \ - if (! riscix_squirt_out_relocs (abfd, obj_textsec (abfd))) \ - return false; \ - if (bfd_seek (abfd, (file_ptr)(N_DRELOFF(*execp)), SEEK_SET) != 0) \ - return false; \ - \ - if (!NAME(aout,squirt_out_relocs)(abfd, obj_datasec (abfd))) \ - return false; \ - } \ - } - -#include "libaout.h" -#include "aout/aout64.h" - -static bfd_reloc_status_type -riscix_fix_pcrel_26_done PARAMS ((bfd *, arelent *, asymbol *, PTR, - asection *, bfd *, char **)); - -static bfd_reloc_status_type -riscix_fix_pcrel_26 PARAMS ((bfd *, arelent *, asymbol *, PTR, - asection *, bfd *, char **)); - -static reloc_howto_type riscix_std_reloc_howto[] = { - /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */ - HOWTO( 0, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", true, 0x000000ff,0x000000ff, false), - HOWTO( 1, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", true, 0x0000ffff,0x0000ffff, false), - HOWTO( 2, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", true, 0xffffffff,0xffffffff, false), - HOWTO( 3, 2, 3, 26, true, 0, complain_overflow_signed, riscix_fix_pcrel_26 , "ARM26", true, 0x00ffffff,0x00ffffff, false), - HOWTO( 4, 0, 0, 8, true, 0, complain_overflow_signed, 0,"DISP8", true, 0x000000ff,0x000000ff, true), - HOWTO( 5, 0, 1, 16, true, 0, complain_overflow_signed, 0,"DISP16", true, 0x0000ffff,0x0000ffff, true), - HOWTO( 6, 0, 2, 32, true, 0, complain_overflow_signed, 0,"DISP32", true, 0xffffffff,0xffffffff, true), - HOWTO( 7, 2, 3, 26, false, 0, complain_overflow_signed, riscix_fix_pcrel_26_done, "ARM26D",true,0x00ffffff,0x00ffffff, false), - {-1}, - HOWTO( 9, 0, -1, 16, false, 0, complain_overflow_bitfield,0,"NEG16", true, 0x0000ffff,0x0000ffff, false), - HOWTO( 10, 0, -2, 32, false, 0, complain_overflow_bitfield,0,"NEG32", true, 0xffffffff,0xffffffff, false) -}; - -#define RISCIX_TABLE_SIZE \ - (sizeof (riscix_std_reloc_howto) / sizeof (reloc_howto_type)) - - -static bfd_reloc_status_type -riscix_fix_pcrel_26_done (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - /* This is dead simple at present. */ - return bfd_reloc_ok; -} - -static bfd_reloc_status_type -riscix_fix_pcrel_26 (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_vma relocation; - bfd_size_type addr = reloc_entry->address; - long target = bfd_get_32 (abfd, (bfd_byte *) data + addr); - bfd_reloc_status_type flag = bfd_reloc_ok; - - /* If this is an undefined symbol, return error */ - if (symbol->section == &bfd_und_section - && (symbol->flags & BSF_WEAK) == 0) - return output_bfd ? bfd_reloc_continue : bfd_reloc_undefined; - - /* If the sections are different, and we are doing a partial relocation, - just ignore it for now. */ - if (symbol->section->name != input_section->name - && output_bfd != (bfd *)NULL) - return bfd_reloc_continue; - - relocation = (target & 0x00ffffff) << 2; - relocation = (relocation ^ 0x02000000) - 0x02000000; /* Sign extend */ - relocation += symbol->value; - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; - relocation -= input_section->output_section->vma; - relocation -= input_section->output_offset; - relocation -= addr; - if (relocation & 3) - return bfd_reloc_overflow; - - /* Check for overflow */ - if (relocation & 0x02000000) - { - if ((relocation & ~0x03ffffff) != ~0x03ffffff) - flag = bfd_reloc_overflow; - } - else if (relocation & ~0x03ffffff) - flag = bfd_reloc_overflow; - - target &= ~0x00ffffff; - target |= (relocation >> 2) & 0x00ffffff; - bfd_put_32 (abfd, target, (bfd_byte *) data + addr); - - /* Now the ARM magic... Change the reloc type so that it is marked as done. - Strictly this is only necessary if we are doing a partial relocation. */ - reloc_entry->howto = &riscix_std_reloc_howto[7]; - - return flag; -} - -reloc_howto_type * -DEFUN(riscix_reloc_type_lookup,(abfd,code), - bfd *abfd AND - bfd_reloc_code_real_type code) -{ -#define ASTD(i,j) case i: return &riscix_std_reloc_howto[j] - if (code == BFD_RELOC_CTOR) - switch (bfd_get_arch_info (abfd)->bits_per_address) - { - case 32: - code = BFD_RELOC_32; - break; - default: return (reloc_howto_type *) NULL; - } - - switch (code) - { - ASTD (BFD_RELOC_16, 1); - ASTD (BFD_RELOC_32, 2); - ASTD (BFD_RELOC_ARM_PCREL_BRANCH, 3); - ASTD (BFD_RELOC_8_PCREL, 4); - ASTD (BFD_RELOC_16_PCREL, 5); - ASTD (BFD_RELOC_32_PCREL, 6); - default: return (reloc_howto_type *) NULL; - } -} - -#define MY_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define MY_bfd_final_link _bfd_generic_final_link - -#define MY_bfd_reloc_type_lookup riscix_reloc_type_lookup -#define MY_canonicalize_reloc riscix_canonicalize_reloc -#define MY_object_p riscix_object_p - -static const bfd_target *riscix_callback PARAMS ((bfd *)); - -void -riscix_swap_std_reloc_out (abfd, g, natptr) - bfd *abfd; - arelent *g; - struct reloc_std_external *natptr; -{ - int r_index; - asymbol *sym = *(g->sym_ptr_ptr); - int r_extern; - int r_length; - int r_pcrel; - int r_neg = 0; /* Negative relocs use the BASEREL bit. */ - asection *output_section = sym->section->output_section; - - PUT_WORD(abfd, g->address, natptr->r_address); - - r_length = g->howto->size ; /* Size as a power of two */ - if (r_length < 0) - { - r_length = -r_length; - r_neg = 1; - } - - r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */ - - /* For RISC iX, in pc-relative relocs the r_pcrel bit means that the - relocation has been done already (Only for the 26-bit one I think)???!!! - */ - - if (r_length == 3) - r_pcrel = r_pcrel ? 0 : 1; - - -#if 0 - /* For a standard reloc, the addend is in the object file. */ - r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; -#endif - - /* name was clobbered by aout_write_syms to be symbol index */ - - /* If this relocation is relative to a symbol then set the - r_index to the symbols index, and the r_extern bit. - - Absolute symbols can come in in two ways, either as an offset - from the abs section, or as a symbol which has an abs value. - check for that here - */ - - if (bfd_is_com_section (output_section) - || output_section == &bfd_abs_section - || output_section == &bfd_und_section) - { - if (bfd_abs_section.symbol == sym) - { - /* Whoops, looked like an abs symbol, but is really an offset - from the abs section */ - r_index = 0; - r_extern = 0; - } - else - { - /* Fill in symbol */ - r_extern = 1; - r_index = stoi((*(g->sym_ptr_ptr))->flags); - } - } - else - { - /* Just an ordinary section */ - r_extern = 0; - r_index = output_section->target_index; - } - - /* now the fun stuff */ - if (bfd_header_big_endian (abfd)) - { - natptr->r_index[0] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[2] = r_index; - natptr->r_type[0] = - ( (r_extern ? RELOC_STD_BITS_EXTERN_BIG: 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG: 0) - | (r_neg ? RELOC_STD_BITS_BASEREL_BIG: 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG)); - } - else - { - natptr->r_index[2] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[0] = r_index; - natptr->r_type[0] = - ( (r_extern ? RELOC_STD_BITS_EXTERN_LITTLE: 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE: 0) - | (r_neg ? RELOC_STD_BITS_BASEREL_LITTLE: 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE)); - } -} - -boolean -riscix_squirt_out_relocs (abfd, section) - bfd *abfd; - asection *section; -{ - arelent **generic; - unsigned char *native, *natptr; - size_t each_size; - - unsigned int count = section->reloc_count; - size_t natsize; - - if (count == 0) return true; - - each_size = obj_reloc_entry_size (abfd); - natsize = each_size * count; - native = (unsigned char *) bfd_zalloc (abfd, natsize); - if (!native) - return false; - - generic = section->orelocation; - - for (natptr = native; - count != 0; - --count, natptr += each_size, ++generic) - riscix_swap_std_reloc_out (abfd, *generic, - (struct reloc_std_external *) natptr); - - if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) - { - bfd_release(abfd, native); - return false; - } - - bfd_release (abfd, native); - return true; -} - - -/* - * This is just like the standard aoutx.h version but we need to do our - * own mapping of external reloc type values to howto entries. - */ -long -MY(canonicalize_reloc)(abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - arelent *tblptr = section->relocation; - unsigned int count, c; - extern reloc_howto_type NAME(aout,std_howto_table)[]; - - /* If we have already read in the relocation table, return the values. */ - if (section->flags & SEC_CONSTRUCTOR) { - arelent_chain *chain = section->constructor_chain; - - for (count = 0; count < section->reloc_count; count++) { - *relptr++ = &chain->relent; - chain = chain->next; - } - *relptr = 0; - return section->reloc_count; - } - if (tblptr && section->reloc_count) { - for (count = 0; count++ < section->reloc_count;) - *relptr++ = tblptr++; - *relptr = 0; - return section->reloc_count; - } - - if (!NAME(aout,slurp_reloc_table)(abfd, section, symbols)) - return -1; - tblptr = section->relocation; - - /* fix up howto entries */ - for (count = 0; count++ < section->reloc_count;) - { - c = tblptr->howto - NAME(aout,std_howto_table); - assert (c < RISCIX_TABLE_SIZE); - tblptr->howto = &riscix_std_reloc_howto[c]; - - *relptr++ = tblptr++; - } - *relptr = 0; - return section->reloc_count; -} - -/* This is the same as NAME(aout,some_aout_object_p), but has different - expansions of the macro definitions. */ - -const bfd_target * -riscix_some_aout_object_p (abfd, execp, callback_to_real_object_p) - bfd *abfd; - struct internal_exec *execp; - const bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *)); -{ - struct aout_data_struct *rawptr, *oldrawptr; - const bfd_target *result; - - rawptr = ((struct aout_data_struct *) - bfd_zalloc (abfd, sizeof (struct aout_data_struct ))); - - if (rawptr == NULL) - return 0; - - oldrawptr = abfd->tdata.aout_data; - abfd->tdata.aout_data = rawptr; - - /* Copy the contents of the old tdata struct. - In particular, we want the subformat, since for hpux it was set in - hp300hpux.c:swap_exec_header_in and will be used in - hp300hpux.c:callback. */ - if (oldrawptr != NULL) - *abfd->tdata.aout_data = *oldrawptr; - - abfd->tdata.aout_data->a.hdr = &rawptr->e; - *(abfd->tdata.aout_data->a.hdr) = *execp; /* Copy in the internal_exec - struct */ - execp = abfd->tdata.aout_data->a.hdr; - - /* Set the file flags */ - abfd->flags = NO_FLAGS; - if (execp->a_drsize || execp->a_trsize) - abfd->flags |= HAS_RELOC; - /* Setting of EXEC_P has been deferred to the bottom of this function */ - if (execp->a_syms) - abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS; - if (N_DYNAMIC(*execp)) - abfd->flags |= DYNAMIC; - - - if ((execp->a_info & MF_SQUEEZED) != 0) /* Squeezed files aren't supported - (yet)! */ - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - else if ((execp->a_info & MF_IS_SL) != 0) /* Nor are shared libraries */ - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - else if (N_MAGIC (*execp) == ZMAGIC) - { - abfd->flags |= D_PAGED | WP_TEXT; - adata (abfd).magic = z_magic; - } - else if (N_MAGIC (*execp) == NMAGIC) - { - abfd->flags |= WP_TEXT; - adata (abfd).magic = n_magic; - } - else if (N_MAGIC (*execp) == OMAGIC) - adata (abfd).magic = o_magic; - else - { - /* Should have been checked with N_BADMAG before this routine - was called. */ - abort (); - } - - bfd_get_start_address (abfd) = execp->a_entry; - - obj_aout_symbols (abfd) = (aout_symbol_type *)NULL; - bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist); - - /* The default relocation entry size is that of traditional V7 Unix. */ - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - - /* The default symbol entry size is that of traditional Unix. */ - obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE; - - obj_aout_external_syms (abfd) = NULL; - obj_aout_external_strings (abfd) = NULL; - obj_aout_sym_hashes (abfd) = NULL; - - if (! NAME(aout,make_sections) (abfd)) - return NULL; - - obj_datasec (abfd)->_raw_size = execp->a_data; - obj_bsssec (abfd)->_raw_size = execp->a_bss; - - obj_textsec (abfd)->flags = - (execp->a_trsize != 0 - ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC) - : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS)); - obj_datasec (abfd)->flags = - (execp->a_drsize != 0 - ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC) - : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS)); - obj_bsssec (abfd)->flags = SEC_ALLOC; - - result = (*callback_to_real_object_p)(abfd); - -#if defined(MACH) || defined(STAT_FOR_EXEC) - /* The original heuristic doesn't work in some important cases. The - * a.out file has no information about the text start address. For - * files (like kernels) linked to non-standard addresses (ld -Ttext - * nnn) the entry point may not be between the default text start - * (obj_textsec(abfd)->vma) and (obj_textsec(abfd)->vma) + text size - * This is not just a mach issue. Many kernels are loaded at non - * standard addresses. - */ - { - struct stat stat_buf; - if (abfd->iostream != NULL - && (abfd->flags & BFD_IN_MEMORY) == 0 - && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0) - && ((stat_buf.st_mode & 0111) != 0)) - abfd->flags |= EXEC_P; - } -#else /* ! MACH */ - /* Now that the segment addresses have been worked out, take a better - guess at whether the file is executable. If the entry point - is within the text segment, assume it is. (This makes files - executable even if their entry point address is 0, as long as - their text starts at zero.) - - At some point we should probably break down and stat the file and - declare it executable if (one of) its 'x' bits are on... */ - if ((execp->a_entry >= obj_textsec(abfd)->vma) && - (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size)) - abfd->flags |= EXEC_P; -#endif /* MACH */ - if (result) - { - } - else - { - free (rawptr); - abfd->tdata.aout_data = oldrawptr; - } - return result; -} - - -static const bfd_target * -MY(object_p) (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; /* Raw exec header from file */ - struct internal_exec exec; /* Cleaned-up exec header */ - const bfd_target *target; - - if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) - != EXEC_BYTES_SIZE) { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - exec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info); - - if (N_BADMAG (exec)) return 0; -#ifdef MACHTYPE_OK - if (!(MACHTYPE_OK (N_MACHTYPE (exec)))) return 0; -#endif - - NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, &exec); - - target = riscix_some_aout_object_p (abfd, &exec, MY(callback)); - - return target; -} - - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/rs6000-core.c b/contrib/gdb/bfd/rs6000-core.c deleted file mode 100644 index 4889f72..0000000 --- a/contrib/gdb/bfd/rs6000-core.c +++ /dev/null @@ -1,396 +0,0 @@ -/* IBM RS/6000 "XCOFF" back-end for BFD. - Copyright (C) 1990, 1991, 1995 Free Software Foundation, Inc. - FIXME: Can someone provide a transliteration of this name into ASCII? - Using the following chars caused a compiler warning on HIUX (so I replaced - them with octal escapes), and isn't useful without an understanding of what - character set it is. - Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365, - and John Gilmore. - Archive support from Damon A. Permezel. - Contributed by IBM Corporation and Cygnus Support. - -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 port currently only handles reading object files, except when - compiled on an RS/6000 host. -- no archive support, no core files. - In all cases, it does not support writing. - - FIXMEmgo comments are left from Metin Ozisik's original port. - - This is in a separate file from coff-rs6000.c, because it includes - system include files that conflict with coff/rs6000.h. - */ - -/* Internalcoff.h and coffcode.h modify themselves based on this flag. */ -#define RS6000COFF_C 1 - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#ifdef AIX_CORE - -/* AOUTHDR is defined by the above. We need another defn of it, from the - system include files. Punt the old one and get us a new name for the - typedef in the system include files. */ -#ifdef AOUTHDR -#undef AOUTHDR -#endif -#define AOUTHDR second_AOUTHDR - -#undef SCNHDR - - -/* ------------------------------------------------------------------------ */ -/* Support for core file stuff.. */ -/* ------------------------------------------------------------------------ */ - -#include <sys/user.h> -#include <sys/ldr.h> -#include <sys/core.h> - - -/* Number of special purpose registers supported by gdb. This value - should match `tm.h' in gdb directory. Clean this mess up and use - the macros in sys/reg.h. FIXMEmgo. */ - -#define NUM_OF_SPEC_REGS 7 - -#define core_hdr(bfd) (((Rs6kCorData*)(bfd->tdata.any))->hdr) -#define core_datasec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->data_section) -#define core_stacksec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->stack_section) -#define core_regsec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->reg_section) -#define core_reg2sec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->reg2_section) - -/* AIX 4.1 Changed the names and locations of a few items in the core file, - this seems to be the quickest easiet way to deal with it. - - Note however that encoding magic addresses (STACK_END_ADDR) is going - to be _very_ fragile. But I don't see any easy way to get that info - right now. */ -#ifdef CORE_VERSION_1 -#define CORE_DATA_SIZE_FIELD c_u.U_dsize -#define CORE_COMM_FIELD c_u.U_comm -#define SAVE_FIELD c_mst -#define STACK_END_ADDR 0x2ff23000 -#else -#define CORE_DATA_SIZE_FIELD c_u.u_dsize -#define CORE_COMM_FIELD c_u.u_comm -#define SAVE_FIELD c_u.u_save -#define STACK_END_ADDR 0x2ff80000 -#endif - -/* These are stored in the bfd's tdata */ -typedef struct { - struct core_dump hdr; /* core file header */ - asection *data_section, - *stack_section, - *reg_section, /* section for GPRs and special registers. */ - *reg2_section; /* section for FPRs. */ - - /* This tells us where everything is mapped (shared libraries and so on). - GDB needs it. */ - asection *ldinfo_section; -#define core_ldinfosec(bfd) (((Rs6kCorData *)(bfd->tdata.any))->ldinfo_section) -} Rs6kCorData; - - -/* Decide if a given bfd represents a `core' file or not. There really is no - magic number or anything like, in rs6000coff. */ - -const bfd_target * -rs6000coff_core_p (abfd) - bfd *abfd; -{ - int fd; - struct core_dump coredata; - struct stat statbuf; - char *tmpptr; - - /* Use bfd_xxx routines, rather than O/S primitives to read coredata. FIXMEmgo */ - fd = open (abfd->filename, O_RDONLY); - if (fd < 0) - { - bfd_set_error (bfd_error_system_call); - return NULL; - } - - if (fstat (fd, &statbuf) < 0) - { - bfd_set_error (bfd_error_system_call); - close (fd); - return NULL; - } - if (read (fd, &coredata, sizeof (struct core_dump)) - != sizeof (struct core_dump)) - { - bfd_set_error (bfd_error_wrong_format); - close (fd); - return NULL; - } - - if (close (fd) < 0) - { - bfd_set_error (bfd_error_system_call); - return NULL; - } - - /* If the core file ulimit is too small, the system will first - omit the data segment, then omit the stack, then decline to - dump core altogether (as far as I know UBLOCK_VALID and LE_VALID - are always set) (this is based on experimentation on AIX 3.2). - Now, the thing is that GDB users will be surprised - if segments just silently don't appear (well, maybe they would - think to check "info files", I don't know), but we have no way of - returning warnings (as opposed to errors). - - For the data segment, we have no choice but to keep going if it's - not there, since the default behavior is not to dump it (regardless - of the ulimit, it's based on SA_FULLDUMP). But for the stack segment, - if it's not there, we refuse to have anything to do with this core - file. The usefulness of a core dump without a stack segment is pretty - limited anyway. */ - - if (!(coredata.c_flag & UBLOCK_VALID) - || !(coredata.c_flag & LE_VALID)) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - if ((coredata.c_flag & CORE_TRUNC) - || !(coredata.c_flag & USTACK_VALID)) - { - bfd_set_error (bfd_error_file_truncated); - return NULL; - } - - /* Don't check the core file size for a full core, AIX 4.1 includes - additional shared library sections in a full core. */ - if (!(coredata.c_flag & FULL_CORE) - && ((bfd_vma)coredata.c_stack + coredata.c_size) != statbuf.st_size) - { - /* If the size is wrong, it means we're misinterpreting something. */ - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* Sanity check on the c_tab field. */ - if ((u_long) coredata.c_tab < sizeof coredata || - (u_long) coredata.c_tab >= statbuf.st_size || - (long) coredata.c_tab >= (long)coredata.c_stack) - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* maybe you should alloc space for the whole core chunk over here!! FIXMEmgo */ - tmpptr = (char*)bfd_zalloc (abfd, sizeof (Rs6kCorData)); - if (!tmpptr) - return NULL; - - set_tdata (abfd, tmpptr); - - /* Copy core file header. */ - core_hdr (abfd) = coredata; - - /* .stack section. */ - if ((core_stacksec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection))) - == NULL) - return NULL; - core_stacksec (abfd)->name = ".stack"; - core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - core_stacksec (abfd)->_raw_size = coredata.c_size; - core_stacksec (abfd)->vma = STACK_END_ADDR - coredata.c_size; - core_stacksec (abfd)->filepos = (int)coredata.c_stack; /*???? */ - - /* .reg section for GPRs and special registers. */ - if ((core_regsec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection))) - == NULL) - return NULL; - core_regsec (abfd)->name = ".reg"; - core_regsec (abfd)->flags = SEC_HAS_CONTENTS; - core_regsec (abfd)->_raw_size = (32 + NUM_OF_SPEC_REGS) * 4; - core_regsec (abfd)->vma = 0; /* not used?? */ - core_regsec (abfd)->filepos = - (char*)&coredata.SAVE_FIELD - (char*)&coredata; - - /* .reg2 section for FPRs (floating point registers). */ - if ((core_reg2sec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection))) - == NULL) - return NULL; - core_reg2sec (abfd)->name = ".reg2"; - core_reg2sec (abfd)->flags = SEC_HAS_CONTENTS; - core_reg2sec (abfd)->_raw_size = 8 * 32; /* 32 FPRs. */ - core_reg2sec (abfd)->vma = 0; /* not used?? */ - core_reg2sec (abfd)->filepos = - (char*)&coredata.SAVE_FIELD.fpr[0] - (char*)&coredata; - - if ((core_ldinfosec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection))) - == NULL) - return NULL; - core_ldinfosec (abfd)->name = ".ldinfo"; - core_ldinfosec (abfd)->flags = SEC_HAS_CONTENTS; - /* To actually find out how long this section is in this particular - core dump would require going down the whole list of struct ld_info's. - See if we can just fake it. */ - core_ldinfosec (abfd)->_raw_size = 0x7fffffff; - /* Not relevant for ldinfo section. */ - core_ldinfosec (abfd)->vma = 0; - core_ldinfosec (abfd)->filepos = (file_ptr) coredata.c_tab; - - /* set up section chain here. */ - abfd->section_count = 4; - abfd->sections = core_stacksec (abfd); - core_stacksec (abfd)->next = core_regsec(abfd); - core_regsec (abfd)->next = core_reg2sec (abfd); - core_reg2sec (abfd)->next = core_ldinfosec (abfd); - core_ldinfosec (abfd)->next = NULL; - - if (coredata.c_flag & FULL_CORE) - { - asection *sec = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (sec == NULL) - return NULL; - sec->name = ".data"; - sec->flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS; - sec->_raw_size = coredata.CORE_DATA_SIZE_FIELD; - sec->vma = CDATA_ADDR (coredata.CORE_DATA_SIZE_FIELD); - sec->filepos = (int)coredata.c_stack + coredata.c_size; - - sec->next = abfd->sections; - abfd->sections = sec; - ++abfd->section_count; - } - - return abfd->xvec; /* this is garbage for now. */ -} - - - -/* return `true' if given core is from the given executable.. */ -boolean -rs6000coff_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd; - bfd *exec_bfd; -{ - FILE *fd; - struct core_dump coredata; - struct ld_info ldinfo; - char pathname [1024]; - const char *str1, *str2; - - /* Use bfd_xxx routines, rather than O/S primitives, do error checking!! - FIXMEmgo */ - /* Actually should be able to use bfd_get_section_contents now that - we have a .ldinfo section. */ - fd = fopen (core_bfd->filename, FOPEN_RB); - - fread (&coredata, sizeof (struct core_dump), 1, fd); - fseek (fd, (long)coredata.c_tab, 0); - fread (&ldinfo, (char*)&ldinfo.ldinfo_filename[0] - (char*)&ldinfo.ldinfo_next, - 1, fd); - fscanf (fd, "%s", pathname); - - str1 = strrchr (pathname, '/'); - str2 = strrchr (exec_bfd->filename, '/'); - - /* step over character '/' */ - str1 = str1 ? str1+1 : &pathname[0]; - str2 = str2 ? str2+1 : exec_bfd->filename; - - fclose (fd); - return strcmp (str1, str2) == 0; -} - -char * -rs6000coff_core_file_failing_command (abfd) - bfd *abfd; -{ - char *com = core_hdr (abfd).CORE_COMM_FIELD; - if (*com) - return com; - else - return 0; -} - -int -rs6000coff_core_file_failing_signal (abfd) - bfd *abfd; -{ - return core_hdr (abfd).c_signo; -} - - -boolean -rs6000coff_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - int count; -{ - if (count == 0) - return true; - - /* Reading a core file's sections will be slightly different. For the - rest of them we can use bfd_generic_get_section_contents () I suppose. */ - /* Make sure this routine works for any bfd and any section. FIXMEmgo. */ - - if (abfd->format == bfd_core && strcmp (section->name, ".reg") == 0) { - - struct mstsave mstatus; - int regoffset = (char*)&mstatus.gpr[0] - (char*)&mstatus; - - /* Assert that the only way this code will be executed is reading the - whole section. */ - if (offset || count != (sizeof(mstatus.gpr) + (4 * NUM_OF_SPEC_REGS))) - (*_bfd_error_handler) - ("ERROR! in rs6000coff_get_section_contents()\n"); - - /* for `.reg' section, `filepos' is a pointer to the `mstsave' structure - in the core file. */ - - /* read GPR's into the location. */ - if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1 - || bfd_read(location, sizeof (mstatus.gpr), 1, abfd) != sizeof (mstatus.gpr)) - return (false); /* on error */ - - /* increment location to the beginning of special registers in the section, - reset register offset value to the beginning of first special register - in mstsave structure, and read special registers. */ - - location = (PTR) ((char*)location + sizeof (mstatus.gpr)); - regoffset = (char*)&mstatus.iar - (char*)&mstatus; - - if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1 - || bfd_read(location, 4 * NUM_OF_SPEC_REGS, 1, abfd) != - 4 * NUM_OF_SPEC_REGS) - return (false); /* on error */ - - /* increment location address, and read the special registers.. */ - /* FIXMEmgo */ - return (true); - } - - /* else, use default bfd section content transfer. */ - else - return _bfd_generic_get_section_contents - (abfd, section, location, offset, count); -} - -#endif /* AIX_CORE */ diff --git a/contrib/gdb/bfd/som.c b/contrib/gdb/bfd/som.c deleted file mode 100644 index dd03d99..0000000 --- a/contrib/gdb/bfd/som.c +++ /dev/null @@ -1,5999 +0,0 @@ -/* bfd back-end for HP PA-RISC SOM objects. - Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996 - Free Software Foundation, Inc. - - Contributed by the Center for Software Science at the - University of Utah (pa-gdb-bugs@cs.utah.edu). - - 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. */ - -#include "bfd.h" -#include "sysdep.h" - -#if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD) || defined (HOST_HPPAOSF) - -#include "libbfd.h" -#include "som.h" - -#include <stdio.h> -#include <sys/types.h> -#include <sys/param.h> -#include <signal.h> -#include <machine/reg.h> -#include <sys/file.h> -#include <errno.h> - -/* Magic not defined in standard HP-UX header files until 8.0 */ - -#ifndef CPU_PA_RISC1_0 -#define CPU_PA_RISC1_0 0x20B -#endif /* CPU_PA_RISC1_0 */ - -#ifndef CPU_PA_RISC1_1 -#define CPU_PA_RISC1_1 0x210 -#endif /* CPU_PA_RISC1_1 */ - -#ifndef _PA_RISC1_0_ID -#define _PA_RISC1_0_ID CPU_PA_RISC1_0 -#endif /* _PA_RISC1_0_ID */ - -#ifndef _PA_RISC1_1_ID -#define _PA_RISC1_1_ID CPU_PA_RISC1_1 -#endif /* _PA_RISC1_1_ID */ - -#ifndef _PA_RISC_MAXID -#define _PA_RISC_MAXID 0x2FF -#endif /* _PA_RISC_MAXID */ - -#ifndef _PA_RISC_ID -#define _PA_RISC_ID(__m_num) \ - (((__m_num) == _PA_RISC1_0_ID) || \ - ((__m_num) >= _PA_RISC1_1_ID && (__m_num) <= _PA_RISC_MAXID)) -#endif /* _PA_RISC_ID */ - - -/* HIUX in it's infinite stupidity changed the names for several "well - known" constants. Work around such braindamage. Try the HPUX version - first, then the HIUX version, and finally provide a default. */ -#ifdef HPUX_AUX_ID -#define EXEC_AUX_ID HPUX_AUX_ID -#endif - -#if !defined (EXEC_AUX_ID) && defined (HIUX_AUX_ID) -#define EXEC_AUX_ID HIUX_AUX_ID -#endif - -#ifndef EXEC_AUX_ID -#define EXEC_AUX_ID 0 -#endif - -/* Size (in chars) of the temporary buffers used during fixup and string - table writes. */ - -#define SOM_TMP_BUFSIZE 8192 - -/* Size of the hash table in archives. */ -#define SOM_LST_HASH_SIZE 31 - -/* Max number of SOMs to be found in an archive. */ -#define SOM_LST_MODULE_LIMIT 1024 - -/* Generic alignment macro. */ -#define SOM_ALIGN(val, alignment) \ - (((val) + (alignment) - 1) & ~((alignment) - 1)) - -/* SOM allows any one of the four previous relocations to be reused - with a "R_PREV_FIXUP" relocation entry. Since R_PREV_FIXUP - relocations are always a single byte, using a R_PREV_FIXUP instead - of some multi-byte relocation makes object files smaller. - - Note one side effect of using a R_PREV_FIXUP is the relocation that - is being repeated moves to the front of the queue. */ -struct reloc_queue - { - unsigned char *reloc; - unsigned int size; - } reloc_queue[4]; - -/* This fully describes the symbol types which may be attached to - an EXPORT or IMPORT directive. Only SOM uses this formation - (ELF has no need for it). */ -typedef enum -{ - SYMBOL_TYPE_UNKNOWN, - SYMBOL_TYPE_ABSOLUTE, - SYMBOL_TYPE_CODE, - SYMBOL_TYPE_DATA, - SYMBOL_TYPE_ENTRY, - SYMBOL_TYPE_MILLICODE, - SYMBOL_TYPE_PLABEL, - SYMBOL_TYPE_PRI_PROG, - SYMBOL_TYPE_SEC_PROG, -} pa_symbol_type; - -struct section_to_type -{ - char *section; - char type; -}; - -/* Assorted symbol information that needs to be derived from the BFD symbol - and/or the BFD backend private symbol data. */ -struct som_misc_symbol_info -{ - unsigned int symbol_type; - unsigned int symbol_scope; - unsigned int arg_reloc; - unsigned int symbol_info; - unsigned int symbol_value; -}; - -/* Forward declarations */ - -static boolean som_mkobject PARAMS ((bfd *)); -static const bfd_target * som_object_setup PARAMS ((bfd *, - struct header *, - struct som_exec_auxhdr *)); -static boolean setup_sections PARAMS ((bfd *, struct header *)); -static const bfd_target * som_object_p PARAMS ((bfd *)); -static boolean som_write_object_contents PARAMS ((bfd *)); -static boolean som_slurp_string_table PARAMS ((bfd *)); -static unsigned int som_slurp_symbol_table PARAMS ((bfd *)); -static long som_get_symtab_upper_bound PARAMS ((bfd *)); -static long som_canonicalize_reloc PARAMS ((bfd *, sec_ptr, - arelent **, asymbol **)); -static long som_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr)); -static unsigned int som_set_reloc_info PARAMS ((unsigned char *, unsigned int, - arelent *, asection *, - asymbol **, boolean)); -static boolean som_slurp_reloc_table PARAMS ((bfd *, asection *, - asymbol **, boolean)); -static long som_get_symtab PARAMS ((bfd *, asymbol **)); -static asymbol * som_make_empty_symbol PARAMS ((bfd *)); -static void som_print_symbol PARAMS ((bfd *, PTR, - asymbol *, bfd_print_symbol_type)); -static boolean som_new_section_hook PARAMS ((bfd *, asection *)); -static boolean som_bfd_copy_private_symbol_data PARAMS ((bfd *, asymbol *, - bfd *, asymbol *)); -static boolean som_bfd_copy_private_section_data PARAMS ((bfd *, asection *, - bfd *, asection *)); -static boolean som_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *)); -#define som_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data -#define som_bfd_set_private_flags _bfd_generic_bfd_set_private_flags -static boolean som_bfd_is_local_label PARAMS ((bfd *, asymbol *)); -static boolean som_set_section_contents PARAMS ((bfd *, sec_ptr, PTR, - file_ptr, bfd_size_type)); -static boolean som_get_section_contents PARAMS ((bfd *, sec_ptr, PTR, - file_ptr, bfd_size_type)); -static boolean som_set_arch_mach PARAMS ((bfd *, enum bfd_architecture, - unsigned long)); -static boolean som_find_nearest_line PARAMS ((bfd *, asection *, - asymbol **, bfd_vma, - CONST char **, - CONST char **, - unsigned int *)); -static void som_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *)); -static asection * bfd_section_from_som_symbol PARAMS ((bfd *, - struct symbol_dictionary_record *)); -static int log2 PARAMS ((unsigned int)); -static bfd_reloc_status_type hppa_som_reloc PARAMS ((bfd *, arelent *, - asymbol *, PTR, - asection *, bfd *, - char **)); -static void som_initialize_reloc_queue PARAMS ((struct reloc_queue *)); -static void som_reloc_queue_insert PARAMS ((unsigned char *, unsigned int, - struct reloc_queue *)); -static void som_reloc_queue_fix PARAMS ((struct reloc_queue *, unsigned int)); -static int som_reloc_queue_find PARAMS ((unsigned char *, unsigned int, - struct reloc_queue *)); -static unsigned char * try_prev_fixup PARAMS ((bfd *, int *, unsigned char *, - unsigned int, - struct reloc_queue *)); - -static unsigned char * som_reloc_skip PARAMS ((bfd *, unsigned int, - unsigned char *, unsigned int *, - struct reloc_queue *)); -static unsigned char * som_reloc_addend PARAMS ((bfd *, int, unsigned char *, - unsigned int *, - struct reloc_queue *)); -static unsigned char * som_reloc_call PARAMS ((bfd *, unsigned char *, - unsigned int *, - arelent *, int, - struct reloc_queue *)); -static unsigned long som_count_spaces PARAMS ((bfd *)); -static unsigned long som_count_subspaces PARAMS ((bfd *)); -static int compare_syms PARAMS ((const void *, const void *)); -static int compare_subspaces PARAMS ((const void *, const void *)); -static unsigned long som_compute_checksum PARAMS ((bfd *)); -static boolean som_prep_headers PARAMS ((bfd *)); -static int som_sizeof_headers PARAMS ((bfd *, boolean)); -static boolean som_finish_writing PARAMS ((bfd *)); -static boolean som_build_and_write_symbol_table PARAMS ((bfd *)); -static void som_prep_for_fixups PARAMS ((bfd *, asymbol **, unsigned long)); -static boolean som_write_fixups PARAMS ((bfd *, unsigned long, unsigned int *)); -static boolean som_write_space_strings PARAMS ((bfd *, unsigned long, - unsigned int *)); -static boolean som_write_symbol_strings PARAMS ((bfd *, unsigned long, - asymbol **, unsigned int, - unsigned *)); -static boolean som_begin_writing PARAMS ((bfd *)); -static reloc_howto_type * som_bfd_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static char som_section_type PARAMS ((const char *)); -static int som_decode_symclass PARAMS ((asymbol *)); -static boolean som_bfd_count_ar_symbols PARAMS ((bfd *, struct lst_header *, - symindex *)); - -static boolean som_bfd_fill_in_ar_symbols PARAMS ((bfd *, struct lst_header *, - carsym **syms)); -static boolean som_slurp_armap PARAMS ((bfd *)); -static boolean som_write_armap PARAMS ((bfd *, unsigned int, struct orl *, - unsigned int, int)); -static void som_bfd_derive_misc_symbol_info PARAMS ((bfd *, asymbol *, - struct som_misc_symbol_info *)); -static boolean som_bfd_prep_for_ar_write PARAMS ((bfd *, unsigned int *, - unsigned int *)); -static unsigned int som_bfd_ar_symbol_hash PARAMS ((asymbol *)); -static boolean som_bfd_ar_write_symbol_stuff PARAMS ((bfd *, unsigned int, - unsigned int, - struct lst_header)); -static CONST char *normalize PARAMS ((CONST char *file)); -static boolean som_is_space PARAMS ((asection *)); -static boolean som_is_subspace PARAMS ((asection *)); -static boolean som_is_container PARAMS ((asection *, asection *)); -static boolean som_bfd_free_cached_info PARAMS ((bfd *)); -static boolean som_bfd_link_split_section PARAMS ((bfd *, asection *)); - -/* Map SOM section names to POSIX/BSD single-character symbol types. - - This table includes all the standard subspaces as defined in the - current "PRO ABI for PA-RISC Systems", $UNWIND$ which for - some reason was left out, and sections specific to embedded stabs. */ - -static const struct section_to_type stt[] = { - {"$TEXT$", 't'}, - {"$SHLIB_INFO$", 't'}, - {"$MILLICODE$", 't'}, - {"$LIT$", 't'}, - {"$CODE$", 't'}, - {"$UNWIND_START$", 't'}, - {"$UNWIND$", 't'}, - {"$PRIVATE$", 'd'}, - {"$PLT$", 'd'}, - {"$SHLIB_DATA$", 'd'}, - {"$DATA$", 'd'}, - {"$SHORTDATA$", 'g'}, - {"$DLT$", 'd'}, - {"$GLOBAL$", 'g'}, - {"$SHORTBSS$", 's'}, - {"$BSS$", 'b'}, - {"$GDB_STRINGS$", 'N'}, - {"$GDB_SYMBOLS$", 'N'}, - {0, 0} -}; - -/* About the relocation formatting table... - - There are 256 entries in the table, one for each possible - relocation opcode available in SOM. We index the table by - the relocation opcode. The names and operations are those - defined by a.out_800 (4). - - Right now this table is only used to count and perform minimal - processing on relocation streams so that they can be internalized - into BFD and symbolically printed by utilities. To make actual use - of them would be much more difficult, BFD's concept of relocations - is far too simple to handle SOM relocations. The basic assumption - that a relocation can be completely processed independent of other - relocations before an object file is written is invalid for SOM. - - The SOM relocations are meant to be processed as a stream, they - specify copying of data from the input section to the output section - while possibly modifying the data in some manner. They also can - specify that a variable number of zeros or uninitialized data be - inserted on in the output segment at the current offset. Some - relocations specify that some previous relocation be re-applied at - the current location in the input/output sections. And finally a number - of relocations have effects on other sections (R_ENTRY, R_EXIT, - R_UNWIND_AUX and a variety of others). There isn't even enough room - in the BFD relocation data structure to store enough information to - perform all the relocations. - - Each entry in the table has three fields. - - The first entry is an index into this "class" of relocations. This - index can then be used as a variable within the relocation itself. - - The second field is a format string which actually controls processing - of the relocation. It uses a simple postfix machine to do calculations - based on variables/constants found in the string and the relocation - stream. - - The third field specifys whether or not this relocation may use - a constant (V) from the previous R_DATA_OVERRIDE rather than a constant - stored in the instruction. - - Variables: - - L = input space byte count - D = index into class of relocations - M = output space byte count - N = statement number (unused?) - O = stack operation - R = parameter relocation bits - S = symbol index - T = first 32 bits of stack unwind information - U = second 32 bits of stack unwind information - V = a literal constant (usually used in the next relocation) - P = a previous relocation - - Lower case letters (starting with 'b') refer to following - bytes in the relocation stream. 'b' is the next 1 byte, - c is the next 2 bytes, d is the next 3 bytes, etc... - This is the variable part of the relocation entries that - makes our life a living hell. - - numerical constants are also used in the format string. Note - the constants are represented in decimal. - - '+', "*" and "=" represents the obvious postfix operators. - '<' represents a left shift. - - Stack Operations: - - Parameter Relocation Bits: - - Unwind Entries: - - Previous Relocations: The index field represents which in the queue - of 4 previous fixups should be re-applied. - - Literal Constants: These are generally used to represent addend - parts of relocations when these constants are not stored in the - fields of the instructions themselves. For example the instruction - addil foo-$global$-0x1234 would use an override for "0x1234" rather - than storing it into the addil itself. */ - -struct fixup_format -{ - int D; - char *format; -}; - -static const struct fixup_format som_fixup_formats[256] = -{ - /* R_NO_RELOCATION */ - 0, "LD1+4*=", /* 0x00 */ - 1, "LD1+4*=", /* 0x01 */ - 2, "LD1+4*=", /* 0x02 */ - 3, "LD1+4*=", /* 0x03 */ - 4, "LD1+4*=", /* 0x04 */ - 5, "LD1+4*=", /* 0x05 */ - 6, "LD1+4*=", /* 0x06 */ - 7, "LD1+4*=", /* 0x07 */ - 8, "LD1+4*=", /* 0x08 */ - 9, "LD1+4*=", /* 0x09 */ - 10, "LD1+4*=", /* 0x0a */ - 11, "LD1+4*=", /* 0x0b */ - 12, "LD1+4*=", /* 0x0c */ - 13, "LD1+4*=", /* 0x0d */ - 14, "LD1+4*=", /* 0x0e */ - 15, "LD1+4*=", /* 0x0f */ - 16, "LD1+4*=", /* 0x10 */ - 17, "LD1+4*=", /* 0x11 */ - 18, "LD1+4*=", /* 0x12 */ - 19, "LD1+4*=", /* 0x13 */ - 20, "LD1+4*=", /* 0x14 */ - 21, "LD1+4*=", /* 0x15 */ - 22, "LD1+4*=", /* 0x16 */ - 23, "LD1+4*=", /* 0x17 */ - 0, "LD8<b+1+4*=", /* 0x18 */ - 1, "LD8<b+1+4*=", /* 0x19 */ - 2, "LD8<b+1+4*=", /* 0x1a */ - 3, "LD8<b+1+4*=", /* 0x1b */ - 0, "LD16<c+1+4*=", /* 0x1c */ - 1, "LD16<c+1+4*=", /* 0x1d */ - 2, "LD16<c+1+4*=", /* 0x1e */ - 0, "Ld1+=", /* 0x1f */ - /* R_ZEROES */ - 0, "Lb1+4*=", /* 0x20 */ - 1, "Ld1+=", /* 0x21 */ - /* R_UNINIT */ - 0, "Lb1+4*=", /* 0x22 */ - 1, "Ld1+=", /* 0x23 */ - /* R_RELOCATION */ - 0, "L4=", /* 0x24 */ - /* R_DATA_ONE_SYMBOL */ - 0, "L4=Sb=", /* 0x25 */ - 1, "L4=Sd=", /* 0x26 */ - /* R_DATA_PLEBEL */ - 0, "L4=Sb=", /* 0x27 */ - 1, "L4=Sd=", /* 0x28 */ - /* R_SPACE_REF */ - 0, "L4=", /* 0x29 */ - /* R_REPEATED_INIT */ - 0, "L4=Mb1+4*=", /* 0x2a */ - 1, "Lb4*=Mb1+L*=", /* 0x2b */ - 2, "Lb4*=Md1+4*=", /* 0x2c */ - 3, "Ld1+=Me1+=", /* 0x2d */ - /* R_SHORT_PCREL_MODE */ - 0, "", /* 0x2e */ - /* R_LONG_PCREL_MODE */ - 0, "", /* 0x2f */ - /* R_PCREL_CALL */ - 0, "L4=RD=Sb=", /* 0x30 */ - 1, "L4=RD=Sb=", /* 0x31 */ - 2, "L4=RD=Sb=", /* 0x32 */ - 3, "L4=RD=Sb=", /* 0x33 */ - 4, "L4=RD=Sb=", /* 0x34 */ - 5, "L4=RD=Sb=", /* 0x35 */ - 6, "L4=RD=Sb=", /* 0x36 */ - 7, "L4=RD=Sb=", /* 0x37 */ - 8, "L4=RD=Sb=", /* 0x38 */ - 9, "L4=RD=Sb=", /* 0x39 */ - 0, "L4=RD8<b+=Sb=",/* 0x3a */ - 1, "L4=RD8<b+=Sb=",/* 0x3b */ - 0, "L4=RD8<b+=Sd=",/* 0x3c */ - 1, "L4=RD8<b+=Sd=",/* 0x3d */ - /* R_RESERVED */ - 0, "", /* 0x3e */ - 0, "", /* 0x3f */ - /* R_ABS_CALL */ - 0, "L4=RD=Sb=", /* 0x40 */ - 1, "L4=RD=Sb=", /* 0x41 */ - 2, "L4=RD=Sb=", /* 0x42 */ - 3, "L4=RD=Sb=", /* 0x43 */ - 4, "L4=RD=Sb=", /* 0x44 */ - 5, "L4=RD=Sb=", /* 0x45 */ - 6, "L4=RD=Sb=", /* 0x46 */ - 7, "L4=RD=Sb=", /* 0x47 */ - 8, "L4=RD=Sb=", /* 0x48 */ - 9, "L4=RD=Sb=", /* 0x49 */ - 0, "L4=RD8<b+=Sb=",/* 0x4a */ - 1, "L4=RD8<b+=Sb=",/* 0x4b */ - 0, "L4=RD8<b+=Sd=",/* 0x4c */ - 1, "L4=RD8<b+=Sd=",/* 0x4d */ - /* R_RESERVED */ - 0, "", /* 0x4e */ - 0, "", /* 0x4f */ - /* R_DP_RELATIVE */ - 0, "L4=SD=", /* 0x50 */ - 1, "L4=SD=", /* 0x51 */ - 2, "L4=SD=", /* 0x52 */ - 3, "L4=SD=", /* 0x53 */ - 4, "L4=SD=", /* 0x54 */ - 5, "L4=SD=", /* 0x55 */ - 6, "L4=SD=", /* 0x56 */ - 7, "L4=SD=", /* 0x57 */ - 8, "L4=SD=", /* 0x58 */ - 9, "L4=SD=", /* 0x59 */ - 10, "L4=SD=", /* 0x5a */ - 11, "L4=SD=", /* 0x5b */ - 12, "L4=SD=", /* 0x5c */ - 13, "L4=SD=", /* 0x5d */ - 14, "L4=SD=", /* 0x5e */ - 15, "L4=SD=", /* 0x5f */ - 16, "L4=SD=", /* 0x60 */ - 17, "L4=SD=", /* 0x61 */ - 18, "L4=SD=", /* 0x62 */ - 19, "L4=SD=", /* 0x63 */ - 20, "L4=SD=", /* 0x64 */ - 21, "L4=SD=", /* 0x65 */ - 22, "L4=SD=", /* 0x66 */ - 23, "L4=SD=", /* 0x67 */ - 24, "L4=SD=", /* 0x68 */ - 25, "L4=SD=", /* 0x69 */ - 26, "L4=SD=", /* 0x6a */ - 27, "L4=SD=", /* 0x6b */ - 28, "L4=SD=", /* 0x6c */ - 29, "L4=SD=", /* 0x6d */ - 30, "L4=SD=", /* 0x6e */ - 31, "L4=SD=", /* 0x6f */ - 32, "L4=Sb=", /* 0x70 */ - 33, "L4=Sd=", /* 0x71 */ - /* R_RESERVED */ - 0, "", /* 0x72 */ - 0, "", /* 0x73 */ - 0, "", /* 0x74 */ - 0, "", /* 0x75 */ - 0, "", /* 0x76 */ - 0, "", /* 0x77 */ - /* R_DLT_REL */ - 0, "L4=Sb=", /* 0x78 */ - 1, "L4=Sd=", /* 0x79 */ - /* R_RESERVED */ - 0, "", /* 0x7a */ - 0, "", /* 0x7b */ - 0, "", /* 0x7c */ - 0, "", /* 0x7d */ - 0, "", /* 0x7e */ - 0, "", /* 0x7f */ - /* R_CODE_ONE_SYMBOL */ - 0, "L4=SD=", /* 0x80 */ - 1, "L4=SD=", /* 0x81 */ - 2, "L4=SD=", /* 0x82 */ - 3, "L4=SD=", /* 0x83 */ - 4, "L4=SD=", /* 0x84 */ - 5, "L4=SD=", /* 0x85 */ - 6, "L4=SD=", /* 0x86 */ - 7, "L4=SD=", /* 0x87 */ - 8, "L4=SD=", /* 0x88 */ - 9, "L4=SD=", /* 0x89 */ - 10, "L4=SD=", /* 0x8q */ - 11, "L4=SD=", /* 0x8b */ - 12, "L4=SD=", /* 0x8c */ - 13, "L4=SD=", /* 0x8d */ - 14, "L4=SD=", /* 0x8e */ - 15, "L4=SD=", /* 0x8f */ - 16, "L4=SD=", /* 0x90 */ - 17, "L4=SD=", /* 0x91 */ - 18, "L4=SD=", /* 0x92 */ - 19, "L4=SD=", /* 0x93 */ - 20, "L4=SD=", /* 0x94 */ - 21, "L4=SD=", /* 0x95 */ - 22, "L4=SD=", /* 0x96 */ - 23, "L4=SD=", /* 0x97 */ - 24, "L4=SD=", /* 0x98 */ - 25, "L4=SD=", /* 0x99 */ - 26, "L4=SD=", /* 0x9a */ - 27, "L4=SD=", /* 0x9b */ - 28, "L4=SD=", /* 0x9c */ - 29, "L4=SD=", /* 0x9d */ - 30, "L4=SD=", /* 0x9e */ - 31, "L4=SD=", /* 0x9f */ - 32, "L4=Sb=", /* 0xa0 */ - 33, "L4=Sd=", /* 0xa1 */ - /* R_RESERVED */ - 0, "", /* 0xa2 */ - 0, "", /* 0xa3 */ - 0, "", /* 0xa4 */ - 0, "", /* 0xa5 */ - 0, "", /* 0xa6 */ - 0, "", /* 0xa7 */ - 0, "", /* 0xa8 */ - 0, "", /* 0xa9 */ - 0, "", /* 0xaa */ - 0, "", /* 0xab */ - 0, "", /* 0xac */ - 0, "", /* 0xad */ - /* R_MILLI_REL */ - 0, "L4=Sb=", /* 0xae */ - 1, "L4=Sd=", /* 0xaf */ - /* R_CODE_PLABEL */ - 0, "L4=Sb=", /* 0xb0 */ - 1, "L4=Sd=", /* 0xb1 */ - /* R_BREAKPOINT */ - 0, "L4=", /* 0xb2 */ - /* R_ENTRY */ - 0, "Te=Ue=", /* 0xb3 */ - 1, "Uf=", /* 0xb4 */ - /* R_ALT_ENTRY */ - 0, "", /* 0xb5 */ - /* R_EXIT */ - 0, "", /* 0xb6 */ - /* R_BEGIN_TRY */ - 0, "", /* 0xb7 */ - /* R_END_TRY */ - 0, "R0=", /* 0xb8 */ - 1, "Rb4*=", /* 0xb9 */ - 2, "Rd4*=", /* 0xba */ - /* R_BEGIN_BRTAB */ - 0, "", /* 0xbb */ - /* R_END_BRTAB */ - 0, "", /* 0xbc */ - /* R_STATEMENT */ - 0, "Nb=", /* 0xbd */ - 1, "Nc=", /* 0xbe */ - 2, "Nd=", /* 0xbf */ - /* R_DATA_EXPR */ - 0, "L4=", /* 0xc0 */ - /* R_CODE_EXPR */ - 0, "L4=", /* 0xc1 */ - /* R_FSEL */ - 0, "", /* 0xc2 */ - /* R_LSEL */ - 0, "", /* 0xc3 */ - /* R_RSEL */ - 0, "", /* 0xc4 */ - /* R_N_MODE */ - 0, "", /* 0xc5 */ - /* R_S_MODE */ - 0, "", /* 0xc6 */ - /* R_D_MODE */ - 0, "", /* 0xc7 */ - /* R_R_MODE */ - 0, "", /* 0xc8 */ - /* R_DATA_OVERRIDE */ - 0, "V0=", /* 0xc9 */ - 1, "Vb=", /* 0xca */ - 2, "Vc=", /* 0xcb */ - 3, "Vd=", /* 0xcc */ - 4, "Ve=", /* 0xcd */ - /* R_TRANSLATED */ - 0, "", /* 0xce */ - /* R_RESERVED */ - 0, "", /* 0xcf */ - /* R_COMP1 */ - 0, "Ob=", /* 0xd0 */ - /* R_COMP2 */ - 0, "Ob=Sd=", /* 0xd1 */ - /* R_COMP3 */ - 0, "Ob=Ve=", /* 0xd2 */ - /* R_PREV_FIXUP */ - 0, "P", /* 0xd3 */ - 1, "P", /* 0xd4 */ - 2, "P", /* 0xd5 */ - 3, "P", /* 0xd6 */ - /* R_SEC_STMT */ - 0, "", /* 0xd7 */ - /* R_N0SEL */ - 0, "", /* 0xd8 */ - /* R_N1SEL */ - 0, "", /* 0xd9 */ - /* R_LINETAB */ - 0, "", /* 0xda */ - /* R_LINETAB_ESC */ - 0, "", /* 0xdb */ - /* R_LTP_OVERRIDE */ - 0, "", /* 0xdc */ - /* R_COMMENT */ - 0, "", /* 0xdd */ - /* R_RESERVED */ - 0, "", /* 0xde */ - 0, "", /* 0xdf */ - 0, "", /* 0xe0 */ - 0, "", /* 0xe1 */ - 0, "", /* 0xe2 */ - 0, "", /* 0xe3 */ - 0, "", /* 0xe4 */ - 0, "", /* 0xe5 */ - 0, "", /* 0xe6 */ - 0, "", /* 0xe7 */ - 0, "", /* 0xe8 */ - 0, "", /* 0xe9 */ - 0, "", /* 0xea */ - 0, "", /* 0xeb */ - 0, "", /* 0xec */ - 0, "", /* 0xed */ - 0, "", /* 0xee */ - 0, "", /* 0xef */ - 0, "", /* 0xf0 */ - 0, "", /* 0xf1 */ - 0, "", /* 0xf2 */ - 0, "", /* 0xf3 */ - 0, "", /* 0xf4 */ - 0, "", /* 0xf5 */ - 0, "", /* 0xf6 */ - 0, "", /* 0xf7 */ - 0, "", /* 0xf8 */ - 0, "", /* 0xf9 */ - 0, "", /* 0xfa */ - 0, "", /* 0xfb */ - 0, "", /* 0xfc */ - 0, "", /* 0xfd */ - 0, "", /* 0xfe */ - 0, "", /* 0xff */ -}; - -static const int comp1_opcodes[] = -{ - 0x00, - 0x40, - 0x41, - 0x42, - 0x43, - 0x44, - 0x45, - 0x46, - 0x47, - 0x48, - 0x49, - 0x4a, - 0x4b, - 0x60, - 0x80, - 0xa0, - 0xc0, - -1 -}; - -static const int comp2_opcodes[] = -{ - 0x00, - 0x80, - 0x82, - 0xc0, - -1 -}; - -static const int comp3_opcodes[] = -{ - 0x00, - 0x02, - -1 -}; - -/* These apparently are not in older versions of hpux reloc.h (hpux7). */ -#ifndef R_DLT_REL -#define R_DLT_REL 0x78 -#endif - -#ifndef R_AUX_UNWIND -#define R_AUX_UNWIND 0xcf -#endif - -#ifndef R_SEC_STMT -#define R_SEC_STMT 0xd7 -#endif - -/* And these first appeared in hpux10. */ -#ifndef R_SHORT_PCREL_MODE -#define R_SHORT_PCREL_MODE 0x3e -#endif - -#ifndef R_LONG_PCREL_MODE -#define R_LONG_PCREL_MODE 0x3f -#endif - -#ifndef R_N0SEL -#define R_N0SEL 0xd8 -#endif - -#ifndef R_N1SEL -#define R_N1SEL 0xd9 -#endif - -#ifndef R_LINETAB -#define R_LINETAB 0xda -#endif - -#ifndef R_LINETAB_ESC -#define R_LINETAB_ESC 0xdb -#endif - -#ifndef R_LTP_OVERRIDE -#define R_LTP_OVERRIDE 0xdc -#endif - -#ifndef R_COMMENT -#define R_COMMENT 0xdd -#endif - -static reloc_howto_type som_hppa_howto_table[] = -{ - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_NO_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_NO_RELOCATION"}, - {R_ZEROES, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ZEROES"}, - {R_ZEROES, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ZEROES"}, - {R_UNINIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_UNINIT"}, - {R_UNINIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_UNINIT"}, - {R_RELOCATION, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RELOCATION"}, - {R_DATA_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_ONE_SYMBOL"}, - {R_DATA_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_ONE_SYMBOL"}, - {R_DATA_PLABEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_PLABEL"}, - {R_DATA_PLABEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_PLABEL"}, - {R_SPACE_REF, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_SPACE_REF"}, - {R_REPEATED_INIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "REPEATED_INIT"}, - {R_REPEATED_INIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "REPEATED_INIT"}, - {R_REPEATED_INIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "REPEATED_INIT"}, - {R_REPEATED_INIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "REPEATED_INIT"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"}, - {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"}, - {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"}, - {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"}, - {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"}, - {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"}, - {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"}, - {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"}, - {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"}, - {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"}, - {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"}, - {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"}, - {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"}, - {R_PCREL_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PCREL_CALL"}, - {R_SHORT_PCREL_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_SHORT_PCREL_MODE"}, - {R_LONG_PCREL_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_LONG_PCREL_MODE"}, - {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"}, - {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"}, - {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"}, - {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"}, - {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"}, - {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"}, - {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"}, - {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"}, - {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"}, - {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"}, - {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"}, - {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"}, - {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"}, - {R_ABS_CALL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ABS_CALL"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_DP_RELATIVE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DP_RELATIVE"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_DLT_REL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DLT_REL"}, - {R_DLT_REL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DLT_REL"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_CODE_ONE_SYMBOL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_ONE_SYMBOL"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_MILLI_REL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_MILLI_REL"}, - {R_MILLI_REL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_MILLI_REL"}, - {R_CODE_PLABEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_PLABEL"}, - {R_CODE_PLABEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_PLABEL"}, - {R_BREAKPOINT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_BREAKPOINT"}, - {R_ENTRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ENTRY"}, - {R_ENTRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ENTRY"}, - {R_ALT_ENTRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_ALT_ENTRY"}, - {R_EXIT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_EXIT"}, - {R_BEGIN_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_BEGIN_TRY"}, - {R_END_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_TRY"}, - {R_END_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_TRY"}, - {R_END_TRY, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_TRY"}, - {R_BEGIN_BRTAB, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_BEGIN_BRTAB"}, - {R_END_BRTAB, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_END_BRTAB"}, - {R_STATEMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_STATEMENT"}, - {R_STATEMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_STATEMENT"}, - {R_STATEMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_STATEMENT"}, - {R_DATA_EXPR, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_EXPR"}, - {R_CODE_EXPR, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_CODE_EXPR"}, - {R_FSEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_FSEL"}, - {R_LSEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_LSEL"}, - {R_RSEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RSEL"}, - {R_N_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_N_MODE"}, - {R_S_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_S_MODE"}, - {R_D_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_D_MODE"}, - {R_R_MODE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_R_MODE"}, - {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"}, - {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"}, - {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"}, - {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"}, - {R_DATA_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_DATA_OVERRIDE"}, - {R_TRANSLATED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_TRANSLATED"}, - {R_AUX_UNWIND, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_AUX_UNWIND"}, - {R_COMP1, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_COMP1"}, - {R_COMP2, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_COMP2"}, - {R_COMP3, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_COMP3"}, - {R_PREV_FIXUP, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PREV_FIXUP"}, - {R_PREV_FIXUP, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PREV_FIXUP"}, - {R_PREV_FIXUP, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PREV_FIXUP"}, - {R_PREV_FIXUP, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_PREV_FIXUP"}, - {R_SEC_STMT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_SEC_STMT"}, - {R_N0SEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_N0SEL"}, - {R_N1SEL, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_N1SEL"}, - {R_LINETAB, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_LINETAB"}, - {R_LINETAB_ESC, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_LINETAB_ESC"}, - {R_LTP_OVERRIDE, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_LTP_OVERRIDE"}, - {R_COMMENT, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_COMMENT"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}, - {R_RESERVED, 0, 0, 32, false, 0, 0, hppa_som_reloc, "R_RESERVED"}}; - -/* Initialize the SOM relocation queue. By definition the queue holds - the last four multibyte fixups. */ - -static void -som_initialize_reloc_queue (queue) - struct reloc_queue *queue; -{ - queue[0].reloc = NULL; - queue[0].size = 0; - queue[1].reloc = NULL; - queue[1].size = 0; - queue[2].reloc = NULL; - queue[2].size = 0; - queue[3].reloc = NULL; - queue[3].size = 0; -} - -/* Insert a new relocation into the relocation queue. */ - -static void -som_reloc_queue_insert (p, size, queue) - unsigned char *p; - unsigned int size; - struct reloc_queue *queue; -{ - queue[3].reloc = queue[2].reloc; - queue[3].size = queue[2].size; - queue[2].reloc = queue[1].reloc; - queue[2].size = queue[1].size; - queue[1].reloc = queue[0].reloc; - queue[1].size = queue[0].size; - queue[0].reloc = p; - queue[0].size = size; -} - -/* When an entry in the relocation queue is reused, the entry moves - to the front of the queue. */ - -static void -som_reloc_queue_fix (queue, index) - struct reloc_queue *queue; - unsigned int index; -{ - if (index == 0) - return; - - if (index == 1) - { - unsigned char *tmp1 = queue[0].reloc; - unsigned int tmp2 = queue[0].size; - queue[0].reloc = queue[1].reloc; - queue[0].size = queue[1].size; - queue[1].reloc = tmp1; - queue[1].size = tmp2; - return; - } - - if (index == 2) - { - unsigned char *tmp1 = queue[0].reloc; - unsigned int tmp2 = queue[0].size; - queue[0].reloc = queue[2].reloc; - queue[0].size = queue[2].size; - queue[2].reloc = queue[1].reloc; - queue[2].size = queue[1].size; - queue[1].reloc = tmp1; - queue[1].size = tmp2; - return; - } - - if (index == 3) - { - unsigned char *tmp1 = queue[0].reloc; - unsigned int tmp2 = queue[0].size; - queue[0].reloc = queue[3].reloc; - queue[0].size = queue[3].size; - queue[3].reloc = queue[2].reloc; - queue[3].size = queue[2].size; - queue[2].reloc = queue[1].reloc; - queue[2].size = queue[1].size; - queue[1].reloc = tmp1; - queue[1].size = tmp2; - return; - } - abort(); -} - -/* Search for a particular relocation in the relocation queue. */ - -static int -som_reloc_queue_find (p, size, queue) - unsigned char *p; - unsigned int size; - struct reloc_queue *queue; -{ - if (queue[0].reloc && !memcmp (p, queue[0].reloc, size) - && size == queue[0].size) - return 0; - if (queue[1].reloc && !memcmp (p, queue[1].reloc, size) - && size == queue[1].size) - return 1; - if (queue[2].reloc && !memcmp (p, queue[2].reloc, size) - && size == queue[2].size) - return 2; - if (queue[3].reloc && !memcmp (p, queue[3].reloc, size) - && size == queue[3].size) - return 3; - return -1; -} - -static unsigned char * -try_prev_fixup (abfd, subspace_reloc_sizep, p, size, queue) - bfd *abfd; - int *subspace_reloc_sizep; - unsigned char *p; - unsigned int size; - struct reloc_queue *queue; -{ - int queue_index = som_reloc_queue_find (p, size, queue); - - if (queue_index != -1) - { - /* Found this in a previous fixup. Undo the fixup we - just built and use R_PREV_FIXUP instead. We saved - a total of size - 1 bytes in the fixup stream. */ - bfd_put_8 (abfd, R_PREV_FIXUP + queue_index, p); - p += 1; - *subspace_reloc_sizep += 1; - som_reloc_queue_fix (queue, queue_index); - } - else - { - som_reloc_queue_insert (p, size, queue); - *subspace_reloc_sizep += size; - p += size; - } - return p; -} - -/* Emit the proper R_NO_RELOCATION fixups to map the next SKIP - bytes without any relocation. Update the size of the subspace - relocation stream via SUBSPACE_RELOC_SIZE_P; also return the - current pointer into the relocation stream. */ - -static unsigned char * -som_reloc_skip (abfd, skip, p, subspace_reloc_sizep, queue) - bfd *abfd; - unsigned int skip; - unsigned char *p; - unsigned int *subspace_reloc_sizep; - struct reloc_queue *queue; -{ - /* Use a 4 byte R_NO_RELOCATION entry with a maximal value - then R_PREV_FIXUPs to get the difference down to a - reasonable size. */ - if (skip >= 0x1000000) - { - skip -= 0x1000000; - bfd_put_8 (abfd, R_NO_RELOCATION + 31, p); - bfd_put_8 (abfd, 0xff, p + 1); - bfd_put_16 (abfd, 0xffff, p + 2); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue); - while (skip >= 0x1000000) - { - skip -= 0x1000000; - bfd_put_8 (abfd, R_PREV_FIXUP, p); - p++; - *subspace_reloc_sizep += 1; - /* No need to adjust queue here since we are repeating the - most recent fixup. */ - } - } - - /* The difference must be less than 0x1000000. Use one - more R_NO_RELOCATION entry to get to the right difference. */ - if ((skip & 3) == 0 && skip <= 0xc0000 && skip > 0) - { - /* Difference can be handled in a simple single-byte - R_NO_RELOCATION entry. */ - if (skip <= 0x60) - { - bfd_put_8 (abfd, R_NO_RELOCATION + (skip >> 2) - 1, p); - *subspace_reloc_sizep += 1; - p++; - } - /* Handle it with a two byte R_NO_RELOCATION entry. */ - else if (skip <= 0x1000) - { - bfd_put_8 (abfd, R_NO_RELOCATION + 24 + (((skip >> 2) - 1) >> 8), p); - bfd_put_8 (abfd, (skip >> 2) - 1, p + 1); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue); - } - /* Handle it with a three byte R_NO_RELOCATION entry. */ - else - { - bfd_put_8 (abfd, R_NO_RELOCATION + 28 + (((skip >> 2) - 1) >> 16), p); - bfd_put_16 (abfd, (skip >> 2) - 1, p + 1); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue); - } - } - /* Ugh. Punt and use a 4 byte entry. */ - else if (skip > 0) - { - bfd_put_8 (abfd, R_NO_RELOCATION + 31, p); - bfd_put_8 (abfd, (skip - 1) >> 16, p + 1); - bfd_put_16 (abfd, skip - 1, p + 2); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue); - } - return p; -} - -/* Emit the proper R_DATA_OVERRIDE fixups to handle a nonzero addend - from a BFD relocation. Update the size of the subspace relocation - stream via SUBSPACE_RELOC_SIZE_P; also return the current pointer - into the relocation stream. */ - -static unsigned char * -som_reloc_addend (abfd, addend, p, subspace_reloc_sizep, queue) - bfd *abfd; - int addend; - unsigned char *p; - unsigned int *subspace_reloc_sizep; - struct reloc_queue *queue; -{ - if ((unsigned)(addend) + 0x80 < 0x100) - { - bfd_put_8 (abfd, R_DATA_OVERRIDE + 1, p); - bfd_put_8 (abfd, addend, p + 1); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue); - } - else if ((unsigned) (addend) + 0x8000 < 0x10000) - { - bfd_put_8 (abfd, R_DATA_OVERRIDE + 2, p); - bfd_put_16 (abfd, addend, p + 1); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue); - } - else if ((unsigned) (addend) + 0x800000 < 0x1000000) - { - bfd_put_8 (abfd, R_DATA_OVERRIDE + 3, p); - bfd_put_8 (abfd, addend >> 16, p + 1); - bfd_put_16 (abfd, addend, p + 2); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 4, queue); - } - else - { - bfd_put_8 (abfd, R_DATA_OVERRIDE + 4, p); - bfd_put_32 (abfd, addend, p + 1); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 5, queue); - } - return p; -} - -/* Handle a single function call relocation. */ - -static unsigned char * -som_reloc_call (abfd, p, subspace_reloc_sizep, bfd_reloc, sym_num, queue) - bfd *abfd; - unsigned char *p; - unsigned int *subspace_reloc_sizep; - arelent *bfd_reloc; - int sym_num; - struct reloc_queue *queue; -{ - int arg_bits = HPPA_R_ARG_RELOC (bfd_reloc->addend); - int rtn_bits = arg_bits & 0x3; - int type, done = 0; - - /* You'll never believe all this is necessary to handle relocations - for function calls. Having to compute and pack the argument - relocation bits is the real nightmare. - - If you're interested in how this works, just forget it. You really - do not want to know about this braindamage. */ - - /* First see if this can be done with a "simple" relocation. Simple - relocations have a symbol number < 0x100 and have simple encodings - of argument relocations. */ - - if (sym_num < 0x100) - { - switch (arg_bits) - { - case 0: - case 1: - type = 0; - break; - case 1 << 8: - case 1 << 8 | 1: - type = 1; - break; - case 1 << 8 | 1 << 6: - case 1 << 8 | 1 << 6 | 1: - type = 2; - break; - case 1 << 8 | 1 << 6 | 1 << 4: - case 1 << 8 | 1 << 6 | 1 << 4 | 1: - type = 3; - break; - case 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2: - case 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2 | 1: - type = 4; - break; - default: - /* Not one of the easy encodings. This will have to be - handled by the more complex code below. */ - type = -1; - break; - } - if (type != -1) - { - /* Account for the return value too. */ - if (rtn_bits) - type += 5; - - /* Emit a 2 byte relocation. Then see if it can be handled - with a relocation which is already in the relocation queue. */ - bfd_put_8 (abfd, bfd_reloc->howto->type + type, p); - bfd_put_8 (abfd, sym_num, p + 1); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 2, queue); - done = 1; - } - } - - /* If this could not be handled with a simple relocation, then do a hard - one. Hard relocations occur if the symbol number was too high or if - the encoding of argument relocation bits is too complex. */ - if (! done) - { - /* Don't ask about these magic sequences. I took them straight - from gas-1.36 which took them from the a.out man page. */ - type = rtn_bits; - if ((arg_bits >> 6 & 0xf) == 0xe) - type += 9 * 40; - else - type += (3 * (arg_bits >> 8 & 3) + (arg_bits >> 6 & 3)) * 40; - if ((arg_bits >> 2 & 0xf) == 0xe) - type += 9 * 4; - else - type += (3 * (arg_bits >> 4 & 3) + (arg_bits >> 2 & 3)) * 4; - - /* Output the first two bytes of the relocation. These describe - the length of the relocation and encoding style. */ - bfd_put_8 (abfd, bfd_reloc->howto->type + 10 - + 2 * (sym_num >= 0x100) + (type >= 0x100), - p); - bfd_put_8 (abfd, type, p + 1); - - /* Now output the symbol index and see if this bizarre relocation - just happened to be in the relocation queue. */ - if (sym_num < 0x100) - { - bfd_put_8 (abfd, sym_num, p + 2); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 3, queue); - } - else - { - bfd_put_8 (abfd, sym_num >> 16, p + 2); - bfd_put_16 (abfd, sym_num, p + 3); - p = try_prev_fixup (abfd, subspace_reloc_sizep, p, 5, queue); - } - } - return p; -} - - -/* Return the logarithm of X, base 2, considering X unsigned. - Abort -1 if X is not a power or two or is zero. */ - -static int -log2 (x) - unsigned int x; -{ - int log = 0; - - /* Test for 0 or a power of 2. */ - if (x == 0 || x != (x & -x)) - return -1; - - while ((x >>= 1) != 0) - log++; - return log; -} - -static bfd_reloc_status_type -hppa_som_reloc (abfd, reloc_entry, symbol_in, data, - input_section, output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol_in; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - if (output_bfd) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - return bfd_reloc_ok; -} - -/* Given a generic HPPA relocation type, the instruction format, - and a field selector, return one or more appropriate SOM relocations. */ - -int ** -hppa_som_gen_reloc_type (abfd, base_type, format, field, sym_diff) - bfd *abfd; - int base_type; - int format; - enum hppa_reloc_field_selector_type_alt field; - int sym_diff; -{ - int *final_type, **final_types; - - final_types = (int **) bfd_alloc_by_size_t (abfd, sizeof (int *) * 6); - final_type = (int *) bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types || !final_type) - return NULL; - - /* The field selector may require additional relocations to be - generated. It's impossible to know at this moment if additional - relocations will be needed, so we make them. The code to actually - write the relocation/fixup stream is responsible for removing - any redundant relocations. */ - switch (field) - { - case e_fsel: - case e_psel: - case e_lpsel: - case e_rpsel: - final_types[0] = final_type; - final_types[1] = NULL; - final_types[2] = NULL; - *final_type = base_type; - break; - - case e_tsel: - case e_ltsel: - case e_rtsel: - final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[0]) - return NULL; - if (field == e_tsel) - *final_types[0] = R_FSEL; - else if (field == e_ltsel) - *final_types[0] = R_LSEL; - else - *final_types[0] = R_RSEL; - final_types[1] = final_type; - final_types[2] = NULL; - *final_type = base_type; - break; - - case e_lssel: - case e_rssel: - final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[0]) - return NULL; - *final_types[0] = R_S_MODE; - final_types[1] = final_type; - final_types[2] = NULL; - *final_type = base_type; - break; - - case e_lsel: - case e_rsel: - final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[0]) - return NULL; - *final_types[0] = R_N_MODE; - final_types[1] = final_type; - final_types[2] = NULL; - *final_type = base_type; - break; - - case e_ldsel: - case e_rdsel: - final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[0]) - return NULL; - *final_types[0] = R_D_MODE; - final_types[1] = final_type; - final_types[2] = NULL; - *final_type = base_type; - break; - - case e_lrsel: - case e_rrsel: - final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[0]) - return NULL; - *final_types[0] = R_R_MODE; - final_types[1] = final_type; - final_types[2] = NULL; - *final_type = base_type; - break; - - case e_nsel: - final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[0]) - return NULL; - *final_types[0] = R_N1SEL; - final_types[1] = final_type; - final_types[2] = NULL; - *final_type = base_type; - break; - - case e_nlsel: - case e_nlrsel: - final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[0]) - return NULL; - *final_types[0] = R_N0SEL; - final_types[1] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[1]) - return NULL; - if (field == e_nlsel) - *final_types[1] = R_N_MODE; - else - *final_types[1] = R_R_MODE; - final_types[2] = final_type; - final_types[3] = NULL; - *final_type = base_type; - break; - } - - switch (base_type) - { - case R_HPPA: - /* The difference of two symbols needs *very* special handling. */ - if (sym_diff) - { - final_types[0] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int)); - final_types[1] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int)); - final_types[2] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int)); - final_types[3] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[0] || !final_types[1] || !final_types[2]) - return NULL; - if (field == e_fsel) - *final_types[0] = R_FSEL; - else if (field == e_rsel) - *final_types[0] = R_RSEL; - else if (field == e_lsel) - *final_types[0] = R_LSEL; - *final_types[1] = R_COMP2; - *final_types[2] = R_COMP2; - *final_types[3] = R_COMP1; - final_types[4] = final_type; - *final_types[4] = R_CODE_EXPR; - final_types[5] = NULL; - break; - } - /* PLABELs get their own relocation type. */ - else if (field == e_psel - || field == e_lpsel - || field == e_rpsel) - { - /* A PLABEL relocation that has a size of 32 bits must - be a R_DATA_PLABEL. All others are R_CODE_PLABELs. */ - if (format == 32) - *final_type = R_DATA_PLABEL; - else - *final_type = R_CODE_PLABEL; - } - /* PIC stuff. */ - else if (field == e_tsel - || field == e_ltsel - || field == e_rtsel) - *final_type = R_DLT_REL; - /* A relocation in the data space is always a full 32bits. */ - else if (format == 32) - *final_type = R_DATA_ONE_SYMBOL; - - break; - - case R_HPPA_GOTOFF: - /* More PLABEL special cases. */ - if (field == e_psel - || field == e_lpsel - || field == e_rpsel) - *final_type = R_DATA_PLABEL; - break; - - case R_HPPA_COMPLEX: - /* The difference of two symbols needs *very* special handling. */ - if (sym_diff) - { - final_types[0] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int)); - final_types[1] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int)); - final_types[2] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int)); - final_types[3] = (int *)bfd_alloc_by_size_t (abfd, sizeof (int)); - if (!final_types[0] || !final_types[1] || !final_types[2]) - return NULL; - if (field == e_fsel) - *final_types[0] = R_FSEL; - else if (field == e_rsel) - *final_types[0] = R_RSEL; - else if (field == e_lsel) - *final_types[0] = R_LSEL; - *final_types[1] = R_COMP2; - *final_types[2] = R_COMP2; - *final_types[3] = R_COMP1; - final_types[4] = final_type; - *final_types[4] = R_CODE_EXPR; - final_types[5] = NULL; - break; - } - else - break; - - case R_HPPA_NONE: - case R_HPPA_ABS_CALL: - case R_HPPA_PCREL_CALL: - /* Right now we can default all these. */ - break; - } - return final_types; -} - -/* Return the address of the correct entry in the PA SOM relocation - howto table. */ - -/*ARGSUSED*/ -static reloc_howto_type * -som_bfd_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - if ((int) code < (int) R_NO_RELOCATION + 255) - { - BFD_ASSERT ((int) som_hppa_howto_table[(int) code].type == (int) code); - return &som_hppa_howto_table[(int) code]; - } - - return (reloc_howto_type *) 0; -} - -/* Perform some initialization for an object. Save results of this - initialization in the BFD. */ - -static const bfd_target * -som_object_setup (abfd, file_hdrp, aux_hdrp) - bfd *abfd; - struct header *file_hdrp; - struct som_exec_auxhdr *aux_hdrp; -{ - asection *section; - int found; - - /* som_mkobject will set bfd_error if som_mkobject fails. */ - if (som_mkobject (abfd) != true) - return 0; - - /* Set BFD flags based on what information is available in the SOM. */ - abfd->flags = NO_FLAGS; - if (file_hdrp->symbol_total) - abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS; - - switch (file_hdrp->a_magic) - { - case DEMAND_MAGIC: - abfd->flags |= (D_PAGED | WP_TEXT | EXEC_P); - break; - case SHARE_MAGIC: - abfd->flags |= (WP_TEXT | EXEC_P); - break; - case EXEC_MAGIC: - abfd->flags |= (EXEC_P); - break; - case RELOC_MAGIC: - abfd->flags |= HAS_RELOC; - break; -#ifdef SHL_MAGIC - case SHL_MAGIC: -#endif -#ifdef DL_MAGIC - case DL_MAGIC: -#endif - abfd->flags |= DYNAMIC; - break; - - default: - break; - } - - /* Allocate space to hold the saved exec header information. */ - obj_som_exec_data (abfd) = (struct som_exec_data *) - bfd_zalloc (abfd, sizeof (struct som_exec_data )); - if (obj_som_exec_data (abfd) == NULL) - return NULL; - - /* The braindamaged OSF1 linker switched exec_flags and exec_entry! - - We used to identify OSF1 binaries based on NEW_VERSION_ID, but - apparently the latest HPUX linker is using NEW_VERSION_ID now. - - It's about time, OSF has used the new id since at least 1992; - HPUX didn't start till nearly 1995!. - - The new approach examines the entry field. If it's zero or not 4 - byte aligned then it's not a proper code address and we guess it's - really the executable flags. */ - found = 0; - for (section = abfd->sections; section; section = section->next) - { - if ((section->flags & SEC_CODE) == 0) - continue; - if (aux_hdrp->exec_entry >= section->vma - && aux_hdrp->exec_entry < section->vma + section->_cooked_size) - found = 1; - } - if (aux_hdrp->exec_entry == 0 - || (aux_hdrp->exec_entry & 0x3) != 0 - || ! found) - { - bfd_get_start_address (abfd) = aux_hdrp->exec_flags; - obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_entry; - } - else - { - bfd_get_start_address (abfd) = aux_hdrp->exec_entry; - obj_som_exec_data (abfd)->exec_flags = aux_hdrp->exec_flags; - } - - bfd_default_set_arch_mach (abfd, bfd_arch_hppa, pa10); - bfd_get_symcount (abfd) = file_hdrp->symbol_total; - - /* Initialize the saved symbol table and string table to NULL. - Save important offsets and sizes from the SOM header into - the BFD. */ - obj_som_stringtab (abfd) = (char *) NULL; - obj_som_symtab (abfd) = (som_symbol_type *) NULL; - obj_som_sorted_syms (abfd) = NULL; - obj_som_stringtab_size (abfd) = file_hdrp->symbol_strings_size; - obj_som_sym_filepos (abfd) = file_hdrp->symbol_location; - obj_som_str_filepos (abfd) = file_hdrp->symbol_strings_location; - obj_som_reloc_filepos (abfd) = file_hdrp->fixup_request_location; - obj_som_exec_data (abfd)->system_id = file_hdrp->system_id; - - return abfd->xvec; -} - -/* Convert all of the space and subspace info into BFD sections. Each space - contains a number of subspaces, which in turn describe the mapping between - regions of the exec file, and the address space that the program runs in. - BFD sections which correspond to spaces will overlap the sections for the - associated subspaces. */ - -static boolean -setup_sections (abfd, file_hdr) - bfd *abfd; - struct header *file_hdr; -{ - char *space_strings; - unsigned int space_index, i; - unsigned int total_subspaces = 0; - asection **subspace_sections, *section; - - /* First, read in space names */ - - space_strings = bfd_malloc (file_hdr->space_strings_size); - if (!space_strings && file_hdr->space_strings_size != 0) - goto error_return; - - if (bfd_seek (abfd, file_hdr->space_strings_location, SEEK_SET) < 0) - goto error_return; - if (bfd_read (space_strings, 1, file_hdr->space_strings_size, abfd) - != file_hdr->space_strings_size) - goto error_return; - - /* Loop over all of the space dictionaries, building up sections */ - for (space_index = 0; space_index < file_hdr->space_total; space_index++) - { - struct space_dictionary_record space; - struct subspace_dictionary_record subspace, save_subspace; - int subspace_index; - asection *space_asect; - char *newname; - - /* Read the space dictionary element */ - if (bfd_seek (abfd, file_hdr->space_location - + space_index * sizeof space, SEEK_SET) < 0) - goto error_return; - if (bfd_read (&space, 1, sizeof space, abfd) != sizeof space) - goto error_return; - - /* Setup the space name string */ - space.name.n_name = space.name.n_strx + space_strings; - - /* Make a section out of it */ - newname = bfd_alloc (abfd, strlen (space.name.n_name) + 1); - if (!newname) - goto error_return; - strcpy (newname, space.name.n_name); - - space_asect = bfd_make_section_anyway (abfd, newname); - if (!space_asect) - goto error_return; - - if (space.is_loadable == 0) - space_asect->flags |= SEC_DEBUGGING; - - /* Set up all the attributes for the space. */ - if (bfd_som_set_section_attributes (space_asect, space.is_defined, - space.is_private, space.sort_key, - space.space_number) == false) - goto error_return; - - /* If the space has no subspaces, then we're done. */ - if (space.subspace_quantity == 0) - continue; - - /* Now, read in the first subspace for this space */ - if (bfd_seek (abfd, file_hdr->subspace_location - + space.subspace_index * sizeof subspace, - SEEK_SET) < 0) - goto error_return; - if (bfd_read (&subspace, 1, sizeof subspace, abfd) != sizeof subspace) - goto error_return; - /* Seek back to the start of the subspaces for loop below */ - if (bfd_seek (abfd, file_hdr->subspace_location - + space.subspace_index * sizeof subspace, - SEEK_SET) < 0) - goto error_return; - - /* Setup the start address and file loc from the first subspace record */ - space_asect->vma = subspace.subspace_start; - space_asect->filepos = subspace.file_loc_init_value; - space_asect->alignment_power = log2 (subspace.alignment); - if (space_asect->alignment_power == -1) - goto error_return; - - /* Initialize save_subspace so we can reliably determine if this - loop placed any useful values into it. */ - memset (&save_subspace, 0, sizeof (struct subspace_dictionary_record)); - - /* Loop over the rest of the subspaces, building up more sections */ - for (subspace_index = 0; subspace_index < space.subspace_quantity; - subspace_index++) - { - asection *subspace_asect; - - /* Read in the next subspace */ - if (bfd_read (&subspace, 1, sizeof subspace, abfd) - != sizeof subspace) - goto error_return; - - /* Setup the subspace name string */ - subspace.name.n_name = subspace.name.n_strx + space_strings; - - newname = bfd_alloc (abfd, strlen (subspace.name.n_name) + 1); - if (!newname) - goto error_return; - strcpy (newname, subspace.name.n_name); - - /* Make a section out of this subspace */ - subspace_asect = bfd_make_section_anyway (abfd, newname); - if (!subspace_asect) - goto error_return; - - /* Store private information about the section. */ - if (bfd_som_set_subsection_attributes (subspace_asect, space_asect, - subspace.access_control_bits, - subspace.sort_key, - subspace.quadrant) == false) - goto error_return; - - /* Keep an easy mapping between subspaces and sections. - Note we do not necessarily read the subspaces in the - same order in which they appear in the object file. - - So to make the target index come out correctly, we - store the location of the subspace header in target - index, then sort using the location of the subspace - header as the key. Then we can assign correct - subspace indices. */ - total_subspaces++; - subspace_asect->target_index = bfd_tell (abfd) - sizeof (subspace); - - /* Set SEC_READONLY and SEC_CODE/SEC_DATA as specified - by the access_control_bits in the subspace header. */ - switch (subspace.access_control_bits >> 4) - { - /* Readonly data. */ - case 0x0: - subspace_asect->flags |= SEC_DATA | SEC_READONLY; - break; - - /* Normal data. */ - case 0x1: - subspace_asect->flags |= SEC_DATA; - break; - - /* Readonly code and the gateways. - Gateways have other attributes which do not map - into anything BFD knows about. */ - case 0x2: - case 0x4: - case 0x5: - case 0x6: - case 0x7: - subspace_asect->flags |= SEC_CODE | SEC_READONLY; - break; - - /* dynamic (writable) code. */ - case 0x3: - subspace_asect->flags |= SEC_CODE; - break; - } - - if (subspace.dup_common || subspace.is_common) - subspace_asect->flags |= SEC_IS_COMMON; - else if (subspace.subspace_length > 0) - subspace_asect->flags |= SEC_HAS_CONTENTS; - - if (subspace.is_loadable) - subspace_asect->flags |= SEC_ALLOC | SEC_LOAD; - else - subspace_asect->flags |= SEC_DEBUGGING; - - if (subspace.code_only) - subspace_asect->flags |= SEC_CODE; - - /* Both file_loc_init_value and initialization_length will - be zero for a BSS like subspace. */ - if (subspace.file_loc_init_value == 0 - && subspace.initialization_length == 0) - subspace_asect->flags &= ~(SEC_DATA | SEC_LOAD | SEC_HAS_CONTENTS); - - /* This subspace has relocations. - The fixup_request_quantity is a byte count for the number of - entries in the relocation stream; it is not the actual number - of relocations in the subspace. */ - if (subspace.fixup_request_quantity != 0) - { - subspace_asect->flags |= SEC_RELOC; - subspace_asect->rel_filepos = subspace.fixup_request_index; - som_section_data (subspace_asect)->reloc_size - = subspace.fixup_request_quantity; - /* We can not determine this yet. When we read in the - relocation table the correct value will be filled in. */ - subspace_asect->reloc_count = -1; - } - - /* Update save_subspace if appropriate. */ - if (subspace.file_loc_init_value > save_subspace.file_loc_init_value) - save_subspace = subspace; - - subspace_asect->vma = subspace.subspace_start; - subspace_asect->_cooked_size = subspace.subspace_length; - subspace_asect->_raw_size = subspace.subspace_length; - subspace_asect->filepos = subspace.file_loc_init_value; - subspace_asect->alignment_power = log2 (subspace.alignment); - if (subspace_asect->alignment_power == -1) - goto error_return; - } - - /* Yow! there is no subspace within the space which actually - has initialized information in it; this should never happen - as far as I know. */ - if (!save_subspace.file_loc_init_value) - goto error_return; - - /* Setup the sizes for the space section based upon the info in the - last subspace of the space. */ - space_asect->_cooked_size = save_subspace.subspace_start - - space_asect->vma + save_subspace.subspace_length; - space_asect->_raw_size = save_subspace.file_loc_init_value - - space_asect->filepos + save_subspace.initialization_length; - } - /* Now that we've read in all the subspace records, we need to assign - a target index to each subspace. */ - subspace_sections = (asection **) bfd_malloc (total_subspaces - * sizeof (asection *)); - if (subspace_sections == NULL) - goto error_return; - - for (i = 0, section = abfd->sections; section; section = section->next) - { - if (!som_is_subspace (section)) - continue; - - subspace_sections[i] = section; - i++; - } - qsort (subspace_sections, total_subspaces, - sizeof (asection *), compare_subspaces); - - /* subspace_sections is now sorted in the order in which the subspaces - appear in the object file. Assign an index to each one now. */ - for (i = 0; i < total_subspaces; i++) - subspace_sections[i]->target_index = i; - - if (space_strings != NULL) - free (space_strings); - - if (subspace_sections != NULL) - free (subspace_sections); - - return true; - - error_return: - if (space_strings != NULL) - free (space_strings); - - if (subspace_sections != NULL) - free (subspace_sections); - return false; -} - -/* Read in a SOM object and make it into a BFD. */ - -static const bfd_target * -som_object_p (abfd) - bfd *abfd; -{ - struct header file_hdr; - struct som_exec_auxhdr aux_hdr; - - if (bfd_read ((PTR) & file_hdr, 1, FILE_HDR_SIZE, abfd) != FILE_HDR_SIZE) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - if (!_PA_RISC_ID (file_hdr.system_id)) - { - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - switch (file_hdr.a_magic) - { - case RELOC_MAGIC: - case EXEC_MAGIC: - case SHARE_MAGIC: - case DEMAND_MAGIC: -#ifdef DL_MAGIC - case DL_MAGIC: -#endif -#ifdef SHL_MAGIC - case SHL_MAGIC: -#endif -#ifdef EXECLIBMAGIC - case EXECLIBMAGIC: -#endif -#ifdef SHARED_MAGIC_CNX - case SHARED_MAGIC_CNX: -#endif - break; - default: - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - if (file_hdr.version_id != VERSION_ID - && file_hdr.version_id != NEW_VERSION_ID) - { - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - /* If the aux_header_size field in the file header is zero, then this - object is an incomplete executable (a .o file). Do not try to read - a non-existant auxiliary header. */ - memset (&aux_hdr, 0, sizeof (struct som_exec_auxhdr)); - if (file_hdr.aux_header_size != 0) - { - if (bfd_read ((PTR) & aux_hdr, 1, AUX_HDR_SIZE, abfd) != AUX_HDR_SIZE) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - } - - if (!setup_sections (abfd, &file_hdr)) - { - /* setup_sections does not bubble up a bfd error code. */ - bfd_set_error (bfd_error_bad_value); - return 0; - } - - /* This appears to be a valid SOM object. Do some initialization. */ - return som_object_setup (abfd, &file_hdr, &aux_hdr); -} - -/* Create a SOM object. */ - -static boolean -som_mkobject (abfd) - bfd *abfd; -{ - /* Allocate memory to hold backend information. */ - abfd->tdata.som_data = (struct som_data_struct *) - bfd_zalloc (abfd, sizeof (struct som_data_struct)); - if (abfd->tdata.som_data == NULL) - return false; - return true; -} - -/* Initialize some information in the file header. This routine makes - not attempt at doing the right thing for a full executable; it - is only meant to handle relocatable objects. */ - -static boolean -som_prep_headers (abfd) - bfd *abfd; -{ - struct header *file_hdr; - asection *section; - - /* Make and attach a file header to the BFD. */ - file_hdr = (struct header *) bfd_zalloc (abfd, sizeof (struct header)); - if (file_hdr == NULL) - return false; - obj_som_file_hdr (abfd) = file_hdr; - - if (abfd->flags & (EXEC_P | DYNAMIC)) - { - - /* Make and attach an exec header to the BFD. */ - obj_som_exec_hdr (abfd) = (struct som_exec_auxhdr *) - bfd_zalloc (abfd, sizeof (struct som_exec_auxhdr)); - if (obj_som_exec_hdr (abfd) == NULL) - return false; - - if (abfd->flags & D_PAGED) - file_hdr->a_magic = DEMAND_MAGIC; - else if (abfd->flags & WP_TEXT) - file_hdr->a_magic = SHARE_MAGIC; -#ifdef SHL_MAGIC - else if (abfd->flags & DYNAMIC) - file_hdr->a_magic = SHL_MAGIC; -#endif - else - file_hdr->a_magic = EXEC_MAGIC; - } - else - file_hdr->a_magic = RELOC_MAGIC; - - /* Only new format SOM is supported. */ - file_hdr->version_id = NEW_VERSION_ID; - - /* These fields are optional, and embedding timestamps is not always - a wise thing to do, it makes comparing objects during a multi-stage - bootstrap difficult. */ - file_hdr->file_time.secs = 0; - file_hdr->file_time.nanosecs = 0; - - file_hdr->entry_space = 0; - file_hdr->entry_subspace = 0; - file_hdr->entry_offset = 0; - file_hdr->presumed_dp = 0; - - /* Now iterate over the sections translating information from - BFD sections to SOM spaces/subspaces. */ - - for (section = abfd->sections; section != NULL; section = section->next) - { - /* Ignore anything which has not been marked as a space or - subspace. */ - if (!som_is_space (section) && !som_is_subspace (section)) - continue; - - if (som_is_space (section)) - { - /* Allocate space for the space dictionary. */ - som_section_data (section)->space_dict - = (struct space_dictionary_record *) - bfd_zalloc (abfd, sizeof (struct space_dictionary_record)); - if (som_section_data (section)->space_dict == NULL) - return false; - /* Set space attributes. Note most attributes of SOM spaces - are set based on the subspaces it contains. */ - som_section_data (section)->space_dict->loader_fix_index = -1; - som_section_data (section)->space_dict->init_pointer_index = -1; - - /* Set more attributes that were stuffed away in private data. */ - som_section_data (section)->space_dict->sort_key = - som_section_data (section)->copy_data->sort_key; - som_section_data (section)->space_dict->is_defined = - som_section_data (section)->copy_data->is_defined; - som_section_data (section)->space_dict->is_private = - som_section_data (section)->copy_data->is_private; - som_section_data (section)->space_dict->space_number = - som_section_data (section)->copy_data->space_number; - } - else - { - /* Allocate space for the subspace dictionary. */ - som_section_data (section)->subspace_dict - = (struct subspace_dictionary_record *) - bfd_zalloc (abfd, sizeof (struct subspace_dictionary_record)); - if (som_section_data (section)->subspace_dict == NULL) - return false; - - /* Set subspace attributes. Basic stuff is done here, additional - attributes are filled in later as more information becomes - available. */ - if (section->flags & SEC_IS_COMMON) - { - som_section_data (section)->subspace_dict->dup_common = 1; - som_section_data (section)->subspace_dict->is_common = 1; - } - - if (section->flags & SEC_ALLOC) - som_section_data (section)->subspace_dict->is_loadable = 1; - - if (section->flags & SEC_CODE) - som_section_data (section)->subspace_dict->code_only = 1; - - som_section_data (section)->subspace_dict->subspace_start = - section->vma; - som_section_data (section)->subspace_dict->subspace_length = - bfd_section_size (abfd, section); - som_section_data (section)->subspace_dict->initialization_length = - bfd_section_size (abfd, section); - som_section_data (section)->subspace_dict->alignment = - 1 << section->alignment_power; - - /* Set more attributes that were stuffed away in private data. */ - som_section_data (section)->subspace_dict->sort_key = - som_section_data (section)->copy_data->sort_key; - som_section_data (section)->subspace_dict->access_control_bits = - som_section_data (section)->copy_data->access_control_bits; - som_section_data (section)->subspace_dict->quadrant = - som_section_data (section)->copy_data->quadrant; - } - } - return true; -} - -/* Return true if the given section is a SOM space, false otherwise. */ - -static boolean -som_is_space (section) - asection *section; -{ - /* If no copy data is available, then it's neither a space nor a - subspace. */ - if (som_section_data (section)->copy_data == NULL) - return false; - - /* If the containing space isn't the same as the given section, - then this isn't a space. */ - if (som_section_data (section)->copy_data->container != section - && (som_section_data (section)->copy_data->container->output_section - != section)) - return false; - - /* OK. Must be a space. */ - return true; -} - -/* Return true if the given section is a SOM subspace, false otherwise. */ - -static boolean -som_is_subspace (section) - asection *section; -{ - /* If no copy data is available, then it's neither a space nor a - subspace. */ - if (som_section_data (section)->copy_data == NULL) - return false; - - /* If the containing space is the same as the given section, - then this isn't a subspace. */ - if (som_section_data (section)->copy_data->container == section - || (som_section_data (section)->copy_data->container->output_section - == section)) - return false; - - /* OK. Must be a subspace. */ - return true; -} - -/* Return true if the given space containins the given subspace. It - is safe to assume space really is a space, and subspace really - is a subspace. */ - -static boolean -som_is_container (space, subspace) - asection *space, *subspace; -{ - return (som_section_data (subspace)->copy_data->container == space - || (som_section_data (subspace)->copy_data->container->output_section - == space)); -} - -/* Count and return the number of spaces attached to the given BFD. */ - -static unsigned long -som_count_spaces (abfd) - bfd *abfd; -{ - int count = 0; - asection *section; - - for (section = abfd->sections; section != NULL; section = section->next) - count += som_is_space (section); - - return count; -} - -/* Count the number of subspaces attached to the given BFD. */ - -static unsigned long -som_count_subspaces (abfd) - bfd *abfd; -{ - int count = 0; - asection *section; - - for (section = abfd->sections; section != NULL; section = section->next) - count += som_is_subspace (section); - - return count; -} - -/* Return -1, 0, 1 indicating the relative ordering of sym1 and sym2. - - We desire symbols to be ordered starting with the symbol with the - highest relocation count down to the symbol with the lowest relocation - count. Doing so compacts the relocation stream. */ - -static int -compare_syms (arg1, arg2) - const PTR arg1; - const PTR arg2; - -{ - asymbol **sym1 = (asymbol **) arg1; - asymbol **sym2 = (asymbol **) arg2; - unsigned int count1, count2; - - /* Get relocation count for each symbol. Note that the count - is stored in the udata pointer for section symbols! */ - if ((*sym1)->flags & BSF_SECTION_SYM) - count1 = (*sym1)->udata.i; - else - count1 = som_symbol_data (*sym1)->reloc_count; - - if ((*sym2)->flags & BSF_SECTION_SYM) - count2 = (*sym2)->udata.i; - else - count2 = som_symbol_data (*sym2)->reloc_count; - - /* Return the appropriate value. */ - if (count1 < count2) - return 1; - else if (count1 > count2) - return -1; - return 0; -} - -/* Return -1, 0, 1 indicating the relative ordering of subspace1 - and subspace. */ - -static int -compare_subspaces (arg1, arg2) - const PTR arg1; - const PTR arg2; - -{ - asection **subspace1 = (asection **) arg1; - asection **subspace2 = (asection **) arg2; - unsigned int count1, count2; - - if ((*subspace1)->target_index < (*subspace2)->target_index) - return -1; - else if ((*subspace2)->target_index < (*subspace1)->target_index) - return 1; - else - return 0; -} - -/* Perform various work in preparation for emitting the fixup stream. */ - -static void -som_prep_for_fixups (abfd, syms, num_syms) - bfd *abfd; - asymbol **syms; - unsigned long num_syms; -{ - int i; - asection *section; - asymbol **sorted_syms; - - /* Most SOM relocations involving a symbol have a length which is - dependent on the index of the symbol. So symbols which are - used often in relocations should have a small index. */ - - /* First initialize the counters for each symbol. */ - for (i = 0; i < num_syms; i++) - { - /* Handle a section symbol; these have no pointers back to the - SOM symbol info. So we just use the udata field to hold the - relocation count. */ - if (som_symbol_data (syms[i]) == NULL - || syms[i]->flags & BSF_SECTION_SYM) - { - syms[i]->flags |= BSF_SECTION_SYM; - syms[i]->udata.i = 0; - } - else - som_symbol_data (syms[i])->reloc_count = 0; - } - - /* Now that the counters are initialized, make a weighted count - of how often a given symbol is used in a relocation. */ - for (section = abfd->sections; section != NULL; section = section->next) - { - int i; - - /* Does this section have any relocations? */ - if (section->reloc_count <= 0) - continue; - - /* Walk through each relocation for this section. */ - for (i = 1; i < section->reloc_count; i++) - { - arelent *reloc = section->orelocation[i]; - int scale; - - /* A relocation against a symbol in the *ABS* section really - does not have a symbol. Likewise if the symbol isn't associated - with any section. */ - if (reloc->sym_ptr_ptr == NULL - || bfd_is_abs_section ((*reloc->sym_ptr_ptr)->section)) - continue; - - /* Scaling to encourage symbols involved in R_DP_RELATIVE - and R_CODE_ONE_SYMBOL relocations to come first. These - two relocations have single byte versions if the symbol - index is very small. */ - if (reloc->howto->type == R_DP_RELATIVE - || reloc->howto->type == R_CODE_ONE_SYMBOL) - scale = 2; - else - scale = 1; - - /* Handle section symbols by storing the count in the udata - field. It will not be used and the count is very important - for these symbols. */ - if ((*reloc->sym_ptr_ptr)->flags & BSF_SECTION_SYM) - { - (*reloc->sym_ptr_ptr)->udata.i = - (*reloc->sym_ptr_ptr)->udata.i + scale; - continue; - } - - /* A normal symbol. Increment the count. */ - som_symbol_data (*reloc->sym_ptr_ptr)->reloc_count += scale; - } - } - - /* Sort a copy of the symbol table, rather than the canonical - output symbol table. */ - sorted_syms = (asymbol **) bfd_zalloc (abfd, num_syms * sizeof (asymbol *)); - memcpy (sorted_syms, syms, num_syms * sizeof (asymbol *)); - qsort (sorted_syms, num_syms, sizeof (asymbol *), compare_syms); - obj_som_sorted_syms (abfd) = sorted_syms; - - /* Compute the symbol indexes, they will be needed by the relocation - code. */ - for (i = 0; i < num_syms; i++) - { - /* A section symbol. Again, there is no pointer to backend symbol - information, so we reuse the udata field again. */ - if (sorted_syms[i]->flags & BSF_SECTION_SYM) - sorted_syms[i]->udata.i = i; - else - som_symbol_data (sorted_syms[i])->index = i; - } -} - -static boolean -som_write_fixups (abfd, current_offset, total_reloc_sizep) - bfd *abfd; - unsigned long current_offset; - unsigned int *total_reloc_sizep; -{ - unsigned int i, j; - /* Chunk of memory that we can use as buffer space, then throw - away. */ - unsigned char tmp_space[SOM_TMP_BUFSIZE]; - unsigned char *p; - unsigned int total_reloc_size = 0; - unsigned int subspace_reloc_size = 0; - unsigned int num_spaces = obj_som_file_hdr (abfd)->space_total; - asection *section = abfd->sections; - - memset (tmp_space, 0, SOM_TMP_BUFSIZE); - p = tmp_space; - - /* All the fixups for a particular subspace are emitted in a single - stream. All the subspaces for a particular space are emitted - as a single stream. - - So, to get all the locations correct one must iterate through all the - spaces, for each space iterate through its subspaces and output a - fixups stream. */ - for (i = 0; i < num_spaces; i++) - { - asection *subsection; - - /* Find a space. */ - while (!som_is_space (section)) - section = section->next; - - /* Now iterate through each of its subspaces. */ - for (subsection = abfd->sections; - subsection != NULL; - subsection = subsection->next) - { - int reloc_offset, current_rounding_mode; - - /* Find a subspace of this space. */ - if (!som_is_subspace (subsection) - || !som_is_container (section, subsection)) - continue; - - /* If this subspace does not have real data, then we are - finised with it. */ - if ((subsection->flags & SEC_HAS_CONTENTS) == 0) - { - som_section_data (subsection)->subspace_dict->fixup_request_index - = -1; - continue; - } - - /* This subspace has some relocations. Put the relocation stream - index into the subspace record. */ - som_section_data (subsection)->subspace_dict->fixup_request_index - = total_reloc_size; - - /* To make life easier start over with a clean slate for - each subspace. Seek to the start of the relocation stream - for this subspace in preparation for writing out its fixup - stream. */ - if (bfd_seek (abfd, current_offset + total_reloc_size, SEEK_SET) < 0) - return false; - - /* Buffer space has already been allocated. Just perform some - initialization here. */ - p = tmp_space; - subspace_reloc_size = 0; - reloc_offset = 0; - som_initialize_reloc_queue (reloc_queue); - current_rounding_mode = R_N_MODE; - - /* Translate each BFD relocation into one or more SOM - relocations. */ - for (j = 0; j < subsection->reloc_count; j++) - { - arelent *bfd_reloc = subsection->orelocation[j]; - unsigned int skip; - int sym_num; - - /* Get the symbol number. Remember it's stored in a - special place for section symbols. */ - if ((*bfd_reloc->sym_ptr_ptr)->flags & BSF_SECTION_SYM) - sym_num = (*bfd_reloc->sym_ptr_ptr)->udata.i; - else - sym_num = som_symbol_data (*bfd_reloc->sym_ptr_ptr)->index; - - /* If there is not enough room for the next couple relocations, - then dump the current buffer contents now. Also reinitialize - the relocation queue. - - No single BFD relocation could ever translate into more - than 100 bytes of SOM relocations (20bytes is probably the - upper limit, but leave lots of space for growth). */ - if (p - tmp_space + 100 > SOM_TMP_BUFSIZE) - { - if (bfd_write ((PTR) tmp_space, p - tmp_space, 1, abfd) - != p - tmp_space) - return false; - - p = tmp_space; - som_initialize_reloc_queue (reloc_queue); - } - - /* Emit R_NO_RELOCATION fixups to map any bytes which were - skipped. */ - skip = bfd_reloc->address - reloc_offset; - p = som_reloc_skip (abfd, skip, p, - &subspace_reloc_size, reloc_queue); - - /* Update reloc_offset for the next iteration. - - Many relocations do not consume input bytes. They - are markers, or set state necessary to perform some - later relocation. */ - switch (bfd_reloc->howto->type) - { - /* This only needs to handle relocations that may be - made by hppa_som_gen_reloc. */ - case R_ENTRY: - case R_ALT_ENTRY: - case R_EXIT: - case R_N_MODE: - case R_S_MODE: - case R_D_MODE: - case R_R_MODE: - case R_FSEL: - case R_LSEL: - case R_RSEL: - case R_COMP1: - case R_COMP2: - case R_BEGIN_BRTAB: - case R_END_BRTAB: - case R_N0SEL: - case R_N1SEL: - reloc_offset = bfd_reloc->address; - break; - - default: - reloc_offset = bfd_reloc->address + 4; - break; - } - - /* Now the actual relocation we care about. */ - switch (bfd_reloc->howto->type) - { - case R_PCREL_CALL: - case R_ABS_CALL: - p = som_reloc_call (abfd, p, &subspace_reloc_size, - bfd_reloc, sym_num, reloc_queue); - break; - - case R_CODE_ONE_SYMBOL: - case R_DP_RELATIVE: - /* Account for any addend. */ - if (bfd_reloc->addend) - p = som_reloc_addend (abfd, bfd_reloc->addend, p, - &subspace_reloc_size, reloc_queue); - - if (sym_num < 0x20) - { - bfd_put_8 (abfd, bfd_reloc->howto->type + sym_num, p); - subspace_reloc_size += 1; - p += 1; - } - else if (sym_num < 0x100) - { - bfd_put_8 (abfd, bfd_reloc->howto->type + 32, p); - bfd_put_8 (abfd, sym_num, p + 1); - p = try_prev_fixup (abfd, &subspace_reloc_size, p, - 2, reloc_queue); - } - else if (sym_num < 0x10000000) - { - bfd_put_8 (abfd, bfd_reloc->howto->type + 33, p); - bfd_put_8 (abfd, sym_num >> 16, p + 1); - bfd_put_16 (abfd, sym_num, p + 2); - p = try_prev_fixup (abfd, &subspace_reloc_size, - p, 4, reloc_queue); - } - else - abort (); - break; - - case R_DATA_ONE_SYMBOL: - case R_DATA_PLABEL: - case R_CODE_PLABEL: - case R_DLT_REL: - /* Account for any addend using R_DATA_OVERRIDE. */ - if (bfd_reloc->howto->type != R_DATA_ONE_SYMBOL - && bfd_reloc->addend) - p = som_reloc_addend (abfd, bfd_reloc->addend, p, - &subspace_reloc_size, reloc_queue); - - if (sym_num < 0x100) - { - bfd_put_8 (abfd, bfd_reloc->howto->type, p); - bfd_put_8 (abfd, sym_num, p + 1); - p = try_prev_fixup (abfd, &subspace_reloc_size, p, - 2, reloc_queue); - } - else if (sym_num < 0x10000000) - { - bfd_put_8 (abfd, bfd_reloc->howto->type + 1, p); - bfd_put_8 (abfd, sym_num >> 16, p + 1); - bfd_put_16 (abfd, sym_num, p + 2); - p = try_prev_fixup (abfd, &subspace_reloc_size, - p, 4, reloc_queue); - } - else - abort (); - break; - - case R_ENTRY: - { - int tmp; - arelent *tmp_reloc = NULL; - bfd_put_8 (abfd, R_ENTRY, p); - - /* R_ENTRY relocations have 64 bits of associated - data. Unfortunately the addend field of a bfd - relocation is only 32 bits. So, we split up - the 64bit unwind information and store part in - the R_ENTRY relocation, and the rest in the R_EXIT - relocation. */ - bfd_put_32 (abfd, bfd_reloc->addend, p + 1); - - /* Find the next R_EXIT relocation. */ - for (tmp = j; tmp < subsection->reloc_count; tmp++) - { - tmp_reloc = subsection->orelocation[tmp]; - if (tmp_reloc->howto->type == R_EXIT) - break; - } - - if (tmp == subsection->reloc_count) - abort (); - - bfd_put_32 (abfd, tmp_reloc->addend, p + 5); - p = try_prev_fixup (abfd, &subspace_reloc_size, - p, 9, reloc_queue); - break; - } - - case R_N_MODE: - case R_S_MODE: - case R_D_MODE: - case R_R_MODE: - /* If this relocation requests the current rounding - mode, then it is redundant. */ - if (bfd_reloc->howto->type != current_rounding_mode) - { - bfd_put_8 (abfd, bfd_reloc->howto->type, p); - subspace_reloc_size += 1; - p += 1; - current_rounding_mode = bfd_reloc->howto->type; - } - break; - - case R_EXIT: - case R_ALT_ENTRY: - case R_FSEL: - case R_LSEL: - case R_RSEL: - case R_BEGIN_BRTAB: - case R_END_BRTAB: - case R_N0SEL: - case R_N1SEL: - bfd_put_8 (abfd, bfd_reloc->howto->type, p); - subspace_reloc_size += 1; - p += 1; - break; - - case R_COMP1: - /* The only time we generate R_COMP1, R_COMP2 and - R_CODE_EXPR relocs is for the difference of two - symbols. Hence we can cheat here. */ - bfd_put_8 (abfd, bfd_reloc->howto->type, p); - bfd_put_8 (abfd, 0x44, p + 1); - p = try_prev_fixup (abfd, &subspace_reloc_size, - p, 2, reloc_queue); - break; - - case R_COMP2: - /* The only time we generate R_COMP1, R_COMP2 and - R_CODE_EXPR relocs is for the difference of two - symbols. Hence we can cheat here. */ - bfd_put_8 (abfd, bfd_reloc->howto->type, p); - bfd_put_8 (abfd, 0x80, p + 1); - bfd_put_8 (abfd, sym_num >> 16, p + 2); - bfd_put_16 (abfd, sym_num, p + 3); - p = try_prev_fixup (abfd, &subspace_reloc_size, - p, 5, reloc_queue); - break; - - case R_CODE_EXPR: - /* The only time we generate R_COMP1, R_COMP2 and - R_CODE_EXPR relocs is for the difference of two - symbols. Hence we can cheat here. */ - bfd_put_8 (abfd, bfd_reloc->howto->type, p); - subspace_reloc_size += 1; - p += 1; - break; - - /* Put a "R_RESERVED" relocation in the stream if - we hit something we do not understand. The linker - will complain loudly if this ever happens. */ - default: - bfd_put_8 (abfd, 0xff, p); - subspace_reloc_size += 1; - p += 1; - break; - } - } - - /* Last BFD relocation for a subspace has been processed. - Map the rest of the subspace with R_NO_RELOCATION fixups. */ - p = som_reloc_skip (abfd, bfd_section_size (abfd, subsection) - - reloc_offset, - p, &subspace_reloc_size, reloc_queue); - - /* Scribble out the relocations. */ - if (bfd_write ((PTR) tmp_space, p - tmp_space, 1, abfd) - != p - tmp_space) - return false; - p = tmp_space; - - total_reloc_size += subspace_reloc_size; - som_section_data (subsection)->subspace_dict->fixup_request_quantity - = subspace_reloc_size; - } - section = section->next; - } - *total_reloc_sizep = total_reloc_size; - return true; -} - -/* Write out the space/subspace string table. */ - -static boolean -som_write_space_strings (abfd, current_offset, string_sizep) - bfd *abfd; - unsigned long current_offset; - unsigned int *string_sizep; -{ - /* Chunk of memory that we can use as buffer space, then throw - away. */ - unsigned char tmp_space[SOM_TMP_BUFSIZE]; - unsigned char *p; - unsigned int strings_size = 0; - asection *section; - - memset (tmp_space, 0, SOM_TMP_BUFSIZE); - p = tmp_space; - - /* Seek to the start of the space strings in preparation for writing - them out. */ - if (bfd_seek (abfd, current_offset, SEEK_SET) < 0) - return false; - - /* Walk through all the spaces and subspaces (order is not important) - building up and writing string table entries for their names. */ - for (section = abfd->sections; section != NULL; section = section->next) - { - int length; - - /* Only work with space/subspaces; avoid any other sections - which might have been made (.text for example). */ - if (!som_is_space (section) && !som_is_subspace (section)) - continue; - - /* Get the length of the space/subspace name. */ - length = strlen (section->name); - - /* If there is not enough room for the next entry, then dump the - current buffer contents now. Each entry will take 4 bytes to - hold the string length + the string itself + null terminator. */ - if (p - tmp_space + 5 + length > SOM_TMP_BUFSIZE) - { - if (bfd_write ((PTR) &tmp_space[0], p - tmp_space, 1, abfd) - != p - tmp_space) - return false; - /* Reset to beginning of the buffer space. */ - p = tmp_space; - } - - /* First element in a string table entry is the length of the - string. Alignment issues are already handled. */ - bfd_put_32 (abfd, length, p); - p += 4; - strings_size += 4; - - /* Record the index in the space/subspace records. */ - if (som_is_space (section)) - som_section_data (section)->space_dict->name.n_strx = strings_size; - else - som_section_data (section)->subspace_dict->name.n_strx = strings_size; - - /* Next comes the string itself + a null terminator. */ - strcpy (p, section->name); - p += length + 1; - strings_size += length + 1; - - /* Always align up to the next word boundary. */ - while (strings_size % 4) - { - bfd_put_8 (abfd, 0, p); - p++; - strings_size++; - } - } - - /* Done with the space/subspace strings. Write out any information - contained in a partial block. */ - if (bfd_write ((PTR) &tmp_space[0], p - tmp_space, 1, abfd) != p - tmp_space) - return false; - *string_sizep = strings_size; - return true; -} - -/* Write out the symbol string table. */ - -static boolean -som_write_symbol_strings (abfd, current_offset, syms, num_syms, string_sizep) - bfd *abfd; - unsigned long current_offset; - asymbol **syms; - unsigned int num_syms; - unsigned int *string_sizep; -{ - unsigned int i; - - /* Chunk of memory that we can use as buffer space, then throw - away. */ - unsigned char tmp_space[SOM_TMP_BUFSIZE]; - unsigned char *p; - unsigned int strings_size = 0; - - memset (tmp_space, 0, SOM_TMP_BUFSIZE); - p = tmp_space; - - /* Seek to the start of the space strings in preparation for writing - them out. */ - if (bfd_seek (abfd, current_offset, SEEK_SET) < 0) - return false; - - for (i = 0; i < num_syms; i++) - { - int length = strlen (syms[i]->name); - - /* If there is not enough room for the next entry, then dump the - current buffer contents now. */ - if (p - tmp_space + 5 + length > SOM_TMP_BUFSIZE) - { - if (bfd_write ((PTR) &tmp_space[0], p - tmp_space, 1, abfd) - != p - tmp_space) - return false; - /* Reset to beginning of the buffer space. */ - p = tmp_space; - } - - /* First element in a string table entry is the length of the - string. This must always be 4 byte aligned. This is also - an appropriate time to fill in the string index field in the - symbol table entry. */ - bfd_put_32 (abfd, length, p); - strings_size += 4; - p += 4; - - /* Next comes the string itself + a null terminator. */ - strcpy (p, syms[i]->name); - - som_symbol_data(syms[i])->stringtab_offset = strings_size; - p += length + 1; - strings_size += length + 1; - - /* Always align up to the next word boundary. */ - while (strings_size % 4) - { - bfd_put_8 (abfd, 0, p); - strings_size++; - p++; - } - } - - /* Scribble out any partial block. */ - if (bfd_write ((PTR) &tmp_space[0], p - tmp_space, 1, abfd) != p - tmp_space) - return false; - - *string_sizep = strings_size; - return true; -} - -/* Compute variable information to be placed in the SOM headers, - space/subspace dictionaries, relocation streams, etc. Begin - writing parts of the object file. */ - -static boolean -som_begin_writing (abfd) - bfd *abfd; -{ - unsigned long current_offset = 0; - int strings_size = 0; - unsigned int total_reloc_size = 0; - unsigned long num_spaces, num_subspaces, i; - asection *section; - unsigned int total_subspaces = 0; - struct som_exec_auxhdr *exec_header = NULL; - - /* The file header will always be first in an object file, - everything else can be in random locations. To keep things - "simple" BFD will lay out the object file in the manner suggested - by the PRO ABI for PA-RISC Systems. */ - - /* Before any output can really begin offsets for all the major - portions of the object file must be computed. So, starting - with the initial file header compute (and sometimes write) - each portion of the object file. */ - - /* Make room for the file header, it's contents are not complete - yet, so it can not be written at this time. */ - current_offset += sizeof (struct header); - - /* Any auxiliary headers will follow the file header. Right now - we support only the copyright and version headers. */ - obj_som_file_hdr (abfd)->aux_header_location = current_offset; - obj_som_file_hdr (abfd)->aux_header_size = 0; - if (abfd->flags & (EXEC_P | DYNAMIC)) - { - /* Parts of the exec header will be filled in later, so - delay writing the header itself. Fill in the defaults, - and write it later. */ - current_offset += sizeof (struct som_exec_auxhdr); - obj_som_file_hdr (abfd)->aux_header_size - += sizeof (struct som_exec_auxhdr); - exec_header = obj_som_exec_hdr (abfd); - exec_header->som_auxhdr.type = EXEC_AUX_ID; - exec_header->som_auxhdr.length = 40; - } - if (obj_som_version_hdr (abfd) != NULL) - { - unsigned int len; - - if (bfd_seek (abfd, current_offset, SEEK_SET) < 0) - return false; - - /* Write the aux_id structure and the string length. */ - len = sizeof (struct aux_id) + sizeof (unsigned int); - obj_som_file_hdr (abfd)->aux_header_size += len; - current_offset += len; - if (bfd_write ((PTR) obj_som_version_hdr (abfd), len, 1, abfd) != len) - return false; - - /* Write the version string. */ - len = obj_som_version_hdr (abfd)->header_id.length - sizeof (int); - obj_som_file_hdr (abfd)->aux_header_size += len; - current_offset += len; - if (bfd_write ((PTR) obj_som_version_hdr (abfd)->user_string, - len, 1, abfd) != len) - return false; - } - - if (obj_som_copyright_hdr (abfd) != NULL) - { - unsigned int len; - - if (bfd_seek (abfd, current_offset, SEEK_SET) < 0) - return false; - - /* Write the aux_id structure and the string length. */ - len = sizeof (struct aux_id) + sizeof (unsigned int); - obj_som_file_hdr (abfd)->aux_header_size += len; - current_offset += len; - if (bfd_write ((PTR) obj_som_copyright_hdr (abfd), len, 1, abfd) != len) - return false; - - /* Write the copyright string. */ - len = obj_som_copyright_hdr (abfd)->header_id.length - sizeof (int); - obj_som_file_hdr (abfd)->aux_header_size += len; - current_offset += len; - if (bfd_write ((PTR) obj_som_copyright_hdr (abfd)->copyright, - len, 1, abfd) != len) - return false; - } - - /* Next comes the initialization pointers; we have no initialization - pointers, so current offset does not change. */ - obj_som_file_hdr (abfd)->init_array_location = current_offset; - obj_som_file_hdr (abfd)->init_array_total = 0; - - /* Next are the space records. These are fixed length records. - - Count the number of spaces to determine how much room is needed - in the object file for the space records. - - The names of the spaces are stored in a separate string table, - and the index for each space into the string table is computed - below. Therefore, it is not possible to write the space headers - at this time. */ - num_spaces = som_count_spaces (abfd); - obj_som_file_hdr (abfd)->space_location = current_offset; - obj_som_file_hdr (abfd)->space_total = num_spaces; - current_offset += num_spaces * sizeof (struct space_dictionary_record); - - /* Next are the subspace records. These are fixed length records. - - Count the number of subspaes to determine how much room is needed - in the object file for the subspace records. - - A variety if fields in the subspace record are still unknown at - this time (index into string table, fixup stream location/size, etc). */ - num_subspaces = som_count_subspaces (abfd); - obj_som_file_hdr (abfd)->subspace_location = current_offset; - obj_som_file_hdr (abfd)->subspace_total = num_subspaces; - current_offset += num_subspaces * sizeof (struct subspace_dictionary_record); - - /* Next is the string table for the space/subspace names. We will - build and write the string table on the fly. At the same time - we will fill in the space/subspace name index fields. */ - - /* The string table needs to be aligned on a word boundary. */ - if (current_offset % 4) - current_offset += (4 - (current_offset % 4)); - - /* Mark the offset of the space/subspace string table in the - file header. */ - obj_som_file_hdr (abfd)->space_strings_location = current_offset; - - /* Scribble out the space strings. */ - if (som_write_space_strings (abfd, current_offset, &strings_size) == false) - return false; - - /* Record total string table size in the header and update the - current offset. */ - obj_som_file_hdr (abfd)->space_strings_size = strings_size; - current_offset += strings_size; - - /* Next is the compiler records. We do not use these. */ - obj_som_file_hdr (abfd)->compiler_location = current_offset; - obj_som_file_hdr (abfd)->compiler_total = 0; - - /* Now compute the file positions for the loadable subspaces, taking - care to make sure everything stays properly aligned. */ - - section = abfd->sections; - for (i = 0; i < num_spaces; i++) - { - asection *subsection; - int first_subspace; - unsigned int subspace_offset = 0; - - /* Find a space. */ - while (!som_is_space (section)) - section = section->next; - - first_subspace = 1; - /* Now look for all its subspaces. */ - for (subsection = abfd->sections; - subsection != NULL; - subsection = subsection->next) - { - - if (!som_is_subspace (subsection) - || !som_is_container (section, subsection) - || (subsection->flags & SEC_ALLOC) == 0) - continue; - - /* If this is the first subspace in the space, and we are - building an executable, then take care to make sure all - the alignments are correct and update the exec header. */ - if (first_subspace - && (abfd->flags & (EXEC_P | DYNAMIC))) - { - /* Demand paged executables have each space aligned to a - page boundary. Sharable executables (write-protected - text) have just the private (aka data & bss) space aligned - to a page boundary. Ugh. Not true for HPUX. - - The HPUX kernel requires the text to always be page aligned - within the file regardless of the executable's type. */ - if (abfd->flags & (D_PAGED | DYNAMIC) - || (subsection->flags & SEC_CODE) - || ((abfd->flags & WP_TEXT) - && (subsection->flags & SEC_DATA))) - current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE); - - /* Update the exec header. */ - if (subsection->flags & SEC_CODE && exec_header->exec_tfile == 0) - { - exec_header->exec_tmem = section->vma; - exec_header->exec_tfile = current_offset; - } - if (subsection->flags & SEC_DATA && exec_header->exec_dfile == 0) - { - exec_header->exec_dmem = section->vma; - exec_header->exec_dfile = current_offset; - } - - /* Keep track of exactly where we are within a particular - space. This is necessary as the braindamaged HPUX - loader will create holes between subspaces *and* - subspace alignments are *NOT* preserved. What a crock. */ - subspace_offset = subsection->vma; - - /* Only do this for the first subspace within each space. */ - first_subspace = 0; - } - else if (abfd->flags & (EXEC_P | DYNAMIC)) - { - /* The braindamaged HPUX loader may have created a hole - between two subspaces. It is *not* sufficient to use - the alignment specifications within the subspaces to - account for these holes -- I've run into at least one - case where the loader left one code subspace unaligned - in a final executable. - - To combat this we keep a current offset within each space, - and use the subspace vma fields to detect and preserve - holes. What a crock! - - ps. This is not necessary for unloadable space/subspaces. */ - current_offset += subsection->vma - subspace_offset; - if (subsection->flags & SEC_CODE) - exec_header->exec_tsize += subsection->vma - subspace_offset; - else - exec_header->exec_dsize += subsection->vma - subspace_offset; - subspace_offset += subsection->vma - subspace_offset; - } - - - subsection->target_index = total_subspaces++; - /* This is real data to be loaded from the file. */ - if (subsection->flags & SEC_LOAD) - { - /* Update the size of the code & data. */ - if (abfd->flags & (EXEC_P | DYNAMIC) - && subsection->flags & SEC_CODE) - exec_header->exec_tsize += subsection->_cooked_size; - else if (abfd->flags & (EXEC_P | DYNAMIC) - && subsection->flags & SEC_DATA) - exec_header->exec_dsize += subsection->_cooked_size; - som_section_data (subsection)->subspace_dict->file_loc_init_value - = current_offset; - subsection->filepos = current_offset; - current_offset += bfd_section_size (abfd, subsection); - subspace_offset += bfd_section_size (abfd, subsection); - } - /* Looks like uninitialized data. */ - else - { - /* Update the size of the bss section. */ - if (abfd->flags & (EXEC_P | DYNAMIC)) - exec_header->exec_bsize += subsection->_cooked_size; - - som_section_data (subsection)->subspace_dict->file_loc_init_value - = 0; - som_section_data (subsection)->subspace_dict-> - initialization_length = 0; - } - } - /* Goto the next section. */ - section = section->next; - } - - /* Finally compute the file positions for unloadable subspaces. - If building an executable, start the unloadable stuff on its - own page. */ - - if (abfd->flags & (EXEC_P | DYNAMIC)) - current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE); - - obj_som_file_hdr (abfd)->unloadable_sp_location = current_offset; - section = abfd->sections; - for (i = 0; i < num_spaces; i++) - { - asection *subsection; - - /* Find a space. */ - while (!som_is_space (section)) - section = section->next; - - if (abfd->flags & (EXEC_P | DYNAMIC)) - current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE); - - /* Now look for all its subspaces. */ - for (subsection = abfd->sections; - subsection != NULL; - subsection = subsection->next) - { - - if (!som_is_subspace (subsection) - || !som_is_container (section, subsection) - || (subsection->flags & SEC_ALLOC) != 0) - continue; - - subsection->target_index = total_subspaces++; - /* This is real data to be loaded from the file. */ - if ((subsection->flags & SEC_LOAD) == 0) - { - som_section_data (subsection)->subspace_dict->file_loc_init_value - = current_offset; - subsection->filepos = current_offset; - current_offset += bfd_section_size (abfd, subsection); - } - /* Looks like uninitialized data. */ - else - { - som_section_data (subsection)->subspace_dict->file_loc_init_value - = 0; - som_section_data (subsection)->subspace_dict-> - initialization_length = bfd_section_size (abfd, subsection); - } - } - /* Goto the next section. */ - section = section->next; - } - - /* If building an executable, then make sure to seek to and write - one byte at the end of the file to make sure any necessary - zeros are filled in. Ugh. */ - if (abfd->flags & (EXEC_P | DYNAMIC)) - current_offset = SOM_ALIGN (current_offset, PA_PAGESIZE); - if (bfd_seek (abfd, current_offset - 1, SEEK_SET) < 0) - return false; - if (bfd_write ((PTR) "", 1, 1, abfd) != 1) - return false; - - obj_som_file_hdr (abfd)->unloadable_sp_size - = current_offset - obj_som_file_hdr (abfd)->unloadable_sp_location; - - /* Loader fixups are not supported in any way shape or form. */ - obj_som_file_hdr (abfd)->loader_fixup_location = 0; - obj_som_file_hdr (abfd)->loader_fixup_total = 0; - - /* Done. Store the total size of the SOM so far. */ - obj_som_file_hdr (abfd)->som_length = current_offset; - - return true; -} - -/* Finally, scribble out the various headers to the disk. */ - -static boolean -som_finish_writing (abfd) - bfd *abfd; -{ - int num_spaces = som_count_spaces (abfd); - asymbol **syms = bfd_get_outsymbols (abfd); - int i, num_syms, strings_size; - int subspace_index = 0; - file_ptr location; - asection *section; - unsigned long current_offset; - unsigned int total_reloc_size; - - /* Next is the symbol table. These are fixed length records. - - Count the number of symbols to determine how much room is needed - in the object file for the symbol table. - - The names of the symbols are stored in a separate string table, - and the index for each symbol name into the string table is computed - below. Therefore, it is not possible to write the symbol table - at this time. - - These used to be output before the subspace contents, but they - were moved here to work around a stupid bug in the hpux linker - (fixed in hpux10). */ - current_offset = obj_som_file_hdr (abfd)->som_length; - - /* Make sure we're on a word boundary. */ - if (current_offset % 4) - current_offset += (4 - (current_offset % 4)); - - num_syms = bfd_get_symcount (abfd); - obj_som_file_hdr (abfd)->symbol_location = current_offset; - obj_som_file_hdr (abfd)->symbol_total = num_syms; - current_offset += num_syms * sizeof (struct symbol_dictionary_record); - - /* Next are the symbol strings. - Align them to a word boundary. */ - if (current_offset % 4) - current_offset += (4 - (current_offset % 4)); - obj_som_file_hdr (abfd)->symbol_strings_location = current_offset; - - /* Scribble out the symbol strings. */ - if (som_write_symbol_strings (abfd, current_offset, syms, - num_syms, &strings_size) - == false) - return false; - - /* Record total string table size in header and update the - current offset. */ - obj_som_file_hdr (abfd)->symbol_strings_size = strings_size; - current_offset += strings_size; - - /* Do prep work before handling fixups. */ - som_prep_for_fixups (abfd, - bfd_get_outsymbols (abfd), - bfd_get_symcount (abfd)); - - /* At the end of the file is the fixup stream which starts on a - word boundary. */ - if (current_offset % 4) - current_offset += (4 - (current_offset % 4)); - obj_som_file_hdr (abfd)->fixup_request_location = current_offset; - - /* Write the fixups and update fields in subspace headers which - relate to the fixup stream. */ - if (som_write_fixups (abfd, current_offset, &total_reloc_size) == false) - return false; - - /* Record the total size of the fixup stream in the file header. */ - obj_som_file_hdr (abfd)->fixup_request_total = total_reloc_size; - - /* Done. Store the total size of the SOM. */ - obj_som_file_hdr (abfd)->som_length = current_offset + total_reloc_size; - - /* Now that the symbol table information is complete, build and - write the symbol table. */ - if (som_build_and_write_symbol_table (abfd) == false) - return false; - - /* Subspaces are written first so that we can set up information - about them in their containing spaces as the subspace is written. */ - - /* Seek to the start of the subspace dictionary records. */ - location = obj_som_file_hdr (abfd)->subspace_location; - if (bfd_seek (abfd, location, SEEK_SET) < 0) - return false; - - section = abfd->sections; - /* Now for each loadable space write out records for its subspaces. */ - for (i = 0; i < num_spaces; i++) - { - asection *subsection; - - /* Find a space. */ - while (!som_is_space (section)) - section = section->next; - - /* Now look for all its subspaces. */ - for (subsection = abfd->sections; - subsection != NULL; - subsection = subsection->next) - { - - /* Skip any section which does not correspond to a space - or subspace. Or does not have SEC_ALLOC set (and therefore - has no real bits on the disk). */ - if (!som_is_subspace (subsection) - || !som_is_container (section, subsection) - || (subsection->flags & SEC_ALLOC) == 0) - continue; - - /* If this is the first subspace for this space, then save - the index of the subspace in its containing space. Also - set "is_loadable" in the containing space. */ - - if (som_section_data (section)->space_dict->subspace_quantity == 0) - { - som_section_data (section)->space_dict->is_loadable = 1; - som_section_data (section)->space_dict->subspace_index - = subspace_index; - } - - /* Increment the number of subspaces seen and the number of - subspaces contained within the current space. */ - subspace_index++; - som_section_data (section)->space_dict->subspace_quantity++; - - /* Mark the index of the current space within the subspace's - dictionary record. */ - som_section_data (subsection)->subspace_dict->space_index = i; - - /* Dump the current subspace header. */ - if (bfd_write ((PTR) som_section_data (subsection)->subspace_dict, - sizeof (struct subspace_dictionary_record), 1, abfd) - != sizeof (struct subspace_dictionary_record)) - return false; - } - /* Goto the next section. */ - section = section->next; - } - - /* Now repeat the process for unloadable subspaces. */ - section = abfd->sections; - /* Now for each space write out records for its subspaces. */ - for (i = 0; i < num_spaces; i++) - { - asection *subsection; - - /* Find a space. */ - while (!som_is_space (section)) - section = section->next; - - /* Now look for all its subspaces. */ - for (subsection = abfd->sections; - subsection != NULL; - subsection = subsection->next) - { - - /* Skip any section which does not correspond to a space or - subspace, or which SEC_ALLOC set (and therefore handled - in the loadable spaces/subspaces code above). */ - - if (!som_is_subspace (subsection) - || !som_is_container (section, subsection) - || (subsection->flags & SEC_ALLOC) != 0) - continue; - - /* If this is the first subspace for this space, then save - the index of the subspace in its containing space. Clear - "is_loadable". */ - - if (som_section_data (section)->space_dict->subspace_quantity == 0) - { - som_section_data (section)->space_dict->is_loadable = 0; - som_section_data (section)->space_dict->subspace_index - = subspace_index; - } - - /* Increment the number of subspaces seen and the number of - subspaces contained within the current space. */ - som_section_data (section)->space_dict->subspace_quantity++; - subspace_index++; - - /* Mark the index of the current space within the subspace's - dictionary record. */ - som_section_data (subsection)->subspace_dict->space_index = i; - - /* Dump this subspace header. */ - if (bfd_write ((PTR) som_section_data (subsection)->subspace_dict, - sizeof (struct subspace_dictionary_record), 1, abfd) - != sizeof (struct subspace_dictionary_record)) - return false; - } - /* Goto the next section. */ - section = section->next; - } - - /* All the subspace dictiondary records are written, and all the - fields are set up in the space dictionary records. - - Seek to the right location and start writing the space - dictionary records. */ - location = obj_som_file_hdr (abfd)->space_location; - if (bfd_seek (abfd, location, SEEK_SET) < 0) - return false; - - section = abfd->sections; - for (i = 0; i < num_spaces; i++) - { - - /* Find a space. */ - while (!som_is_space (section)) - section = section->next; - - /* Dump its header */ - if (bfd_write ((PTR) som_section_data (section)->space_dict, - sizeof (struct space_dictionary_record), 1, abfd) - != sizeof (struct space_dictionary_record)) - return false; - - /* Goto the next section. */ - section = section->next; - } - - /* Setting of the system_id has to happen very late now that copying of - BFD private data happens *after* section contents are set. */ - if (abfd->flags & (EXEC_P | DYNAMIC)) - obj_som_file_hdr(abfd)->system_id = obj_som_exec_data (abfd)->system_id; - else if (bfd_get_mach (abfd) == pa11) - obj_som_file_hdr(abfd)->system_id = CPU_PA_RISC1_1; - else - obj_som_file_hdr(abfd)->system_id = CPU_PA_RISC1_0; - - /* Compute the checksum for the file header just before writing - the header to disk. */ - obj_som_file_hdr (abfd)->checksum = som_compute_checksum (abfd); - - /* Only thing left to do is write out the file header. It is always - at location zero. Seek there and write it. */ - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) < 0) - return false; - if (bfd_write ((PTR) obj_som_file_hdr (abfd), - sizeof (struct header), 1, abfd) - != sizeof (struct header)) - return false; - - /* Now write the exec header. */ - if (abfd->flags & (EXEC_P | DYNAMIC)) - { - long tmp; - struct som_exec_auxhdr *exec_header; - - exec_header = obj_som_exec_hdr (abfd); - exec_header->exec_entry = bfd_get_start_address (abfd); - exec_header->exec_flags = obj_som_exec_data (abfd)->exec_flags; - - /* Oh joys. Ram some of the BSS data into the DATA section - to be compatable with how the hp linker makes objects - (saves memory space). */ - tmp = exec_header->exec_dsize; - tmp = SOM_ALIGN (tmp, PA_PAGESIZE); - exec_header->exec_bsize -= (tmp - exec_header->exec_dsize); - if (exec_header->exec_bsize < 0) - exec_header->exec_bsize = 0; - exec_header->exec_dsize = tmp; - - if (bfd_seek (abfd, obj_som_file_hdr (abfd)->aux_header_location, - SEEK_SET) < 0) - return false; - - if (bfd_write ((PTR) exec_header, AUX_HDR_SIZE, 1, abfd) - != AUX_HDR_SIZE) - return false; - } - return true; -} - -/* Compute and return the checksum for a SOM file header. */ - -static unsigned long -som_compute_checksum (abfd) - bfd *abfd; -{ - unsigned long checksum, count, i; - unsigned long *buffer = (unsigned long *) obj_som_file_hdr (abfd); - - checksum = 0; - count = sizeof (struct header) / sizeof (unsigned long); - for (i = 0; i < count; i++) - checksum ^= *(buffer + i); - - return checksum; -} - -static void -som_bfd_derive_misc_symbol_info (abfd, sym, info) - bfd *abfd; - asymbol *sym; - struct som_misc_symbol_info *info; -{ - /* Initialize. */ - memset (info, 0, sizeof (struct som_misc_symbol_info)); - - /* The HP SOM linker requires detailed type information about - all symbols (including undefined symbols!). Unfortunately, - the type specified in an import/export statement does not - always match what the linker wants. Severe braindamage. */ - - /* Section symbols will not have a SOM symbol type assigned to - them yet. Assign all section symbols type ST_DATA. */ - if (sym->flags & BSF_SECTION_SYM) - info->symbol_type = ST_DATA; - else - { - /* Common symbols must have scope SS_UNSAT and type - ST_STORAGE or the linker will choke. */ - if (bfd_is_com_section (sym->section)) - { - info->symbol_scope = SS_UNSAT; - info->symbol_type = ST_STORAGE; - } - - /* It is possible to have a symbol without an associated - type. This happens if the user imported the symbol - without a type and the symbol was never defined - locally. If BSF_FUNCTION is set for this symbol, then - assign it type ST_CODE (the HP linker requires undefined - external functions to have type ST_CODE rather than ST_ENTRY). */ - else if ((som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN - || som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE) - && bfd_is_und_section (sym->section) - && sym->flags & BSF_FUNCTION) - info->symbol_type = ST_CODE; - - /* Handle function symbols which were defined in this file. - They should have type ST_ENTRY. Also retrieve the argument - relocation bits from the SOM backend information. */ - else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ENTRY - || (som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE - && (sym->flags & BSF_FUNCTION)) - || (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN - && (sym->flags & BSF_FUNCTION))) - { - info->symbol_type = ST_ENTRY; - info->arg_reloc = som_symbol_data (sym)->tc_data.hppa_arg_reloc; - } - - /* If the type is unknown at this point, it should be ST_DATA or - ST_CODE (function/ST_ENTRY symbols were handled as special - cases above). */ - else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN) - { - if (sym->section->flags & SEC_CODE) - info->symbol_type = ST_CODE; - else - info->symbol_type = ST_DATA; - } - - /* From now on it's a very simple mapping. */ - else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ABSOLUTE) - info->symbol_type = ST_ABSOLUTE; - else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_CODE) - info->symbol_type = ST_CODE; - else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_DATA) - info->symbol_type = ST_DATA; - else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_MILLICODE) - info->symbol_type = ST_MILLICODE; - else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_PLABEL) - info->symbol_type = ST_PLABEL; - else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_PRI_PROG) - info->symbol_type = ST_PRI_PROG; - else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_SEC_PROG) - info->symbol_type = ST_SEC_PROG; - } - - /* Now handle the symbol's scope. Exported data which is not - in the common section has scope SS_UNIVERSAL. Note scope - of common symbols was handled earlier! */ - if (bfd_is_und_section (sym->section)) - info->symbol_scope = SS_UNSAT; - else if (sym->flags & BSF_EXPORT && ! bfd_is_com_section (sym->section)) - info->symbol_scope = SS_UNIVERSAL; - /* Anything else which is not in the common section has scope - SS_LOCAL. */ - else if (! bfd_is_com_section (sym->section)) - info->symbol_scope = SS_LOCAL; - - /* Now set the symbol_info field. It has no real meaning - for undefined or common symbols, but the HP linker will - choke if it's not set to some "reasonable" value. We - use zero as a reasonable value. */ - if (bfd_is_com_section (sym->section) - || bfd_is_und_section (sym->section) - || bfd_is_abs_section (sym->section)) - info->symbol_info = 0; - /* For all other symbols, the symbol_info field contains the - subspace index of the space this symbol is contained in. */ - else - info->symbol_info = sym->section->target_index; - - /* Set the symbol's value. */ - info->symbol_value = sym->value + sym->section->vma; -} - -/* Build and write, in one big chunk, the entire symbol table for - this BFD. */ - -static boolean -som_build_and_write_symbol_table (abfd) - bfd *abfd; -{ - unsigned int num_syms = bfd_get_symcount (abfd); - file_ptr symtab_location = obj_som_file_hdr (abfd)->symbol_location; - asymbol **bfd_syms = obj_som_sorted_syms (abfd); - struct symbol_dictionary_record *som_symtab = NULL; - int i, symtab_size; - - /* Compute total symbol table size and allocate a chunk of memory - to hold the symbol table as we build it. */ - symtab_size = num_syms * sizeof (struct symbol_dictionary_record); - som_symtab = (struct symbol_dictionary_record *) bfd_malloc (symtab_size); - if (som_symtab == NULL && symtab_size != 0) - goto error_return; - memset (som_symtab, 0, symtab_size); - - /* Walk over each symbol. */ - for (i = 0; i < num_syms; i++) - { - struct som_misc_symbol_info info; - - /* This is really an index into the symbol strings table. - By the time we get here, the index has already been - computed and stored into the name field in the BFD symbol. */ - som_symtab[i].name.n_strx = som_symbol_data(bfd_syms[i])->stringtab_offset; - - /* Derive SOM information from the BFD symbol. */ - som_bfd_derive_misc_symbol_info (abfd, bfd_syms[i], &info); - - /* Now use it. */ - som_symtab[i].symbol_type = info.symbol_type; - som_symtab[i].symbol_scope = info.symbol_scope; - som_symtab[i].arg_reloc = info.arg_reloc; - som_symtab[i].symbol_info = info.symbol_info; - som_symtab[i].symbol_value = info.symbol_value; - } - - /* Everything is ready, seek to the right location and - scribble out the symbol table. */ - if (bfd_seek (abfd, symtab_location, SEEK_SET) != 0) - return false; - - if (bfd_write ((PTR) som_symtab, symtab_size, 1, abfd) != symtab_size) - goto error_return; - - if (som_symtab != NULL) - free (som_symtab); - return true; - error_return: - if (som_symtab != NULL) - free (som_symtab); - return false; -} - -/* Write an object in SOM format. */ - -static boolean -som_write_object_contents (abfd) - bfd *abfd; -{ - if (abfd->output_has_begun == false) - { - /* Set up fixed parts of the file, space, and subspace headers. - Notify the world that output has begun. */ - som_prep_headers (abfd); - abfd->output_has_begun = true; - /* Start writing the object file. This include all the string - tables, fixup streams, and other portions of the object file. */ - som_begin_writing (abfd); - } - - return (som_finish_writing (abfd)); -} - - -/* Read and save the string table associated with the given BFD. */ - -static boolean -som_slurp_string_table (abfd) - bfd *abfd; -{ - char *stringtab; - - /* Use the saved version if its available. */ - if (obj_som_stringtab (abfd) != NULL) - return true; - - /* I don't think this can currently happen, and I'm not sure it should - really be an error, but it's better than getting unpredictable results - from the host's malloc when passed a size of zero. */ - if (obj_som_stringtab_size (abfd) == 0) - { - bfd_set_error (bfd_error_no_symbols); - return false; - } - - /* Allocate and read in the string table. */ - stringtab = bfd_malloc (obj_som_stringtab_size (abfd)); - if (stringtab == NULL) - return false; - memset (stringtab, 0, obj_som_stringtab_size (abfd)); - - if (bfd_seek (abfd, obj_som_str_filepos (abfd), SEEK_SET) < 0) - return false; - - if (bfd_read (stringtab, obj_som_stringtab_size (abfd), 1, abfd) - != obj_som_stringtab_size (abfd)) - return false; - - /* Save our results and return success. */ - obj_som_stringtab (abfd) = stringtab; - return true; -} - -/* Return the amount of data (in bytes) required to hold the symbol - table for this object. */ - -static long -som_get_symtab_upper_bound (abfd) - bfd *abfd; -{ - if (!som_slurp_symbol_table (abfd)) - return -1; - - return (bfd_get_symcount (abfd) + 1) * (sizeof (asymbol *)); -} - -/* Convert from a SOM subspace index to a BFD section. */ - -static asection * -bfd_section_from_som_symbol (abfd, symbol) - bfd *abfd; - struct symbol_dictionary_record *symbol; -{ - asection *section; - - /* The meaning of the symbol_info field changes for functions - within executables. So only use the quick symbol_info mapping for - incomplete objects and non-function symbols in executables. */ - if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 - || (symbol->symbol_type != ST_ENTRY - && symbol->symbol_type != ST_PRI_PROG - && symbol->symbol_type != ST_SEC_PROG - && symbol->symbol_type != ST_MILLICODE)) - { - unsigned int index = symbol->symbol_info; - for (section = abfd->sections; section != NULL; section = section->next) - if (section->target_index == index && som_is_subspace (section)) - return section; - - /* Could be a symbol from an external library (such as an OMOS - shared library). Don't abort. */ - return bfd_abs_section_ptr; - - } - else - { - unsigned int value = symbol->symbol_value; - - /* For executables we will have to use the symbol's address and - find out what section would contain that address. Yuk. */ - for (section = abfd->sections; section; section = section->next) - { - if (value >= section->vma - && value <= section->vma + section->_cooked_size - && som_is_subspace (section)) - return section; - } - - /* Could be a symbol from an external library (such as an OMOS - shared library). Don't abort. */ - return bfd_abs_section_ptr; - - } -} - -/* Read and save the symbol table associated with the given BFD. */ - -static unsigned int -som_slurp_symbol_table (abfd) - bfd *abfd; -{ - int symbol_count = bfd_get_symcount (abfd); - int symsize = sizeof (struct symbol_dictionary_record); - char *stringtab; - struct symbol_dictionary_record *buf = NULL, *bufp, *endbufp; - som_symbol_type *sym, *symbase; - - /* Return saved value if it exists. */ - if (obj_som_symtab (abfd) != NULL) - goto successful_return; - - /* Special case. This is *not* an error. */ - if (symbol_count == 0) - goto successful_return; - - if (!som_slurp_string_table (abfd)) - goto error_return; - - stringtab = obj_som_stringtab (abfd); - - symbase = ((som_symbol_type *) - bfd_malloc (symbol_count * sizeof (som_symbol_type))); - if (symbase == NULL) - goto error_return; - memset (symbase, 0, symbol_count * sizeof (som_symbol_type)); - - /* Read in the external SOM representation. */ - buf = bfd_malloc (symbol_count * symsize); - if (buf == NULL && symbol_count * symsize != 0) - goto error_return; - if (bfd_seek (abfd, obj_som_sym_filepos (abfd), SEEK_SET) < 0) - goto error_return; - if (bfd_read (buf, symbol_count * symsize, 1, abfd) - != symbol_count * symsize) - goto error_return; - - /* Iterate over all the symbols and internalize them. */ - endbufp = buf + symbol_count; - for (bufp = buf, sym = symbase; bufp < endbufp; ++bufp) - { - - /* I don't think we care about these. */ - if (bufp->symbol_type == ST_SYM_EXT - || bufp->symbol_type == ST_ARG_EXT) - continue; - - /* Set some private data we care about. */ - if (bufp->symbol_type == ST_NULL) - som_symbol_data (sym)->som_type = SYMBOL_TYPE_UNKNOWN; - else if (bufp->symbol_type == ST_ABSOLUTE) - som_symbol_data (sym)->som_type = SYMBOL_TYPE_ABSOLUTE; - else if (bufp->symbol_type == ST_DATA) - som_symbol_data (sym)->som_type = SYMBOL_TYPE_DATA; - else if (bufp->symbol_type == ST_CODE) - som_symbol_data (sym)->som_type = SYMBOL_TYPE_CODE; - else if (bufp->symbol_type == ST_PRI_PROG) - som_symbol_data (sym)->som_type = SYMBOL_TYPE_PRI_PROG; - else if (bufp->symbol_type == ST_SEC_PROG) - som_symbol_data (sym)->som_type = SYMBOL_TYPE_SEC_PROG; - else if (bufp->symbol_type == ST_ENTRY) - som_symbol_data (sym)->som_type = SYMBOL_TYPE_ENTRY; - else if (bufp->symbol_type == ST_MILLICODE) - som_symbol_data (sym)->som_type = SYMBOL_TYPE_MILLICODE; - else if (bufp->symbol_type == ST_PLABEL) - som_symbol_data (sym)->som_type = SYMBOL_TYPE_PLABEL; - else - som_symbol_data (sym)->som_type = SYMBOL_TYPE_UNKNOWN; - som_symbol_data (sym)->tc_data.hppa_arg_reloc = bufp->arg_reloc; - - /* Some reasonable defaults. */ - sym->symbol.the_bfd = abfd; - sym->symbol.name = bufp->name.n_strx + stringtab; - sym->symbol.value = bufp->symbol_value; - sym->symbol.section = 0; - sym->symbol.flags = 0; - - switch (bufp->symbol_type) - { - case ST_ENTRY: - case ST_MILLICODE: - sym->symbol.flags |= BSF_FUNCTION; - sym->symbol.value &= ~0x3; - break; - - case ST_STUB: - case ST_CODE: - case ST_PRI_PROG: - case ST_SEC_PROG: - sym->symbol.value &= ~0x3; - /* If the symbol's scope is ST_UNSAT, then these are - undefined function symbols. */ - if (bufp->symbol_scope == SS_UNSAT) - sym->symbol.flags |= BSF_FUNCTION; - - - default: - break; - } - - /* Handle scoping and section information. */ - switch (bufp->symbol_scope) - { - /* symbol_info field is undefined for SS_EXTERNAL and SS_UNSAT symbols, - so the section associated with this symbol can't be known. */ - case SS_EXTERNAL: - if (bufp->symbol_type != ST_STORAGE) - sym->symbol.section = bfd_und_section_ptr; - else - sym->symbol.section = bfd_com_section_ptr; - sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL); - break; - - case SS_UNSAT: - if (bufp->symbol_type != ST_STORAGE) - sym->symbol.section = bfd_und_section_ptr; - else - sym->symbol.section = bfd_com_section_ptr; - break; - - case SS_UNIVERSAL: - sym->symbol.flags |= (BSF_EXPORT | BSF_GLOBAL); - sym->symbol.section = bfd_section_from_som_symbol (abfd, bufp); - sym->symbol.value -= sym->symbol.section->vma; - break; - -#if 0 - /* SS_GLOBAL and SS_LOCAL are two names for the same thing. - Sound dumb? It is. */ - case SS_GLOBAL: -#endif - case SS_LOCAL: - sym->symbol.flags |= BSF_LOCAL; - sym->symbol.section = bfd_section_from_som_symbol (abfd, bufp); - sym->symbol.value -= sym->symbol.section->vma; - break; - } - - /* Mark section symbols and symbols used by the debugger. - Note $START$ is a magic code symbol, NOT a section symbol. */ - if (sym->symbol.name[0] == '$' - && sym->symbol.name[strlen (sym->symbol.name) - 1] == '$' - && !strcmp (sym->symbol.name, sym->symbol.section->name)) - sym->symbol.flags |= BSF_SECTION_SYM; - else if (!strncmp (sym->symbol.name, "L$0\002", 4)) - { - sym->symbol.flags |= BSF_SECTION_SYM; - sym->symbol.name = sym->symbol.section->name; - } - else if (!strncmp (sym->symbol.name, "L$0\001", 4)) - sym->symbol.flags |= BSF_DEBUGGING; - - /* Note increment at bottom of loop, since we skip some symbols - we can not include it as part of the for statement. */ - sym++; - } - - /* Save our results and return success. */ - obj_som_symtab (abfd) = symbase; - successful_return: - if (buf != NULL) - free (buf); - return (true); - - error_return: - if (buf != NULL) - free (buf); - return false; -} - -/* Canonicalize a SOM symbol table. Return the number of entries - in the symbol table. */ - -static long -som_get_symtab (abfd, location) - bfd *abfd; - asymbol **location; -{ - int i; - som_symbol_type *symbase; - - if (!som_slurp_symbol_table (abfd)) - return -1; - - i = bfd_get_symcount (abfd); - symbase = obj_som_symtab (abfd); - - for (; i > 0; i--, location++, symbase++) - *location = &symbase->symbol; - - /* Final null pointer. */ - *location = 0; - return (bfd_get_symcount (abfd)); -} - -/* Make a SOM symbol. There is nothing special to do here. */ - -static asymbol * -som_make_empty_symbol (abfd) - bfd *abfd; -{ - som_symbol_type *new = - (som_symbol_type *) bfd_zalloc (abfd, sizeof (som_symbol_type)); - if (new == NULL) - return 0; - new->symbol.the_bfd = abfd; - - return &new->symbol; -} - -/* Print symbol information. */ - -static void -som_print_symbol (ignore_abfd, afile, symbol, how) - bfd *ignore_abfd; - PTR afile; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *) afile; - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - case bfd_print_symbol_more: - fprintf (file, "som "); - fprintf_vma (file, symbol->value); - fprintf (file, " %lx", (long) symbol->flags); - break; - case bfd_print_symbol_all: - { - CONST char *section_name; - section_name = symbol->section ? symbol->section->name : "(*none*)"; - bfd_print_symbol_vandf ((PTR) file, symbol); - fprintf (file, " %s\t%s", section_name, symbol->name); - break; - } - } -} - -static boolean -som_bfd_is_local_label (abfd, sym) - bfd *abfd; - asymbol *sym; -{ - return (sym->name[0] == 'L' && sym->name[1] == '$'); -} - -/* Count or process variable-length SOM fixup records. - - To avoid code duplication we use this code both to compute the number - of relocations requested by a stream, and to internalize the stream. - - When computing the number of relocations requested by a stream the - variables rptr, section, and symbols have no meaning. - - Return the number of relocations requested by the fixup stream. When - not just counting - - This needs at least two or three more passes to get it cleaned up. */ - -static unsigned int -som_set_reloc_info (fixup, end, internal_relocs, section, symbols, just_count) - unsigned char *fixup; - unsigned int end; - arelent *internal_relocs; - asection *section; - asymbol **symbols; - boolean just_count; -{ - unsigned int op, varname, deallocate_contents = 0; - unsigned char *end_fixups = &fixup[end]; - const struct fixup_format *fp; - char *cp; - unsigned char *save_fixup; - int variables[26], stack[20], c, v, count, prev_fixup, *sp, saved_unwind_bits; - const int *subop; - arelent *rptr= internal_relocs; - unsigned int offset = 0; - -#define var(c) variables[(c) - 'A'] -#define push(v) (*sp++ = (v)) -#define pop() (*--sp) -#define emptystack() (sp == stack) - - som_initialize_reloc_queue (reloc_queue); - memset (variables, 0, sizeof (variables)); - memset (stack, 0, sizeof (stack)); - count = 0; - prev_fixup = 0; - saved_unwind_bits = 0; - sp = stack; - - while (fixup < end_fixups) - { - - /* Save pointer to the start of this fixup. We'll use - it later to determine if it is necessary to put this fixup - on the queue. */ - save_fixup = fixup; - - /* Get the fixup code and its associated format. */ - op = *fixup++; - fp = &som_fixup_formats[op]; - - /* Handle a request for a previous fixup. */ - if (*fp->format == 'P') - { - /* Get pointer to the beginning of the prev fixup, move - the repeated fixup to the head of the queue. */ - fixup = reloc_queue[fp->D].reloc; - som_reloc_queue_fix (reloc_queue, fp->D); - prev_fixup = 1; - - /* Get the fixup code and its associated format. */ - op = *fixup++; - fp = &som_fixup_formats[op]; - } - - /* If this fixup will be passed to BFD, set some reasonable defaults. */ - if (! just_count - && som_hppa_howto_table[op].type != R_NO_RELOCATION - && som_hppa_howto_table[op].type != R_DATA_OVERRIDE) - { - rptr->address = offset; - rptr->howto = &som_hppa_howto_table[op]; - rptr->addend = 0; - rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - } - - /* Set default input length to 0. Get the opcode class index - into D. */ - var ('L') = 0; - var ('D') = fp->D; - var ('U') = saved_unwind_bits; - - /* Get the opcode format. */ - cp = fp->format; - - /* Process the format string. Parsing happens in two phases, - parse RHS, then assign to LHS. Repeat until no more - characters in the format string. */ - while (*cp) - { - /* The variable this pass is going to compute a value for. */ - varname = *cp++; - - /* Start processing RHS. Continue until a NULL or '=' is found. */ - do - { - c = *cp++; - - /* If this is a variable, push it on the stack. */ - if (isupper (c)) - push (var (c)); - - /* If this is a lower case letter, then it represents - additional data from the fixup stream to be pushed onto - the stack. */ - else if (islower (c)) - { - int bits = (c - 'a') * 8; - for (v = 0; c > 'a'; --c) - v = (v << 8) | *fixup++; - if (varname == 'V') - v = sign_extend (v, bits); - push (v); - } - - /* A decimal constant. Push it on the stack. */ - else if (isdigit (c)) - { - v = c - '0'; - while (isdigit (*cp)) - v = (v * 10) + (*cp++ - '0'); - push (v); - } - else - - /* An operator. Pop two two values from the stack and - use them as operands to the given operation. Push - the result of the operation back on the stack. */ - switch (c) - { - case '+': - v = pop (); - v += pop (); - push (v); - break; - case '*': - v = pop (); - v *= pop (); - push (v); - break; - case '<': - v = pop (); - v = pop () << v; - push (v); - break; - default: - abort (); - } - } - while (*cp && *cp != '='); - - /* Move over the equal operator. */ - cp++; - - /* Pop the RHS off the stack. */ - c = pop (); - - /* Perform the assignment. */ - var (varname) = c; - - /* Handle side effects. and special 'O' stack cases. */ - switch (varname) - { - /* Consume some bytes from the input space. */ - case 'L': - offset += c; - break; - /* A symbol to use in the relocation. Make a note - of this if we are not just counting. */ - case 'S': - if (! just_count) - rptr->sym_ptr_ptr = &symbols[c]; - break; - /* Argument relocation bits for a function call. */ - case 'R': - if (! just_count) - { - unsigned int tmp = var ('R'); - rptr->addend = 0; - - if ((som_hppa_howto_table[op].type == R_PCREL_CALL - && R_PCREL_CALL + 10 > op) - || (som_hppa_howto_table[op].type == R_ABS_CALL - && R_ABS_CALL + 10 > op)) - { - /* Simple encoding. */ - if (tmp > 4) - { - tmp -= 5; - rptr->addend |= 1; - } - if (tmp == 4) - rptr->addend |= 1 << 8 | 1 << 6 | 1 << 4 | 1 << 2; - else if (tmp == 3) - rptr->addend |= 1 << 8 | 1 << 6 | 1 << 4; - else if (tmp == 2) - rptr->addend |= 1 << 8 | 1 << 6; - else if (tmp == 1) - rptr->addend |= 1 << 8; - } - else - { - unsigned int tmp1, tmp2; - - /* First part is easy -- low order two bits are - directly copied, then shifted away. */ - rptr->addend = tmp & 0x3; - tmp >>= 2; - - /* Diving the result by 10 gives us the second - part. If it is 9, then the first two words - are a double precision paramater, else it is - 3 * the first arg bits + the 2nd arg bits. */ - tmp1 = tmp / 10; - tmp -= tmp1 * 10; - if (tmp1 == 9) - rptr->addend += (0xe << 6); - else - { - /* Get the two pieces. */ - tmp2 = tmp1 / 3; - tmp1 -= tmp2 * 3; - /* Put them in the addend. */ - rptr->addend += (tmp2 << 8) + (tmp1 << 6); - } - - /* What's left is the third part. It's unpacked - just like the second. */ - if (tmp == 9) - rptr->addend += (0xe << 2); - else - { - tmp2 = tmp / 3; - tmp -= tmp2 * 3; - rptr->addend += (tmp2 << 4) + (tmp << 2); - } - } - rptr->addend = HPPA_R_ADDEND (rptr->addend, 0); - } - break; - /* Handle the linker expression stack. */ - case 'O': - switch (op) - { - case R_COMP1: - subop = comp1_opcodes; - break; - case R_COMP2: - subop = comp2_opcodes; - break; - case R_COMP3: - subop = comp3_opcodes; - break; - default: - abort (); - } - while (*subop <= (unsigned char) c) - ++subop; - --subop; - break; - /* The lower 32unwind bits must be persistent. */ - case 'U': - saved_unwind_bits = var ('U'); - break; - - default: - break; - } - } - - /* If we used a previous fixup, clean up after it. */ - if (prev_fixup) - { - fixup = save_fixup + 1; - prev_fixup = 0; - } - /* Queue it. */ - else if (fixup > save_fixup + 1) - som_reloc_queue_insert (save_fixup, fixup - save_fixup, reloc_queue); - - /* We do not pass R_DATA_OVERRIDE or R_NO_RELOCATION - fixups to BFD. */ - if (som_hppa_howto_table[op].type != R_DATA_OVERRIDE - && som_hppa_howto_table[op].type != R_NO_RELOCATION) - { - /* Done with a single reloction. Loop back to the top. */ - if (! just_count) - { - if (som_hppa_howto_table[op].type == R_ENTRY) - rptr->addend = var ('T'); - else if (som_hppa_howto_table[op].type == R_EXIT) - rptr->addend = var ('U'); - else if (som_hppa_howto_table[op].type == R_PCREL_CALL - || som_hppa_howto_table[op].type == R_ABS_CALL) - ; - else if (som_hppa_howto_table[op].type == R_DATA_ONE_SYMBOL) - { - unsigned addend = var ('V'); - - /* Try what was specified in R_DATA_OVERRIDE first - (if anything). Then the hard way using the - section contents. */ - rptr->addend = var ('V'); - - if (rptr->addend == 0 && !section->contents) - { - /* Got to read the damn contents first. We don't - bother saving the contents (yet). Add it one - day if the need arises. */ - section->contents = bfd_malloc (section->_raw_size); - if (section->contents == NULL) - return -1; - - deallocate_contents = 1; - bfd_get_section_contents (section->owner, - section, - section->contents, - 0, - section->_raw_size); - } - else if (rptr->addend == 0) - rptr->addend = bfd_get_32 (section->owner, - (section->contents - + offset - var ('L'))); - - } - else - rptr->addend = var ('V'); - rptr++; - } - count++; - /* Now that we've handled a "full" relocation, reset - some state. */ - memset (variables, 0, sizeof (variables)); - memset (stack, 0, sizeof (stack)); - } - } - if (deallocate_contents) - free (section->contents); - - return count; - -#undef var -#undef push -#undef pop -#undef emptystack -} - -/* Read in the relocs (aka fixups in SOM terms) for a section. - - som_get_reloc_upper_bound calls this routine with JUST_COUNT - set to true to indicate it only needs a count of the number - of actual relocations. */ - -static boolean -som_slurp_reloc_table (abfd, section, symbols, just_count) - bfd *abfd; - asection *section; - asymbol **symbols; - boolean just_count; -{ - char *external_relocs; - unsigned int fixup_stream_size; - arelent *internal_relocs; - unsigned int num_relocs; - - fixup_stream_size = som_section_data (section)->reloc_size; - /* If there were no relocations, then there is nothing to do. */ - if (section->reloc_count == 0) - return true; - - /* If reloc_count is -1, then the relocation stream has not been - parsed. We must do so now to know how many relocations exist. */ - if (section->reloc_count == -1) - { - external_relocs = (char *) bfd_malloc (fixup_stream_size); - if (external_relocs == (char *) NULL) - return false; - /* Read in the external forms. */ - if (bfd_seek (abfd, - obj_som_reloc_filepos (abfd) + section->rel_filepos, - SEEK_SET) - != 0) - return false; - if (bfd_read (external_relocs, 1, fixup_stream_size, abfd) - != fixup_stream_size) - return false; - - /* Let callers know how many relocations found. - also save the relocation stream as we will - need it again. */ - section->reloc_count = som_set_reloc_info (external_relocs, - fixup_stream_size, - NULL, NULL, NULL, true); - - som_section_data (section)->reloc_stream = external_relocs; - } - - /* If the caller only wanted a count, then return now. */ - if (just_count) - return true; - - num_relocs = section->reloc_count; - external_relocs = som_section_data (section)->reloc_stream; - /* Return saved information about the relocations if it is available. */ - if (section->relocation != (arelent *) NULL) - return true; - - internal_relocs = (arelent *) - bfd_zalloc (abfd, (num_relocs * sizeof (arelent))); - if (internal_relocs == (arelent *) NULL) - return false; - - /* Process and internalize the relocations. */ - som_set_reloc_info (external_relocs, fixup_stream_size, - internal_relocs, section, symbols, false); - - /* We're done with the external relocations. Free them. */ - free (external_relocs); - - /* Save our results and return success. */ - section->relocation = internal_relocs; - return (true); -} - -/* Return the number of bytes required to store the relocation - information associated with the given section. */ - -static long -som_get_reloc_upper_bound (abfd, asect) - bfd *abfd; - sec_ptr asect; -{ - /* If section has relocations, then read in the relocation stream - and parse it to determine how many relocations exist. */ - if (asect->flags & SEC_RELOC) - { - if (! som_slurp_reloc_table (abfd, asect, NULL, true)) - return -1; - return (asect->reloc_count + 1) * sizeof (arelent *); - } - /* There are no relocations. */ - return 0; -} - -/* Convert relocations from SOM (external) form into BFD internal - form. Return the number of relocations. */ - -static long -som_canonicalize_reloc (abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - arelent *tblptr; - int count; - - if (som_slurp_reloc_table (abfd, section, symbols, false) == false) - return -1; - - count = section->reloc_count; - tblptr = section->relocation; - - while (count--) - *relptr++ = tblptr++; - - *relptr = (arelent *) NULL; - return section->reloc_count; -} - -extern const bfd_target som_vec; - -/* A hook to set up object file dependent section information. */ - -static boolean -som_new_section_hook (abfd, newsect) - bfd *abfd; - asection *newsect; -{ - newsect->used_by_bfd = - (PTR) bfd_zalloc (abfd, sizeof (struct som_section_data_struct)); - if (!newsect->used_by_bfd) - return false; - newsect->alignment_power = 3; - - /* We allow more than three sections internally */ - return true; -} - -/* Copy any private info we understand from the input symbol - to the output symbol. */ - -static boolean -som_bfd_copy_private_symbol_data (ibfd, isymbol, obfd, osymbol) - bfd *ibfd; - asymbol *isymbol; - bfd *obfd; - asymbol *osymbol; -{ - struct som_symbol *input_symbol = (struct som_symbol *) isymbol; - struct som_symbol *output_symbol = (struct som_symbol *) osymbol; - - /* One day we may try to grok other private data. */ - if (ibfd->xvec->flavour != bfd_target_som_flavour - || obfd->xvec->flavour != bfd_target_som_flavour) - return false; - - /* The only private information we need to copy is the argument relocation - bits. */ - output_symbol->tc_data.hppa_arg_reloc = input_symbol->tc_data.hppa_arg_reloc; - - return true; -} - -/* Copy any private info we understand from the input section - to the output section. */ -static boolean -som_bfd_copy_private_section_data (ibfd, isection, obfd, osection) - bfd *ibfd; - asection *isection; - bfd *obfd; - asection *osection; -{ - /* One day we may try to grok other private data. */ - if (ibfd->xvec->flavour != bfd_target_som_flavour - || obfd->xvec->flavour != bfd_target_som_flavour - || (!som_is_space (isection) && !som_is_subspace (isection))) - return true; - - som_section_data (osection)->copy_data - = (struct som_copyable_section_data_struct *) - bfd_zalloc (obfd, sizeof (struct som_copyable_section_data_struct)); - if (som_section_data (osection)->copy_data == NULL) - return false; - - memcpy (som_section_data (osection)->copy_data, - som_section_data (isection)->copy_data, - sizeof (struct som_copyable_section_data_struct)); - - /* Reparent if necessary. */ - if (som_section_data (osection)->copy_data->container) - som_section_data (osection)->copy_data->container = - som_section_data (osection)->copy_data->container->output_section; - - return true; -} - -/* Copy any private info we understand from the input bfd - to the output bfd. */ - -static boolean -som_bfd_copy_private_bfd_data (ibfd, obfd) - bfd *ibfd, *obfd; -{ - /* One day we may try to grok other private data. */ - if (ibfd->xvec->flavour != bfd_target_som_flavour - || obfd->xvec->flavour != bfd_target_som_flavour) - return true; - - /* Allocate some memory to hold the data we need. */ - obj_som_exec_data (obfd) = (struct som_exec_data *) - bfd_zalloc (obfd, sizeof (struct som_exec_data)); - if (obj_som_exec_data (obfd) == NULL) - return false; - - /* Now copy the data. */ - memcpy (obj_som_exec_data (obfd), obj_som_exec_data (ibfd), - sizeof (struct som_exec_data)); - - return true; -} - -/* Set backend info for sections which can not be described - in the BFD data structures. */ - -boolean -bfd_som_set_section_attributes (section, defined, private, sort_key, spnum) - asection *section; - int defined; - int private; - unsigned int sort_key; - int spnum; -{ - /* Allocate memory to hold the magic information. */ - if (som_section_data (section)->copy_data == NULL) - { - som_section_data (section)->copy_data - = (struct som_copyable_section_data_struct *) - bfd_zalloc (section->owner, - sizeof (struct som_copyable_section_data_struct)); - if (som_section_data (section)->copy_data == NULL) - return false; - } - som_section_data (section)->copy_data->sort_key = sort_key; - som_section_data (section)->copy_data->is_defined = defined; - som_section_data (section)->copy_data->is_private = private; - som_section_data (section)->copy_data->container = section; - som_section_data (section)->copy_data->space_number = spnum; - return true; -} - -/* Set backend info for subsections which can not be described - in the BFD data structures. */ - -boolean -bfd_som_set_subsection_attributes (section, container, access, - sort_key, quadrant) - asection *section; - asection *container; - int access; - unsigned int sort_key; - int quadrant; -{ - /* Allocate memory to hold the magic information. */ - if (som_section_data (section)->copy_data == NULL) - { - som_section_data (section)->copy_data - = (struct som_copyable_section_data_struct *) - bfd_zalloc (section->owner, - sizeof (struct som_copyable_section_data_struct)); - if (som_section_data (section)->copy_data == NULL) - return false; - } - som_section_data (section)->copy_data->sort_key = sort_key; - som_section_data (section)->copy_data->access_control_bits = access; - som_section_data (section)->copy_data->quadrant = quadrant; - som_section_data (section)->copy_data->container = container; - return true; -} - -/* Set the full SOM symbol type. SOM needs far more symbol information - than any other object file format I'm aware of. It is mandatory - to be able to know if a symbol is an entry point, millicode, data, - code, absolute, storage request, or procedure label. If you get - the symbol type wrong your program will not link. */ - -void -bfd_som_set_symbol_type (symbol, type) - asymbol *symbol; - unsigned int type; -{ - som_symbol_data (symbol)->som_type = type; -} - -/* Attach an auxiliary header to the BFD backend so that it may be - written into the object file. */ -boolean -bfd_som_attach_aux_hdr (abfd, type, string) - bfd *abfd; - int type; - char *string; -{ - if (type == VERSION_AUX_ID) - { - int len = strlen (string); - int pad = 0; - - if (len % 4) - pad = (4 - (len % 4)); - obj_som_version_hdr (abfd) = (struct user_string_aux_hdr *) - bfd_zalloc (abfd, sizeof (struct aux_id) - + sizeof (unsigned int) + len + pad); - if (!obj_som_version_hdr (abfd)) - return false; - obj_som_version_hdr (abfd)->header_id.type = VERSION_AUX_ID; - obj_som_version_hdr (abfd)->header_id.length = len + pad; - obj_som_version_hdr (abfd)->header_id.length += sizeof (int); - obj_som_version_hdr (abfd)->string_length = len; - strncpy (obj_som_version_hdr (abfd)->user_string, string, len); - } - else if (type == COPYRIGHT_AUX_ID) - { - int len = strlen (string); - int pad = 0; - - if (len % 4) - pad = (4 - (len % 4)); - obj_som_copyright_hdr (abfd) = (struct copyright_aux_hdr *) - bfd_zalloc (abfd, sizeof (struct aux_id) - + sizeof (unsigned int) + len + pad); - if (!obj_som_copyright_hdr (abfd)) - return false; - obj_som_copyright_hdr (abfd)->header_id.type = COPYRIGHT_AUX_ID; - obj_som_copyright_hdr (abfd)->header_id.length = len + pad; - obj_som_copyright_hdr (abfd)->header_id.length += sizeof (int); - obj_som_copyright_hdr (abfd)->string_length = len; - strcpy (obj_som_copyright_hdr (abfd)->copyright, string); - } - return true; -} - -static boolean -som_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if (count == 0 || ((section->flags & SEC_HAS_CONTENTS) == 0)) - return true; - if ((bfd_size_type)(offset+count) > section->_raw_size - || bfd_seek (abfd, (file_ptr)(section->filepos + offset), SEEK_SET) == -1 - || bfd_read (location, (bfd_size_type)1, count, abfd) != count) - return (false); /* on error */ - return (true); -} - -static boolean -som_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if (abfd->output_has_begun == false) - { - /* Set up fixed parts of the file, space, and subspace headers. - Notify the world that output has begun. */ - som_prep_headers (abfd); - abfd->output_has_begun = true; - /* Start writing the object file. This include all the string - tables, fixup streams, and other portions of the object file. */ - som_begin_writing (abfd); - } - - /* Only write subspaces which have "real" contents (eg. the contents - are not generated at run time by the OS). */ - if (!som_is_subspace (section) - || ((section->flags & SEC_HAS_CONTENTS) == 0)) - return true; - - /* Seek to the proper offset within the object file and write the - data. */ - offset += som_section_data (section)->subspace_dict->file_loc_init_value; - if (bfd_seek (abfd, offset, SEEK_SET) == -1) - return false; - - if (bfd_write ((PTR) location, 1, count, abfd) != count) - return false; - return true; -} - -static boolean -som_set_arch_mach (abfd, arch, machine) - bfd *abfd; - enum bfd_architecture arch; - unsigned long machine; -{ - /* Allow any architecture to be supported by the SOM backend */ - return bfd_default_set_arch_mach (abfd, arch, machine); -} - -static boolean -som_find_nearest_line (abfd, section, symbols, offset, filename_ptr, - functionname_ptr, line_ptr) - bfd *abfd; - asection *section; - asymbol **symbols; - bfd_vma offset; - CONST char **filename_ptr; - CONST char **functionname_ptr; - unsigned int *line_ptr; -{ - return (false); -} - -static int -som_sizeof_headers (abfd, reloc) - bfd *abfd; - boolean reloc; -{ - (*_bfd_error_handler) ("som_sizeof_headers unimplemented"); - fflush (stderr); - abort (); - return (0); -} - -/* Return the single-character symbol type corresponding to - SOM section S, or '?' for an unknown SOM section. */ - -static char -som_section_type (s) - const char *s; -{ - const struct section_to_type *t; - - for (t = &stt[0]; t->section; t++) - if (!strcmp (s, t->section)) - return t->type; - return '?'; -} - -static int -som_decode_symclass (symbol) - asymbol *symbol; -{ - char c; - - if (bfd_is_com_section (symbol->section)) - return 'C'; - if (bfd_is_und_section (symbol->section)) - return 'U'; - if (bfd_is_ind_section (symbol->section)) - return 'I'; - if (!(symbol->flags & (BSF_GLOBAL|BSF_LOCAL))) - return '?'; - - if (bfd_is_abs_section (symbol->section) - || (som_symbol_data (symbol) != NULL - && som_symbol_data (symbol)->som_type == SYMBOL_TYPE_ABSOLUTE)) - c = 'a'; - else if (symbol->section) - c = som_section_type (symbol->section->name); - else - return '?'; - if (symbol->flags & BSF_GLOBAL) - c = toupper (c); - return c; -} - -/* Return information about SOM symbol SYMBOL in RET. */ - -static void -som_get_symbol_info (ignore_abfd, symbol, ret) - bfd *ignore_abfd; - asymbol *symbol; - symbol_info *ret; -{ - ret->type = som_decode_symclass (symbol); - if (ret->type != 'U') - ret->value = symbol->value+symbol->section->vma; - else - ret->value = 0; - ret->name = symbol->name; -} - -/* Count the number of symbols in the archive symbol table. Necessary - so that we can allocate space for all the carsyms at once. */ - -static boolean -som_bfd_count_ar_symbols (abfd, lst_header, count) - bfd *abfd; - struct lst_header *lst_header; - symindex *count; -{ - unsigned int i; - unsigned int *hash_table = NULL; - file_ptr lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header); - - hash_table = - (unsigned int *) bfd_malloc (lst_header->hash_size - * sizeof (unsigned int)); - if (hash_table == NULL && lst_header->hash_size != 0) - goto error_return; - - /* Don't forget to initialize the counter! */ - *count = 0; - - /* Read in the hash table. The has table is an array of 32bit file offsets - which point to the hash chains. */ - if (bfd_read ((PTR) hash_table, lst_header->hash_size, 4, abfd) - != lst_header->hash_size * 4) - goto error_return; - - /* Walk each chain counting the number of symbols found on that particular - chain. */ - for (i = 0; i < lst_header->hash_size; i++) - { - struct lst_symbol_record lst_symbol; - - /* An empty chain has zero as it's file offset. */ - if (hash_table[i] == 0) - continue; - - /* Seek to the first symbol in this hash chain. */ - if (bfd_seek (abfd, lst_filepos + hash_table[i], SEEK_SET) < 0) - goto error_return; - - /* Read in this symbol and update the counter. */ - if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd) - != sizeof (lst_symbol)) - goto error_return; - - (*count)++; - - /* Now iterate through the rest of the symbols on this chain. */ - while (lst_symbol.next_entry) - { - - /* Seek to the next symbol. */ - if (bfd_seek (abfd, lst_filepos + lst_symbol.next_entry, SEEK_SET) - < 0) - goto error_return; - - /* Read the symbol in and update the counter. */ - if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd) - != sizeof (lst_symbol)) - goto error_return; - - (*count)++; - } - } - if (hash_table != NULL) - free (hash_table); - return true; - - error_return: - if (hash_table != NULL) - free (hash_table); - return false; -} - -/* Fill in the canonical archive symbols (SYMS) from the archive described - by ABFD and LST_HEADER. */ - -static boolean -som_bfd_fill_in_ar_symbols (abfd, lst_header, syms) - bfd *abfd; - struct lst_header *lst_header; - carsym **syms; -{ - unsigned int i, len; - carsym *set = syms[0]; - unsigned int *hash_table = NULL; - struct som_entry *som_dict = NULL; - file_ptr lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header); - - hash_table = - (unsigned int *) bfd_malloc (lst_header->hash_size - * sizeof (unsigned int)); - if (hash_table == NULL && lst_header->hash_size != 0) - goto error_return; - - som_dict = - (struct som_entry *) bfd_malloc (lst_header->module_count - * sizeof (struct som_entry)); - if (som_dict == NULL && lst_header->module_count != 0) - goto error_return; - - /* Read in the hash table. The has table is an array of 32bit file offsets - which point to the hash chains. */ - if (bfd_read ((PTR) hash_table, lst_header->hash_size, 4, abfd) - != lst_header->hash_size * 4) - goto error_return; - - /* Seek to and read in the SOM dictionary. We will need this to fill - in the carsym's filepos field. */ - if (bfd_seek (abfd, lst_filepos + lst_header->dir_loc, SEEK_SET) < 0) - goto error_return; - - if (bfd_read ((PTR) som_dict, lst_header->module_count, - sizeof (struct som_entry), abfd) - != lst_header->module_count * sizeof (struct som_entry)) - goto error_return; - - /* Walk each chain filling in the carsyms as we go along. */ - for (i = 0; i < lst_header->hash_size; i++) - { - struct lst_symbol_record lst_symbol; - - /* An empty chain has zero as it's file offset. */ - if (hash_table[i] == 0) - continue; - - /* Seek to and read the first symbol on the chain. */ - if (bfd_seek (abfd, lst_filepos + hash_table[i], SEEK_SET) < 0) - goto error_return; - - if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd) - != sizeof (lst_symbol)) - goto error_return; - - /* Get the name of the symbol, first get the length which is stored - as a 32bit integer just before the symbol. - - One might ask why we don't just read in the entire string table - and index into it. Well, according to the SOM ABI the string - index can point *anywhere* in the archive to save space, so just - using the string table would not be safe. */ - if (bfd_seek (abfd, lst_filepos + lst_header->string_loc - + lst_symbol.name.n_strx - 4, SEEK_SET) < 0) - goto error_return; - - if (bfd_read (&len, 1, 4, abfd) != 4) - goto error_return; - - /* Allocate space for the name and null terminate it too. */ - set->name = bfd_zalloc (abfd, len + 1); - if (!set->name) - goto error_return; - if (bfd_read (set->name, 1, len, abfd) != len) - goto error_return; - - set->name[len] = 0; - - /* Fill in the file offset. Note that the "location" field points - to the SOM itself, not the ar_hdr in front of it. */ - set->file_offset = som_dict[lst_symbol.som_index].location - - sizeof (struct ar_hdr); - - /* Go to the next symbol. */ - set++; - - /* Iterate through the rest of the chain. */ - while (lst_symbol.next_entry) - { - /* Seek to the next symbol and read it in. */ - if (bfd_seek (abfd, lst_filepos + lst_symbol.next_entry, SEEK_SET) <0) - goto error_return; - - if (bfd_read ((PTR) & lst_symbol, 1, sizeof (lst_symbol), abfd) - != sizeof (lst_symbol)) - goto error_return; - - /* Seek to the name length & string and read them in. */ - if (bfd_seek (abfd, lst_filepos + lst_header->string_loc - + lst_symbol.name.n_strx - 4, SEEK_SET) < 0) - goto error_return; - - if (bfd_read (&len, 1, 4, abfd) != 4) - goto error_return; - - /* Allocate space for the name and null terminate it too. */ - set->name = bfd_zalloc (abfd, len + 1); - if (!set->name) - goto error_return; - - if (bfd_read (set->name, 1, len, abfd) != len) - goto error_return; - set->name[len] = 0; - - /* Fill in the file offset. Note that the "location" field points - to the SOM itself, not the ar_hdr in front of it. */ - set->file_offset = som_dict[lst_symbol.som_index].location - - sizeof (struct ar_hdr); - - /* Go on to the next symbol. */ - set++; - } - } - /* If we haven't died by now, then we successfully read the entire - archive symbol table. */ - if (hash_table != NULL) - free (hash_table); - if (som_dict != NULL) - free (som_dict); - return true; - - error_return: - if (hash_table != NULL) - free (hash_table); - if (som_dict != NULL) - free (som_dict); - return false; -} - -/* Read in the LST from the archive. */ -static boolean -som_slurp_armap (abfd) - bfd *abfd; -{ - struct lst_header lst_header; - struct ar_hdr ar_header; - unsigned int parsed_size; - struct artdata *ardata = bfd_ardata (abfd); - char nextname[17]; - int i = bfd_read ((PTR) nextname, 1, 16, abfd); - - /* Special cases. */ - if (i == 0) - return true; - if (i != 16) - return false; - - if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) < 0) - return false; - - /* For archives without .o files there is no symbol table. */ - if (strncmp (nextname, "/ ", 16)) - { - bfd_has_map (abfd) = false; - return true; - } - - /* Read in and sanity check the archive header. */ - if (bfd_read ((PTR) &ar_header, 1, sizeof (struct ar_hdr), abfd) - != sizeof (struct ar_hdr)) - return false; - - if (strncmp (ar_header.ar_fmag, ARFMAG, 2)) - { - bfd_set_error (bfd_error_malformed_archive); - return false; - } - - /* How big is the archive symbol table entry? */ - errno = 0; - parsed_size = strtol (ar_header.ar_size, NULL, 10); - if (errno != 0) - { - bfd_set_error (bfd_error_malformed_archive); - return false; - } - - /* Save off the file offset of the first real user data. */ - ardata->first_file_filepos = bfd_tell (abfd) + parsed_size; - - /* Read in the library symbol table. We'll make heavy use of this - in just a minute. */ - if (bfd_read ((PTR) & lst_header, 1, sizeof (struct lst_header), abfd) - != sizeof (struct lst_header)) - return false; - - /* Sanity check. */ - if (lst_header.a_magic != LIBMAGIC) - { - bfd_set_error (bfd_error_malformed_archive); - return false; - } - - /* Count the number of symbols in the library symbol table. */ - if (som_bfd_count_ar_symbols (abfd, &lst_header, &ardata->symdef_count) - == false) - return false; - - /* Get back to the start of the library symbol table. */ - if (bfd_seek (abfd, ardata->first_file_filepos - parsed_size - + sizeof (struct lst_header), SEEK_SET) < 0) - return false; - - /* Initializae the cache and allocate space for the library symbols. */ - ardata->cache = 0; - ardata->symdefs = (carsym *) bfd_alloc (abfd, - (ardata->symdef_count - * sizeof (carsym))); - if (!ardata->symdefs) - return false; - - /* Now fill in the canonical archive symbols. */ - if (som_bfd_fill_in_ar_symbols (abfd, &lst_header, &ardata->symdefs) - == false) - return false; - - /* Seek back to the "first" file in the archive. Note the "first" - file may be the extended name table. */ - if (bfd_seek (abfd, ardata->first_file_filepos, SEEK_SET) < 0) - return false; - - /* Notify the generic archive code that we have a symbol map. */ - bfd_has_map (abfd) = true; - return true; -} - -/* Begin preparing to write a SOM library symbol table. - - As part of the prep work we need to determine the number of symbols - and the size of the associated string section. */ - -static boolean -som_bfd_prep_for_ar_write (abfd, num_syms, stringsize) - bfd *abfd; - unsigned int *num_syms, *stringsize; -{ - bfd *curr_bfd = abfd->archive_head; - - /* Some initialization. */ - *num_syms = 0; - *stringsize = 0; - - /* Iterate over each BFD within this archive. */ - while (curr_bfd != NULL) - { - unsigned int curr_count, i; - som_symbol_type *sym; - - /* Don't bother for non-SOM objects. */ - if (curr_bfd->format != bfd_object - || curr_bfd->xvec->flavour != bfd_target_som_flavour) - { - curr_bfd = curr_bfd->next; - continue; - } - - /* Make sure the symbol table has been read, then snag a pointer - to it. It's a little slimey to grab the symbols via obj_som_symtab, - but doing so avoids allocating lots of extra memory. */ - if (som_slurp_symbol_table (curr_bfd) == false) - return false; - - sym = obj_som_symtab (curr_bfd); - curr_count = bfd_get_symcount (curr_bfd); - - /* Examine each symbol to determine if it belongs in the - library symbol table. */ - for (i = 0; i < curr_count; i++, sym++) - { - struct som_misc_symbol_info info; - - /* Derive SOM information from the BFD symbol. */ - som_bfd_derive_misc_symbol_info (curr_bfd, &sym->symbol, &info); - - /* Should we include this symbol? */ - if (info.symbol_type == ST_NULL - || info.symbol_type == ST_SYM_EXT - || info.symbol_type == ST_ARG_EXT) - continue; - - /* Only global symbols and unsatisfied commons. */ - if (info.symbol_scope != SS_UNIVERSAL - && info.symbol_type != ST_STORAGE) - continue; - - /* Do no include undefined symbols. */ - if (bfd_is_und_section (sym->symbol.section)) - continue; - - /* Bump the various counters, being careful to honor - alignment considerations in the string table. */ - (*num_syms)++; - *stringsize = *stringsize + strlen (sym->symbol.name) + 5; - while (*stringsize % 4) - (*stringsize)++; - } - - curr_bfd = curr_bfd->next; - } - return true; -} - -/* Hash a symbol name based on the hashing algorithm presented in the - SOM ABI. */ -static unsigned int -som_bfd_ar_symbol_hash (symbol) - asymbol *symbol; -{ - unsigned int len = strlen (symbol->name); - - /* Names with length 1 are special. */ - if (len == 1) - return 0x1000100 | (symbol->name[0] << 16) | symbol->name[0]; - - return ((len & 0x7f) << 24) | (symbol->name[1] << 16) - | (symbol->name[len-2] << 8) | symbol->name[len-1]; -} - -static CONST char * -normalize (file) - CONST char *file; -{ - CONST char *filename = strrchr (file, '/'); - - if (filename != NULL) - filename++; - else - filename = file; - return filename; -} - -/* Do the bulk of the work required to write the SOM library - symbol table. */ - -static boolean -som_bfd_ar_write_symbol_stuff (abfd, nsyms, string_size, lst) - bfd *abfd; - unsigned int nsyms, string_size; - struct lst_header lst; -{ - file_ptr lst_filepos; - char *strings = NULL, *p; - struct lst_symbol_record *lst_syms = NULL, *curr_lst_sym; - bfd *curr_bfd; - unsigned int *hash_table = NULL; - struct som_entry *som_dict = NULL; - struct lst_symbol_record **last_hash_entry = NULL; - unsigned int curr_som_offset, som_index, extended_name_length = 0; - unsigned int maxname = abfd->xvec->ar_max_namelen; - - hash_table = - (unsigned int *) bfd_malloc (lst.hash_size * sizeof (unsigned int)); - if (hash_table == NULL && lst.hash_size != 0) - goto error_return; - som_dict = - (struct som_entry *) bfd_malloc (lst.module_count - * sizeof (struct som_entry)); - if (som_dict == NULL && lst.module_count != 0) - goto error_return; - - last_hash_entry = - ((struct lst_symbol_record **) - bfd_malloc (lst.hash_size * sizeof (struct lst_symbol_record *))); - if (last_hash_entry == NULL && lst.hash_size != 0) - goto error_return; - - /* Lots of fields are file positions relative to the start - of the lst record. So save its location. */ - lst_filepos = bfd_tell (abfd) - sizeof (struct lst_header); - - /* Some initialization. */ - memset (hash_table, 0, 4 * lst.hash_size); - memset (som_dict, 0, lst.module_count * sizeof (struct som_entry)); - memset (last_hash_entry, 0, - lst.hash_size * sizeof (struct lst_symbol_record *)); - - /* Symbols have som_index fields, so we have to keep track of the - index of each SOM in the archive. - - The SOM dictionary has (among other things) the absolute file - position for the SOM which a particular dictionary entry - describes. We have to compute that information as we iterate - through the SOMs/symbols. */ - som_index = 0; - curr_som_offset = 8 + 2 * sizeof (struct ar_hdr) + lst.file_end; - - /* Yow! We have to know the size of the extended name table - too. */ - for (curr_bfd = abfd->archive_head; - curr_bfd != NULL; - curr_bfd = curr_bfd->next) - { - CONST char *normal = normalize (curr_bfd->filename); - unsigned int thislen; - - if (!normal) - return false; - thislen = strlen (normal); - if (thislen > maxname) - extended_name_length += thislen + 1; - } - - /* Make room for the archive header and the contents of the - extended string table. */ - if (extended_name_length) - curr_som_offset += extended_name_length + sizeof (struct ar_hdr); - - /* Make sure we're properly aligned. */ - curr_som_offset = (curr_som_offset + 0x1) & ~0x1; - - /* FIXME should be done with buffers just like everything else... */ - lst_syms = bfd_malloc (nsyms * sizeof (struct lst_symbol_record)); - if (lst_syms == NULL && nsyms != 0) - goto error_return; - strings = bfd_malloc (string_size); - if (strings == NULL && string_size != 0) - goto error_return; - - p = strings; - curr_lst_sym = lst_syms; - - curr_bfd = abfd->archive_head; - while (curr_bfd != NULL) - { - unsigned int curr_count, i; - som_symbol_type *sym; - - /* Don't bother for non-SOM objects. */ - if (curr_bfd->format != bfd_object - || curr_bfd->xvec->flavour != bfd_target_som_flavour) - { - curr_bfd = curr_bfd->next; - continue; - } - - /* Make sure the symbol table has been read, then snag a pointer - to it. It's a little slimey to grab the symbols via obj_som_symtab, - but doing so avoids allocating lots of extra memory. */ - if (som_slurp_symbol_table (curr_bfd) == false) - goto error_return; - - sym = obj_som_symtab (curr_bfd); - curr_count = bfd_get_symcount (curr_bfd); - - for (i = 0; i < curr_count; i++, sym++) - { - struct som_misc_symbol_info info; - - /* Derive SOM information from the BFD symbol. */ - som_bfd_derive_misc_symbol_info (curr_bfd, &sym->symbol, &info); - - /* Should we include this symbol? */ - if (info.symbol_type == ST_NULL - || info.symbol_type == ST_SYM_EXT - || info.symbol_type == ST_ARG_EXT) - continue; - - /* Only global symbols and unsatisfied commons. */ - if (info.symbol_scope != SS_UNIVERSAL - && info.symbol_type != ST_STORAGE) - continue; - - /* Do no include undefined symbols. */ - if (bfd_is_und_section (sym->symbol.section)) - continue; - - /* If this is the first symbol from this SOM, then update - the SOM dictionary too. */ - if (som_dict[som_index].location == 0) - { - som_dict[som_index].location = curr_som_offset; - som_dict[som_index].length = arelt_size (curr_bfd); - } - - /* Fill in the lst symbol record. */ - curr_lst_sym->hidden = 0; - curr_lst_sym->secondary_def = 0; - curr_lst_sym->symbol_type = info.symbol_type; - curr_lst_sym->symbol_scope = info.symbol_scope; - curr_lst_sym->check_level = 0; - curr_lst_sym->must_qualify = 0; - curr_lst_sym->initially_frozen = 0; - curr_lst_sym->memory_resident = 0; - curr_lst_sym->is_common = bfd_is_com_section (sym->symbol.section); - curr_lst_sym->dup_common = 0; - curr_lst_sym->xleast = 0; - curr_lst_sym->arg_reloc = info.arg_reloc; - curr_lst_sym->name.n_strx = p - strings + 4; - curr_lst_sym->qualifier_name.n_strx = 0; - curr_lst_sym->symbol_info = info.symbol_info; - curr_lst_sym->symbol_value = info.symbol_value; - curr_lst_sym->symbol_descriptor = 0; - curr_lst_sym->reserved = 0; - curr_lst_sym->som_index = som_index; - curr_lst_sym->symbol_key = som_bfd_ar_symbol_hash (&sym->symbol); - curr_lst_sym->next_entry = 0; - - /* Insert into the hash table. */ - if (hash_table[curr_lst_sym->symbol_key % lst.hash_size]) - { - struct lst_symbol_record *tmp; - - /* There is already something at the head of this hash chain, - so tack this symbol onto the end of the chain. */ - tmp = last_hash_entry[curr_lst_sym->symbol_key % lst.hash_size]; - tmp->next_entry - = (curr_lst_sym - lst_syms) * sizeof (struct lst_symbol_record) - + lst.hash_size * 4 - + lst.module_count * sizeof (struct som_entry) - + sizeof (struct lst_header); - } - else - { - /* First entry in this hash chain. */ - hash_table[curr_lst_sym->symbol_key % lst.hash_size] - = (curr_lst_sym - lst_syms) * sizeof (struct lst_symbol_record) - + lst.hash_size * 4 - + lst.module_count * sizeof (struct som_entry) - + sizeof (struct lst_header); - } - - /* Keep track of the last symbol we added to this chain so we can - easily update its next_entry pointer. */ - last_hash_entry[curr_lst_sym->symbol_key % lst.hash_size] - = curr_lst_sym; - - - /* Update the string table. */ - bfd_put_32 (abfd, strlen (sym->symbol.name), p); - p += 4; - strcpy (p, sym->symbol.name); - p += strlen (sym->symbol.name) + 1; - while ((int)p % 4) - { - bfd_put_8 (abfd, 0, p); - p++; - } - - /* Head to the next symbol. */ - curr_lst_sym++; - } - - /* Keep track of where each SOM will finally reside; then look - at the next BFD. */ - curr_som_offset += arelt_size (curr_bfd) + sizeof (struct ar_hdr); - - /* A particular object in the archive may have an odd length; the - linker requires objects begin on an even boundary. So round - up the current offset as necessary. */ - curr_som_offset = (curr_som_offset + 0x1) & ~0x1; - curr_bfd = curr_bfd->next; - som_index++; - } - - /* Now scribble out the hash table. */ - if (bfd_write ((PTR) hash_table, lst.hash_size, 4, abfd) - != lst.hash_size * 4) - goto error_return; - - /* Then the SOM dictionary. */ - if (bfd_write ((PTR) som_dict, lst.module_count, - sizeof (struct som_entry), abfd) - != lst.module_count * sizeof (struct som_entry)) - goto error_return; - - /* The library symbols. */ - if (bfd_write ((PTR) lst_syms, nsyms, sizeof (struct lst_symbol_record), abfd) - != nsyms * sizeof (struct lst_symbol_record)) - goto error_return; - - /* And finally the strings. */ - if (bfd_write ((PTR) strings, string_size, 1, abfd) != string_size) - goto error_return; - - if (hash_table != NULL) - free (hash_table); - if (som_dict != NULL) - free (som_dict); - if (last_hash_entry != NULL) - free (last_hash_entry); - if (lst_syms != NULL) - free (lst_syms); - if (strings != NULL) - free (strings); - return true; - - error_return: - if (hash_table != NULL) - free (hash_table); - if (som_dict != NULL) - free (som_dict); - if (last_hash_entry != NULL) - free (last_hash_entry); - if (lst_syms != NULL) - free (lst_syms); - if (strings != NULL) - free (strings); - - return false; -} - -/* SOM almost uses the SVR4 style extended name support, but not - quite. */ - -static boolean -som_construct_extended_name_table (abfd, tabloc, tablen, name) - bfd *abfd; - char **tabloc; - bfd_size_type *tablen; - const char **name; -{ - *name = "//"; - return _bfd_construct_extended_name_table (abfd, false, tabloc, tablen); -} - -/* Write out the LST for the archive. - - You'll never believe this is really how armaps are handled in SOM... */ - -/*ARGSUSED*/ -static boolean -som_write_armap (abfd, elength, map, orl_count, stridx) - bfd *abfd; - unsigned int elength; - struct orl *map; - unsigned int orl_count; - int stridx; -{ - bfd *curr_bfd; - struct stat statbuf; - unsigned int i, lst_size, nsyms, stringsize; - struct ar_hdr hdr; - struct lst_header lst; - int *p; - - /* We'll use this for the archive's date and mode later. */ - if (stat (abfd->filename, &statbuf) != 0) - { - bfd_set_error (bfd_error_system_call); - return false; - } - /* Fudge factor. */ - bfd_ardata (abfd)->armap_timestamp = statbuf.st_mtime + 60; - - /* Account for the lst header first. */ - lst_size = sizeof (struct lst_header); - - /* Start building the LST header. */ - /* FIXME: Do we need to examine each element to determine the - largest id number? */ - lst.system_id = CPU_PA_RISC1_0; - lst.a_magic = LIBMAGIC; - lst.version_id = VERSION_ID; - lst.file_time.secs = 0; - lst.file_time.nanosecs = 0; - - lst.hash_loc = lst_size; - lst.hash_size = SOM_LST_HASH_SIZE; - - /* Hash table is a SOM_LST_HASH_SIZE 32bit offsets. */ - lst_size += 4 * SOM_LST_HASH_SIZE; - - /* We need to count the number of SOMs in this archive. */ - curr_bfd = abfd->archive_head; - lst.module_count = 0; - while (curr_bfd != NULL) - { - /* Only true SOM objects count. */ - if (curr_bfd->format == bfd_object - && curr_bfd->xvec->flavour == bfd_target_som_flavour) - lst.module_count++; - curr_bfd = curr_bfd->next; - } - lst.module_limit = lst.module_count; - lst.dir_loc = lst_size; - lst_size += sizeof (struct som_entry) * lst.module_count; - - /* We don't support import/export tables, auxiliary headers, - or free lists yet. Make the linker work a little harder - to make our life easier. */ - - lst.export_loc = 0; - lst.export_count = 0; - lst.import_loc = 0; - lst.aux_loc = 0; - lst.aux_size = 0; - - /* Count how many symbols we will have on the hash chains and the - size of the associated string table. */ - if (som_bfd_prep_for_ar_write (abfd, &nsyms, &stringsize) == false) - return false; - - lst_size += sizeof (struct lst_symbol_record) * nsyms; - - /* For the string table. One day we might actually use this info - to avoid small seeks/reads when reading archives. */ - lst.string_loc = lst_size; - lst.string_size = stringsize; - lst_size += stringsize; - - /* SOM ABI says this must be zero. */ - lst.free_list = 0; - lst.file_end = lst_size; - - /* Compute the checksum. Must happen after the entire lst header - has filled in. */ - p = (int *)&lst; - lst.checksum = 0; - for (i = 0; i < sizeof (struct lst_header)/sizeof (int) - 1; i++) - lst.checksum ^= *p++; - - sprintf (hdr.ar_name, "/ "); - sprintf (hdr.ar_date, "%ld", bfd_ardata (abfd)->armap_timestamp); - sprintf (hdr.ar_uid, "%ld", (long) getuid ()); - sprintf (hdr.ar_gid, "%ld", (long) getgid ()); - sprintf (hdr.ar_mode, "%-8o", (unsigned int) statbuf.st_mode); - sprintf (hdr.ar_size, "%-10d", (int) lst_size); - hdr.ar_fmag[0] = '`'; - hdr.ar_fmag[1] = '\012'; - - /* Turn any nulls into spaces. */ - for (i = 0; i < sizeof (struct ar_hdr); i++) - if (((char *) (&hdr))[i] == '\0') - (((char *) (&hdr))[i]) = ' '; - - /* Scribble out the ar header. */ - if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), abfd) - != sizeof (struct ar_hdr)) - return false; - - /* Now scribble out the lst header. */ - if (bfd_write ((PTR) &lst, 1, sizeof (struct lst_header), abfd) - != sizeof (struct lst_header)) - return false; - - /* Build and write the armap. */ - if (som_bfd_ar_write_symbol_stuff (abfd, nsyms, stringsize, lst) == false) - return false; - - /* Done. */ - return true; -} - -/* Free all information we have cached for this BFD. We can always - read it again later if we need it. */ - -static boolean -som_bfd_free_cached_info (abfd) - bfd *abfd; -{ - asection *o; - - if (bfd_get_format (abfd) != bfd_object) - return true; - -#define FREE(x) if (x != NULL) { free (x); x = NULL; } - /* Free the native string and symbol tables. */ - FREE (obj_som_symtab (abfd)); - FREE (obj_som_stringtab (abfd)); - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - /* Free the native relocations. */ - o->reloc_count = -1; - FREE (som_section_data (o)->reloc_stream); - /* Free the generic relocations. */ - FREE (o->relocation); - } -#undef FREE - - return true; -} - -/* End of miscellaneous support functions. */ - -/* Linker support functions. */ -static boolean -som_bfd_link_split_section (abfd, sec) - bfd *abfd; - asection *sec; -{ - return (som_is_subspace (sec) && sec->_raw_size > 240000); -} - -#define som_close_and_cleanup som_bfd_free_cached_info - -#define som_read_ar_hdr _bfd_generic_read_ar_hdr -#define som_openr_next_archived_file bfd_generic_openr_next_archived_file -#define som_get_elt_at_index _bfd_generic_get_elt_at_index -#define som_generic_stat_arch_elt bfd_generic_stat_arch_elt -#define som_truncate_arname bfd_bsd_truncate_arname -#define som_slurp_extended_name_table _bfd_slurp_extended_name_table -#define som_update_armap_timestamp bfd_true -#define som_bfd_print_private_bfd_data _bfd_generic_bfd_print_private_bfd_data - -#define som_get_lineno _bfd_nosymbols_get_lineno -#define som_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define som_read_minisymbols _bfd_generic_read_minisymbols -#define som_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol -#define som_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -#define som_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define som_bfd_relax_section bfd_generic_relax_section -#define som_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define som_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define som_bfd_final_link _bfd_generic_final_link - - -const bfd_target som_vec = -{ - "som", /* name */ - bfd_target_som_flavour, - BFD_ENDIAN_BIG, /* target byte order */ - BFD_ENDIAN_BIG, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | DYNAMIC), - (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - -/* leading_symbol_char: is the first char of a user symbol - predictable, and if so what is it */ - 0, - '/', /* ar_pad_char */ - 14, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - {_bfd_dummy_target, - som_object_p, /* bfd_check_format */ - bfd_generic_archive_p, - _bfd_dummy_target - }, - { - bfd_false, - som_mkobject, - _bfd_generic_mkarchive, - bfd_false - }, - { - bfd_false, - som_write_object_contents, - _bfd_write_archive_contents, - bfd_false, - }, -#undef som - - BFD_JUMP_TABLE_GENERIC (som), - BFD_JUMP_TABLE_COPY (som), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (som), - BFD_JUMP_TABLE_SYMBOLS (som), - BFD_JUMP_TABLE_RELOCS (som), - BFD_JUMP_TABLE_WRITE (som), - BFD_JUMP_TABLE_LINK (som), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; - -#endif /* HOST_HPPAHPUX || HOST_HPPABSD || HOST_HPPAOSF */ diff --git a/contrib/gdb/bfd/som.h b/contrib/gdb/bfd/som.h deleted file mode 100644 index 6290e88..0000000 --- a/contrib/gdb/bfd/som.h +++ /dev/null @@ -1,224 +0,0 @@ -/* HP PA-RISC SOM object file format: definitions internal to BFD. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - - Contributed by the Center for Software Science at the - University of Utah (pa-gdb-bugs@cs.utah.edu). - - 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. */ - -#ifndef _SOM_H -#define _SOM_H - -#include "../bfd/sysdep.h" -#include "libhppa.h" - -#include <a.out.h> -#include <lst.h> -#include <ar.h> - -/* The SOM BFD backend doesn't currently use anything from these - two include files, but it's likely to need them in the future. */ -#ifdef R_DLT_REL -#include <shl.h> -#include <dl.h> -#endif - -#if defined(HOST_HPPABSD) || defined (HOST_HPPAOSF) -/* BSD uses a completely different scheme for object file identification. - so for now, define _PA_RISC_ID to accept any random value for a model - number. */ -#undef _PA_RISC_ID -#define _PA_RISC_ID(__m_num) 1 -#endif /* HOST_HPPABSD */ - -#define FILE_HDR_SIZE sizeof(struct header) -#define AUX_HDR_SIZE sizeof(struct som_exec_auxhdr) - -typedef struct som_symbol - { - asymbol symbol; - unsigned int som_type; - - /* Structured like the ELF tc_data union. Allows more code sharing - in GAS this way. */ - union - { - unsigned int hppa_arg_reloc; - PTR any; - } - tc_data; - - /* Index of this symbol in the symbol table. Only used when - building relocation streams for incomplete objects. */ - int index; - - /* How many times this symbol is used in a relocation. By sorting - the symbols from most used to least used we can significantly - reduce the size of the relocation stream for incomplete objects. */ - int reloc_count; - - /* During object file writing, the offset of the name of this symbol - in the SOM string table. */ - int stringtab_offset; - } -som_symbol_type; - -/* A structure containing all the magic information stored in a BFD's - private data which needs to be copied during an objcopy/strip run. */ -struct som_exec_data - { - /* Sort-of a magic number. BSD uses it to distinguish between - native executables and hpux executables. */ - short system_id; - - /* Magic exec flags. These control things like whether or not - null pointer dereferencing is allowed and the like. */ - long exec_flags; - - /* Add more stuff here as needed. Good examples of information - we might want to pass would be presumed_dp, entry_* and maybe - others from the file header. */ - }; - -struct somdata - { - /* All the magic information about an executable which lives - in the private BFD structure and needs to be copied from - the input bfd to the output bfd during a objcopy/strip. */ - struct som_exec_data *exec_data; - - /* These three fields are only used when writing files and are - generated from scratch. They need not be copied for objcopy - or strip to work. */ - struct header *file_hdr; - struct copyright_aux_hdr *copyright_aux_hdr; - struct user_string_aux_hdr *version_aux_hdr; - struct som_exec_auxhdr *exec_hdr; - - /* Pointers to a saved copy of the symbol and string tables. These - need not be copied for objcopy or strip to work. */ - som_symbol_type *symtab; - char *stringtab; - asymbol **sorted_syms; - - /* We remember these offsets so that after check_file_format, we have - no dependencies on the particular format of the exec_hdr. - These offsets need not be copied for objcopy or strip to work. */ - - file_ptr sym_filepos; - file_ptr str_filepos; - file_ptr reloc_filepos; - unsigned stringtab_size; - }; - -struct som_data_struct - { - struct somdata a; - }; - -/* Substructure of som_section_data_struct used to hold information - which can't be represented by the generic BFD section structure, - but which must be copied during objcopy or strip. */ -struct som_copyable_section_data_struct - { - /* Various fields in space and subspace headers that we need - to pass around. */ - unsigned int sort_key : 8; - unsigned int access_control_bits : 7; - unsigned int is_defined : 1; - unsigned int is_private : 1; - unsigned int quadrant : 2; - - /* For subspaces, this points to the section which represents the - space in which the subspace is contained. For spaces it points - back to the section for this space. */ - asection *container; - - /* The user-specified space number. It is wrong to use this as - an index since duplicates and holes are allowed. */ - int space_number; - - /* Add more stuff here as needed. Good examples of information - we might want to pass would be initialization pointers, - and the many subspace flags we do not represent yet. */ - }; - -/* Used to keep extra SOM specific information for a given section. - - reloc_size holds the size of the relocation stream, note this - is very different from the number of relocations as SOM relocations - are variable length. - - reloc_stream is the actual stream of relocation entries. */ - -struct som_section_data_struct - { - struct som_copyable_section_data_struct *copy_data; - unsigned int reloc_size; - char *reloc_stream; - struct space_dictionary_record *space_dict; - struct subspace_dictionary_record *subspace_dict; - }; - -#define somdata(bfd) ((bfd)->tdata.som_data->a) -#define obj_som_exec_data(bfd) (somdata(bfd).exec_data) -#define obj_som_file_hdr(bfd) (somdata(bfd).file_hdr) -#define obj_som_exec_hdr(bfd) (somdata(bfd).exec_hdr) -#define obj_som_copyright_hdr(bfd) (somdata(bfd).copyright_aux_hdr) -#define obj_som_version_hdr(bfd) (somdata(bfd).version_aux_hdr) -#define obj_som_symtab(bfd) (somdata(bfd).symtab) -#define obj_som_stringtab(bfd) (somdata(bfd).stringtab) -#define obj_som_sym_filepos(bfd) (somdata(bfd).sym_filepos) -#define obj_som_str_filepos(bfd) (somdata(bfd).str_filepos) -#define obj_som_stringtab_size(bfd) (somdata(bfd).stringtab_size) -#define obj_som_reloc_filepos(bfd) (somdata(bfd).reloc_filepos) -#define obj_som_sorted_syms(bfd) (somdata(bfd).sorted_syms) -#define som_section_data(sec) \ - ((struct som_section_data_struct *)sec->used_by_bfd) -#define som_symbol_data(symbol) ((som_symbol_type *) symbol) - - -/* Defines groups of basic relocations. FIXME: These should - be the only basic relocations created by GAS. The rest - should be internal to the BFD backend. - - The idea is both SOM and ELF define these basic relocation - types so they map into a SOM or ELF specific reloation as - appropriate. This allows GAS to share much more code - between the two object formats. */ - -#define R_HPPA_NONE R_NO_RELOCATION -#define R_HPPA R_CODE_ONE_SYMBOL -#define R_HPPA_PCREL_CALL R_PCREL_CALL -#define R_HPPA_ABS_CALL R_ABS_CALL -#define R_HPPA_GOTOFF R_DP_RELATIVE -#define R_HPPA_ENTRY R_ENTRY -#define R_HPPA_EXIT R_EXIT -#define R_HPPA_COMPLEX R_COMP1 -#define R_HPPA_BEGIN_BRTAB R_BEGIN_BRTAB -#define R_HPPA_END_BRTAB R_END_BRTAB - -/* Exported functions, mostly for use by GAS. */ -boolean bfd_som_set_section_attributes PARAMS ((asection *, int, int, - unsigned int, int)); -boolean bfd_som_set_subsection_attributes PARAMS ((asection *, asection *, - int, unsigned int, int)); -void bfd_som_set_symbol_type PARAMS ((asymbol *, unsigned int)); -boolean bfd_som_attach_aux_hdr PARAMS ((bfd *, int, char *)); -int ** hppa_som_gen_reloc_type - PARAMS ((bfd *, int, int, enum hppa_reloc_field_selector_type_alt, int)); -#endif /* _SOM_H */ diff --git a/contrib/gdb/bfd/sparclynx.c b/contrib/gdb/bfd/sparclynx.c deleted file mode 100644 index 0885620..0000000 --- a/contrib/gdb/bfd/sparclynx.c +++ /dev/null @@ -1,265 +0,0 @@ -/* BFD support for Sparc binaries under LynxOS. - Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - -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. */ - -#if 0 -#define BYTES_IN_WORD 4 -#define N_SHARED_LIB(x) 0 - -#define TEXT_START_ADDR 0 -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE TARGET_PAGE_SIZE -#define DEFAULT_ARCH bfd_arch_sparc - -#endif - -#define MY(OP) CAT(sparclynx_aout_,OP) -#define TARGETNAME "a.out-sparc-lynx" - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -#include "aout/sun4.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -#include "aout/aout64.h" -#include "aout/stab_gnu.h" -#include "aout/ar.h" - -/* This is needed to reject a NewsOS file, e.g. in - gdb/testsuite/gdb.t10/crossload.exp. <kingdon@cygnus.com> - I needed to add M_UNKNOWN to recognize a 68000 object, so this will - probably no longer reject a NewsOS object. <ian@cygnus.com>. */ -#define MACHTYPE_OK(mtype) ((mtype) == M_UNKNOWN \ - || (mtype) == M_68010 \ - || (mtype) == M_68020 \ - || (mtype) == M_SPARC) - -/* -The file @code{aoutf1.h} contains the code for BFD's -a.out back end. Control over the generated back end is given by these -two preprocessor names: -@table @code -@item ARCH_SIZE -This value should be either 32 or 64, depending upon the size of an -int in the target format. It changes the sizes of the structs which -perform the memory/disk mapping of structures. - -The 64 bit backend may only be used if the host compiler supports 64 -ints (eg long long with gcc), by defining the name @code{BFD_HOST_64_BIT} in @code{bfd.h}. -With this name defined, @emph{all} bfd operations are performed with 64bit -arithmetic, not just those to a 64bit target. - -@item TARGETNAME -The name put into the target vector. -@item -@end table - -*/ - -/*SUPPRESS558*/ -/*SUPPRESS529*/ - -void -NAME(lynx,set_arch_mach) (abfd, machtype) - bfd *abfd; - int machtype; -{ - /* Determine the architecture and machine type of the object file. */ - enum bfd_architecture arch; - long machine; - switch (machtype) - { - - case M_UNKNOWN: - /* Some Sun3s make magic numbers without cpu types in them, so - we'll default to the 68000. */ - arch = bfd_arch_m68k; - machine = 68000; - break; - - case M_68010: - case M_HP200: - arch = bfd_arch_m68k; - machine = 68010; - break; - - case M_68020: - case M_HP300: - arch = bfd_arch_m68k; - machine = 68020; - break; - - case M_SPARC: - arch = bfd_arch_sparc; - machine = 0; - break; - - case M_386: - case M_386_DYNIX: - arch = bfd_arch_i386; - machine = 0; - break; - - case M_29K: - arch = bfd_arch_a29k; - machine = 0; - break; - - case M_HPUX: - arch = bfd_arch_m68k; - machine = 0; - break; - - default: - arch = bfd_arch_obscure; - machine = 0; - break; - } - bfd_set_arch_mach (abfd, arch, machine); -} - -#define SET_ARCH_MACH(ABFD, EXEC) \ - NAME(lynx,set_arch_mach)(ABFD, N_MACHTYPE (EXEC)); \ - choose_reloc_size(ABFD); - -/* Determine the size of a relocation entry, based on the architecture */ -static void -choose_reloc_size (abfd) - bfd *abfd; -{ - switch (bfd_get_arch (abfd)) - { - case bfd_arch_sparc: - case bfd_arch_a29k: - obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE; - break; - default: - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - break; - } -} - -/* Write an object file in LynxOS format. - Section contents have already been written. We write the - file header, symbols, and relocation. */ - -static boolean -NAME(aout,sparclynx_write_object_contents) (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - - /* Magic number, maestro, please! */ - switch (bfd_get_arch (abfd)) - { - case bfd_arch_m68k: - switch (bfd_get_mach (abfd)) - { - case 68010: - N_SET_MACHTYPE (*execp, M_68010); - break; - default: - case 68020: - N_SET_MACHTYPE (*execp, M_68020); - break; - } - break; - case bfd_arch_sparc: - N_SET_MACHTYPE (*execp, M_SPARC); - break; - case bfd_arch_i386: - N_SET_MACHTYPE (*execp, M_386); - break; - case bfd_arch_a29k: - N_SET_MACHTYPE (*execp, M_29K); - break; - default: - N_SET_MACHTYPE (*execp, M_UNKNOWN); - } - - choose_reloc_size (abfd); - - N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags); - - WRITE_HEADERS (abfd, execp); - - return true; -} - -#define MY_set_sizes sparclynx_set_sizes -static boolean -sparclynx_set_sizes (abfd) - bfd *abfd; -{ - switch (bfd_get_arch (abfd)) - { - default: - return false; - case bfd_arch_sparc: - adata (abfd).page_size = 0x2000; - adata (abfd).segment_size = 0x2000; - adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE; - return true; - case bfd_arch_m68k: - adata (abfd).page_size = 0x2000; - adata (abfd).segment_size = 0x20000; - adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE; - return true; - } -} - -static CONST struct aout_backend_data sparclynx_aout_backend = -{ - 0, 1, 1, 0, sparclynx_set_sizes, 0, - 0, /* add_dynamic_symbols */ - 0, /* add_one_symbol */ - 0, /* link_dynamic_object */ - 0, /* write_dynamic_symbol */ - 0, /* check_dynamic_reloc */ - 0 /* finish_dynamic_link */ -}; - - -#define MY_bfd_debug_info_start bfd_void -#define MY_bfd_debug_info_end bfd_void -#define MY_bfd_debug_info_accumulate \ - (void (*) PARAMS ((bfd *, struct sec *))) bfd_void - -#define MY_write_object_contents NAME(aout,sparclynx_write_object_contents) -#define MY_backend_data &sparclynx_aout_backend - -#define TARGET_IS_BIG_ENDIAN_P - -#ifdef LYNX_CORE - -char *lynx_core_file_failing_command (); -int lynx_core_file_failing_signal (); -boolean lynx_core_file_matches_executable_p (); -const bfd_target *lynx_core_file_p (); - -#define MY_core_file_failing_command lynx_core_file_failing_command -#define MY_core_file_failing_signal lynx_core_file_failing_signal -#define MY_core_file_matches_executable_p lynx_core_file_matches_executable_p -#define MY_core_file_p lynx_core_file_p - -#endif /* LYNX_CORE */ - -#include "aout-target.h" diff --git a/contrib/gdb/bfd/sparcnetbsd.c b/contrib/gdb/bfd/sparcnetbsd.c deleted file mode 100644 index 69240f5..0000000 --- a/contrib/gdb/bfd/sparcnetbsd.c +++ /dev/null @@ -1,33 +0,0 @@ -/* BFD back-end for NetBSD/sparc a.out-ish binaries. - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - -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. */ - -#define BYTES_IN_WORD 4 -#define TARGET_IS_BIG_ENDIAN_P - -#define TARGET_PAGE_SIZE 4096 -#define SEGMENT_SIZE 4096 - -#define DEFAULT_ARCH bfd_arch_sparc -#define MACHTYPE_OK(mtype) ((mtype) == M_SPARC_NETBSD || (mtype) == M_UNKNOWN) - -#define MY(OP) CAT(sparcnetbsd_,OP) -/* This needs to start with a.out so GDB knows it is an a.out variant. */ -#define TARGETNAME "a.out-sparc-netbsd" - -#include "netbsd.h" diff --git a/contrib/gdb/bfd/sunos.c b/contrib/gdb/bfd/sunos.c deleted file mode 100644 index 77bf319..0000000 --- a/contrib/gdb/bfd/sunos.c +++ /dev/null @@ -1,2767 +0,0 @@ -/* BFD backend for SunOS binaries. - Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - Written by Cygnus Support. - -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. */ - -#define TARGETNAME "a.out-sunos-big" -#define MY(OP) CAT(sunos_big_,OP) - -#include "bfd.h" -#include "bfdlink.h" -#include "libaout.h" - -/* Static routines defined in this file. */ - -static boolean sunos_read_dynamic_info PARAMS ((bfd *)); -static long sunos_get_dynamic_symtab_upper_bound PARAMS ((bfd *)); -static boolean sunos_slurp_dynamic_symtab PARAMS ((bfd *)); -static long sunos_canonicalize_dynamic_symtab PARAMS ((bfd *, asymbol **)); -static long sunos_get_dynamic_reloc_upper_bound PARAMS ((bfd *)); -static long sunos_canonicalize_dynamic_reloc - PARAMS ((bfd *, arelent **, asymbol **)); -static struct bfd_hash_entry *sunos_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static struct bfd_link_hash_table *sunos_link_hash_table_create - PARAMS ((bfd *)); -static boolean sunos_create_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *, boolean)); -static boolean sunos_add_dynamic_symbols - PARAMS ((bfd *, struct bfd_link_info *, struct external_nlist **, - bfd_size_type *, char **)); -static boolean sunos_add_one_symbol - PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *, - bfd_vma, const char *, boolean, boolean, - struct bfd_link_hash_entry **)); -static boolean sunos_scan_relocs - PARAMS ((struct bfd_link_info *, bfd *, asection *, bfd_size_type)); -static boolean sunos_scan_std_relocs - PARAMS ((struct bfd_link_info *, bfd *, asection *, - const struct reloc_std_external *, bfd_size_type)); -static boolean sunos_scan_ext_relocs - PARAMS ((struct bfd_link_info *, bfd *, asection *, - const struct reloc_ext_external *, bfd_size_type)); -static boolean sunos_link_dynamic_object - PARAMS ((struct bfd_link_info *, bfd *)); -static boolean sunos_write_dynamic_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct aout_link_hash_entry *)); -static boolean sunos_check_dynamic_reloc - PARAMS ((struct bfd_link_info *, bfd *, asection *, - struct aout_link_hash_entry *, PTR, bfd_byte *, boolean *, - bfd_vma *)); -static boolean sunos_finish_dynamic_link - PARAMS ((bfd *, struct bfd_link_info *)); - -#define MY_get_dynamic_symtab_upper_bound sunos_get_dynamic_symtab_upper_bound -#define MY_canonicalize_dynamic_symtab sunos_canonicalize_dynamic_symtab -#define MY_get_dynamic_reloc_upper_bound sunos_get_dynamic_reloc_upper_bound -#define MY_canonicalize_dynamic_reloc sunos_canonicalize_dynamic_reloc -#define MY_bfd_link_hash_table_create sunos_link_hash_table_create -#define MY_add_dynamic_symbols sunos_add_dynamic_symbols -#define MY_add_one_symbol sunos_add_one_symbol -#define MY_link_dynamic_object sunos_link_dynamic_object -#define MY_write_dynamic_symbol sunos_write_dynamic_symbol -#define MY_check_dynamic_reloc sunos_check_dynamic_reloc -#define MY_finish_dynamic_link sunos_finish_dynamic_link - -/* Include the usual a.out support. */ -#include "aoutf1.h" - -/* SunOS shared library support. We store a pointer to this structure - in obj_aout_dynamic_info (abfd). */ - -struct sunos_dynamic_info -{ - /* Whether we found any dynamic information. */ - boolean valid; - /* Dynamic information. */ - struct internal_sun4_dynamic_link dyninfo; - /* Number of dynamic symbols. */ - unsigned long dynsym_count; - /* Read in nlists for dynamic symbols. */ - struct external_nlist *dynsym; - /* asymbol structures for dynamic symbols. */ - aout_symbol_type *canonical_dynsym; - /* Read in dynamic string table. */ - char *dynstr; - /* Number of dynamic relocs. */ - unsigned long dynrel_count; - /* Read in dynamic relocs. This may be reloc_std_external or - reloc_ext_external. */ - PTR dynrel; - /* arelent structures for dynamic relocs. */ - arelent *canonical_dynrel; -}; - -/* The hash table of dynamic symbols is composed of two word entries. - See include/aout/sun4.h for details. */ - -#define HASH_ENTRY_SIZE (2 * BYTES_IN_WORD) - -/* Read in the basic dynamic information. This locates the __DYNAMIC - structure and uses it to find the dynamic_link structure. It - creates and saves a sunos_dynamic_info structure. If it can't find - __DYNAMIC, it sets the valid field of the sunos_dynamic_info - structure to false to avoid doing this work again. */ - -static boolean -sunos_read_dynamic_info (abfd) - bfd *abfd; -{ - struct sunos_dynamic_info *info; - asection *dynsec; - bfd_vma dynoff; - struct external_sun4_dynamic dyninfo; - unsigned long dynver; - struct external_sun4_dynamic_link linkinfo; - - if (obj_aout_dynamic_info (abfd) != (PTR) NULL) - return true; - - if ((abfd->flags & DYNAMIC) == 0) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - info = ((struct sunos_dynamic_info *) - bfd_zalloc (abfd, sizeof (struct sunos_dynamic_info))); - if (!info) - return false; - info->valid = false; - info->dynsym = NULL; - info->dynstr = NULL; - info->canonical_dynsym = NULL; - info->dynrel = NULL; - info->canonical_dynrel = NULL; - obj_aout_dynamic_info (abfd) = (PTR) info; - - /* This code used to look for the __DYNAMIC symbol to locate the dynamic - linking information. - However this inhibits recovering the dynamic symbols from a - stripped object file, so blindly assume that the dynamic linking - information is located at the start of the data section. - We could verify this assumption later by looking through the dynamic - symbols for the __DYNAMIC symbol. */ - if ((abfd->flags & DYNAMIC) == 0) - return true; - if (! bfd_get_section_contents (abfd, obj_datasec (abfd), (PTR) &dyninfo, - (file_ptr) 0, sizeof dyninfo)) - return true; - - dynver = GET_WORD (abfd, dyninfo.ld_version); - if (dynver != 2 && dynver != 3) - return true; - - dynoff = GET_WORD (abfd, dyninfo.ld); - - /* dynoff is a virtual address. It is probably always in the .data - section, but this code should work even if it moves. */ - if (dynoff < bfd_get_section_vma (abfd, obj_datasec (abfd))) - dynsec = obj_textsec (abfd); - else - dynsec = obj_datasec (abfd); - dynoff -= bfd_get_section_vma (abfd, dynsec); - if (dynoff > bfd_section_size (abfd, dynsec)) - return true; - - /* This executable appears to be dynamically linked in a way that we - can understand. */ - if (! bfd_get_section_contents (abfd, dynsec, (PTR) &linkinfo, dynoff, - (bfd_size_type) sizeof linkinfo)) - return true; - - /* Swap in the dynamic link information. */ - info->dyninfo.ld_loaded = GET_WORD (abfd, linkinfo.ld_loaded); - info->dyninfo.ld_need = GET_WORD (abfd, linkinfo.ld_need); - info->dyninfo.ld_rules = GET_WORD (abfd, linkinfo.ld_rules); - info->dyninfo.ld_got = GET_WORD (abfd, linkinfo.ld_got); - info->dyninfo.ld_plt = GET_WORD (abfd, linkinfo.ld_plt); - info->dyninfo.ld_rel = GET_WORD (abfd, linkinfo.ld_rel); - info->dyninfo.ld_hash = GET_WORD (abfd, linkinfo.ld_hash); - info->dyninfo.ld_stab = GET_WORD (abfd, linkinfo.ld_stab); - info->dyninfo.ld_stab_hash = GET_WORD (abfd, linkinfo.ld_stab_hash); - info->dyninfo.ld_buckets = GET_WORD (abfd, linkinfo.ld_buckets); - info->dyninfo.ld_symbols = GET_WORD (abfd, linkinfo.ld_symbols); - info->dyninfo.ld_symb_size = GET_WORD (abfd, linkinfo.ld_symb_size); - info->dyninfo.ld_text = GET_WORD (abfd, linkinfo.ld_text); - info->dyninfo.ld_plt_sz = GET_WORD (abfd, linkinfo.ld_plt_sz); - - /* Reportedly the addresses need to be offset by the size of the - exec header in an NMAGIC file. */ - if (adata (abfd).magic == n_magic) - { - unsigned long exec_bytes_size = adata (abfd).exec_bytes_size; - - info->dyninfo.ld_need += exec_bytes_size; - info->dyninfo.ld_rules += exec_bytes_size; - info->dyninfo.ld_rel += exec_bytes_size; - info->dyninfo.ld_hash += exec_bytes_size; - info->dyninfo.ld_stab += exec_bytes_size; - info->dyninfo.ld_symbols += exec_bytes_size; - } - - /* The only way to get the size of the symbol information appears to - be to determine the distance between it and the string table. */ - info->dynsym_count = ((info->dyninfo.ld_symbols - info->dyninfo.ld_stab) - / EXTERNAL_NLIST_SIZE); - BFD_ASSERT (info->dynsym_count * EXTERNAL_NLIST_SIZE - == (unsigned long) (info->dyninfo.ld_symbols - - info->dyninfo.ld_stab)); - - /* Similarly, the relocs end at the hash table. */ - info->dynrel_count = ((info->dyninfo.ld_hash - info->dyninfo.ld_rel) - / obj_reloc_entry_size (abfd)); - BFD_ASSERT (info->dynrel_count * obj_reloc_entry_size (abfd) - == (unsigned long) (info->dyninfo.ld_hash - - info->dyninfo.ld_rel)); - - info->valid = true; - - return true; -} - -/* Return the amount of memory required for the dynamic symbols. */ - -static long -sunos_get_dynamic_symtab_upper_bound (abfd) - bfd *abfd; -{ - struct sunos_dynamic_info *info; - - if (! sunos_read_dynamic_info (abfd)) - return -1; - - info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); - if (! info->valid) - { - bfd_set_error (bfd_error_no_symbols); - return -1; - } - - return (info->dynsym_count + 1) * sizeof (asymbol *); -} - -/* Read the external dynamic symbols. */ - -static boolean -sunos_slurp_dynamic_symtab (abfd) - bfd *abfd; -{ - struct sunos_dynamic_info *info; - - /* Get the general dynamic information. */ - if (obj_aout_dynamic_info (abfd) == NULL) - { - if (! sunos_read_dynamic_info (abfd)) - return false; - } - - info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); - if (! info->valid) - { - bfd_set_error (bfd_error_no_symbols); - return false; - } - - /* Get the dynamic nlist structures. */ - if (info->dynsym == (struct external_nlist *) NULL) - { - info->dynsym = ((struct external_nlist *) - bfd_alloc (abfd, - (info->dynsym_count - * EXTERNAL_NLIST_SIZE))); - if (info->dynsym == NULL && info->dynsym_count != 0) - return false; - if (bfd_seek (abfd, info->dyninfo.ld_stab, SEEK_SET) != 0 - || (bfd_read ((PTR) info->dynsym, info->dynsym_count, - EXTERNAL_NLIST_SIZE, abfd) - != info->dynsym_count * EXTERNAL_NLIST_SIZE)) - { - if (info->dynsym != NULL) - { - bfd_release (abfd, info->dynsym); - info->dynsym = NULL; - } - return false; - } - } - - /* Get the dynamic strings. */ - if (info->dynstr == (char *) NULL) - { - info->dynstr = (char *) bfd_alloc (abfd, info->dyninfo.ld_symb_size); - if (info->dynstr == NULL && info->dyninfo.ld_symb_size != 0) - return false; - if (bfd_seek (abfd, info->dyninfo.ld_symbols, SEEK_SET) != 0 - || (bfd_read ((PTR) info->dynstr, 1, info->dyninfo.ld_symb_size, - abfd) - != info->dyninfo.ld_symb_size)) - { - if (info->dynstr != NULL) - { - bfd_release (abfd, info->dynstr); - info->dynstr = NULL; - } - return false; - } - } - - return true; -} - -/* Read in the dynamic symbols. */ - -static long -sunos_canonicalize_dynamic_symtab (abfd, storage) - bfd *abfd; - asymbol **storage; -{ - struct sunos_dynamic_info *info; - unsigned long i; - - if (! sunos_slurp_dynamic_symtab (abfd)) - return -1; - - info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); - -#ifdef CHECK_DYNAMIC_HASH - /* Check my understanding of the dynamic hash table by making sure - that each symbol can be located in the hash table. */ - { - bfd_size_type table_size; - bfd_byte *table; - bfd_size_type i; - - if (info->dyninfo.ld_buckets > info->dynsym_count) - abort (); - table_size = info->dyninfo.ld_stab - info->dyninfo.ld_hash; - table = (bfd_byte *) bfd_malloc (table_size); - if (table == NULL && table_size != 0) - abort (); - if (bfd_seek (abfd, info->dyninfo.ld_hash, SEEK_SET) != 0 - || bfd_read ((PTR) table, 1, table_size, abfd) != table_size) - abort (); - for (i = 0; i < info->dynsym_count; i++) - { - unsigned char *name; - unsigned long hash; - - name = ((unsigned char *) info->dynstr - + GET_WORD (abfd, info->dynsym[i].e_strx)); - hash = 0; - while (*name != '\0') - hash = (hash << 1) + *name++; - hash &= 0x7fffffff; - hash %= info->dyninfo.ld_buckets; - while (GET_WORD (abfd, table + hash * HASH_ENTRY_SIZE) != i) - { - hash = GET_WORD (abfd, - table + hash * HASH_ENTRY_SIZE + BYTES_IN_WORD); - if (hash == 0 || hash >= table_size / HASH_ENTRY_SIZE) - abort (); - } - } - free (table); - } -#endif /* CHECK_DYNAMIC_HASH */ - - /* Get the asymbol structures corresponding to the dynamic nlist - structures. */ - if (info->canonical_dynsym == (aout_symbol_type *) NULL) - { - info->canonical_dynsym = ((aout_symbol_type *) - bfd_alloc (abfd, - (info->dynsym_count - * sizeof (aout_symbol_type)))); - if (info->canonical_dynsym == NULL && info->dynsym_count != 0) - return -1; - - if (! aout_32_translate_symbol_table (abfd, info->canonical_dynsym, - info->dynsym, info->dynsym_count, - info->dynstr, - info->dyninfo.ld_symb_size, - true)) - { - if (info->canonical_dynsym != NULL) - { - bfd_release (abfd, info->canonical_dynsym); - info->canonical_dynsym = NULL; - } - return -1; - } - } - - /* Return pointers to the dynamic asymbol structures. */ - for (i = 0; i < info->dynsym_count; i++) - *storage++ = (asymbol *) (info->canonical_dynsym + i); - *storage = NULL; - - return info->dynsym_count; -} - -/* Return the amount of memory required for the dynamic relocs. */ - -static long -sunos_get_dynamic_reloc_upper_bound (abfd) - bfd *abfd; -{ - struct sunos_dynamic_info *info; - - if (! sunos_read_dynamic_info (abfd)) - return -1; - - info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); - if (! info->valid) - { - bfd_set_error (bfd_error_no_symbols); - return -1; - } - - return (info->dynrel_count + 1) * sizeof (arelent *); -} - -/* Read in the dynamic relocs. */ - -static long -sunos_canonicalize_dynamic_reloc (abfd, storage, syms) - bfd *abfd; - arelent **storage; - asymbol **syms; -{ - struct sunos_dynamic_info *info; - unsigned long i; - - /* Get the general dynamic information. */ - if (obj_aout_dynamic_info (abfd) == (PTR) NULL) - { - if (! sunos_read_dynamic_info (abfd)) - return -1; - } - - info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); - if (! info->valid) - { - bfd_set_error (bfd_error_no_symbols); - return -1; - } - - /* Get the dynamic reloc information. */ - if (info->dynrel == NULL) - { - info->dynrel = (PTR) bfd_alloc (abfd, - (info->dynrel_count - * obj_reloc_entry_size (abfd))); - if (info->dynrel == NULL && info->dynrel_count != 0) - return -1; - if (bfd_seek (abfd, info->dyninfo.ld_rel, SEEK_SET) != 0 - || (bfd_read ((PTR) info->dynrel, info->dynrel_count, - obj_reloc_entry_size (abfd), abfd) - != info->dynrel_count * obj_reloc_entry_size (abfd))) - { - if (info->dynrel != NULL) - { - bfd_release (abfd, info->dynrel); - info->dynrel = NULL; - } - return -1; - } - } - - /* Get the arelent structures corresponding to the dynamic reloc - information. */ - if (info->canonical_dynrel == (arelent *) NULL) - { - arelent *to; - - info->canonical_dynrel = ((arelent *) - bfd_alloc (abfd, - (info->dynrel_count - * sizeof (arelent)))); - if (info->canonical_dynrel == NULL && info->dynrel_count != 0) - return -1; - - to = info->canonical_dynrel; - - if (obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE) - { - register struct reloc_ext_external *p; - struct reloc_ext_external *pend; - - p = (struct reloc_ext_external *) info->dynrel; - pend = p + info->dynrel_count; - for (; p < pend; p++, to++) - NAME(aout,swap_ext_reloc_in) (abfd, p, to, syms, - info->dynsym_count); - } - else - { - register struct reloc_std_external *p; - struct reloc_std_external *pend; - - p = (struct reloc_std_external *) info->dynrel; - pend = p + info->dynrel_count; - for (; p < pend; p++, to++) - NAME(aout,swap_std_reloc_in) (abfd, p, to, syms, - info->dynsym_count); - } - } - - /* Return pointers to the dynamic arelent structures. */ - for (i = 0; i < info->dynrel_count; i++) - *storage++ = info->canonical_dynrel + i; - *storage = NULL; - - return info->dynrel_count; -} - -/* Code to handle linking of SunOS shared libraries. */ - -/* A SPARC procedure linkage table entry is 12 bytes. The first entry - in the table is a jump which is filled in by the runtime linker. - The remaining entries are branches back to the first entry, - followed by an index into the relocation table encoded to look like - a sethi of %g0. */ - -#define SPARC_PLT_ENTRY_SIZE (12) - -static const bfd_byte sparc_plt_first_entry[SPARC_PLT_ENTRY_SIZE] = -{ - /* sethi %hi(0),%g1; address filled in by runtime linker. */ - 0x3, 0, 0, 0, - /* jmp %g1; offset filled in by runtime linker. */ - 0x81, 0xc0, 0x60, 0, - /* nop */ - 0x1, 0, 0, 0 -}; - -/* save %sp, -96, %sp */ -#define SPARC_PLT_ENTRY_WORD0 0x9de3bfa0 -/* call; address filled in later. */ -#define SPARC_PLT_ENTRY_WORD1 0x40000000 -/* sethi; reloc index filled in later. */ -#define SPARC_PLT_ENTRY_WORD2 0x01000000 - -/* This sequence is used when for the jump table entry to a defined - symbol in a complete executable. It is used when linking PIC - compiled code which is not being put into a shared library. */ -/* sethi <address to be filled in later>, %g1 */ -#define SPARC_PLT_PIC_WORD0 0x03000000 -/* jmp %g1 + <address to be filled in later> */ -#define SPARC_PLT_PIC_WORD1 0x81c06000 -/* nop */ -#define SPARC_PLT_PIC_WORD2 0x01000000 - -/* An m68k procedure linkage table entry is 8 bytes. The first entry - in the table is a jump which is filled in the by the runtime - linker. The remaining entries are branches back to the first - entry, followed by a two byte index into the relocation table. */ - -#define M68K_PLT_ENTRY_SIZE (8) - -static const bfd_byte m68k_plt_first_entry[M68K_PLT_ENTRY_SIZE] = -{ - /* jmps @# */ - 0x4e, 0xf9, - /* Filled in by runtime linker with a magic address. */ - 0, 0, 0, 0, - /* Not used? */ - 0, 0 -}; - -/* bsrl */ -#define M68K_PLT_ENTRY_WORD0 (0x61ff) -/* Remaining words filled in later. */ - -/* An entry in the SunOS linker hash table. */ - -struct sunos_link_hash_entry -{ - struct aout_link_hash_entry root; - - /* If this is a dynamic symbol, this is its index into the dynamic - symbol table. This is initialized to -1. As the linker looks at - the input files, it changes this to -2 if it will be added to the - dynamic symbol table. After all the input files have been seen, - the linker will know whether to build a dynamic symbol table; if - it does build one, this becomes the index into the table. */ - long dynindx; - - /* If this is a dynamic symbol, this is the index of the name in the - dynamic symbol string table. */ - long dynstr_index; - - /* The offset into the global offset table used for this symbol. If - the symbol does not require a GOT entry, this is 0. */ - bfd_vma got_offset; - - /* The offset into the procedure linkage table used for this symbol. - If the symbol does not require a PLT entry, this is 0. */ - bfd_vma plt_offset; - - /* Some linker flags. */ - unsigned char flags; - /* Symbol is referenced by a regular object. */ -#define SUNOS_REF_REGULAR 01 - /* Symbol is defined by a regular object. */ -#define SUNOS_DEF_REGULAR 02 - /* Symbol is referenced by a dynamic object. */ -#define SUNOS_REF_DYNAMIC 04 - /* Symbol is defined by a dynamic object. */ -#define SUNOS_DEF_DYNAMIC 010 - /* Symbol is a constructor symbol in a regular object. */ -#define SUNOS_CONSTRUCTOR 020 -}; - -/* The SunOS linker hash table. */ - -struct sunos_link_hash_table -{ - struct aout_link_hash_table root; - - /* The object which holds the dynamic sections. */ - bfd *dynobj; - - /* Whether we have created the dynamic sections. */ - boolean dynamic_sections_created; - - /* Whether we need the dynamic sections. */ - boolean dynamic_sections_needed; - - /* The number of dynamic symbols. */ - size_t dynsymcount; - - /* The number of buckets in the hash table. */ - size_t bucketcount; - - /* The list of dynamic objects needed by dynamic objects included in - the link. */ - struct bfd_link_needed_list *needed; -}; - -/* Routine to create an entry in an SunOS link hash table. */ - -static struct bfd_hash_entry * -sunos_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct sunos_link_hash_entry *ret = (struct sunos_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct sunos_link_hash_entry *) NULL) - ret = ((struct sunos_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct sunos_link_hash_entry))); - if (ret == (struct sunos_link_hash_entry *) NULL) - return (struct bfd_hash_entry *) ret; - - /* Call the allocation method of the superclass. */ - ret = ((struct sunos_link_hash_entry *) - NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret, - table, string)); - if (ret != NULL) - { - /* Set local fields. */ - ret->dynindx = -1; - ret->dynstr_index = -1; - ret->got_offset = 0; - ret->plt_offset = 0; - ret->flags = 0; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Create a SunOS link hash table. */ - -static struct bfd_link_hash_table * -sunos_link_hash_table_create (abfd) - bfd *abfd; -{ - struct sunos_link_hash_table *ret; - - ret = ((struct sunos_link_hash_table *) - bfd_alloc (abfd, sizeof (struct sunos_link_hash_table))); - if (ret == (struct sunos_link_hash_table *) NULL) - return (struct bfd_link_hash_table *) NULL; - if (! NAME(aout,link_hash_table_init) (&ret->root, abfd, - sunos_link_hash_newfunc)) - { - bfd_release (abfd, ret); - return (struct bfd_link_hash_table *) NULL; - } - - ret->dynobj = NULL; - ret->dynamic_sections_created = false; - ret->dynamic_sections_needed = false; - ret->dynsymcount = 0; - ret->bucketcount = 0; - ret->needed = NULL; - - return &ret->root.root; -} - -/* Look up an entry in an SunOS link hash table. */ - -#define sunos_link_hash_lookup(table, string, create, copy, follow) \ - ((struct sunos_link_hash_entry *) \ - aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\ - (follow))) - -/* Traverse a SunOS link hash table. */ - -#define sunos_link_hash_traverse(table, func, info) \ - (aout_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the SunOS link hash table from the info structure. This is - just a cast. */ - -#define sunos_hash_table(p) ((struct sunos_link_hash_table *) ((p)->hash)) - -static boolean sunos_scan_dynamic_symbol - PARAMS ((struct sunos_link_hash_entry *, PTR)); - -/* Create the dynamic sections needed if we are linking against a - dynamic object, or if we are linking PIC compiled code. ABFD is a - bfd we can attach the dynamic sections to. The linker script will - look for these special sections names and put them in the right - place in the output file. See include/aout/sun4.h for more details - of the dynamic linking information. */ - -static boolean -sunos_create_dynamic_sections (abfd, info, needed) - bfd *abfd; - struct bfd_link_info *info; - boolean needed; -{ - asection *s; - - if (! sunos_hash_table (info)->dynamic_sections_created) - { - flagword flags; - - sunos_hash_table (info)->dynobj = abfd; - - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - - /* The .dynamic section holds the basic dynamic information: the - sun4_dynamic structure, the dynamic debugger information, and - the sun4_dynamic_link structure. */ - s = bfd_make_section (abfd, ".dynamic"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - /* The .got section holds the global offset table. The address - is put in the ld_got field. */ - s = bfd_make_section (abfd, ".got"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - /* The .plt section holds the procedure linkage table. The - address is put in the ld_plt field. */ - s = bfd_make_section (abfd, ".plt"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_CODE) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - /* The .dynrel section holds the dynamic relocs. The address is - put in the ld_rel field. */ - s = bfd_make_section (abfd, ".dynrel"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - /* The .hash section holds the dynamic hash table. The address - is put in the ld_hash field. */ - s = bfd_make_section (abfd, ".hash"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - /* The .dynsym section holds the dynamic symbols. The address - is put in the ld_stab field. */ - s = bfd_make_section (abfd, ".dynsym"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - /* The .dynstr section holds the dynamic symbol string table. - The address is put in the ld_symbols field. */ - s = bfd_make_section (abfd, ".dynstr"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - sunos_hash_table (info)->dynamic_sections_created = true; - } - - if (needed && ! sunos_hash_table (info)->dynamic_sections_needed) - { - bfd *dynobj; - - dynobj = sunos_hash_table (info)->dynobj; - - s = bfd_get_section_by_name (dynobj, ".got"); - s->_raw_size = BYTES_IN_WORD; - - sunos_hash_table (info)->dynamic_sections_needed = true; - } - - return true; -} - -/* Add dynamic symbols during a link. This is called by the a.out - backend linker when it encounters an object with the DYNAMIC flag - set. */ - -static boolean -sunos_add_dynamic_symbols (abfd, info, symsp, sym_countp, stringsp) - bfd *abfd; - struct bfd_link_info *info; - struct external_nlist **symsp; - bfd_size_type *sym_countp; - char **stringsp; -{ - asection *s; - bfd *dynobj; - struct sunos_dynamic_info *dinfo; - unsigned long need; - - /* We do not want to include the sections in a dynamic object in the - output file. We hack by simply clobbering the list of sections - in the BFD. This could be handled more cleanly by, say, a new - section flag; the existing SEC_NEVER_LOAD flag is not the one we - want, because that one still implies that the section takes up - space in the output file. */ - abfd->sections = NULL; - - /* The native linker seems to just ignore dynamic objects when -r is - used. */ - if (info->relocateable) - return true; - - /* There's no hope of using a dynamic object which does not exactly - match the format of the output file. */ - if (info->hash->creator != abfd->xvec) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - /* Make sure we have all the required information. */ - if (! sunos_create_dynamic_sections (abfd, info, true)) - return false; - - /* Make sure we have a .need and a .rules sections. These are only - needed if there really is a dynamic object in the link, so they - are not added by sunos_create_dynamic_sections. */ - dynobj = sunos_hash_table (info)->dynobj; - if (bfd_get_section_by_name (dynobj, ".need") == NULL) - { - /* The .need section holds the list of names of shared objets - which must be included at runtime. The address of this - section is put in the ld_need field. */ - s = bfd_make_section (dynobj, ".need"); - if (s == NULL - || ! bfd_set_section_flags (dynobj, s, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, s, 2)) - return false; - } - - if (bfd_get_section_by_name (dynobj, ".rules") == NULL) - { - /* The .rules section holds the path to search for shared - objects. The address of this section is put in the ld_rules - field. */ - s = bfd_make_section (dynobj, ".rules"); - if (s == NULL - || ! bfd_set_section_flags (dynobj, s, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, s, 2)) - return false; - } - - /* Pick up the dynamic symbols and return them to the caller. */ - if (! sunos_slurp_dynamic_symtab (abfd)) - return false; - - dinfo = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); - *symsp = dinfo->dynsym; - *sym_countp = dinfo->dynsym_count; - *stringsp = dinfo->dynstr; - - /* Record information about any other objects needed by this one. */ - need = dinfo->dyninfo.ld_need; - while (need != 0) - { - bfd_byte buf[16]; - unsigned long name, flags; - unsigned short major_vno, minor_vno; - struct bfd_link_needed_list *needed, **pp; - bfd_byte b; - - if (bfd_seek (abfd, need, SEEK_SET) != 0 - || bfd_read (buf, 1, 16, abfd) != 16) - return false; - - /* For the format of an ld_need entry, see aout/sun4.h. We - should probably define structs for this manipulation. */ - - name = bfd_get_32 (abfd, buf); - flags = bfd_get_32 (abfd, buf + 4); - major_vno = bfd_get_16 (abfd, buf + 8); - minor_vno = bfd_get_16 (abfd, buf + 10); - need = bfd_get_32 (abfd, buf + 12); - - needed = (struct bfd_link_needed_list *) bfd_alloc (abfd, sizeof (struct bfd_link_needed_list)); - if (needed == NULL) - return false; - needed->by = abfd; - - /* We return the name as [-l]name[.maj][.min]. */ - - if ((flags & 0x80000000) != 0) - bfd_alloc_grow (abfd, "-l", 2); - if (bfd_seek (abfd, name, SEEK_SET) != 0) - return false; - do - { - if (bfd_read (&b, 1, 1, abfd) != 1) - return false; - bfd_alloc_grow (abfd, &b, 1); - } - while (b != '\0'); - if (major_vno != 0) - { - char verbuf[30]; - - sprintf (verbuf, ".%d", major_vno); - bfd_alloc_grow (abfd, verbuf, strlen (verbuf)); - if (minor_vno != 0) - { - sprintf (verbuf, ".%d", minor_vno); - bfd_alloc_grow (abfd, verbuf, strlen (verbuf)); - } - } - needed->name = bfd_alloc_finish (abfd); - if (needed->name == NULL) - return false; - - needed->next = NULL; - - for (pp = &sunos_hash_table (info)->needed; - *pp != NULL; - pp = &(*pp)->next) - ; - *pp = needed; - } - - return true; -} - -/* Function to add a single symbol to the linker hash table. This is - a wrapper around _bfd_generic_link_add_one_symbol which handles the - tweaking needed for dynamic linking support. */ - -static boolean -sunos_add_one_symbol (info, abfd, name, flags, section, value, string, - copy, collect, hashp) - struct bfd_link_info *info; - bfd *abfd; - const char *name; - flagword flags; - asection *section; - bfd_vma value; - const char *string; - boolean copy; - boolean collect; - struct bfd_link_hash_entry **hashp; -{ - struct sunos_link_hash_entry *h; - int new_flag; - - if (! sunos_hash_table (info)->dynamic_sections_created) - { - /* We must create the dynamic sections while reading the input - files, even though at this point we don't know if any of the - sections will be needed. This will ensure that the dynamic - sections are mapped to the right output section. It does no - harm to create these sections if they are not needed. */ - if (! sunos_create_dynamic_sections (abfd, info, false)) - return false; - } - - if ((flags & (BSF_INDIRECT | BSF_WARNING | BSF_CONSTRUCTOR)) != 0 - || ! bfd_is_und_section (section)) - h = sunos_link_hash_lookup (sunos_hash_table (info), name, true, copy, - false); - else - h = ((struct sunos_link_hash_entry *) - bfd_wrapped_link_hash_lookup (abfd, info, name, true, copy, false)); - if (h == NULL) - return false; - - if (hashp != NULL) - *hashp = (struct bfd_link_hash_entry *) h; - - /* Treat a common symbol in a dynamic object as defined in the .bss - section of the dynamic object. We don't want to allocate space - for it in our process image. */ - if ((abfd->flags & DYNAMIC) != 0 - && bfd_is_com_section (section)) - section = obj_bsssec (abfd); - - if (! bfd_is_und_section (section) - && h->root.root.type != bfd_link_hash_new - && h->root.root.type != bfd_link_hash_undefined - && h->root.root.type != bfd_link_hash_defweak) - { - /* We are defining the symbol, and it is already defined. This - is a potential multiple definition error. */ - if ((abfd->flags & DYNAMIC) != 0) - { - /* The definition we are adding is from a dynamic object. - We do not want this new definition to override the - existing definition, so we pretend it is just a - reference. */ - section = bfd_und_section_ptr; - } - else if (h->root.root.type == bfd_link_hash_defined - && h->root.root.u.def.section->owner != NULL - && (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0) - { - /* The existing definition is from a dynamic object. We - want to override it with the definition we just found. - Clobber the existing definition. */ - h->root.root.type = bfd_link_hash_new; - } - else if (h->root.root.type == bfd_link_hash_common - && (h->root.root.u.c.p->section->owner->flags & DYNAMIC) != 0) - { - /* The existing definition is from a dynamic object. We - want to override it with the definition we just found. - Clobber the existing definition. We can't set it to new, - because it is on the undefined list. */ - h->root.root.type = bfd_link_hash_undefined; - h->root.root.u.undef.abfd = h->root.root.u.c.p->section->owner; - } - } - - if ((abfd->flags & DYNAMIC) != 0 - && abfd->xvec == info->hash->creator - && (h->flags & SUNOS_CONSTRUCTOR) != 0) - { - /* The existing symbol is a constructor symbol, and this symbol - is from a dynamic object. A constructor symbol is actually a - definition, although the type will be bfd_link_hash_undefined - at this point. We want to ignore the definition from the - dynamic object. */ - section = bfd_und_section_ptr; - } - else if ((flags & BSF_CONSTRUCTOR) != 0 - && (abfd->flags & DYNAMIC) == 0 - && h->root.root.type == bfd_link_hash_defined - && h->root.root.u.def.section->owner != NULL - && (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0) - { - /* The existing symbol is defined by a dynamic object, and this - is a constructor symbol. As above, we want to force the use - of the constructor symbol from the regular object. */ - h->root.root.type = bfd_link_hash_new; - } - - /* Do the usual procedure for adding a symbol. */ - if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, - value, string, copy, collect, - hashp)) - return false; - - if (abfd->xvec == info->hash->creator) - { - /* Set a flag in the hash table entry indicating the type of - reference or definition we just found. Keep a count of the - number of dynamic symbols we find. A dynamic symbol is one - which is referenced or defined by both a regular object and a - shared object. */ - if ((abfd->flags & DYNAMIC) == 0) - { - if (bfd_is_und_section (section)) - new_flag = SUNOS_REF_REGULAR; - else - new_flag = SUNOS_DEF_REGULAR; - } - else - { - if (bfd_is_und_section (section)) - new_flag = SUNOS_REF_DYNAMIC; - else - new_flag = SUNOS_DEF_DYNAMIC; - } - h->flags |= new_flag; - - if (h->dynindx == -1 - && (h->flags & (SUNOS_DEF_REGULAR | SUNOS_REF_REGULAR)) != 0) - { - ++sunos_hash_table (info)->dynsymcount; - h->dynindx = -2; - } - - if ((flags & BSF_CONSTRUCTOR) != 0 - && (abfd->flags & DYNAMIC) == 0) - h->flags |= SUNOS_CONSTRUCTOR; - } - - return true; -} - -/* Return the list of objects needed by BFD. */ - -/*ARGSUSED*/ -struct bfd_link_needed_list * -bfd_sunos_get_needed_list (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - if (info->hash->creator != &MY(vec)) - return NULL; - return sunos_hash_table (info)->needed; -} - -/* Record an assignment made to a symbol by a linker script. We need - this in case some dynamic object refers to this symbol. */ - -boolean -bfd_sunos_record_link_assignment (output_bfd, info, name) - bfd *output_bfd; - struct bfd_link_info *info; - const char *name; -{ - struct sunos_link_hash_entry *h; - - if (output_bfd->xvec != &MY(vec)) - return true; - - /* This is called after we have examined all the input objects. If - the symbol does not exist, it merely means that no object refers - to it, and we can just ignore it at this point. */ - h = sunos_link_hash_lookup (sunos_hash_table (info), name, - false, false, false); - if (h == NULL) - return true; - - /* In a shared library, the __DYNAMIC symbol does not appear in the - dynamic symbol table. */ - if (! info->shared || strcmp (name, "__DYNAMIC") != 0) - { - h->flags |= SUNOS_DEF_REGULAR; - - if (h->dynindx == -1) - { - ++sunos_hash_table (info)->dynsymcount; - h->dynindx = -2; - } - } - - return true; -} - -/* Set up the sizes and contents of the dynamic sections created in - sunos_add_dynamic_symbols. This is called by the SunOS linker - emulation before_allocation routine. We must set the sizes of the - sections before the linker sets the addresses of the various - sections. This unfortunately requires reading all the relocs so - that we can work out which ones need to become dynamic relocs. If - info->keep_memory is true, we keep the relocs in memory; otherwise, - we discard them, and will read them again later. */ - -boolean -bfd_sunos_size_dynamic_sections (output_bfd, info, sdynptr, sneedptr, - srulesptr) - bfd *output_bfd; - struct bfd_link_info *info; - asection **sdynptr; - asection **sneedptr; - asection **srulesptr; -{ - bfd *dynobj; - size_t dynsymcount; - struct sunos_link_hash_entry *h; - asection *s; - size_t bucketcount; - size_t hashalloc; - size_t i; - bfd *sub; - - *sdynptr = NULL; - *sneedptr = NULL; - *srulesptr = NULL; - - if (output_bfd->xvec != &MY(vec)) - return true; - - /* Look through all the input BFD's and read their relocs. It would - be better if we didn't have to do this, but there is no other way - to determine the number of dynamic relocs we need, and, more - importantly, there is no other way to know which symbols should - get an entry in the procedure linkage table. */ - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - if ((sub->flags & DYNAMIC) == 0 - && sub->xvec == output_bfd->xvec) - { - if (! sunos_scan_relocs (info, sub, obj_textsec (sub), - exec_hdr (sub)->a_trsize) - || ! sunos_scan_relocs (info, sub, obj_datasec (sub), - exec_hdr (sub)->a_drsize)) - return false; - } - } - - dynobj = sunos_hash_table (info)->dynobj; - dynsymcount = sunos_hash_table (info)->dynsymcount; - - /* If there were no dynamic objects in the link, and we don't need - to build a global offset table, there is nothing to do here. */ - if (! sunos_hash_table (info)->dynamic_sections_needed) - return true; - - /* If __GLOBAL_OFFSET_TABLE_ was mentioned, define it. */ - h = sunos_link_hash_lookup (sunos_hash_table (info), - "__GLOBAL_OFFSET_TABLE_", false, false, false); - if (h != NULL && (h->flags & SUNOS_REF_REGULAR) != 0) - { - h->flags |= SUNOS_DEF_REGULAR; - if (h->dynindx == -1) - { - ++sunos_hash_table (info)->dynsymcount; - h->dynindx = -2; - } - h->root.root.type = bfd_link_hash_defined; - h->root.root.u.def.section = bfd_get_section_by_name (dynobj, ".got"); - h->root.root.u.def.value = 0; - } - - /* The .dynamic section is always the same size. */ - s = bfd_get_section_by_name (dynobj, ".dynamic"); - BFD_ASSERT (s != NULL); - s->_raw_size = (sizeof (struct external_sun4_dynamic) - + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE - + sizeof (struct external_sun4_dynamic_link)); - - /* Set the size of the .dynsym and .hash sections. We counted the - number of dynamic symbols as we read the input files. We will - build the dynamic symbol table (.dynsym) and the hash table - (.hash) when we build the final symbol table, because until then - we do not know the correct value to give the symbols. We build - the dynamic symbol string table (.dynstr) in a traversal of the - symbol table using sunos_scan_dynamic_symbol. */ - s = bfd_get_section_by_name (dynobj, ".dynsym"); - BFD_ASSERT (s != NULL); - s->_raw_size = dynsymcount * sizeof (struct external_nlist); - s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) - return false; - - /* The number of buckets is just the number of symbols divided by - four. To compute the final size of the hash table, we must - actually compute the hash table. Normally we need exactly as - many entries in the hash table as there are dynamic symbols, but - if some of the buckets are not used we will need additional - entries. In the worst case, every symbol will hash to the same - bucket, and we will need BUCKETCOUNT - 1 extra entries. */ - if (dynsymcount >= 4) - bucketcount = dynsymcount / 4; - else if (dynsymcount > 0) - bucketcount = dynsymcount; - else - bucketcount = 1; - s = bfd_get_section_by_name (dynobj, ".hash"); - BFD_ASSERT (s != NULL); - hashalloc = (dynsymcount + bucketcount - 1) * HASH_ENTRY_SIZE; - s->contents = (bfd_byte *) bfd_alloc (dynobj, hashalloc); - if (s->contents == NULL && dynsymcount > 0) - return false; - memset (s->contents, 0, hashalloc); - for (i = 0; i < bucketcount; i++) - PUT_WORD (output_bfd, (bfd_vma) -1, s->contents + i * HASH_ENTRY_SIZE); - s->_raw_size = bucketcount * HASH_ENTRY_SIZE; - - sunos_hash_table (info)->bucketcount = bucketcount; - - /* Scan all the symbols, place them in the dynamic symbol table, and - build the dynamic hash table. We reuse dynsymcount as a counter - for the number of symbols we have added so far. */ - sunos_hash_table (info)->dynsymcount = 0; - sunos_link_hash_traverse (sunos_hash_table (info), - sunos_scan_dynamic_symbol, - (PTR) info); - BFD_ASSERT (sunos_hash_table (info)->dynsymcount == dynsymcount); - - /* The SunOS native linker seems to align the total size of the - symbol strings to a multiple of 8. I don't know if this is - important, but it can't hurt much. */ - s = bfd_get_section_by_name (dynobj, ".dynstr"); - BFD_ASSERT (s != NULL); - if ((s->_raw_size & 7) != 0) - { - bfd_size_type add; - bfd_byte *contents; - - add = 8 - (s->_raw_size & 7); - contents = (bfd_byte *) bfd_realloc (s->contents, - (size_t) (s->_raw_size + add)); - if (contents == NULL) - return false; - memset (contents + s->_raw_size, 0, (size_t) add); - s->contents = contents; - s->_raw_size += add; - } - - /* Now that we have worked out the sizes of the procedure linkage - table and the dynamic relocs, allocate storage for them. */ - s = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (s != NULL); - if (s->_raw_size != 0) - { - s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); - if (s->contents == NULL) - return false; - - /* Fill in the first entry in the table. */ - switch (bfd_get_arch (dynobj)) - { - case bfd_arch_sparc: - memcpy (s->contents, sparc_plt_first_entry, SPARC_PLT_ENTRY_SIZE); - break; - - case bfd_arch_m68k: - memcpy (s->contents, m68k_plt_first_entry, M68K_PLT_ENTRY_SIZE); - break; - - default: - abort (); - } - } - - s = bfd_get_section_by_name (dynobj, ".dynrel"); - if (s->_raw_size != 0) - { - s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); - if (s->contents == NULL) - return false; - } - /* We use the reloc_count field to keep track of how many of the - relocs we have output so far. */ - s->reloc_count = 0; - - /* Make space for the global offset table. */ - s = bfd_get_section_by_name (dynobj, ".got"); - s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); - if (s->contents == NULL) - return false; - - *sdynptr = bfd_get_section_by_name (dynobj, ".dynamic"); - *sneedptr = bfd_get_section_by_name (dynobj, ".need"); - *srulesptr = bfd_get_section_by_name (dynobj, ".rules"); - - return true; -} - -/* Scan the relocs for an input section. */ - -static boolean -sunos_scan_relocs (info, abfd, sec, rel_size) - struct bfd_link_info *info; - bfd *abfd; - asection *sec; - bfd_size_type rel_size; -{ - PTR relocs; - PTR free_relocs = NULL; - - if (rel_size == 0) - return true; - - if (! info->keep_memory) - relocs = free_relocs = bfd_malloc ((size_t) rel_size); - else - { - struct aout_section_data_struct *n; - - n = ((struct aout_section_data_struct *) - bfd_alloc (abfd, sizeof (struct aout_section_data_struct))); - if (n == NULL) - relocs = NULL; - else - { - set_aout_section_data (sec, n); - relocs = bfd_malloc ((size_t) rel_size); - aout_section_data (sec)->relocs = relocs; - } - } - if (relocs == NULL) - return false; - - if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0 - || bfd_read (relocs, 1, rel_size, abfd) != rel_size) - goto error_return; - - if (obj_reloc_entry_size (abfd) == RELOC_STD_SIZE) - { - if (! sunos_scan_std_relocs (info, abfd, sec, - (struct reloc_std_external *) relocs, - rel_size)) - goto error_return; - } - else - { - if (! sunos_scan_ext_relocs (info, abfd, sec, - (struct reloc_ext_external *) relocs, - rel_size)) - goto error_return; - } - - if (free_relocs != NULL) - free (free_relocs); - - return true; - - error_return: - if (free_relocs != NULL) - free (free_relocs); - return false; -} - -/* Scan the relocs for an input section using standard relocs. We - need to figure out what to do for each reloc against a dynamic - symbol. If the symbol is in the .text section, an entry is made in - the procedure linkage table. Note that this will do the wrong - thing if the symbol is actually data; I don't think the Sun 3 - native linker handles this case correctly either. If the symbol is - not in the .text section, we must preserve the reloc as a dynamic - reloc. FIXME: We should also handle the PIC relocs here by - building global offset table entries. */ - -static boolean -sunos_scan_std_relocs (info, abfd, sec, relocs, rel_size) - struct bfd_link_info *info; - bfd *abfd; - asection *sec; - const struct reloc_std_external *relocs; - bfd_size_type rel_size; -{ - bfd *dynobj; - asection *splt = NULL; - asection *srel = NULL; - struct sunos_link_hash_entry **sym_hashes; - const struct reloc_std_external *rel, *relend; - - /* We only know how to handle m68k plt entries. */ - if (bfd_get_arch (abfd) != bfd_arch_m68k) - { - bfd_set_error (bfd_error_invalid_target); - return false; - } - - dynobj = NULL; - - sym_hashes = (struct sunos_link_hash_entry **) obj_aout_sym_hashes (abfd); - - relend = relocs + rel_size / RELOC_STD_SIZE; - for (rel = relocs; rel < relend; rel++) - { - int r_index; - struct sunos_link_hash_entry *h; - - /* We only want relocs against external symbols. */ - if (bfd_header_big_endian (abfd)) - { - if ((rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG) == 0) - continue; - } - else - { - if ((rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE) == 0) - continue; - } - - /* Get the symbol index. */ - if (bfd_header_big_endian (abfd)) - r_index = ((rel->r_index[0] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[2]); - else - r_index = ((rel->r_index[2] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[0]); - - /* Get the hash table entry. */ - h = sym_hashes[r_index]; - if (h == NULL) - { - /* This should not normally happen, but it will in any case - be caught in the relocation phase. */ - continue; - } - - /* At this point common symbols have already been allocated, so - we don't have to worry about them. We need to consider that - we may have already seen this symbol and marked it undefined; - if the symbol is really undefined, then SUNOS_DEF_DYNAMIC - will be zero. */ - if (h->root.root.type != bfd_link_hash_defined - && h->root.root.type != bfd_link_hash_defweak - && h->root.root.type != bfd_link_hash_undefined) - continue; - - if ((h->flags & SUNOS_DEF_DYNAMIC) == 0 - || (h->flags & SUNOS_DEF_REGULAR) != 0) - continue; - - if (dynobj == NULL) - { - if (! sunos_create_dynamic_sections (abfd, info, true)) - return false; - dynobj = sunos_hash_table (info)->dynobj; - splt = bfd_get_section_by_name (dynobj, ".plt"); - srel = bfd_get_section_by_name (dynobj, ".dynrel"); - BFD_ASSERT (splt != NULL && srel != NULL); - } - - BFD_ASSERT ((h->flags & SUNOS_REF_REGULAR) != 0); - BFD_ASSERT (h->plt_offset != 0 - || ((h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak) - ? (h->root.root.u.def.section->owner->flags - & DYNAMIC) != 0 - : (h->root.root.u.undef.abfd->flags & DYNAMIC) != 0)); - - /* This reloc is against a symbol defined only by a dynamic - object. */ - - if (h->root.root.type == bfd_link_hash_undefined) - { - /* Presumably this symbol was marked as being undefined by - an earlier reloc. */ - srel->_raw_size += RELOC_STD_SIZE; - } - else if ((h->root.root.u.def.section->flags & SEC_CODE) == 0) - { - bfd *sub; - - /* This reloc is not in the .text section. It must be - copied into the dynamic relocs. We mark the symbol as - being undefined. */ - srel->_raw_size += RELOC_STD_SIZE; - sub = h->root.root.u.def.section->owner; - h->root.root.type = bfd_link_hash_undefined; - h->root.root.u.undef.abfd = sub; - } - else - { - /* This symbol is in the .text section. We must give it an - entry in the procedure linkage table, if we have not - already done so. We change the definition of the symbol - to the .plt section; this will cause relocs against it to - be handled correctly. */ - if (h->plt_offset == 0) - { - if (splt->_raw_size == 0) - splt->_raw_size = M68K_PLT_ENTRY_SIZE; - h->plt_offset = splt->_raw_size; - - if ((h->flags & SUNOS_DEF_REGULAR) == 0) - { - h->root.root.u.def.section = splt; - h->root.root.u.def.value = splt->_raw_size; - } - - splt->_raw_size += M68K_PLT_ENTRY_SIZE; - - /* We may also need a dynamic reloc entry. */ - if ((h->flags & SUNOS_DEF_REGULAR) == 0) - srel->_raw_size += RELOC_STD_SIZE; - } - } - } - - return true; -} - -/* Scan the relocs for an input section using extended relocs. We - need to figure out what to do for each reloc against a dynamic - symbol. If the reloc is a WDISP30, and the symbol is in the .text - section, an entry is made in the procedure linkage table. - Otherwise, we must preserve the reloc as a dynamic reloc. */ - -static boolean -sunos_scan_ext_relocs (info, abfd, sec, relocs, rel_size) - struct bfd_link_info *info; - bfd *abfd; - asection *sec; - const struct reloc_ext_external *relocs; - bfd_size_type rel_size; -{ - bfd *dynobj; - struct sunos_link_hash_entry **sym_hashes; - const struct reloc_ext_external *rel, *relend; - asection *splt = NULL; - asection *sgot = NULL; - asection *srel = NULL; - - /* We only know how to handle SPARC plt entries. */ - if (bfd_get_arch (abfd) != bfd_arch_sparc) - { - bfd_set_error (bfd_error_invalid_target); - return false; - } - - dynobj = NULL; - - sym_hashes = (struct sunos_link_hash_entry **) obj_aout_sym_hashes (abfd); - - relend = relocs + rel_size / RELOC_EXT_SIZE; - for (rel = relocs; rel < relend; rel++) - { - unsigned int r_index; - int r_extern; - int r_type; - struct sunos_link_hash_entry *h = NULL; - - /* Swap in the reloc information. */ - if (bfd_header_big_endian (abfd)) - { - r_index = ((rel->r_index[0] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[2]); - r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG)); - r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG) - >> RELOC_EXT_BITS_TYPE_SH_BIG); - } - else - { - r_index = ((rel->r_index[2] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[0]); - r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE)); - r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE) - >> RELOC_EXT_BITS_TYPE_SH_LITTLE); - } - - if (r_extern) - { - h = sym_hashes[r_index]; - if (h == NULL) - { - /* This should not normally happen, but it will in any - case be caught in the relocation phase. */ - continue; - } - } - - /* If this is a base relative reloc, we need to make an entry in - the .got section. */ - if (r_type == RELOC_BASE10 - || r_type == RELOC_BASE13 - || r_type == RELOC_BASE22) - { - if (dynobj == NULL) - { - if (! sunos_create_dynamic_sections (abfd, info, true)) - return false; - dynobj = sunos_hash_table (info)->dynobj; - splt = bfd_get_section_by_name (dynobj, ".plt"); - sgot = bfd_get_section_by_name (dynobj, ".got"); - srel = bfd_get_section_by_name (dynobj, ".dynrel"); - BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL); - } - - if (r_extern) - { - if (h->got_offset != 0) - continue; - - h->got_offset = sgot->_raw_size; - } - else - { - if (r_index >= bfd_get_symcount (abfd)) - { - /* This is abnormal, but should be caught in the - relocation phase. */ - continue; - } - - if (adata (abfd).local_got_offsets == NULL) - { - adata (abfd).local_got_offsets = - (bfd_vma *) bfd_zalloc (abfd, - (bfd_get_symcount (abfd) - * sizeof (bfd_vma))); - if (adata (abfd).local_got_offsets == NULL) - return false; - } - - if (adata (abfd).local_got_offsets[r_index] != 0) - continue; - - adata (abfd).local_got_offsets[r_index] = sgot->_raw_size; - } - - sgot->_raw_size += BYTES_IN_WORD; - - /* If we are making a shared library, or if the symbol is - defined by a dynamic object, we will need a dynamic reloc - entry. */ - if (info->shared - || (h != NULL - && (h->flags & SUNOS_DEF_DYNAMIC) != 0 - && (h->flags & SUNOS_DEF_REGULAR) == 0)) - srel->_raw_size += RELOC_EXT_SIZE; - - continue; - } - - /* Otherwise, we are only interested in relocs against symbols - defined in dynamic objects but not in regular objects. We - only need to consider relocs against external symbols. */ - if (! r_extern) - { - /* But, if we are creating a shared library, we need to - generate an absolute reloc. */ - if (info->shared) - { - if (dynobj == NULL) - { - if (! sunos_create_dynamic_sections (abfd, info, true)) - return false; - dynobj = sunos_hash_table (info)->dynobj; - splt = bfd_get_section_by_name (dynobj, ".plt"); - sgot = bfd_get_section_by_name (dynobj, ".got"); - srel = bfd_get_section_by_name (dynobj, ".dynrel"); - BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL); - } - - srel->_raw_size += RELOC_EXT_SIZE; - } - - continue; - } - - /* At this point common symbols have already been allocated, so - we don't have to worry about them. We need to consider that - we may have already seen this symbol and marked it undefined; - if the symbol is really undefined, then SUNOS_DEF_DYNAMIC - will be zero. */ - if (h->root.root.type != bfd_link_hash_defined - && h->root.root.type != bfd_link_hash_defweak - && h->root.root.type != bfd_link_hash_undefined) - continue; - - if (r_type != RELOC_JMP_TBL - && ! info->shared - && ((h->flags & SUNOS_DEF_DYNAMIC) == 0 - || (h->flags & SUNOS_DEF_REGULAR) != 0)) - continue; - - if (r_type == RELOC_JMP_TBL - && ! info->shared - && (h->flags & SUNOS_DEF_DYNAMIC) == 0 - && (h->flags & SUNOS_DEF_REGULAR) == 0) - { - /* This symbol is apparently undefined. Don't do anything - here; just let the relocation routine report an undefined - symbol. */ - continue; - } - - if (strcmp (h->root.root.root.string, "__GLOBAL_OFFSET_TABLE_") == 0) - continue; - - if (dynobj == NULL) - { - if (! sunos_create_dynamic_sections (abfd, info, true)) - return false; - dynobj = sunos_hash_table (info)->dynobj; - splt = bfd_get_section_by_name (dynobj, ".plt"); - sgot = bfd_get_section_by_name (dynobj, ".got"); - srel = bfd_get_section_by_name (dynobj, ".dynrel"); - BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL); - } - - BFD_ASSERT (r_type == RELOC_JMP_TBL - || info->shared - || (h->flags & SUNOS_REF_REGULAR) != 0); - BFD_ASSERT (r_type == RELOC_JMP_TBL - || info->shared - || h->plt_offset != 0 - || ((h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak) - ? (h->root.root.u.def.section->owner->flags - & DYNAMIC) != 0 - : (h->root.root.u.undef.abfd->flags & DYNAMIC) != 0)); - - /* This reloc is against a symbol defined only by a dynamic - object, or it is a jump table reloc from PIC compiled code. */ - - if (r_type != RELOC_JMP_TBL - && h->root.root.type == bfd_link_hash_undefined) - { - /* Presumably this symbol was marked as being undefined by - an earlier reloc. */ - srel->_raw_size += RELOC_EXT_SIZE; - } - else if (r_type != RELOC_JMP_TBL - && (h->root.root.u.def.section->flags & SEC_CODE) == 0) - { - bfd *sub; - - /* This reloc is not in the .text section. It must be - copied into the dynamic relocs. We mark the symbol as - being undefined. */ - srel->_raw_size += RELOC_EXT_SIZE; - if ((h->flags & SUNOS_DEF_REGULAR) == 0) - { - sub = h->root.root.u.def.section->owner; - h->root.root.type = bfd_link_hash_undefined; - h->root.root.u.undef.abfd = sub; - } - } - else - { - /* This symbol is in the .text section. We must give it an - entry in the procedure linkage table, if we have not - already done so. We change the definition of the symbol - to the .plt section; this will cause relocs against it to - be handled correctly. */ - if (h->plt_offset == 0) - { - if (splt->_raw_size == 0) - splt->_raw_size = SPARC_PLT_ENTRY_SIZE; - h->plt_offset = splt->_raw_size; - - if ((h->flags & SUNOS_DEF_REGULAR) == 0) - { - if (h->root.root.type == bfd_link_hash_undefined) - h->root.root.type = bfd_link_hash_defined; - h->root.root.u.def.section = splt; - h->root.root.u.def.value = splt->_raw_size; - } - - splt->_raw_size += SPARC_PLT_ENTRY_SIZE; - - /* We will also need a dynamic reloc entry, unless this - is a JMP_TBL reloc produced by linking PIC compiled - code, and we are not making a shared library. */ - if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0) - srel->_raw_size += RELOC_EXT_SIZE; - } - - /* If we are creating a shared library, we need to copy over - any reloc other than a jump table reloc. */ - if (info->shared && r_type != RELOC_JMP_TBL) - srel->_raw_size += RELOC_EXT_SIZE; - } - } - - return true; -} - -/* Build the hash table of dynamic symbols, and to mark as written all - symbols from dynamic objects which we do not plan to write out. */ - -static boolean -sunos_scan_dynamic_symbol (h, data) - struct sunos_link_hash_entry *h; - PTR data; -{ - struct bfd_link_info *info = (struct bfd_link_info *) data; - - /* Set the written flag for symbols we do not want to write out as - part of the regular symbol table. This is all symbols which are - not defined in a regular object file. For some reason symbols - which are referenced by a regular object and defined by a dynamic - object do not seem to show up in the regular symbol table. It is - possible for a symbol to have only SUNOS_REF_REGULAR set here, it - is an undefined symbol which was turned into a common symbol - because it was found in an archive object which was not included - in the link. */ - if ((h->flags & SUNOS_DEF_REGULAR) == 0 - && (h->flags & SUNOS_DEF_DYNAMIC) != 0 - && strcmp (h->root.root.root.string, "__DYNAMIC") != 0) - h->root.written = true; - - /* If this symbol is defined by a dynamic object and referenced by a - regular object, see whether we gave it a reasonable value while - scanning the relocs. */ - - if ((h->flags & SUNOS_DEF_REGULAR) == 0 - && (h->flags & SUNOS_DEF_DYNAMIC) != 0 - && (h->flags & SUNOS_REF_REGULAR) != 0) - { - if ((h->root.root.type == bfd_link_hash_defined - || h->root.root.type == bfd_link_hash_defweak) - && ((h->root.root.u.def.section->owner->flags & DYNAMIC) != 0) - && h->root.root.u.def.section->output_section == NULL) - { - bfd *sub; - - /* This symbol is currently defined in a dynamic section - which is not being put into the output file. This - implies that there is no reloc against the symbol. I'm - not sure why this case would ever occur. In any case, we - change the symbol to be undefined. */ - sub = h->root.root.u.def.section->owner; - h->root.root.type = bfd_link_hash_undefined; - h->root.root.u.undef.abfd = sub; - } - } - - /* If this symbol is defined or referenced by a regular file, add it - to the dynamic symbols. */ - if ((h->flags & (SUNOS_DEF_REGULAR | SUNOS_REF_REGULAR)) != 0) - { - asection *s; - size_t len; - bfd_byte *contents; - unsigned char *name; - unsigned long hash; - bfd *dynobj; - - BFD_ASSERT (h->dynindx == -2); - - dynobj = sunos_hash_table (info)->dynobj; - - h->dynindx = sunos_hash_table (info)->dynsymcount; - ++sunos_hash_table (info)->dynsymcount; - - len = strlen (h->root.root.root.string); - - /* We don't bother to construct a BFD hash table for the strings - which are the names of the dynamic symbols. Using a hash - table for the regular symbols is beneficial, because the - regular symbols includes the debugging symbols, which have - long names and are often duplicated in several object files. - There are no debugging symbols in the dynamic symbols. */ - s = bfd_get_section_by_name (dynobj, ".dynstr"); - BFD_ASSERT (s != NULL); - contents = (bfd_byte *) bfd_realloc (s->contents, - s->_raw_size + len + 1); - if (contents == NULL) - return false; - s->contents = contents; - - h->dynstr_index = s->_raw_size; - strcpy (contents + s->_raw_size, h->root.root.root.string); - s->_raw_size += len + 1; - - /* Add it to the dynamic hash table. */ - name = (unsigned char *) h->root.root.root.string; - hash = 0; - while (*name != '\0') - hash = (hash << 1) + *name++; - hash &= 0x7fffffff; - hash %= sunos_hash_table (info)->bucketcount; - - s = bfd_get_section_by_name (dynobj, ".hash"); - BFD_ASSERT (s != NULL); - - if (GET_SWORD (dynobj, s->contents + hash * HASH_ENTRY_SIZE) == -1) - PUT_WORD (dynobj, h->dynindx, s->contents + hash * HASH_ENTRY_SIZE); - else - { - bfd_vma next; - - next = GET_WORD (dynobj, - (s->contents - + hash * HASH_ENTRY_SIZE - + BYTES_IN_WORD)); - PUT_WORD (dynobj, s->_raw_size / HASH_ENTRY_SIZE, - s->contents + hash * HASH_ENTRY_SIZE + BYTES_IN_WORD); - PUT_WORD (dynobj, h->dynindx, s->contents + s->_raw_size); - PUT_WORD (dynobj, next, s->contents + s->_raw_size + BYTES_IN_WORD); - s->_raw_size += HASH_ENTRY_SIZE; - } - } - - return true; -} - -/* Link a dynamic object. We actually don't have anything to do at - this point. This entry point exists to prevent the regular linker - code from doing anything with the object. */ - -/*ARGSUSED*/ -static boolean -sunos_link_dynamic_object (info, abfd) - struct bfd_link_info *info; - bfd *abfd; -{ - return true; -} - -/* Write out a dynamic symbol. This is called by the final traversal - over the symbol table. */ - -static boolean -sunos_write_dynamic_symbol (output_bfd, info, harg) - bfd *output_bfd; - struct bfd_link_info *info; - struct aout_link_hash_entry *harg; -{ - struct sunos_link_hash_entry *h = (struct sunos_link_hash_entry *) harg; - int type; - bfd_vma val; - asection *s; - struct external_nlist *outsym; - - if (h->dynindx < 0) - return true; - - switch (h->root.root.type) - { - default: - case bfd_link_hash_new: - abort (); - /* Avoid variable not initialized warnings. */ - return true; - case bfd_link_hash_undefined: - type = N_UNDF | N_EXT; - val = 0; - break; - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - { - asection *sec; - asection *output_section; - - sec = h->root.root.u.def.section; - output_section = sec->output_section; - BFD_ASSERT (bfd_is_abs_section (output_section) - || output_section->owner == output_bfd); - if (h->plt_offset != 0 - && (h->flags & SUNOS_DEF_REGULAR) == 0) - { - type = N_UNDF | N_EXT; - val = 0; - } - else - { - if (output_section == obj_textsec (output_bfd)) - type = (h->root.root.type == bfd_link_hash_defined - ? N_TEXT - : N_WEAKT); - else if (output_section == obj_datasec (output_bfd)) - type = (h->root.root.type == bfd_link_hash_defined - ? N_DATA - : N_WEAKD); - else if (output_section == obj_bsssec (output_bfd)) - type = (h->root.root.type == bfd_link_hash_defined - ? N_BSS - : N_WEAKB); - else - type = (h->root.root.type == bfd_link_hash_defined - ? N_ABS - : N_WEAKA); - type |= N_EXT; - val = (h->root.root.u.def.value - + output_section->vma - + sec->output_offset); - } - } - break; - case bfd_link_hash_common: - type = N_UNDF | N_EXT; - val = h->root.root.u.c.size; - break; - case bfd_link_hash_undefweak: - type = N_WEAKU; - val = 0; - break; - case bfd_link_hash_indirect: - case bfd_link_hash_warning: - /* FIXME: Ignore these for now. The circumstances under which - they should be written out are not clear to me. */ - return true; - } - - s = bfd_get_section_by_name (sunos_hash_table (info)->dynobj, ".dynsym"); - BFD_ASSERT (s != NULL); - outsym = ((struct external_nlist *) - (s->contents + h->dynindx * EXTERNAL_NLIST_SIZE)); - - bfd_h_put_8 (output_bfd, type, outsym->e_type); - bfd_h_put_8 (output_bfd, 0, outsym->e_other); - - /* FIXME: The native linker doesn't use 0 for desc. It seems to use - one less than the desc value in the shared library, although that - seems unlikely. */ - bfd_h_put_16 (output_bfd, 0, outsym->e_desc); - - PUT_WORD (output_bfd, h->dynstr_index, outsym->e_strx); - PUT_WORD (output_bfd, val, outsym->e_value); - - /* If this symbol is in the procedure linkage table, fill in the - table entry. */ - if (h->plt_offset != 0) - { - bfd *dynobj; - asection *splt; - bfd_byte *p; - asection *s; - bfd_vma r_address; - - dynobj = sunos_hash_table (info)->dynobj; - splt = bfd_get_section_by_name (dynobj, ".plt"); - p = splt->contents + h->plt_offset; - - s = bfd_get_section_by_name (dynobj, ".dynrel"); - - r_address = (splt->output_section->vma - + splt->output_offset - + h->plt_offset); - - switch (bfd_get_arch (output_bfd)) - { - case bfd_arch_sparc: - if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0) - { - bfd_put_32 (output_bfd, SPARC_PLT_ENTRY_WORD0, p); - bfd_put_32 (output_bfd, - (SPARC_PLT_ENTRY_WORD1 - + (((- (h->plt_offset + 4) >> 2) - & 0x3fffffff))), - p + 4); - bfd_put_32 (output_bfd, SPARC_PLT_ENTRY_WORD2 + s->reloc_count, - p + 8); - } - else - { - bfd_vma val; - - val = (h->root.root.u.def.section->output_section->vma - + h->root.root.u.def.section->output_offset - + h->root.root.u.def.value); - bfd_put_32 (output_bfd, - SPARC_PLT_PIC_WORD0 + ((val >> 10) & 0x3fffff), - p); - bfd_put_32 (output_bfd, - SPARC_PLT_PIC_WORD1 + (val & 0x3ff), - p + 4); - bfd_put_32 (output_bfd, SPARC_PLT_PIC_WORD2, p + 8); - } - break; - - case bfd_arch_m68k: - if (! info->shared && (h->flags & SUNOS_DEF_REGULAR) != 0) - abort (); - bfd_put_16 (output_bfd, M68K_PLT_ENTRY_WORD0, p); - bfd_put_32 (output_bfd, (- (h->plt_offset + 2)), p + 2); - bfd_put_16 (output_bfd, s->reloc_count, p + 6); - r_address += 2; - break; - - default: - abort (); - } - - /* We also need to add a jump table reloc, unless this is the - result of a JMP_TBL reloc from PIC compiled code. */ - if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0) - { - BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) - < s->_raw_size); - p = s->contents + s->reloc_count * obj_reloc_entry_size (output_bfd); - if (obj_reloc_entry_size (output_bfd) == RELOC_STD_SIZE) - { - struct reloc_std_external *srel; - - srel = (struct reloc_std_external *) p; - PUT_WORD (output_bfd, r_address, srel->r_address); - if (bfd_header_big_endian (output_bfd)) - { - srel->r_index[0] = h->dynindx >> 16; - srel->r_index[1] = h->dynindx >> 8; - srel->r_index[2] = h->dynindx; - srel->r_type[0] = (RELOC_STD_BITS_EXTERN_BIG - | RELOC_STD_BITS_JMPTABLE_BIG); - } - else - { - srel->r_index[2] = h->dynindx >> 16; - srel->r_index[1] = h->dynindx >> 8; - srel->r_index[0] = h->dynindx; - srel->r_type[0] = (RELOC_STD_BITS_EXTERN_LITTLE - | RELOC_STD_BITS_JMPTABLE_LITTLE); - } - } - else - { - struct reloc_ext_external *erel; - - erel = (struct reloc_ext_external *) p; - PUT_WORD (output_bfd, r_address, erel->r_address); - if (bfd_header_big_endian (output_bfd)) - { - erel->r_index[0] = h->dynindx >> 16; - erel->r_index[1] = h->dynindx >> 8; - erel->r_index[2] = h->dynindx; - erel->r_type[0] = - (RELOC_EXT_BITS_EXTERN_BIG - | (RELOC_JMP_SLOT << RELOC_EXT_BITS_TYPE_SH_BIG)); - } - else - { - erel->r_index[2] = h->dynindx >> 16; - erel->r_index[1] = h->dynindx >> 8; - erel->r_index[0] = h->dynindx; - erel->r_type[0] = - (RELOC_EXT_BITS_EXTERN_LITTLE - | (RELOC_JMP_SLOT << RELOC_EXT_BITS_TYPE_SH_LITTLE)); - } - PUT_WORD (output_bfd, (bfd_vma) 0, erel->r_addend); - } - - ++s->reloc_count; - } - } - - return true; -} - -/* This is called for each reloc against an external symbol. If this - is a reloc which are are going to copy as a dynamic reloc, then - copy it over, and tell the caller to not bother processing this - reloc. */ - -/*ARGSUSED*/ -static boolean -sunos_check_dynamic_reloc (info, input_bfd, input_section, harg, reloc, - contents, skip, relocationp) - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - struct aout_link_hash_entry *harg; - PTR reloc; - bfd_byte *contents; - boolean *skip; - bfd_vma *relocationp; -{ - struct sunos_link_hash_entry *h = (struct sunos_link_hash_entry *) harg; - bfd *dynobj; - boolean baserel; - boolean jmptbl; - asection *s; - bfd_byte *p; - long indx; - - *skip = false; - - dynobj = sunos_hash_table (info)->dynobj; - - if (h != NULL && h->plt_offset != 0) - { - asection *splt; - - /* Redirect the relocation to the PLT entry. */ - splt = bfd_get_section_by_name (dynobj, ".plt"); - *relocationp = (splt->output_section->vma - + splt->output_offset - + h->plt_offset); - } - - if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE) - { - struct reloc_std_external *srel; - - srel = (struct reloc_std_external *) reloc; - if (bfd_header_big_endian (input_bfd)) - { - baserel = (0 != (srel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG)); - jmptbl = (0 != (srel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG)); - } - else - { - baserel = (0 != (srel->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE)); - jmptbl = (0 != (srel->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE)); - } - } - else - { - struct reloc_ext_external *erel; - int r_type; - - erel = (struct reloc_ext_external *) reloc; - if (bfd_header_big_endian (input_bfd)) - r_type = ((erel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG) - >> RELOC_EXT_BITS_TYPE_SH_BIG); - else - r_type = ((erel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE) - >> RELOC_EXT_BITS_TYPE_SH_LITTLE); - baserel = (r_type == RELOC_BASE10 - || r_type == RELOC_BASE13 - || r_type == RELOC_BASE22); - jmptbl = r_type == RELOC_JMP_TBL; - } - - if (baserel) - { - bfd_vma *got_offsetp; - asection *sgot; - - if (h != NULL) - got_offsetp = &h->got_offset; - else if (adata (input_bfd).local_got_offsets == NULL) - got_offsetp = NULL; - else - { - struct reloc_std_external *srel; - int r_index; - - srel = (struct reloc_std_external *) reloc; - if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE) - { - if (bfd_header_big_endian (input_bfd)) - r_index = ((srel->r_index[0] << 16) - | (srel->r_index[1] << 8) - | srel->r_index[2]); - else - r_index = ((srel->r_index[2] << 16) - | (srel->r_index[1] << 8) - | srel->r_index[0]); - } - else - { - struct reloc_ext_external *erel; - - erel = (struct reloc_ext_external *) reloc; - if (bfd_header_big_endian (input_bfd)) - r_index = ((erel->r_index[0] << 16) - | (erel->r_index[1] << 8) - | erel->r_index[2]); - else - r_index = ((erel->r_index[2] << 16) - | (erel->r_index[1] << 8) - | erel->r_index[0]); - } - - got_offsetp = adata (input_bfd).local_got_offsets + r_index; - } - - BFD_ASSERT (got_offsetp != NULL && *got_offsetp != 0); - - sgot = bfd_get_section_by_name (dynobj, ".got"); - - /* We set the least significant bit to indicate whether we have - already initialized the GOT entry. */ - if ((*got_offsetp & 1) == 0) - { - if (h == NULL - || (! info->shared - && ((h->flags & SUNOS_DEF_DYNAMIC) == 0 - || (h->flags & SUNOS_DEF_REGULAR) != 0))) - PUT_WORD (dynobj, *relocationp, sgot->contents + *got_offsetp); - else - PUT_WORD (dynobj, 0, sgot->contents + *got_offsetp); - - if (info->shared - || (h != NULL - && (h->flags & SUNOS_DEF_DYNAMIC) != 0 - && (h->flags & SUNOS_DEF_REGULAR) == 0)) - { - /* We need to create a GLOB_DAT or 32 reloc to tell the - dynamic linker to fill in this entry in the table. */ - - s = bfd_get_section_by_name (dynobj, ".dynrel"); - BFD_ASSERT (s != NULL); - BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) - < s->_raw_size); - - p = (s->contents - + s->reloc_count * obj_reloc_entry_size (dynobj)); - - if (h != NULL) - indx = h->dynindx; - else - indx = 0; - - if (obj_reloc_entry_size (dynobj) == RELOC_STD_SIZE) - { - struct reloc_std_external *srel; - - srel = (struct reloc_std_external *) p; - PUT_WORD (dynobj, - (*got_offsetp - + sgot->output_section->vma - + sgot->output_offset), - srel->r_address); - if (bfd_header_big_endian (dynobj)) - { - srel->r_index[0] = indx >> 16; - srel->r_index[1] = indx >> 8; - srel->r_index[2] = indx; - if (h == NULL) - srel->r_type[0] = 2 << RELOC_STD_BITS_LENGTH_SH_BIG; - else - srel->r_type[0] = - (RELOC_STD_BITS_EXTERN_BIG - | RELOC_STD_BITS_BASEREL_BIG - | RELOC_STD_BITS_RELATIVE_BIG - | (2 << RELOC_STD_BITS_LENGTH_SH_BIG)); - } - else - { - srel->r_index[2] = indx >> 16; - srel->r_index[1] = indx >> 8; - srel->r_index[0] = indx; - if (h == NULL) - srel->r_type[0] = 2 << RELOC_STD_BITS_LENGTH_SH_LITTLE; - else - srel->r_type[0] = - (RELOC_STD_BITS_EXTERN_LITTLE - | RELOC_STD_BITS_BASEREL_LITTLE - | RELOC_STD_BITS_RELATIVE_LITTLE - | (2 << RELOC_STD_BITS_LENGTH_SH_LITTLE)); - } - } - else - { - struct reloc_ext_external *erel; - - erel = (struct reloc_ext_external *) p; - PUT_WORD (dynobj, - (*got_offsetp - + sgot->output_section->vma - + sgot->output_offset), - erel->r_address); - if (bfd_header_big_endian (dynobj)) - { - erel->r_index[0] = indx >> 16; - erel->r_index[1] = indx >> 8; - erel->r_index[2] = indx; - if (h == NULL) - erel->r_type[0] = - RELOC_32 << RELOC_EXT_BITS_TYPE_SH_BIG; - else - erel->r_type[0] = - (RELOC_EXT_BITS_EXTERN_BIG - | (RELOC_GLOB_DAT << RELOC_EXT_BITS_TYPE_SH_BIG)); - } - else - { - erel->r_index[2] = indx >> 16; - erel->r_index[1] = indx >> 8; - erel->r_index[0] = indx; - if (h == NULL) - erel->r_type[0] = - RELOC_32 << RELOC_EXT_BITS_TYPE_SH_LITTLE; - else - erel->r_type[0] = - (RELOC_EXT_BITS_EXTERN_LITTLE - | (RELOC_GLOB_DAT - << RELOC_EXT_BITS_TYPE_SH_LITTLE)); - } - PUT_WORD (dynobj, 0, erel->r_addend); - } - - ++s->reloc_count; - } - - *got_offsetp |= 1; - } - - *relocationp = sgot->vma + (*got_offsetp &~ 1); - - /* There is nothing else to do for a base relative reloc. */ - return true; - } - - if (! sunos_hash_table (info)->dynamic_sections_needed) - return true; - if (! info->shared) - { - if (h == NULL - || h->dynindx == -1 - || h->root.root.type != bfd_link_hash_undefined - || (h->flags & SUNOS_DEF_REGULAR) != 0 - || (h->flags & SUNOS_DEF_DYNAMIC) == 0 - || (h->root.root.u.undef.abfd->flags & DYNAMIC) == 0) - return true; - } - else - { - if (h != NULL - && (h->dynindx == -1 - || jmptbl - || strcmp (h->root.root.root.string, - "__GLOBAL_OFFSET_TABLE_") == 0)) - return true; - } - - /* It looks like this is a reloc we are supposed to copy. */ - - s = bfd_get_section_by_name (dynobj, ".dynrel"); - BFD_ASSERT (s != NULL); - BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) < s->_raw_size); - - p = s->contents + s->reloc_count * obj_reloc_entry_size (dynobj); - - /* Copy the reloc over. */ - memcpy (p, reloc, obj_reloc_entry_size (dynobj)); - - if (h != NULL) - indx = h->dynindx; - else - indx = 0; - - /* Adjust the address and symbol index. */ - if (obj_reloc_entry_size (dynobj) == RELOC_STD_SIZE) - { - struct reloc_std_external *srel; - - srel = (struct reloc_std_external *) p; - PUT_WORD (dynobj, - (GET_WORD (dynobj, srel->r_address) - + input_section->output_section->vma - + input_section->output_offset), - srel->r_address); - if (bfd_header_big_endian (dynobj)) - { - srel->r_index[0] = indx >> 16; - srel->r_index[1] = indx >> 8; - srel->r_index[2] = indx; - } - else - { - srel->r_index[2] = indx >> 16; - srel->r_index[1] = indx >> 8; - srel->r_index[0] = indx; - } - } - else - { - struct reloc_ext_external *erel; - - erel = (struct reloc_ext_external *) p; - PUT_WORD (dynobj, - (GET_WORD (dynobj, erel->r_address) - + input_section->output_section->vma - + input_section->output_offset), - erel->r_address); - if (bfd_header_big_endian (dynobj)) - { - erel->r_index[0] = indx >> 16; - erel->r_index[1] = indx >> 8; - erel->r_index[2] = indx; - } - else - { - erel->r_index[2] = indx >> 16; - erel->r_index[1] = indx >> 8; - erel->r_index[0] = indx; - } - } - - ++s->reloc_count; - - if (h != NULL) - *skip = true; - - return true; -} - -/* Finish up the dynamic linking information. */ - -static boolean -sunos_finish_dynamic_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *o; - asection *s; - asection *sdyn; - struct external_sun4_dynamic esd; - struct external_sun4_dynamic_link esdl; - - if (! sunos_hash_table (info)->dynamic_sections_needed) - return true; - - dynobj = sunos_hash_table (info)->dynobj; - - sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); - BFD_ASSERT (sdyn != NULL); - - /* Finish up the .need section. The linker emulation code filled it - in, but with offsets from the start of the section instead of - real addresses. Now that we know the section location, we can - fill in the final values. */ - s = bfd_get_section_by_name (dynobj, ".need"); - if (s != NULL && s->_raw_size != 0) - { - file_ptr filepos; - bfd_byte *p; - - filepos = s->output_section->filepos + s->output_offset; - p = s->contents; - while (1) - { - bfd_vma val; - - PUT_WORD (dynobj, GET_WORD (dynobj, p) + filepos, p); - val = GET_WORD (dynobj, p + 12); - if (val == 0) - break; - PUT_WORD (dynobj, val + filepos, p + 12); - p += 16; - } - } - - /* The first entry in the .got section is the address of the - dynamic information, unless this is a shared library. */ - s = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (s != NULL); - if (info->shared) - PUT_WORD (dynobj, 0, s->contents); - else - PUT_WORD (dynobj, sdyn->output_section->vma + sdyn->output_offset, - s->contents); - - for (o = dynobj->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_HAS_CONTENTS) != 0 - && o->contents != NULL) - { - BFD_ASSERT (o->output_section != NULL - && o->output_section->owner == abfd); - if (! bfd_set_section_contents (abfd, o->output_section, - o->contents, o->output_offset, - o->_raw_size)) - return false; - } - } - - /* Finish up the dynamic link information. */ - PUT_WORD (dynobj, (bfd_vma) 3, esd.ld_version); - PUT_WORD (dynobj, - sdyn->output_section->vma + sdyn->output_offset + sizeof esd, - esd.ldd); - PUT_WORD (dynobj, - (sdyn->output_section->vma - + sdyn->output_offset - + sizeof esd - + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE), - esd.ld); - - if (! bfd_set_section_contents (abfd, sdyn->output_section, &esd, - sdyn->output_offset, sizeof esd)) - return false; - - - PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_loaded); - - s = bfd_get_section_by_name (dynobj, ".need"); - if (s == NULL || s->_raw_size == 0) - PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_need); - else - PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, - esdl.ld_need); - - s = bfd_get_section_by_name (dynobj, ".rules"); - if (s == NULL || s->_raw_size == 0) - PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_rules); - else - PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, - esdl.ld_rules); - - s = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (s != NULL); - PUT_WORD (dynobj, s->output_section->vma + s->output_offset, esdl.ld_got); - - s = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (s != NULL); - PUT_WORD (dynobj, s->output_section->vma + s->output_offset, esdl.ld_plt); - PUT_WORD (dynobj, s->_raw_size, esdl.ld_plt_sz); - - s = bfd_get_section_by_name (dynobj, ".dynrel"); - BFD_ASSERT (s != NULL); - BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) == s->_raw_size); - PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, - esdl.ld_rel); - - s = bfd_get_section_by_name (dynobj, ".hash"); - BFD_ASSERT (s != NULL); - PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, - esdl.ld_hash); - - s = bfd_get_section_by_name (dynobj, ".dynsym"); - BFD_ASSERT (s != NULL); - PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, - esdl.ld_stab); - - PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_stab_hash); - - PUT_WORD (dynobj, (bfd_vma) sunos_hash_table (info)->bucketcount, - esdl.ld_buckets); - - s = bfd_get_section_by_name (dynobj, ".dynstr"); - BFD_ASSERT (s != NULL); - PUT_WORD (dynobj, s->output_section->filepos + s->output_offset, - esdl.ld_symbols); - PUT_WORD (dynobj, s->_raw_size, esdl.ld_symb_size); - - /* The size of the text area is the size of the .text section - rounded up to a page boundary. FIXME: Should the page size be - conditional on something? */ - PUT_WORD (dynobj, - BFD_ALIGN (obj_textsec (abfd)->_raw_size, 0x2000), - esdl.ld_text); - - if (! bfd_set_section_contents (abfd, sdyn->output_section, &esdl, - (sdyn->output_offset - + sizeof esd - + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE), - sizeof esdl)) - return false; - - abfd->flags |= DYNAMIC; - - return true; -} diff --git a/contrib/gdb/bfd/versados.c b/contrib/gdb/bfd/versados.c deleted file mode 100644 index 84ad114..0000000 --- a/contrib/gdb/bfd/versados.c +++ /dev/null @@ -1,906 +0,0 @@ -/* BFD back-end for VERSAdos-E objects. - - Versados is a Motorola trademark. - - Copyright 1995 Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support <sac@cygnus.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. */ - -/* - SUBSECTION - VERSAdos-E relocateable object file format - - DESCRIPTION - - This module supports reading of VERSAdos relocateable - object files. - - A VERSAdos file looks like contains - - o Indentification Record - o External Symbol Definition Record - o Object Text Recrod - o End Record - - - */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libiberty.h" - - -static boolean versados_mkobject PARAMS ((bfd *)); -static boolean versados_scan PARAMS ((bfd *)); -static const bfd_target *versados_object_p PARAMS ((bfd *)); - - -#define VHEADER '1' -#define VESTDEF '2' -#define VOTR '3' -#define VEND '4' - - -#define ES_BASE 17 /* first symbol has esdid 17 */ - -/* Per file target dependent information */ - -/* one for each section */ -struct esdid - { - asection *section; /* ptr to bfd version */ - unsigned char *contents; /* used to build image */ - int pc; - int relocs; /* reloc count, valid end of pass 1 */ - int donerel; /* have relocs been translated */ - }; - -typedef struct versados_data_struct - { - int es_done; /* count of symbol index, starts at ES_BASE */ - asymbol *symbols; /* pointer to local symbols */ - char *strings; /* strings of all the above */ - int stringlen; /* len of string table (valid end of pass1) */ - int nsecsyms; /* number of sections */ - - int ndefs; /* number of exported symbols (they dont get esdids) */ - int nrefs; /* number of imported symbols (valid end of pass1) */ - - int ref_idx; /* current processed value of the above */ - int def_idx; - - int pass_2_done; - - struct esdid e[16]; /* per section info */ - int alert; /* to see if we're trampling */ - asymbol *rest[256 - 16]; /* per symbol info */ - - } -tdata_type; - -#define VDATA(abfd) (abfd->tdata.versados_data) -#define EDATA(abfd, n) (abfd->tdata.versados_data->e[n]) -#define RDATA(abfd, n) (abfd->tdata.versados_data->rest[n]) - -struct ext_otr - { - unsigned char size; - char type; - unsigned char map[4]; - unsigned char esdid; - unsigned char data[200]; - }; - -struct ext_vheader - { - unsigned char size; - char type; /* record type */ - char name[10]; /* module name */ - char rev; /* module rev number */ - char lang; - char vol[4]; - char user[2]; - char cat[8]; - char fname[8]; - char ext[2]; - char time[3]; - char date[3]; - char rest[211]; - }; - -struct ext_esd - { - unsigned char size; - char type; - unsigned char esd_entries[1]; - }; -#define ESD_ABS 0 -#define ESD_COMMON 1 -#define ESD_STD_REL_SEC 2 -#define ESD_SHRT_REL_SEC 3 -#define ESD_XDEF_IN_SEC 4 -#define ESD_XREF_SYM 7 -#define ESD_XREF_SEC 6 -#define ESD_XDEF_IN_ABS 5 -union ext_any - { - unsigned char size; - struct ext_vheader header; - struct ext_esd esd; - struct ext_otr otr; - }; - -/* Initialize by filling in the hex conversion array. */ - - - - - -/* Set up the tdata information. */ - -static boolean -versados_mkobject (abfd) - bfd *abfd; -{ - if (abfd->tdata.versados_data == NULL) - { - tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type)); - if (tdata == NULL) - return false; - abfd->tdata.versados_data = tdata; - tdata->symbols = NULL; - VDATA (abfd)->alert = 0x12345678; - } - - bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0); - return true; -} - - -/* Report a problem in an S record file. FIXME: This probably should - not call fprintf, but we really do need some mechanism for printing - error messages. */ - - - -static asymbol * -versados_new_symbol (abfd, snum, name, val, sec) - bfd *abfd; - int snum; - const char *name; - bfd_vma val; - asection *sec; -{ - asymbol *n = VDATA (abfd)->symbols + snum; - n->name = name; - n->value = val; - n->section = sec; - n->the_bfd = abfd; - n->flags = 0; - return n; -} - - -static int -get_record (abfd, ptr) - bfd *abfd; - union ext_any *ptr; -{ - bfd_read (&ptr->size, 1, 1, abfd); - if (bfd_read ((char *) ptr + 1, 1, ptr->size, abfd) != ptr->size) - return 0; - return 1; -} - -int -get_4 (pp) - unsigned char **pp; -{ - unsigned char *p = *pp; - *pp += 4; - return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3] << 0); -} - -void -get_10 (pp, name) - unsigned char **pp; - char *name; -{ - char *p = (char *) *pp; - int len = 10; - *pp += len; - while (*p != ' ' - && len) - { - *name++ = *p++; - len--; - } - *name = 0; -} - -static char * -new_symbol_string (abfd, name) - bfd *abfd; - char *name; -{ - char *n = VDATA (abfd)->strings; - strcpy (VDATA (abfd)->strings, name); - VDATA (abfd)->strings += strlen (VDATA (abfd)->strings) + 1; - return n; -} - - -static void -process_esd (abfd, esd, pass) - bfd *abfd; - struct ext_esd *esd; - int pass; -{ - /* Read through the ext def for the est entries */ - int togo = esd->size - 2; - bfd_vma size; - bfd_vma start; - asection *sec; - char name[11]; - unsigned char *ptr = esd->esd_entries; - unsigned char *end = ptr + togo; - while (ptr < end) - { - int scn = *ptr & 0xf; - int typ = (*ptr >> 4) & 0xf; - - /* Declare this section */ - sprintf (name, "%d", scn); - sec = bfd_make_section_old_way (abfd, strdup (name)); - sec->target_index = scn; - EDATA (abfd, scn).section = sec; - ptr++; - switch (typ) - { - default: - abort (); - case ESD_XREF_SEC: - case ESD_XREF_SYM: - { - int snum = VDATA (abfd)->ref_idx++; - get_10 (&ptr, name); - if (pass == 1) - { - VDATA (abfd)->stringlen += strlen (name) + 1; - } - else - { - int esidx; - asymbol *s; - char *n = new_symbol_string (abfd, name); - s = versados_new_symbol (abfd, snum, n, 0, - &bfd_und_section, scn); - esidx = VDATA (abfd)->es_done++; - RDATA (abfd, esidx - ES_BASE) = s; - } - } - break; - - - case ESD_ABS: - size = get_4 (&ptr); - start = get_4 (&ptr); - break; - case ESD_STD_REL_SEC: - case ESD_SHRT_REL_SEC: - { - sec->_raw_size = get_4 (&ptr); - sec->flags |= SEC_ALLOC; - } - break; - case ESD_XDEF_IN_ABS: - sec = (asection *) & bfd_abs_section; - case ESD_XDEF_IN_SEC: - { - int snum = VDATA (abfd)->def_idx++; - long val; - get_10 (&ptr, name); - val = get_4 (&ptr); - if (pass == 1) - { - /* Just remember the symbol */ - VDATA (abfd)->stringlen += strlen (name) + 1; - } - else - { - asymbol *s; - char *n = new_symbol_string (abfd, name); - s = versados_new_symbol (abfd, snum + VDATA (abfd)->nrefs, n, val, sec, scn); - s->flags |= BSF_GLOBAL; - } - } - break; - } - } -} - -#define R_RELWORD 1 -#define R_RELLONG 2 -#define R_RELWORD_NEG 3 -#define R_RELLONG_NEG 4 - -reloc_howto_type versados_howto_table[] = -{ - HOWTO (R_RELWORD, 0, 1, 16, false, - 0, complain_overflow_dont, 0, - "+v16", true, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_RELLONG, 0, 2, 32, false, - 0, complain_overflow_dont, 0, - "+v32", true, 0xffffffff, 0xffffffff, false), - - HOWTO (R_RELWORD_NEG, 0, -1, 16, false, - 0, complain_overflow_dont, 0, - "-v16", true, 0x0000ffff, 0x0000ffff, false), - HOWTO (R_RELLONG_NEG, 0, -2, 32, false, - 0, complain_overflow_dont, 0, - "-v32", true, 0xffffffff, 0xffffffff, false), -}; - - -static int -get_offset (len, ptr) - int len; - unsigned char *ptr; -{ - int val = 0; - if (len) - { - int i; - val = *ptr++; - if (val & 0x80) - val |= ~0xff; - for (i = 1; i < len; i++) - val = (val << 8) | *ptr++; - } - - return val; -} - -static void -process_otr (abfd, otr, pass) - bfd *abfd; - struct ext_otr *otr; - int pass; -{ - unsigned long shift; - unsigned char *srcp = otr->data; - unsigned char *endp = (unsigned char *) otr + otr->size; - unsigned int bits = (otr->map[0] << 24) - | (otr->map[1] << 16) - | (otr->map[2] << 8) - | (otr->map[3] << 0); - - struct esdid *esdid = &EDATA (abfd, otr->esdid - 1); - unsigned char *contents = esdid->contents; - int need_contents = 0; - unsigned int dst_idx = esdid->pc; - - for (shift = (1 << 31); shift && srcp < endp; shift >>= 1) - { - if (bits & shift) - { - int flag = *srcp++; - int esdids = (flag >> 5) & 0x7; - int sizeinwords = ((flag >> 3) & 1) ? 2 : 1; - int offsetlen = flag & 0x7; - int j; - - - if (esdids == 0) - { - /* A zero esdid means the new pc is the offset given */ - dst_idx += get_offset (offsetlen, srcp); - srcp += offsetlen; - } - else - { - int val = get_offset (offsetlen, srcp + esdids); - if (pass == 1) - need_contents = 1; - else - for (j = 0; j < sizeinwords * 2; j++) - { - contents[dst_idx + (sizeinwords * 2) - j - 1] = val; - val >>= 8; - } - - for (j = 0; j < esdids; j++) - { - int esdid = *srcp++; - - if (esdid) - { - int rn = EDATA (abfd, otr->esdid - 1).relocs++; - if (pass == 1) - { - /* this is the first pass over the data, - just remember that we need a reloc */ - } - else - { - arelent *n = - EDATA (abfd, otr->esdid - 1).section->relocation + rn; - n->address = dst_idx; - - n->sym_ptr_ptr = (asymbol **) esdid; - n->addend = 0; - n->howto = versados_howto_table + ((j & 1) * 2) + (sizeinwords - 1); - } - } - } - srcp += offsetlen; - dst_idx += sizeinwords * 2; - } - } - else - { - need_contents = 1; - if (dst_idx < esdid->section->_raw_size) - if (pass == 2) - { - /* absolute code, comes in 16 bit lumps */ - contents[dst_idx] = srcp[0]; - contents[dst_idx + 1] = srcp[1]; - } - dst_idx += 2; - srcp += 2; - } - } - EDATA (abfd, otr->esdid - 1).pc = dst_idx; - - if (!contents && need_contents) - esdid->contents = (unsigned char *) bfd_alloc (abfd, esdid->section->_raw_size); - - -} - -static boolean -versados_scan (abfd) - bfd *abfd; -{ - int loop = 1; - int i; - int j; - int nsecs = 0; - - VDATA (abfd)->nrefs = 0; - VDATA (abfd)->ndefs = 0; - VDATA (abfd)->ref_idx = 0; - VDATA (abfd)->def_idx = 0; - - while (loop) - { - union ext_any any; - if (!get_record (abfd, &any)) - return true; - switch (any.header.type) - { - case VHEADER: - break; - case VEND: - loop = 0; - break; - case VESTDEF: - process_esd (abfd, &any.esd, 1); - break; - case VOTR: - process_otr (abfd, &any.otr, 1); - break; - } - } - - /* Now allocate space for the relocs and sections */ - - VDATA (abfd)->nrefs = VDATA (abfd)->ref_idx; - VDATA (abfd)->ndefs = VDATA (abfd)->def_idx; - VDATA (abfd)->ref_idx = 0; - VDATA (abfd)->def_idx = 0; - - abfd->symcount = VDATA (abfd)->nrefs + VDATA (abfd)->ndefs; - - for (i = 0; i < 16; i++) - { - struct esdid *esdid = &EDATA (abfd, i); - if (esdid->section) - { - esdid->section->relocation - = (arelent *) bfd_alloc (abfd, sizeof (arelent) * esdid->relocs); - - esdid->pc = 0; - - if (esdid->contents) - esdid->section->flags |= SEC_HAS_CONTENTS | SEC_LOAD; - - esdid->section->reloc_count = esdid->relocs; - if (esdid->relocs) - esdid->section->flags |= SEC_RELOC; - - esdid->relocs = 0; - - /* Add an entry into the symbol table for it */ - nsecs++; - VDATA (abfd)->stringlen += strlen (esdid->section->name) + 1; - } - } - - abfd->symcount += nsecs; - - VDATA (abfd)->symbols = (asymbol *) bfd_alloc (abfd, - sizeof (asymbol) * (abfd->symcount)); - - VDATA (abfd)->strings = bfd_alloc (abfd, VDATA (abfd)->stringlen); - - - /* Actually fill in the section symbols, - we stick them at the end of the table */ - - for (j = VDATA (abfd)->nrefs + VDATA (abfd)->ndefs, i = 0; i < 16; i++) - { - struct esdid *esdid = &EDATA (abfd, i); - asection *sec = esdid->section; - if (sec) - { - asymbol *s = VDATA (abfd)->symbols + j; - s->name = new_symbol_string (abfd, sec->name); - s->section = sec; - s->flags = BSF_LOCAL; - s->value = 0; - s->the_bfd = abfd; - j++; - } - } - if (abfd->symcount) - abfd->flags |= HAS_SYMS; - - /* Set this to nsecs - since we've already planted the section - symbols */ - VDATA (abfd)->nsecsyms = nsecs; - - VDATA (abfd)->ref_idx = 0; - - return 1; -} - - - -/* Check whether an existing file is a versados file. */ - -static const bfd_target * -versados_object_p (abfd) - bfd *abfd; -{ - struct ext_vheader ext; - unsigned char len; - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET)) - return NULL; - - - bfd_read (&len, 1, 1, abfd); - if (bfd_read (&ext.type, 1, len, abfd) != len - || ext.type != '1') - { - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* ok, looks like a record, build the tdata and read - in.. */ - - if (!versados_mkobject (abfd) - || !versados_scan (abfd)) - return NULL; - - return abfd->xvec; -} - - -static boolean -versados_pass_2 (abfd) - bfd *abfd; -{ - union ext_any any; - - if (VDATA (abfd)->pass_2_done) - return 1; - - if (bfd_seek (abfd, 0, SEEK_SET) != 0) - return 0; - - VDATA (abfd)->es_done = ES_BASE; - - - /* read records till we get to where we want to be */ - - while (1) - { - get_record (abfd, &any); - switch (any.header.type) - { - case VEND: - VDATA (abfd)->pass_2_done = 1; - return 1; - case VESTDEF: - process_esd (abfd, &any.esd, 2); - break; - case VOTR: - process_otr (abfd, &any.otr, 2); - break; - } - } -} - -static boolean -versados_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - asection *section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if (!versados_pass_2 (abfd)) - return false; - - memcpy (location, - EDATA (abfd, section->target_index).contents + offset, - (size_t) count); - - return true; -} - -#define versados_get_section_contents_in_window \ - _bfd_generic_get_section_contents_in_window - -static boolean -versados_set_section_contents (abfd, section, location, offset, bytes_to_do) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type bytes_to_do; -{ - return false; -} - - -/*ARGSUSED */ -static int -versados_sizeof_headers (abfd, exec) - bfd *abfd; - boolean exec; -{ - return 0; -} - -static asymbol * -versados_make_empty_symbol (abfd) - bfd *abfd; -{ - asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol)); - if (new) - new->the_bfd = abfd; - return new; -} - -/* Return the amount of memory needed to read the symbol table. */ - -static long -versados_get_symtab_upper_bound (abfd) - bfd *abfd; -{ - return (bfd_get_symcount (abfd) + 1) * sizeof (asymbol *); -} - -/* Return the symbol table. */ - -static long -versados_get_symtab (abfd, alocation) - bfd *abfd; - asymbol **alocation; -{ - unsigned int symcount = bfd_get_symcount (abfd); - unsigned int i; - asymbol *s; - - versados_pass_2 (abfd); - - for (i = 0, s = VDATA (abfd)->symbols; - i < symcount; - s++, i++) - { - *alocation++ = s; - } - - *alocation = NULL; - - return symcount; -} - -/*ARGSUSED */ -void -versados_get_symbol_info (ignore_abfd, symbol, ret) - bfd *ignore_abfd; - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); -} - -/*ARGSUSED */ -void -versados_print_symbol (ignore_abfd, afile, symbol, how) - bfd *ignore_abfd; - PTR afile; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *) afile; - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - default: - bfd_print_symbol_vandf ((PTR) file, symbol); - fprintf (file, " %-5s %s", - symbol->section->name, - symbol->name); - - } -} - -long -versados_get_reloc_upper_bound (abfd, asect) - bfd *abfd; - sec_ptr asect; -{ - return (asect->reloc_count + 1) * sizeof (arelent *); -} - - -long -versados_canonicalize_reloc (abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - unsigned int count; - arelent *src; - - versados_pass_2 (abfd); - src = section->relocation; - if (!EDATA (abfd, section->target_index).donerel) - { - EDATA (abfd, section->target_index).donerel = 1; - /* translate from indexes to symptr ptrs */ - for (count = 0; count < section->reloc_count; count++) - { - int esdid = (int) src[count].sym_ptr_ptr; - - if (esdid == 0) - { - src[count].sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr; - } - else if (esdid < ES_BASE) /* Section relative thing */ - { - struct esdid *e = &EDATA (abfd, esdid - 1); - if (!section) - { - /** relocation relative to section which was - never declared ! */ - } - src[count].sym_ptr_ptr = e->section->symbol_ptr_ptr; - } - else - { - src[count].sym_ptr_ptr = symbols + esdid - ES_BASE; - } - - } - } - - for (count = 0; count < section->reloc_count; count++) - { - *relptr++ = src++; - } - *relptr = 0; - return section->reloc_count; -} - -#define versados_close_and_cleanup _bfd_generic_close_and_cleanup -#define versados_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#define versados_new_section_hook _bfd_generic_new_section_hook - -#define versados_bfd_is_local_label bfd_generic_is_local_label -#define versados_get_lineno _bfd_nosymbols_get_lineno -#define versados_find_nearest_line _bfd_nosymbols_find_nearest_line -#define versados_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol -#define versados_read_minisymbols _bfd_generic_read_minisymbols -#define versados_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol - -#define versados_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup - -#define versados_set_arch_mach bfd_default_set_arch_mach - -#define versados_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define versados_bfd_relax_section bfd_generic_relax_section -#define versados_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define versados_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define versados_bfd_final_link _bfd_generic_final_link -#define versados_bfd_link_split_section _bfd_generic_link_split_section - -const bfd_target versados_vec = -{ - "versados", /* name */ - bfd_target_versados_flavour, - BFD_ENDIAN_BIG, /* target byte order */ - BFD_ENDIAN_BIG, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - { - _bfd_dummy_target, - versados_object_p, /* bfd_check_format */ - _bfd_dummy_target, - _bfd_dummy_target, - }, - { - bfd_false, - versados_mkobject, - _bfd_generic_mkarchive, - bfd_false, - }, - { /* bfd_write_contents */ - bfd_false, - bfd_false, - _bfd_write_archive_contents, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (versados), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (versados), - BFD_JUMP_TABLE_RELOCS (versados), - BFD_JUMP_TABLE_WRITE (versados), - BFD_JUMP_TABLE_LINK (versados), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; diff --git a/contrib/gdb/bfd/xcofflink.c b/contrib/gdb/bfd/xcofflink.c deleted file mode 100644 index 16a76cc..0000000 --- a/contrib/gdb/bfd/xcofflink.c +++ /dev/null @@ -1,5798 +0,0 @@ -/* POWER/PowerPC XCOFF linker support. - Copyright 1995, 1996 Free Software Foundation, Inc. - Written by Ian Lance Taylor <ian@cygnus.com>, Cygnus Support. - -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. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "coff/internal.h" -#include "libcoff.h" - -/* This file holds the XCOFF linker code. */ - -#define STRING_SIZE_SIZE (4) - -/* In order to support linking different object file formats into an - XCOFF format, we need to be able to determine whether a particular - bfd_target is an XCOFF vector. FIXME: We need to rethink this - whole approach. */ -#define XCOFF_XVECP(xv) \ - (strcmp ((xv)->name, "aixcoff-rs6000") == 0 \ - || strcmp ((xv)->name, "xcoff-powermac") == 0) - -/* Get the XCOFF hash table entries for a BFD. */ -#define obj_xcoff_sym_hashes(bfd) \ - ((struct xcoff_link_hash_entry **) obj_coff_sym_hashes (bfd)) - -/* XCOFF relocation types. These probably belong in a header file - somewhere. The relocations are described in the function - _bfd_ppc_xcoff_relocate_section in this file. */ - -#define R_POS (0x00) -#define R_NEG (0x01) -#define R_REL (0x02) -#define R_TOC (0x03) -#define R_RTB (0x04) -#define R_GL (0x05) -#define R_TCL (0x06) -#define R_BA (0x08) -#define R_BR (0x0a) -#define R_RL (0x0c) -#define R_RLA (0x0d) -#define R_REF (0x0f) -#define R_TRL (0x12) -#define R_TRLA (0x13) -#define R_RRTBI (0x14) -#define R_RRTBA (0x15) -#define R_CAI (0x16) -#define R_CREL (0x17) -#define R_RBA (0x18) -#define R_RBAC (0x19) -#define R_RBR (0x1a) -#define R_RBRC (0x1b) - -/* The first word of global linkage code. This must be modified by - filling in the correct TOC offset. */ - -#define XCOFF_GLINK_FIRST (0x81820000) /* lwz r12,0(r2) */ - -/* The remaining words of global linkage code. */ - -static unsigned long xcoff_glink_code[] = -{ - 0x90410014, /* stw r2,20(r1) */ - 0x800c0000, /* lwz r0,0(r12) */ - 0x804c0004, /* lwz r2,4(r12) */ - 0x7c0903a6, /* mtctr r0 */ - 0x4e800420, /* bctr */ - 0x0, /* start of traceback table */ - 0x000c8000, /* traceback table */ - 0x0 /* traceback table */ -}; - -#define XCOFF_GLINK_SIZE \ - (((sizeof xcoff_glink_code / sizeof xcoff_glink_code[0]) * 4) + 4) - -/* We reuse the SEC_ROM flag as a mark flag for garbage collection. - This flag will only be used on input sections. */ - -#define SEC_MARK (SEC_ROM) - -/* The ldhdr structure. This appears at the start of the .loader - section. */ - -struct internal_ldhdr -{ - /* The version number: currently always 1. */ - unsigned long l_version; - /* The number of symbol table entries. */ - bfd_size_type l_nsyms; - /* The number of relocation table entries. */ - bfd_size_type l_nreloc; - /* The length of the import file string table. */ - bfd_size_type l_istlen; - /* The number of import files. */ - bfd_size_type l_nimpid; - /* The offset from the start of the .loader section to the first - entry in the import file table. */ - bfd_size_type l_impoff; - /* The length of the string table. */ - bfd_size_type l_stlen; - /* The offset from the start of the .loader section to the first - entry in the string table. */ - bfd_size_type l_stoff; -}; - -struct external_ldhdr -{ - bfd_byte l_version[4]; - bfd_byte l_nsyms[4]; - bfd_byte l_nreloc[4]; - bfd_byte l_istlen[4]; - bfd_byte l_nimpid[4]; - bfd_byte l_impoff[4]; - bfd_byte l_stlen[4]; - bfd_byte l_stoff[4]; -}; - -#define LDHDRSZ (8 * 4) - -/* The ldsym structure. This is used to represent a symbol in the - .loader section. */ - -struct internal_ldsym -{ - union - { - /* The symbol name if <= SYMNMLEN characters. */ - char _l_name[SYMNMLEN]; - struct - { - /* Zero if the symbol name is more than SYMNMLEN characters. */ - long _l_zeroes; - /* The offset in the string table if the symbol name is more - than SYMNMLEN characters. */ - long _l_offset; - } _l_l; - } _l; - /* The symbol value. */ - bfd_vma l_value; - /* The symbol section number. */ - short l_scnum; - /* The symbol type and flags. */ - char l_smtype; - /* The symbol storage class. */ - char l_smclas; - /* The import file ID. */ - bfd_size_type l_ifile; - /* Offset to the parameter type check string. */ - bfd_size_type l_parm; -}; - -struct external_ldsym -{ - union - { - bfd_byte _l_name[SYMNMLEN]; - struct - { - bfd_byte _l_zeroes[4]; - bfd_byte _l_offset[4]; - } _l_l; - } _l; - bfd_byte l_value[4]; - bfd_byte l_scnum[2]; - bfd_byte l_smtype[1]; - bfd_byte l_smclas[1]; - bfd_byte l_ifile[4]; - bfd_byte l_parm[4]; -}; - -#define LDSYMSZ (8 + 3 * 4 + 2 + 2) - -/* These flags are for the l_smtype field (the lower three bits are an - XTY_* value). */ - -/* Imported symbol. */ -#define L_IMPORT (0x40) -/* Entry point. */ -#define L_ENTRY (0x20) -/* Exported symbol. */ -#define L_EXPORT (0x10) - -/* The ldrel structure. This is used to represent a reloc in the - .loader section. */ - -struct internal_ldrel -{ - /* The reloc address. */ - bfd_vma l_vaddr; - /* The symbol table index in the .loader section symbol table. */ - bfd_size_type l_symndx; - /* The relocation type and size. */ - short l_rtype; - /* The section number this relocation applies to. */ - short l_rsecnm; -}; - -struct external_ldrel -{ - bfd_byte l_vaddr[4]; - bfd_byte l_symndx[4]; - bfd_byte l_rtype[2]; - bfd_byte l_rsecnm[2]; -}; - -#define LDRELSZ (2 * 4 + 2 * 2) - -/* The list of import files. */ - -struct xcoff_import_file -{ - /* The next entry in the list. */ - struct xcoff_import_file *next; - /* The path. */ - const char *path; - /* The file name. */ - const char *file; - /* The member name. */ - const char *member; -}; - -/* An entry in the XCOFF linker hash table. */ - -struct xcoff_link_hash_entry -{ - struct bfd_link_hash_entry root; - - /* Symbol index in output file. Set to -1 initially. Set to -2 if - there is a reloc against this symbol. */ - long indx; - - /* If we have created a TOC entry for this symbol, this is the .tc - section which holds it. */ - asection *toc_section; - - union - { - /* If we have created a TOC entry (the XCOFF_SET_TOC flag is - set), this is the offset in toc_section. */ - bfd_vma toc_offset; - /* If the TOC entry comes from an input file, this is set to the - symbo lindex of the C_HIDEXT XMC_TC symbol. */ - long toc_indx; - } u; - - /* If this symbol is a function entry point which is called, this - field holds a pointer to the function descriptor. If this symbol - is a function descriptor, this field holds a pointer to the - function entry point. */ - struct xcoff_link_hash_entry *descriptor; - - /* The .loader symbol table entry, if there is one. */ - struct internal_ldsym *ldsym; - - /* The .loader symbol table index. */ - long ldindx; - - /* Some linker flags. */ - unsigned short flags; - /* Symbol is referenced by a regular object. */ -#define XCOFF_REF_REGULAR (01) - /* Symbol is defined by a regular object. */ -#define XCOFF_DEF_REGULAR (02) - /* Symbol is defined by a dynamic object. */ -#define XCOFF_DEF_DYNAMIC (04) - /* Symbol is used in a reloc being copied into the .loader section. */ -#define XCOFF_LDREL (010) - /* Symbol is the entry point. */ -#define XCOFF_ENTRY (020) - /* Symbol is called; this is, it appears in a R_BR reloc. */ -#define XCOFF_CALLED (040) - /* Symbol needs the TOC entry filled in. */ -#define XCOFF_SET_TOC (0100) - /* Symbol is explicitly imported. */ -#define XCOFF_IMPORT (0200) - /* Symbol is explicitly exported. */ -#define XCOFF_EXPORT (0400) - /* Symbol has been processed by xcoff_build_ldsyms. */ -#define XCOFF_BUILT_LDSYM (01000) - /* Symbol is mentioned by a section which was not garbage collected. */ -#define XCOFF_MARK (02000) - /* Symbol size is recorded in size_list list from hash table. */ -#define XCOFF_HAS_SIZE (04000) - /* Symbol is a function descriptor. */ -#define XCOFF_DESCRIPTOR (010000) - - /* The storage mapping class. */ - unsigned char smclas; -}; - -/* The XCOFF linker hash table. */ - -struct xcoff_link_hash_table -{ - struct bfd_link_hash_table root; - - /* The .debug string hash table. We need to compute this while - reading the input files, so that we know how large the .debug - section will be before we assign section positions. */ - struct bfd_strtab_hash *debug_strtab; - - /* The .debug section we will use for the final output. */ - asection *debug_section; - - /* The .loader section we will use for the final output. */ - asection *loader_section; - - /* A count of non TOC relative relocs which will need to be - allocated in the .loader section. */ - size_t ldrel_count; - - /* The .loader section header. */ - struct internal_ldhdr ldhdr; - - /* The .gl section we use to hold global linkage code. */ - asection *linkage_section; - - /* The .tc section we use to hold toc entries we build for global - linkage code. */ - asection *toc_section; - - /* The .ds section we use to hold function descriptors which we - create for exported symbols. */ - asection *descriptor_section; - - /* The list of import files. */ - struct xcoff_import_file *imports; - - /* Required alignment of sections within the output file. */ - unsigned long file_align; - - /* Whether the .text section must be read-only. */ - boolean textro; - - /* Whether garbage collection was done. */ - boolean gc; - - /* A linked list of symbols for which we have size information. */ - struct xcoff_link_size_list - { - struct xcoff_link_size_list *next; - struct xcoff_link_hash_entry *h; - bfd_size_type size; - } *size_list; - - /* Magic sections: _text, _etext, _data, _edata, _end, end. */ - asection *special_sections[6]; -}; - -/* Information we keep for each section in the output file during the - final link phase. */ - -struct xcoff_link_section_info -{ - /* The relocs to be output. */ - struct internal_reloc *relocs; - /* For each reloc against a global symbol whose index was not known - when the reloc was handled, the global hash table entry. */ - struct xcoff_link_hash_entry **rel_hashes; - /* If there is a TOC relative reloc against a global symbol, and the - index of the TOC symbol is not known when the reloc was handled, - an entry is added to this linked list. This is not an array, - like rel_hashes, because this case is quite uncommon. */ - struct xcoff_toc_rel_hash - { - struct xcoff_toc_rel_hash *next; - struct xcoff_link_hash_entry *h; - struct internal_reloc *rel; - } *toc_rel_hashes; -}; - -/* Information that we pass around while doing the final link step. */ - -struct xcoff_final_link_info -{ - /* General link information. */ - struct bfd_link_info *info; - /* Output BFD. */ - bfd *output_bfd; - /* Hash table for long symbol names. */ - struct bfd_strtab_hash *strtab; - /* Array of information kept for each output section, indexed by the - target_index field. */ - struct xcoff_link_section_info *section_info; - /* Symbol index of last C_FILE symbol (-1 if none). */ - long last_file_index; - /* Contents of last C_FILE symbol. */ - struct internal_syment last_file; - /* Symbol index of TOC symbol. */ - long toc_symindx; - /* Start of .loader symbols. */ - struct external_ldsym *ldsym; - /* Next .loader reloc to swap out. */ - struct external_ldrel *ldrel; - /* File position of start of line numbers. */ - file_ptr line_filepos; - /* Buffer large enough to hold swapped symbols of any input file. */ - struct internal_syment *internal_syms; - /* Buffer large enough to hold output indices of symbols of any - input file. */ - long *sym_indices; - /* Buffer large enough to hold output symbols for any input file. */ - bfd_byte *outsyms; - /* Buffer large enough to hold external line numbers for any input - section. */ - bfd_byte *linenos; - /* Buffer large enough to hold any input section. */ - bfd_byte *contents; - /* Buffer large enough to hold external relocs of any input section. */ - bfd_byte *external_relocs; -}; - -static void xcoff_swap_ldhdr_in - PARAMS ((bfd *, const struct external_ldhdr *, struct internal_ldhdr *)); -static void xcoff_swap_ldhdr_out - PARAMS ((bfd *, const struct internal_ldhdr *, struct external_ldhdr *)); -static void xcoff_swap_ldsym_in - PARAMS ((bfd *, const struct external_ldsym *, struct internal_ldsym *)); -static void xcoff_swap_ldsym_out - PARAMS ((bfd *, const struct internal_ldsym *, struct external_ldsym *)); -static void xcoff_swap_ldrel_out - PARAMS ((bfd *, const struct internal_ldrel *, struct external_ldrel *)); -static struct bfd_hash_entry *xcoff_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static struct internal_reloc *xcoff_read_internal_relocs - PARAMS ((bfd *, asection *, boolean, bfd_byte *, boolean, - struct internal_reloc *)); -static boolean xcoff_link_add_object_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean xcoff_link_check_archive_element - PARAMS ((bfd *, struct bfd_link_info *, boolean *)); -static boolean xcoff_link_check_ar_symbols - PARAMS ((bfd *, struct bfd_link_info *, boolean *)); -static bfd_size_type xcoff_find_reloc - PARAMS ((struct internal_reloc *, bfd_size_type, bfd_vma)); -static boolean xcoff_link_add_symbols PARAMS ((bfd *, struct bfd_link_info *)); -static boolean xcoff_link_add_dynamic_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean xcoff_mark PARAMS ((struct bfd_link_info *, asection *)); -static void xcoff_sweep PARAMS ((struct bfd_link_info *)); -static boolean xcoff_build_ldsyms - PARAMS ((struct xcoff_link_hash_entry *, PTR)); -static boolean xcoff_link_input_bfd - PARAMS ((struct xcoff_final_link_info *, bfd *)); -static boolean xcoff_write_global_symbol - PARAMS ((struct xcoff_link_hash_entry *, PTR)); -static boolean xcoff_reloc_link_order - PARAMS ((bfd *, struct xcoff_final_link_info *, asection *, - struct bfd_link_order *)); -static int xcoff_sort_relocs PARAMS ((const PTR, const PTR)); - -/* Routines to swap information in the XCOFF .loader section. If we - ever need to write an XCOFF loader, this stuff will need to be - moved to another file shared by the linker (which XCOFF calls the - ``binder'') and the loader. */ - -/* Swap in the ldhdr structure. */ - -static void -xcoff_swap_ldhdr_in (abfd, src, dst) - bfd *abfd; - const struct external_ldhdr *src; - struct internal_ldhdr *dst; -{ - dst->l_version = bfd_get_32 (abfd, src->l_version); - dst->l_nsyms = bfd_get_32 (abfd, src->l_nsyms); - dst->l_nreloc = bfd_get_32 (abfd, src->l_nreloc); - dst->l_istlen = bfd_get_32 (abfd, src->l_istlen); - dst->l_nimpid = bfd_get_32 (abfd, src->l_nimpid); - dst->l_impoff = bfd_get_32 (abfd, src->l_impoff); - dst->l_stlen = bfd_get_32 (abfd, src->l_stlen); - dst->l_stoff = bfd_get_32 (abfd, src->l_stoff); -} - -/* Swap out the ldhdr structure. */ - -static void -xcoff_swap_ldhdr_out (abfd, src, dst) - bfd *abfd; - const struct internal_ldhdr *src; - struct external_ldhdr *dst; -{ - bfd_put_32 (abfd, src->l_version, dst->l_version); - bfd_put_32 (abfd, src->l_nsyms, dst->l_nsyms); - bfd_put_32 (abfd, src->l_nreloc, dst->l_nreloc); - bfd_put_32 (abfd, src->l_istlen, dst->l_istlen); - bfd_put_32 (abfd, src->l_nimpid, dst->l_nimpid); - bfd_put_32 (abfd, src->l_impoff, dst->l_impoff); - bfd_put_32 (abfd, src->l_stlen, dst->l_stlen); - bfd_put_32 (abfd, src->l_stoff, dst->l_stoff); -} - -/* Swap in the ldsym structure. */ - -static void -xcoff_swap_ldsym_in (abfd, src, dst) - bfd *abfd; - const struct external_ldsym *src; - struct internal_ldsym *dst; -{ - if (bfd_get_32 (abfd, src->_l._l_l._l_zeroes) != 0) - memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN); - else - { - dst->_l._l_l._l_zeroes = 0; - dst->_l._l_l._l_offset = bfd_get_32 (abfd, src->_l._l_l._l_offset); - } - dst->l_value = bfd_get_32 (abfd, src->l_value); - dst->l_scnum = bfd_get_16 (abfd, src->l_scnum); - dst->l_smtype = bfd_get_8 (abfd, src->l_smtype); - dst->l_smclas = bfd_get_8 (abfd, src->l_smclas); - dst->l_ifile = bfd_get_32 (abfd, src->l_ifile); - dst->l_parm = bfd_get_32 (abfd, src->l_parm); -} - -/* Swap out the ldsym structure. */ - -static void -xcoff_swap_ldsym_out (abfd, src, dst) - bfd *abfd; - const struct internal_ldsym *src; - struct external_ldsym *dst; -{ - if (src->_l._l_l._l_zeroes != 0) - memcpy (dst->_l._l_name, src->_l._l_name, SYMNMLEN); - else - { - bfd_put_32 (abfd, 0, dst->_l._l_l._l_zeroes); - bfd_put_32 (abfd, src->_l._l_l._l_offset, dst->_l._l_l._l_offset); - } - bfd_put_32 (abfd, src->l_value, dst->l_value); - bfd_put_16 (abfd, src->l_scnum, dst->l_scnum); - bfd_put_8 (abfd, src->l_smtype, dst->l_smtype); - bfd_put_8 (abfd, src->l_smclas, dst->l_smclas); - bfd_put_32 (abfd, src->l_ifile, dst->l_ifile); - bfd_put_32 (abfd, src->l_parm, dst->l_parm); -} - -/* As it happens, we never need to swap in the ldrel structure. */ - -/* Swap out the ldrel structure. */ - -static void -xcoff_swap_ldrel_out (abfd, src, dst) - bfd *abfd; - const struct internal_ldrel *src; - struct external_ldrel *dst; -{ - bfd_put_32 (abfd, src->l_vaddr, dst->l_vaddr); - bfd_put_32 (abfd, src->l_symndx, dst->l_symndx); - bfd_put_16 (abfd, src->l_rtype, dst->l_rtype); - bfd_put_16 (abfd, src->l_rsecnm, dst->l_rsecnm); -} - -/* Routine to create an entry in an XCOFF link hash table. */ - -static struct bfd_hash_entry * -xcoff_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct xcoff_link_hash_entry *ret = (struct xcoff_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct xcoff_link_hash_entry *) NULL) - ret = ((struct xcoff_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct xcoff_link_hash_entry))); - if (ret == (struct xcoff_link_hash_entry *) NULL) - return (struct bfd_hash_entry *) ret; - - /* Call the allocation method of the superclass. */ - ret = ((struct xcoff_link_hash_entry *) - _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, - table, string)); - if (ret != NULL) - { - /* Set local fields. */ - ret->indx = -1; - ret->toc_section = NULL; - ret->u.toc_indx = -1; - ret->descriptor = NULL; - ret->ldsym = NULL; - ret->ldindx = -1; - ret->flags = 0; - ret->smclas = XMC_UA; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Create a XCOFF link hash table. */ - -struct bfd_link_hash_table * -_bfd_xcoff_bfd_link_hash_table_create (abfd) - bfd *abfd; -{ - struct xcoff_link_hash_table *ret; - - ret = ((struct xcoff_link_hash_table *) - bfd_alloc (abfd, sizeof (struct xcoff_link_hash_table))); - if (ret == (struct xcoff_link_hash_table *) NULL) - return (struct bfd_link_hash_table *) NULL; - if (! _bfd_link_hash_table_init (&ret->root, abfd, xcoff_link_hash_newfunc)) - { - bfd_release (abfd, ret); - return (struct bfd_link_hash_table *) NULL; - } - - ret->debug_strtab = _bfd_xcoff_stringtab_init (); - ret->debug_section = NULL; - ret->loader_section = NULL; - ret->ldrel_count = 0; - memset (&ret->ldhdr, 0, sizeof (struct internal_ldhdr)); - ret->linkage_section = NULL; - ret->toc_section = NULL; - ret->descriptor_section = NULL; - ret->imports = NULL; - ret->file_align = 0; - ret->textro = false; - ret->gc = false; - memset (ret->special_sections, 0, sizeof ret->special_sections); - - /* The linker will always generate a full a.out header. We need to - record that fact now, before the sizeof_headers routine could be - called. */ - xcoff_data (abfd)->full_aouthdr = true; - - return &ret->root; -} - -/* Look up an entry in an XCOFF link hash table. */ - -#define xcoff_link_hash_lookup(table, string, create, copy, follow) \ - ((struct xcoff_link_hash_entry *) \ - bfd_link_hash_lookup (&(table)->root, (string), (create), (copy),\ - (follow))) - -/* Traverse an XCOFF link hash table. */ - -#define xcoff_link_hash_traverse(table, func, info) \ - (bfd_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the XCOFF link hash table from the info structure. This is - just a cast. */ - -#define xcoff_hash_table(p) ((struct xcoff_link_hash_table *) ((p)->hash)) - -/* Read internal relocs for an XCOFF csect. This is a wrapper around - _bfd_coff_read_internal_relocs which tries to take advantage of any - relocs which may have been cached for the enclosing section. */ - -static struct internal_reloc * -xcoff_read_internal_relocs (abfd, sec, cache, external_relocs, - require_internal, internal_relocs) - bfd *abfd; - asection *sec; - boolean cache; - bfd_byte *external_relocs; - boolean require_internal; - struct internal_reloc *internal_relocs; -{ - if (coff_section_data (abfd, sec) != NULL - && coff_section_data (abfd, sec)->relocs == NULL - && xcoff_section_data (abfd, sec) != NULL) - { - asection *enclosing; - - enclosing = xcoff_section_data (abfd, sec)->enclosing; - - if (enclosing != NULL - && (coff_section_data (abfd, enclosing) == NULL - || coff_section_data (abfd, enclosing)->relocs == NULL) - && cache - && enclosing->reloc_count > 0) - { - if (_bfd_coff_read_internal_relocs (abfd, enclosing, true, - external_relocs, false, - (struct internal_reloc *) NULL) - == NULL) - return NULL; - } - - if (enclosing != NULL - && coff_section_data (abfd, enclosing) != NULL - && coff_section_data (abfd, enclosing)->relocs != NULL) - { - size_t off; - - off = ((sec->rel_filepos - enclosing->rel_filepos) - / bfd_coff_relsz (abfd)); - if (! require_internal) - return coff_section_data (abfd, enclosing)->relocs + off; - memcpy (internal_relocs, - coff_section_data (abfd, enclosing)->relocs + off, - sec->reloc_count * sizeof (struct internal_reloc)); - return internal_relocs; - } - } - - return _bfd_coff_read_internal_relocs (abfd, sec, cache, external_relocs, - require_internal, internal_relocs); -} - -/* Given an XCOFF BFD, add symbols to the global hash table as - appropriate. */ - -boolean -_bfd_xcoff_bfd_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - switch (bfd_get_format (abfd)) - { - case bfd_object: - return xcoff_link_add_object_symbols (abfd, info); - case bfd_archive: - return (_bfd_generic_link_add_archive_symbols - (abfd, info, xcoff_link_check_archive_element)); - default: - bfd_set_error (bfd_error_wrong_format); - return false; - } -} - -/* Add symbols from an XCOFF object file. */ - -static boolean -xcoff_link_add_object_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - if (! _bfd_coff_get_external_symbols (abfd)) - return false; - if (! xcoff_link_add_symbols (abfd, info)) - return false; - if (! info->keep_memory) - { - if (! _bfd_coff_free_symbols (abfd)) - return false; - } - return true; -} - -/* Check a single archive element to see if we need to include it in - the link. *PNEEDED is set according to whether this element is - needed in the link or not. This is called via - _bfd_generic_link_add_archive_symbols. */ - -static boolean -xcoff_link_check_archive_element (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; -{ - if (! _bfd_coff_get_external_symbols (abfd)) - return false; - - if (! xcoff_link_check_ar_symbols (abfd, info, pneeded)) - return false; - - if (*pneeded) - { - if (! xcoff_link_add_symbols (abfd, info)) - return false; - } - - if (! info->keep_memory || ! *pneeded) - { - if (! _bfd_coff_free_symbols (abfd)) - return false; - } - - return true; -} - -/* Look through the symbols to see if this object file should be - included in the link. */ - -static boolean -xcoff_link_check_ar_symbols (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; -{ - bfd_size_type symesz; - bfd_byte *esym; - bfd_byte *esym_end; - - *pneeded = false; - - symesz = bfd_coff_symesz (abfd); - esym = (bfd_byte *) obj_coff_external_syms (abfd); - esym_end = esym + obj_raw_syment_count (abfd) * symesz; - while (esym < esym_end) - { - struct internal_syment sym; - - bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym); - - if (sym.n_sclass == C_EXT && sym.n_scnum != N_UNDEF) - { - const char *name; - char buf[SYMNMLEN + 1]; - struct bfd_link_hash_entry *h; - - /* This symbol is externally visible, and is defined by this - object file. */ - - name = _bfd_coff_internal_syment_name (abfd, &sym, buf); - if (name == NULL) - return false; - h = bfd_link_hash_lookup (info->hash, name, false, false, true); - - /* We are only interested in symbols that are currently - undefined. If a symbol is currently known to be common, - XCOFF linkers do not bring in an object file which - defines it. We also don't bring in symbols to satisfy - undefined references in shared objects. */ - if (h != (struct bfd_link_hash_entry *) NULL - && h->type == bfd_link_hash_undefined) - { - if (! (*info->callbacks->add_archive_element) (info, abfd, name)) - return false; - *pneeded = true; - return true; - } - } - - esym += (sym.n_numaux + 1) * symesz; - } - - /* We do not need this object file. */ - return true; -} - -/* Returns the index of reloc in RELOCS with the least address greater - than or equal to ADDRESS. The relocs are sorted by address. */ - -static bfd_size_type -xcoff_find_reloc (relocs, count, address) - struct internal_reloc *relocs; - bfd_size_type count; - bfd_vma address; -{ - bfd_size_type min, max, this; - - if (count < 2) - { - if (count == 1 && relocs[0].r_vaddr < address) - return 1; - else - return 0; - } - - min = 0; - max = count; - - /* Do a binary search over (min,max]. */ - while (min + 1 < max) - { - bfd_vma raddr; - - this = (max + min) / 2; - raddr = relocs[this].r_vaddr; - if (raddr > address) - max = this; - else if (raddr < address) - min = this; - else - { - min = this; - break; - } - } - - if (relocs[min].r_vaddr < address) - return min + 1; - - while (min > 0 - && relocs[min - 1].r_vaddr == address) - --min; - - return min; -} - -/* Add all the symbols from an object file to the hash table. - - XCOFF is a weird format. A normal XCOFF .o files will have three - COFF sections--.text, .data, and .bss--but each COFF section will - contain many csects. These csects are described in the symbol - table. From the linker's point of view, each csect must be - considered a section in its own right. For example, a TOC entry is - handled as a small XMC_TC csect. The linker must be able to merge - different TOC entries together, which means that it must be able to - extract the XMC_TC csects from the .data section of the input .o - file. - - From the point of view of our linker, this is, of course, a hideous - nightmare. We cope by actually creating sections for each csect, - and discarding the original sections. We then have to handle the - relocation entries carefully, since the only way to tell which - csect they belong to is to examine the address. */ - -static boolean -xcoff_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - unsigned int n_tmask; - unsigned int n_btshft; - boolean default_copy; - bfd_size_type symcount; - struct xcoff_link_hash_entry **sym_hash; - asection **csect_cache; - bfd_size_type linesz; - asection *o; - asection *last_real; - boolean keep_syms; - asection *csect; - unsigned int csect_index; - asection *first_csect; - bfd_size_type symesz; - bfd_byte *esym; - bfd_byte *esym_end; - struct reloc_info_struct - { - struct internal_reloc *relocs; - asection **csects; - bfd_byte *linenos; - } *reloc_info = NULL; - - if ((abfd->flags & DYNAMIC) != 0 - && ! info->static_link) - { - if (! xcoff_link_add_dynamic_symbols (abfd, info)) - return false; - } - - /* We need to build a .loader section, so we do it here. This won't - work if we're producing an XCOFF output file with no XCOFF input - files. FIXME. */ - if (xcoff_hash_table (info)->loader_section == NULL) - { - asection *lsec; - - lsec = bfd_make_section_anyway (abfd, ".loader"); - if (lsec == NULL) - goto error_return; - xcoff_hash_table (info)->loader_section = lsec; - lsec->flags |= SEC_HAS_CONTENTS | SEC_IN_MEMORY; - } - /* Likewise for the linkage section. */ - if (xcoff_hash_table (info)->linkage_section == NULL) - { - asection *lsec; - - lsec = bfd_make_section_anyway (abfd, ".gl"); - if (lsec == NULL) - goto error_return; - xcoff_hash_table (info)->linkage_section = lsec; - lsec->flags |= SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - lsec->alignment_power = 2; - } - /* Likewise for the TOC section. */ - if (xcoff_hash_table (info)->toc_section == NULL) - { - asection *tsec; - - tsec = bfd_make_section_anyway (abfd, ".tc"); - if (tsec == NULL) - goto error_return; - xcoff_hash_table (info)->toc_section = tsec; - tsec->flags |= SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - tsec->alignment_power = 2; - } - /* Likewise for the descriptor section. */ - if (xcoff_hash_table (info)->descriptor_section == NULL) - { - asection *dsec; - - dsec = bfd_make_section_anyway (abfd, ".ds"); - if (dsec == NULL) - goto error_return; - xcoff_hash_table (info)->descriptor_section = dsec; - dsec->flags |= SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - dsec->alignment_power = 2; - } - /* Likewise for the .debug section. */ - if (xcoff_hash_table (info)->debug_section == NULL) - { - asection *dsec; - - dsec = bfd_make_section_anyway (abfd, ".debug"); - if (dsec == NULL) - goto error_return; - xcoff_hash_table (info)->debug_section = dsec; - dsec->flags |= SEC_HAS_CONTENTS | SEC_IN_MEMORY; - } - - if ((abfd->flags & DYNAMIC) != 0 - && ! info->static_link) - return true; - - n_tmask = coff_data (abfd)->local_n_tmask; - n_btshft = coff_data (abfd)->local_n_btshft; - - /* Define macros so that ISFCN, et. al., macros work correctly. */ -#define N_TMASK n_tmask -#define N_BTSHFT n_btshft - - if (info->keep_memory) - default_copy = false; - else - default_copy = true; - - symcount = obj_raw_syment_count (abfd); - - /* We keep a list of the linker hash table entries that correspond - to each external symbol. */ - sym_hash = ((struct xcoff_link_hash_entry **) - bfd_alloc (abfd, - (symcount - * sizeof (struct xcoff_link_hash_entry *)))); - if (sym_hash == NULL && symcount != 0) - goto error_return; - coff_data (abfd)->sym_hashes = (struct coff_link_hash_entry **) sym_hash; - memset (sym_hash, 0, - (size_t) symcount * sizeof (struct xcoff_link_hash_entry *)); - - /* Because of the weird stuff we are doing with XCOFF csects, we can - not easily determine which section a symbol is in, so we store - the information in the tdata for the input file. */ - csect_cache = ((asection **) - bfd_alloc (abfd, symcount * sizeof (asection *))); - if (csect_cache == NULL && symcount != 0) - goto error_return; - xcoff_data (abfd)->csects = csect_cache; - memset (csect_cache, 0, (size_t) symcount * sizeof (asection *)); - - /* While splitting sections into csects, we need to assign the - relocs correctly. The relocs and the csects must both be in - order by VMA within a given section, so we handle this by - scanning along the relocs as we process the csects. We index - into reloc_info using the section target_index. */ - reloc_info = ((struct reloc_info_struct *) - bfd_malloc ((abfd->section_count + 1) - * sizeof (struct reloc_info_struct))); - if (reloc_info == NULL) - goto error_return; - memset ((PTR) reloc_info, 0, - (abfd->section_count + 1) * sizeof (struct reloc_info_struct)); - - /* Read in the relocs and line numbers for each section. */ - linesz = bfd_coff_linesz (abfd); - last_real = NULL; - for (o = abfd->sections; o != NULL; o = o->next) - { - last_real = o; - if ((o->flags & SEC_RELOC) != 0) - { - reloc_info[o->target_index].relocs = - xcoff_read_internal_relocs (abfd, o, true, (bfd_byte *) NULL, - false, (struct internal_reloc *) NULL); - reloc_info[o->target_index].csects = - (asection **) bfd_malloc (o->reloc_count * sizeof (asection *)); - if (reloc_info[o->target_index].csects == NULL) - goto error_return; - memset (reloc_info[o->target_index].csects, 0, - o->reloc_count * sizeof (asection *)); - } - - if ((info->strip == strip_none || info->strip == strip_some) - && o->lineno_count > 0) - { - bfd_byte *linenos; - - linenos = (bfd_byte *) bfd_malloc (o->lineno_count * linesz); - if (linenos == NULL) - goto error_return; - reloc_info[o->target_index].linenos = linenos; - if (bfd_seek (abfd, o->line_filepos, SEEK_SET) != 0 - || (bfd_read (linenos, linesz, o->lineno_count, abfd) - != linesz * o->lineno_count)) - goto error_return; - } - } - - /* Don't let the linker relocation routines discard the symbols. */ - keep_syms = obj_coff_keep_syms (abfd); - obj_coff_keep_syms (abfd) = true; - - csect = NULL; - csect_index = 0; - first_csect = NULL; - - symesz = bfd_coff_symesz (abfd); - BFD_ASSERT (symesz == bfd_coff_auxesz (abfd)); - esym = (bfd_byte *) obj_coff_external_syms (abfd); - esym_end = esym + symcount * symesz; - while (esym < esym_end) - { - struct internal_syment sym; - union internal_auxent aux; - const char *name; - char buf[SYMNMLEN + 1]; - int smtyp; - flagword flags; - asection *section; - bfd_vma value; - struct xcoff_link_hash_entry *set_toc; - - bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym); - - /* In this pass we are only interested in symbols with csect - information. */ - if (sym.n_sclass != C_EXT && sym.n_sclass != C_HIDEXT) - { - if (sym.n_sclass == C_FILE && csect != NULL) - { - xcoff_section_data (abfd, csect)->last_symndx = - ((esym - - (bfd_byte *) obj_coff_external_syms (abfd)) - / symesz); - csect = NULL; - } - - if (csect != NULL) - *csect_cache = csect; - else if (first_csect == NULL || sym.n_sclass == C_FILE) - *csect_cache = coff_section_from_bfd_index (abfd, sym.n_scnum); - else - *csect_cache = NULL; - esym += (sym.n_numaux + 1) * symesz; - sym_hash += sym.n_numaux + 1; - csect_cache += sym.n_numaux + 1; - continue; - } - - name = _bfd_coff_internal_syment_name (abfd, &sym, buf); - if (name == NULL) - goto error_return; - - /* If this symbol has line number information attached to it, - and we're not stripping it, count the number of entries and - add them to the count for this csect. In the final link pass - we are going to attach line number information by symbol, - rather than by section, in order to more easily handle - garbage collection. */ - if ((info->strip == strip_none || info->strip == strip_some) - && sym.n_numaux > 1 - && csect != NULL - && ISFCN (sym.n_type)) - { - union internal_auxent auxlin; - - bfd_coff_swap_aux_in (abfd, (PTR) (esym + symesz), - sym.n_type, sym.n_sclass, - 0, sym.n_numaux, (PTR) &auxlin); - if (auxlin.x_sym.x_fcnary.x_fcn.x_lnnoptr != 0) - { - asection *enclosing; - bfd_size_type linoff; - - enclosing = xcoff_section_data (abfd, csect)->enclosing; - if (enclosing == NULL) - { - (*_bfd_error_handler) - ("%s: `%s' has line numbers but no enclosing section", - bfd_get_filename (abfd), name); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - linoff = (auxlin.x_sym.x_fcnary.x_fcn.x_lnnoptr - - enclosing->line_filepos); - if (linoff < enclosing->lineno_count * linesz) - { - struct internal_lineno lin; - bfd_byte *linpstart; - - linpstart = (reloc_info[enclosing->target_index].linenos - + linoff); - bfd_coff_swap_lineno_in (abfd, (PTR) linpstart, (PTR) &lin); - if (lin.l_lnno == 0 - && ((bfd_size_type) lin.l_addr.l_symndx - == ((esym - - (bfd_byte *) obj_coff_external_syms (abfd)) - / symesz))) - { - bfd_byte *linpend, *linp; - - linpend = (reloc_info[enclosing->target_index].linenos - + enclosing->lineno_count * linesz); - for (linp = linpstart + linesz; - linp < linpend; - linp += linesz) - { - bfd_coff_swap_lineno_in (abfd, (PTR) linp, - (PTR) &lin); - if (lin.l_lnno == 0) - break; - } - csect->lineno_count += (linp - linpstart) / linesz; - /* The setting of line_filepos will only be - useful if all the line number entries for a - csect are contiguous; this only matters for - error reporting. */ - if (csect->line_filepos == 0) - csect->line_filepos = - auxlin.x_sym.x_fcnary.x_fcn.x_lnnoptr; - } - } - } - } - - /* Pick up the csect auxiliary information. */ - - if (sym.n_numaux == 0) - { - (*_bfd_error_handler) - ("%s: class %d symbol `%s' has no aux entries", - bfd_get_filename (abfd), sym.n_sclass, name); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - bfd_coff_swap_aux_in (abfd, - (PTR) (esym + symesz * sym.n_numaux), - sym.n_type, sym.n_sclass, - sym.n_numaux - 1, sym.n_numaux, - (PTR) &aux); - - smtyp = SMTYP_SMTYP (aux.x_csect.x_smtyp); - - flags = BSF_GLOBAL; - section = NULL; - value = 0; - set_toc = NULL; - - switch (smtyp) - { - default: - (*_bfd_error_handler) - ("%s: symbol `%s' has unrecognized csect type %d", - bfd_get_filename (abfd), name, smtyp); - bfd_set_error (bfd_error_bad_value); - goto error_return; - - case XTY_ER: - /* This is an external reference. */ - if (sym.n_sclass == C_HIDEXT - || sym.n_scnum != N_UNDEF - || aux.x_csect.x_scnlen.l != 0) - { - (*_bfd_error_handler) - ("%s: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d", - bfd_get_filename (abfd), name, sym.n_sclass, sym.n_scnum, - aux.x_csect.x_scnlen.l); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - /* An XMC_XO external reference is actually a reference to - an absolute location. */ - if (aux.x_csect.x_smclas != XMC_XO) - section = bfd_und_section_ptr; - else - { - section = bfd_abs_section_ptr; - value = sym.n_value; - } - break; - - case XTY_SD: - /* This is a csect definition. */ - - if (csect != NULL) - { - xcoff_section_data (abfd, csect)->last_symndx = - ((esym - - (bfd_byte *) obj_coff_external_syms (abfd)) - / symesz); - } - - csect = NULL; - csect_index = -1; - - /* When we see a TOC anchor, we record the TOC value. */ - if (aux.x_csect.x_smclas == XMC_TC0) - { - if (sym.n_sclass != C_HIDEXT - || aux.x_csect.x_scnlen.l != 0) - { - (*_bfd_error_handler) - ("%s: XMC_TC0 symbol `%s' is class %d scnlen %d", - bfd_get_filename (abfd), name, sym.n_sclass, - aux.x_csect.x_scnlen.l); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - xcoff_data (abfd)->toc = sym.n_value; - } - - /* We must merge TOC entries for the same symbol. We can - merge two TOC entries if they are both C_HIDEXT, they - both have the same name, they are both 4 bytes long, and - they both have a relocation table entry for an external - symbol with the same name. Unfortunately, this means - that we must look through the relocations. Ick. */ - if (aux.x_csect.x_smclas == XMC_TC - && sym.n_sclass == C_HIDEXT - && aux.x_csect.x_scnlen.l == 4 - && info->hash->creator == abfd->xvec) - { - asection *enclosing; - struct internal_reloc *relocs; - bfd_size_type relindx; - struct internal_reloc *rel; - - enclosing = coff_section_from_bfd_index (abfd, sym.n_scnum); - if (enclosing == NULL) - goto error_return; - - relocs = reloc_info[enclosing->target_index].relocs; - relindx = xcoff_find_reloc (relocs, enclosing->reloc_count, - sym.n_value); - rel = relocs + relindx; - if (relindx < enclosing->reloc_count - && rel->r_vaddr == (bfd_vma) sym.n_value - && rel->r_size == 31 - && rel->r_type == R_POS) - { - bfd_byte *erelsym; - struct internal_syment relsym; - - erelsym = ((bfd_byte *) obj_coff_external_syms (abfd) - + rel->r_symndx * symesz); - bfd_coff_swap_sym_in (abfd, (PTR) erelsym, (PTR) &relsym); - if (relsym.n_sclass == C_EXT) - { - const char *relname; - char relbuf[SYMNMLEN + 1]; - boolean copy; - struct xcoff_link_hash_entry *h; - - /* At this point we know that the TOC entry is - for an externally visible symbol. */ - relname = _bfd_coff_internal_syment_name (abfd, &relsym, - relbuf); - if (relname == NULL) - goto error_return; - - /* We only merge TOC entries if the TC name is - the same as the symbol name. This handles - the normal case, but not common cases like - SYM.P4 which gcc generates to store SYM + 4 - in the TOC. FIXME. */ - if (strcmp (name, relname) == 0) - { - copy = (! info->keep_memory - || relsym._n._n_n._n_zeroes != 0 - || relsym._n._n_n._n_offset == 0); - h = xcoff_link_hash_lookup (xcoff_hash_table (info), - relname, true, copy, - false); - if (h == NULL) - goto error_return; - - /* At this point h->root.type could be - bfd_link_hash_new. That should be OK, - since we know for sure that we will come - across this symbol as we step through the - file. */ - - /* We store h in *sym_hash for the - convenience of the relocate_section - function. */ - *sym_hash = h; - - if (h->toc_section != NULL) - { - asection **rel_csects; - - /* We already have a TOC entry for this - symbol, so we can just ignore this - one. */ - rel_csects = - reloc_info[enclosing->target_index].csects; - rel_csects[relindx] = bfd_und_section_ptr; - break; - } - - /* We are about to create a TOC entry for - this symbol. */ - set_toc = h; - } - } - } - } - - /* We need to create a new section. We get the name from - the csect storage mapping class, so that the linker can - accumulate similar csects together. */ - { - static const char *csect_name_by_class[] = - { - ".pr", ".ro", ".db", ".tc", ".ua", ".rw", ".gl", ".xo", - ".sv", ".bs", ".ds", ".uc", ".ti", ".tb", NULL, ".tc0", - ".td" - }; - const char *csect_name; - asection *enclosing; - - if ((aux.x_csect.x_smclas >= - sizeof csect_name_by_class / sizeof csect_name_by_class[0]) - || csect_name_by_class[aux.x_csect.x_smclas] == NULL) - { - (*_bfd_error_handler) - ("%s: symbol `%s' has unrecognized smclas %d", - bfd_get_filename (abfd), name, aux.x_csect.x_smclas); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - csect_name = csect_name_by_class[aux.x_csect.x_smclas]; - csect = bfd_make_section_anyway (abfd, csect_name); - if (csect == NULL) - goto error_return; - enclosing = coff_section_from_bfd_index (abfd, sym.n_scnum); - if (enclosing == NULL) - goto error_return; - if (! bfd_is_abs_section (enclosing) - && ((bfd_vma) sym.n_value < enclosing->vma - || ((bfd_vma) sym.n_value + aux.x_csect.x_scnlen.l - > enclosing->vma + enclosing->_raw_size))) - { - (*_bfd_error_handler) - ("%s: csect `%s' not in enclosing section", - bfd_get_filename (abfd), name); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - csect->vma = sym.n_value; - csect->filepos = (enclosing->filepos - + sym.n_value - - enclosing->vma); - csect->_raw_size = aux.x_csect.x_scnlen.l; - csect->flags |= SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS; - csect->alignment_power = SMTYP_ALIGN (aux.x_csect.x_smtyp); - - /* Record the enclosing section in the tdata for this new - section. */ - csect->used_by_bfd = - ((struct coff_section_tdata *) - bfd_zalloc (abfd, sizeof (struct coff_section_tdata))); - if (csect->used_by_bfd == NULL) - goto error_return; - coff_section_data (abfd, csect)->tdata = - bfd_zalloc (abfd, sizeof (struct xcoff_section_tdata)); - if (coff_section_data (abfd, csect)->tdata == NULL) - goto error_return; - xcoff_section_data (abfd, csect)->enclosing = enclosing; - xcoff_section_data (abfd, csect)->lineno_count = - enclosing->lineno_count; - - if (enclosing->owner == abfd) - { - struct internal_reloc *relocs; - bfd_size_type relindx; - struct internal_reloc *rel; - asection **rel_csect; - - relocs = reloc_info[enclosing->target_index].relocs; - relindx = xcoff_find_reloc (relocs, enclosing->reloc_count, - csect->vma); - rel = relocs + relindx; - rel_csect = (reloc_info[enclosing->target_index].csects - + relindx); - csect->rel_filepos = (enclosing->rel_filepos - + relindx * bfd_coff_relsz (abfd)); - while (relindx < enclosing->reloc_count - && *rel_csect == NULL - && rel->r_vaddr < csect->vma + csect->_raw_size) - { - *rel_csect = csect; - csect->flags |= SEC_RELOC; - ++csect->reloc_count; - ++relindx; - ++rel; - ++rel_csect; - } - } - - /* There are a number of other fields and section flags - which we do not bother to set. */ - - csect_index = ((esym - - (bfd_byte *) obj_coff_external_syms (abfd)) - / symesz); - - xcoff_section_data (abfd, csect)->first_symndx = csect_index; - - if (first_csect == NULL) - first_csect = csect; - - /* If this symbol is C_EXT, we treat it as starting at the - beginning of the newly created section. */ - if (sym.n_sclass == C_EXT) - { - section = csect; - value = 0; - } - - /* If this is a TOC section for a symbol, record it. */ - if (set_toc != NULL) - set_toc->toc_section = csect; - } - break; - - case XTY_LD: - /* This is a label definition. The x_scnlen field is the - symbol index of the csect. I believe that this must - always follow the appropriate XTY_SD symbol, so I will - insist on it. */ - { - boolean bad; - - bad = false; - if (aux.x_csect.x_scnlen.l < 0 - || (aux.x_csect.x_scnlen.l - >= esym - (bfd_byte *) obj_coff_external_syms (abfd))) - bad = true; - if (! bad) - { - section = xcoff_data (abfd)->csects[aux.x_csect.x_scnlen.l]; - if (section == NULL - || (section->flags & SEC_HAS_CONTENTS) == 0) - bad = true; - } - if (bad) - { - (*_bfd_error_handler) - ("%s: misplaced XTY_LD `%s'", - bfd_get_filename (abfd), name); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - value = sym.n_value - csect->vma; - } - break; - - case XTY_CM: - /* This is an unitialized csect. We could base the name on - the storage mapping class, but we don't bother. If this - csect is externally visible, it is a common symbol. */ - - if (csect != NULL) - { - xcoff_section_data (abfd, csect)->last_symndx = - ((esym - - (bfd_byte *) obj_coff_external_syms (abfd)) - / symesz); - } - - csect = bfd_make_section_anyway (abfd, ".bss"); - if (csect == NULL) - goto error_return; - csect->vma = sym.n_value; - csect->_raw_size = aux.x_csect.x_scnlen.l; - csect->flags |= SEC_ALLOC; - csect->alignment_power = SMTYP_ALIGN (aux.x_csect.x_smtyp); - /* There are a number of other fields and section flags - which we do not bother to set. */ - - csect_index = ((esym - - (bfd_byte *) obj_coff_external_syms (abfd)) - / symesz); - - csect->used_by_bfd = - ((struct coff_section_tdata *) - bfd_zalloc (abfd, sizeof (struct coff_section_tdata))); - if (csect->used_by_bfd == NULL) - goto error_return; - coff_section_data (abfd, csect)->tdata = - bfd_zalloc (abfd, sizeof (struct xcoff_section_tdata)); - if (coff_section_data (abfd, csect)->tdata == NULL) - goto error_return; - xcoff_section_data (abfd, csect)->first_symndx = csect_index; - - if (first_csect == NULL) - first_csect = csect; - - if (sym.n_sclass == C_EXT) - { - csect->flags |= SEC_IS_COMMON; - csect->_raw_size = 0; - section = csect; - value = aux.x_csect.x_scnlen.l; - } - - break; - } - - /* Check for magic symbol names. */ - if ((smtyp == XTY_SD || smtyp == XTY_CM) - && aux.x_csect.x_smclas != XMC_TC) - { - int i; - - i = -1; - if (name[0] == '_') - { - if (strcmp (name, "_text") == 0) - i = 0; - else if (strcmp (name, "_etext") == 0) - i = 1; - else if (strcmp (name, "_data") == 0) - i = 2; - else if (strcmp (name, "_edata") == 0) - i = 3; - else if (strcmp (name, "_end") == 0) - i = 4; - } - else if (name[0] == 'e' && strcmp (name, "end") == 0) - i = 5; - - if (i != -1) - xcoff_hash_table (info)->special_sections[i] = csect; - } - - /* Now we have enough information to add the symbol to the - linker hash table. */ - - if (sym.n_sclass == C_EXT) - { - boolean copy; - - BFD_ASSERT (section != NULL); - - /* We must copy the name into memory if we got it from the - syment itself, rather than the string table. */ - copy = default_copy; - if (sym._n._n_n._n_zeroes != 0 - || sym._n._n_n._n_offset == 0) - copy = true; - - if (info->hash->creator == abfd->xvec) - { - /* If we are statically linking a shared object, it is - OK for symbol redefinitions to occur. I can't figure - out just what the XCOFF linker is doing, but - something like this is required for -bnso to work. */ - if (! bfd_is_und_section (section)) - *sym_hash = xcoff_link_hash_lookup (xcoff_hash_table (info), - name, true, copy, false); - else - *sym_hash = ((struct xcoff_link_hash_entry *) - bfd_wrapped_link_hash_lookup (abfd, info, name, - true, copy, false)); - if (*sym_hash == NULL) - goto error_return; - if (((*sym_hash)->root.type == bfd_link_hash_defined - || (*sym_hash)->root.type == bfd_link_hash_defweak) - && ! bfd_is_und_section (section) - && ! bfd_is_com_section (section)) - { - if ((abfd->flags & DYNAMIC) != 0) - { - section = bfd_und_section_ptr; - value = 0; - } - else if (((*sym_hash)->root.u.def.section->owner->flags - & DYNAMIC) != 0) - { - (*sym_hash)->root.type = bfd_link_hash_undefined; - (*sym_hash)->root.u.undef.abfd = - (*sym_hash)->root.u.def.section->owner; - } - } - } - - /* _bfd_generic_link_add_one_symbol may call the linker to - generate an error message, and the linker may try to read - the symbol table to give a good error. Right now, the - line numbers are in an inconsistent state, since they are - counted both in the real sections and in the new csects. - We need to leave the count in the real sections so that - the linker can report the line number of the error - correctly, so temporarily clobber the link to the csects - so that the linker will not try to read the line numbers - a second time from the csects. */ - BFD_ASSERT (last_real->next == first_csect); - last_real->next = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, name, flags, section, value, - (const char *) NULL, copy, true, - (struct bfd_link_hash_entry **) sym_hash))) - goto error_return; - last_real->next = first_csect; - - if (smtyp == XTY_CM) - { - if ((*sym_hash)->root.type != bfd_link_hash_common - || (*sym_hash)->root.u.c.p->section != csect) - { - /* We don't need the common csect we just created. */ - csect->_raw_size = 0; - } - else - { - (*sym_hash)->root.u.c.p->alignment_power - = csect->alignment_power; - } - } - - if (info->hash->creator == abfd->xvec) - { - int flag; - - if (smtyp == XTY_ER || smtyp == XTY_CM) - flag = XCOFF_REF_REGULAR; - else - flag = XCOFF_DEF_REGULAR; - (*sym_hash)->flags |= flag; - - if ((*sym_hash)->smclas == XMC_UA - || flag == XCOFF_DEF_REGULAR) - (*sym_hash)->smclas = aux.x_csect.x_smclas; - } - } - - *csect_cache = csect; - - esym += (sym.n_numaux + 1) * symesz; - sym_hash += sym.n_numaux + 1; - csect_cache += sym.n_numaux + 1; - } - - BFD_ASSERT (last_real == NULL || last_real->next == first_csect); - - /* Make sure that we have seen all the relocs. */ - for (o = abfd->sections; o != first_csect; o = o->next) - { - /* Reset the section size and the line numebr count, since the - data is now attached to the csects. Don't reset the size of - the .debug section, since we need to read it below in - bfd_xcoff_size_dynamic_sections. */ - if (strcmp (bfd_get_section_name (abfd, o), ".debug") != 0) - o->_raw_size = 0; - o->lineno_count = 0; - - if ((o->flags & SEC_RELOC) != 0) - { - bfd_size_type i; - struct internal_reloc *rel; - asection **rel_csect; - - rel = reloc_info[o->target_index].relocs; - rel_csect = reloc_info[o->target_index].csects; - for (i = 0; i < o->reloc_count; i++, rel++, rel_csect++) - { - if (*rel_csect == NULL) - { - (*_bfd_error_handler) - ("%s: reloc %s:%d not in csect", - bfd_get_filename (abfd), o->name, i); - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - /* We identify all symbols which are called, so that we - can create glue code for calls to functions imported - from dynamic objects. */ - if (info->hash->creator == abfd->xvec - && *rel_csect != bfd_und_section_ptr - && (rel->r_type == R_BR - || rel->r_type == R_RBR) - && obj_xcoff_sym_hashes (abfd)[rel->r_symndx] != NULL) - { - struct xcoff_link_hash_entry *h; - - h = obj_xcoff_sym_hashes (abfd)[rel->r_symndx]; - h->flags |= XCOFF_CALLED; - /* If the symbol name starts with a period, it is - the code of a function. If the symbol is - currently undefined, then add an undefined symbol - for the function descriptor. This should do no - harm, because any regular object that defines the - function should also define the function - descriptor. It helps, because it means that we - will identify the function descriptor with a - dynamic object if a dynamic object defines it. */ - if (h->root.root.string[0] == '.' - && h->descriptor == NULL) - { - struct xcoff_link_hash_entry *hds; - - hds = xcoff_link_hash_lookup (xcoff_hash_table (info), - h->root.root.string + 1, - true, false, true); - if (hds == NULL) - goto error_return; - if (hds->root.type == bfd_link_hash_new) - { - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, hds->root.root.string, - (flagword) 0, bfd_und_section_ptr, - (bfd_vma) 0, (const char *) NULL, false, - true, - (struct bfd_link_hash_entry **) &hds))) - goto error_return; - } - hds->flags |= XCOFF_DESCRIPTOR; - BFD_ASSERT ((hds->flags & XCOFF_CALLED) == 0 - && (h->flags & XCOFF_DESCRIPTOR) == 0); - hds->descriptor = h; - h->descriptor = hds; - } - } - } - - free (reloc_info[o->target_index].csects); - reloc_info[o->target_index].csects = NULL; - - /* Reset SEC_RELOC and the reloc_count, since the reloc - information is now attached to the csects. */ - o->flags &=~ SEC_RELOC; - o->reloc_count = 0; - - /* If we are not keeping memory, free the reloc information. */ - if (! info->keep_memory - && coff_section_data (abfd, o) != NULL - && coff_section_data (abfd, o)->relocs != NULL - && ! coff_section_data (abfd, o)->keep_relocs) - { - free (coff_section_data (abfd, o)->relocs); - coff_section_data (abfd, o)->relocs = NULL; - } - } - - /* Free up the line numbers. FIXME: We could cache these - somewhere for the final link, to avoid reading them again. */ - if (reloc_info[o->target_index].linenos != NULL) - { - free (reloc_info[o->target_index].linenos); - reloc_info[o->target_index].linenos = NULL; - } - } - - free (reloc_info); - - obj_coff_keep_syms (abfd) = keep_syms; - - return true; - - error_return: - if (reloc_info != NULL) - { - for (o = abfd->sections; o != NULL; o = o->next) - { - if (reloc_info[o->target_index].csects != NULL) - free (reloc_info[o->target_index].csects); - if (reloc_info[o->target_index].linenos != NULL) - free (reloc_info[o->target_index].linenos); - } - free (reloc_info); - } - obj_coff_keep_syms (abfd) = keep_syms; - return false; -} - -#undef N_TMASK -#undef N_BTSHFT - -/* This function is used to add symbols from a dynamic object to the - global symbol table. */ - -static boolean -xcoff_link_add_dynamic_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - asection *lsec; - bfd_byte *buf = NULL; - struct internal_ldhdr ldhdr; - const char *strings; - struct external_ldsym *elsym, *elsymend; - struct xcoff_import_file *n; - const char *bname; - const char *mname; - const char *s; - unsigned int c; - struct xcoff_import_file **pp; - - /* We can only handle a dynamic object if we are generating an XCOFF - output file. */ - if (info->hash->creator != abfd->xvec) - { - (*_bfd_error_handler) - ("%s: XCOFF shared object when not producing XCOFF output", - bfd_get_filename (abfd)); - bfd_set_error (bfd_error_invalid_operation); - goto error_return; - } - - /* The symbols we use from a dynamic object are not the symbols in - the normal symbol table, but, rather, the symbols in the export - table. If there is a global symbol in a dynamic object which is - not in the export table, the loader will not be able to find it, - so we don't want to find it either. Also, on AIX 4.1.3, shr.o in - libc.a has symbols in the export table which are not in the - symbol table. */ - - /* Read in the .loader section. FIXME: We should really use the - o_snloader field in the a.out header, rather than grabbing the - section by name. */ - lsec = bfd_get_section_by_name (abfd, ".loader"); - if (lsec == NULL) - { - (*_bfd_error_handler) - ("%s: dynamic object with no .loader section", - bfd_get_filename (abfd)); - bfd_set_error (bfd_error_no_symbols); - goto error_return; - } - - buf = (bfd_byte *) bfd_malloc (lsec->_raw_size); - if (buf == NULL && lsec->_raw_size > 0) - goto error_return; - - if (! bfd_get_section_contents (abfd, lsec, (PTR) buf, (file_ptr) 0, - lsec->_raw_size)) - goto error_return; - - /* Remove the sections from this object, so that they do not get - included in the link. */ - abfd->sections = NULL; - - xcoff_swap_ldhdr_in (abfd, (struct external_ldhdr *) buf, &ldhdr); - - strings = (char *) buf + ldhdr.l_stoff; - - elsym = (struct external_ldsym *) (buf + LDHDRSZ); - elsymend = elsym + ldhdr.l_nsyms; - BFD_ASSERT (sizeof (struct external_ldsym) == LDSYMSZ); - for (; elsym < elsymend; elsym++) - { - struct internal_ldsym ldsym; - char nambuf[SYMNMLEN + 1]; - const char *name; - struct xcoff_link_hash_entry *h; - - xcoff_swap_ldsym_in (abfd, elsym, &ldsym); - - /* We are only interested in exported symbols. */ - if ((ldsym.l_smtype & L_EXPORT) == 0) - continue; - - if (ldsym._l._l_l._l_zeroes == 0) - name = strings + ldsym._l._l_l._l_offset; - else - { - memcpy (nambuf, ldsym._l._l_name, SYMNMLEN); - nambuf[SYMNMLEN] = '\0'; - name = nambuf; - } - - /* Normally we could not call xcoff_link_hash_lookup in an add - symbols routine, since we might not be using an XCOFF hash - table. However, we verified above that we are using an XCOFF - hash table. */ - - h = xcoff_link_hash_lookup (xcoff_hash_table (info), name, true, - true, true); - if (h == NULL) - goto error_return; - - h->flags |= XCOFF_DEF_DYNAMIC; - - /* If the symbol is undefined, and the BFD it was found in is - not a dynamic object, change the BFD to this dynamic object, - so that we can get the correct import file ID. */ - if ((h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - && (h->root.u.undef.abfd == NULL - || (h->root.u.undef.abfd->flags & DYNAMIC) == 0)) - h->root.u.undef.abfd = abfd; - - if (h->root.type == bfd_link_hash_new) - { - h->root.type = bfd_link_hash_undefined; - h->root.u.undef.abfd = abfd; - /* We do not want to add this to the undefined symbol list. */ - } - - if (h->smclas == XMC_UA - || h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - h->smclas = ldsym.l_smclas; - - /* Unless this is an XMC_XO symbol, we don't bother to actually - define it, since we don't have a section to put it in anyhow. - Instead, the relocation routines handle the DEF_DYNAMIC flag - correctly. */ - - if (h->smclas == XMC_XO - && (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak)) - { - /* This symbol has an absolute value. */ - h->root.type = bfd_link_hash_defined; - h->root.u.def.section = bfd_abs_section_ptr; - h->root.u.def.value = ldsym.l_value; - } - } - - if (buf != NULL) - { - free (buf); - buf = NULL; - } - - /* Record this file in the import files. */ - - n = ((struct xcoff_import_file *) - bfd_alloc (abfd, sizeof (struct xcoff_import_file))); - if (n == NULL) - goto error_return; - n->next = NULL; - - /* For some reason, the path entry in the import file list for a - shared object appears to always be empty. The file name is the - base name. */ - n->path = ""; - if (abfd->my_archive == NULL) - { - bname = bfd_get_filename (abfd); - mname = ""; - } - else - { - bname = bfd_get_filename (abfd->my_archive); - mname = bfd_get_filename (abfd); - } - s = strrchr (bname, '/'); - if (s != NULL) - bname = s + 1; - n->file = bname; - n->member = mname; - - /* We start c at 1 because the first import file number is reserved - for LIBPATH. */ - for (pp = &xcoff_hash_table (info)->imports, c = 1; - *pp != NULL; - pp = &(*pp)->next, ++c) - ; - *pp = n; - - xcoff_data (abfd)->import_file_id = c; - - return true; - - error_return: - if (buf != NULL) - free (buf); - return false; -} - -/* Routines that are called after all the input files have been - handled, but before the sections are laid out in memory. */ - -/* Mark a symbol as not being garbage, including the section in which - it is defined. */ - -static INLINE boolean -xcoff_mark_symbol (info, h) - struct bfd_link_info *info; - struct xcoff_link_hash_entry *h; -{ - if ((h->flags & XCOFF_MARK) != 0) - return true; - - h->flags |= XCOFF_MARK; - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - asection *hsec; - - hsec = h->root.u.def.section; - if ((hsec->flags & SEC_MARK) == 0) - { - if (! xcoff_mark (info, hsec)) - return false; - } - } - - if (h->toc_section != NULL - && (h->toc_section->flags & SEC_MARK) == 0) - { - if (! xcoff_mark (info, h->toc_section)) - return false; - } - - return true; -} - -/* The mark phase of garbage collection. For a given section, mark - it, and all the sections which define symbols to which it refers. - Because this function needs to look at the relocs, we also count - the number of relocs which need to be copied into the .loader - section. */ - -static boolean -xcoff_mark (info, sec) - struct bfd_link_info *info; - asection *sec; -{ - if ((sec->flags & SEC_MARK) != 0) - return true; - - sec->flags |= SEC_MARK; - - if (sec->owner->xvec == info->hash->creator - && coff_section_data (sec->owner, sec) != NULL - && xcoff_section_data (sec->owner, sec) != NULL) - { - register struct xcoff_link_hash_entry **hp, **hpend; - struct internal_reloc *rel, *relend; - - /* Mark all the symbols in this section. */ - - hp = (obj_xcoff_sym_hashes (sec->owner) - + xcoff_section_data (sec->owner, sec)->first_symndx); - hpend = (obj_xcoff_sym_hashes (sec->owner) - + xcoff_section_data (sec->owner, sec)->last_symndx); - for (; hp < hpend; hp++) - { - register struct xcoff_link_hash_entry *h; - - h = *hp; - if (h != NULL - && (h->flags & XCOFF_MARK) == 0) - { - if (! xcoff_mark_symbol (info, h)) - return false; - } - } - - /* Look through the section relocs. */ - - if ((sec->flags & SEC_RELOC) != 0 - && sec->reloc_count > 0) - { - rel = xcoff_read_internal_relocs (sec->owner, sec, true, - (bfd_byte *) NULL, false, - (struct internal_reloc *) NULL); - if (rel == NULL) - return false; - relend = rel + sec->reloc_count; - for (; rel < relend; rel++) - { - asection *rsec; - struct xcoff_link_hash_entry *h; - - if ((unsigned int) rel->r_symndx - > obj_raw_syment_count (sec->owner)) - continue; - - h = obj_xcoff_sym_hashes (sec->owner)[rel->r_symndx]; - if (h != NULL - && (h->flags & XCOFF_MARK) == 0) - { - if (! xcoff_mark_symbol (info, h)) - return false; - } - - rsec = xcoff_data (sec->owner)->csects[rel->r_symndx]; - if (rsec != NULL - && (rsec->flags & SEC_MARK) == 0) - { - if (! xcoff_mark (info, rsec)) - return false; - } - - /* See if this reloc needs to be copied into the .loader - section. */ - switch (rel->r_type) - { - default: - if (h == NULL - || h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak - || h->root.type == bfd_link_hash_common - || ((h->flags & XCOFF_CALLED) != 0 - && (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - && h->root.root.string[0] == '.' - && h->descriptor != NULL - && ((h->descriptor->flags & XCOFF_DEF_DYNAMIC) != 0 - || info->shared - || ((h->descriptor->flags & XCOFF_IMPORT) != 0 - && (h->descriptor->flags - & XCOFF_DEF_REGULAR) == 0)))) - break; - /* Fall through. */ - case R_POS: - case R_NEG: - case R_RL: - case R_RLA: - ++xcoff_hash_table (info)->ldrel_count; - if (h != NULL) - h->flags |= XCOFF_LDREL; - break; - case R_TOC: - case R_GL: - case R_TCL: - case R_TRL: - case R_TRLA: - /* We should never need a .loader reloc for a TOC - relative reloc. */ - break; - } - } - - if (! info->keep_memory - && coff_section_data (sec->owner, sec) != NULL - && coff_section_data (sec->owner, sec)->relocs != NULL - && ! coff_section_data (sec->owner, sec)->keep_relocs) - { - free (coff_section_data (sec->owner, sec)->relocs); - coff_section_data (sec->owner, sec)->relocs = NULL; - } - } - } - - return true; -} - -/* The sweep phase of garbage collection. Remove all garbage - sections. */ - -static void -xcoff_sweep (info) - struct bfd_link_info *info; -{ - bfd *sub; - - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - asection *o; - - for (o = sub->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_MARK) == 0) - { - /* Keep all sections from non-XCOFF input files. Keep - special sections. Keep .debug sections for the - moment. */ - if (sub->xvec != info->hash->creator - || o == xcoff_hash_table (info)->debug_section - || o == xcoff_hash_table (info)->loader_section - || o == xcoff_hash_table (info)->linkage_section - || o == xcoff_hash_table (info)->toc_section - || o == xcoff_hash_table (info)->descriptor_section - || strcmp (o->name, ".debug") == 0) - o->flags |= SEC_MARK; - else - { - o->_raw_size = 0; - o->reloc_count = 0; - o->lineno_count = 0; - } - } - } - } -} - -/* Record the number of elements in a set. This is used to output the - correct csect length. */ - -boolean -bfd_xcoff_link_record_set (output_bfd, info, harg, size) - bfd *output_bfd; - struct bfd_link_info *info; - struct bfd_link_hash_entry *harg; - bfd_size_type size; -{ - struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg; - struct xcoff_link_size_list *n; - - if (! XCOFF_XVECP (output_bfd->xvec)) - return true; - - /* This will hardly ever be called. I don't want to burn four bytes - per global symbol, so instead the size is kept on a linked list - attached to the hash table. */ - - n = ((struct xcoff_link_size_list *) - bfd_alloc (output_bfd, sizeof (struct xcoff_link_size_list))); - if (n == NULL) - return false; - n->next = xcoff_hash_table (info)->size_list; - n->h = h; - n->size = size; - xcoff_hash_table (info)->size_list = n; - - h->flags |= XCOFF_HAS_SIZE; - - return true; -} - -/* Import a symbol. */ - -boolean -bfd_xcoff_import_symbol (output_bfd, info, harg, val, imppath, impfile, - impmember) - bfd *output_bfd; - struct bfd_link_info *info; - struct bfd_link_hash_entry *harg; - bfd_vma val; - const char *imppath; - const char *impfile; - const char *impmember; -{ - struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg; - - if (! XCOFF_XVECP (output_bfd->xvec)) - return true; - - h->flags |= XCOFF_IMPORT; - - if (val != (bfd_vma) -1) - { - if (h->root.type == bfd_link_hash_defined - && (! bfd_is_abs_section (h->root.u.def.section) - || h->root.u.def.value != val)) - { - if (! ((*info->callbacks->multiple_definition) - (info, h->root.root.string, h->root.u.def.section->owner, - h->root.u.def.section, h->root.u.def.value, - output_bfd, bfd_abs_section_ptr, val))) - return false; - } - - h->root.type = bfd_link_hash_defined; - h->root.u.def.section = bfd_abs_section_ptr; - h->root.u.def.value = val; - } - - if (h->ldsym == NULL) - { - h->ldsym = ((struct internal_ldsym *) - bfd_zalloc (output_bfd, sizeof (struct internal_ldsym))); - if (h->ldsym == NULL) - return false; - } - - if (imppath == NULL) - h->ldsym->l_ifile = (bfd_size_type) -1; - else - { - unsigned int c; - struct xcoff_import_file **pp; - - /* We start c at 1 because the first entry in the import list is - reserved for the library search path. */ - for (pp = &xcoff_hash_table (info)->imports, c = 1; - *pp != NULL; - pp = &(*pp)->next, ++c) - { - if (strcmp ((*pp)->path, imppath) == 0 - && strcmp ((*pp)->file, impfile) == 0 - && strcmp ((*pp)->member, impmember) == 0) - break; - } - - if (*pp == NULL) - { - struct xcoff_import_file *n; - - n = ((struct xcoff_import_file *) - bfd_alloc (output_bfd, sizeof (struct xcoff_import_file))); - if (n == NULL) - return false; - n->next = NULL; - n->path = imppath; - n->file = impfile; - n->member = impmember; - *pp = n; - } - - h->ldsym->l_ifile = c; - } - - return true; -} - -/* Export a symbol. */ - -boolean -bfd_xcoff_export_symbol (output_bfd, info, harg, syscall) - bfd *output_bfd; - struct bfd_link_info *info; - struct bfd_link_hash_entry *harg; - boolean syscall; -{ - struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg; - - if (! XCOFF_XVECP (output_bfd->xvec)) - return true; - - h->flags |= XCOFF_EXPORT; - - /* FIXME: I'm not at all sure what syscall is supposed to mean, so - I'm just going to ignore it until somebody explains it. */ - - /* See if this is a function descriptor. It may be one even though - it is not so marked. */ - if ((h->flags & XCOFF_DESCRIPTOR) == 0 - && h->root.root.string[0] != '.') - { - char *fnname; - struct xcoff_link_hash_entry *hfn; - - fnname = (char *) bfd_malloc (strlen (h->root.root.string) + 2); - if (fnname == NULL) - return false; - fnname[0] = '.'; - strcpy (fnname + 1, h->root.root.string); - hfn = xcoff_link_hash_lookup (xcoff_hash_table (info), - fnname, false, false, true); - free (fnname); - if (hfn != NULL - && hfn->smclas == XMC_PR - && (hfn->root.type == bfd_link_hash_defined - || hfn->root.type == bfd_link_hash_defweak)) - { - h->flags |= XCOFF_DESCRIPTOR; - h->descriptor = hfn; - hfn->descriptor = h; - } - } - - /* Make sure we don't garbage collect this symbol. */ - if (! xcoff_mark_symbol (info, h)) - return false; - - /* If this is a function descriptor, make sure we don't garbage - collect the associated function code. We normally don't have to - worry about this, because the descriptor will be attached to a - section with relocs, but if we are creating the descriptor - ourselves those relocs will not be visible to the mark code. */ - if ((h->flags & XCOFF_DESCRIPTOR) != 0) - { - if (! xcoff_mark_symbol (info, h->descriptor)) - return false; - } - - return true; -} - -/* Count a reloc against a symbol. This is called for relocs - generated by the linker script, typically for global constructors - and destructors. */ - -boolean -bfd_xcoff_link_count_reloc (output_bfd, info, name) - bfd *output_bfd; - struct bfd_link_info *info; - const char *name; -{ - struct xcoff_link_hash_entry *h; - - if (! XCOFF_XVECP (output_bfd->xvec)) - return true; - - h = ((struct xcoff_link_hash_entry *) - bfd_wrapped_link_hash_lookup (output_bfd, info, name, false, false, - false)); - if (h == NULL) - { - (*_bfd_error_handler) ("%s: no such symbol", name); - bfd_set_error (bfd_error_no_symbols); - return false; - } - - h->flags |= XCOFF_REF_REGULAR | XCOFF_LDREL; - ++xcoff_hash_table (info)->ldrel_count; - - /* Mark the symbol to avoid garbage collection. */ - if (! xcoff_mark_symbol (info, h)) - return false; - - return true; -} - -/* This function is called for each symbol to which the linker script - assigns a value. */ - -boolean -bfd_xcoff_record_link_assignment (output_bfd, info, name) - bfd *output_bfd; - struct bfd_link_info *info; - const char *name; -{ - struct xcoff_link_hash_entry *h; - - if (! XCOFF_XVECP (output_bfd->xvec)) - return true; - - h = xcoff_link_hash_lookup (xcoff_hash_table (info), name, true, true, - false); - if (h == NULL) - return false; - - h->flags |= XCOFF_DEF_REGULAR; - - return true; -} - -/* This structure is used to pass information through - xcoff_link_hash_traverse. */ - -struct xcoff_loader_info -{ - /* Set if a problem occurred. */ - boolean failed; - /* Output BFD. */ - bfd *output_bfd; - /* Link information structure. */ - struct bfd_link_info *info; - /* Whether all defined symbols should be exported. */ - boolean export_defineds; - /* Number of ldsym structures. */ - size_t ldsym_count; - /* Size of string table. */ - size_t string_size; - /* String table. */ - bfd_byte *strings; - /* Allocated size of string table. */ - size_t string_alc; -}; - -/* Build the .loader section. This is called by the XCOFF linker - emulation before_allocation routine. We must set the size of the - .loader section before the linker lays out the output file. - LIBPATH is the library path to search for shared objects; this is - normally built from the -L arguments passed to the linker. ENTRY - is the name of the entry point symbol (the -e linker option). - FILE_ALIGN is the alignment to use for sections within the file - (the -H linker option). MAXSTACK is the maximum stack size (the - -bmaxstack linker option). MAXDATA is the maximum data size (the - -bmaxdata linker option). GC is whether to do garbage collection - (the -bgc linker option). MODTYPE is the module type (the - -bmodtype linker option). TEXTRO is whether the text section must - be read only (the -btextro linker option). EXPORT_DEFINEDS is - whether all defined symbols should be exported (the -unix linker - option). SPECIAL_SECTIONS is set by this routine to csects with - magic names like _end. */ - -boolean -bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry, - file_align, maxstack, maxdata, gc, - modtype, textro, export_defineds, - special_sections) - bfd *output_bfd; - struct bfd_link_info *info; - const char *libpath; - const char *entry; - unsigned long file_align; - unsigned long maxstack; - unsigned long maxdata; - boolean gc; - int modtype; - boolean textro; - boolean export_defineds; - asection **special_sections; -{ - struct xcoff_link_hash_entry *hentry; - asection *lsec; - struct xcoff_loader_info ldinfo; - int i; - size_t impsize, impcount; - struct xcoff_import_file *fl; - struct internal_ldhdr *ldhdr; - bfd_size_type stoff; - register char *out; - asection *sec; - bfd *sub; - struct bfd_strtab_hash *debug_strtab; - bfd_byte *debug_contents = NULL; - - if (! XCOFF_XVECP (output_bfd->xvec)) - { - for (i = 0; i < 6; i++) - special_sections[i] = NULL; - return true; - } - - ldinfo.failed = false; - ldinfo.output_bfd = output_bfd; - ldinfo.info = info; - ldinfo.export_defineds = export_defineds; - ldinfo.ldsym_count = 0; - ldinfo.string_size = 0; - ldinfo.strings = NULL; - ldinfo.string_alc = 0; - - xcoff_data (output_bfd)->maxstack = maxstack; - xcoff_data (output_bfd)->maxdata = maxdata; - xcoff_data (output_bfd)->modtype = modtype; - - xcoff_hash_table (info)->file_align = file_align; - xcoff_hash_table (info)->textro = textro; - - hentry = xcoff_link_hash_lookup (xcoff_hash_table (info), entry, - false, false, true); - if (hentry != NULL) - hentry->flags |= XCOFF_ENTRY; - - /* Garbage collect unused sections. */ - if (info->relocateable - || ! gc - || hentry == NULL - || (hentry->root.type != bfd_link_hash_defined - && hentry->root.type != bfd_link_hash_defweak)) - { - gc = false; - xcoff_hash_table (info)->gc = false; - - /* We still need to call xcoff_mark, in order to set ldrel_count - correctly. */ - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - asection *o; - - for (o = sub->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_MARK) == 0) - { - if (! xcoff_mark (info, o)) - goto error_return; - } - } - } - } - else - { - if (! xcoff_mark (info, hentry->root.u.def.section)) - goto error_return; - xcoff_sweep (info); - xcoff_hash_table (info)->gc = true; - } - - /* Return special sections to the caller. */ - for (i = 0; i < 6; i++) - { - asection *sec; - - sec = xcoff_hash_table (info)->special_sections[i]; - if (sec != NULL - && gc - && (sec->flags & SEC_MARK) == 0) - sec = NULL; - special_sections[i] = sec; - } - - if (info->input_bfds == NULL) - { - /* I'm not sure what to do in this bizarre case. */ - return true; - } - - xcoff_link_hash_traverse (xcoff_hash_table (info), xcoff_build_ldsyms, - (PTR) &ldinfo); - if (ldinfo.failed) - goto error_return; - - /* Work out the size of the import file names. Each import file ID - consists of three null terminated strings: the path, the file - name, and the archive member name. The first entry in the list - of names is the path to use to find objects, which the linker has - passed in as the libpath argument. For some reason, the path - entry in the other import file names appears to always be empty. */ - impsize = strlen (libpath) + 3; - impcount = 1; - for (fl = xcoff_hash_table (info)->imports; fl != NULL; fl = fl->next) - { - ++impcount; - impsize += (strlen (fl->path) - + strlen (fl->file) - + strlen (fl->member) - + 3); - } - - /* Set up the .loader section header. */ - ldhdr = &xcoff_hash_table (info)->ldhdr; - ldhdr->l_version = 1; - ldhdr->l_nsyms = ldinfo.ldsym_count; - ldhdr->l_nreloc = xcoff_hash_table (info)->ldrel_count; - ldhdr->l_istlen = impsize; - ldhdr->l_nimpid = impcount; - ldhdr->l_impoff = (LDHDRSZ - + ldhdr->l_nsyms * LDSYMSZ - + ldhdr->l_nreloc * LDRELSZ); - ldhdr->l_stlen = ldinfo.string_size; - stoff = ldhdr->l_impoff + impsize; - if (ldinfo.string_size == 0) - ldhdr->l_stoff = 0; - else - ldhdr->l_stoff = stoff; - - /* We now know the final size of the .loader section. Allocate - space for it. */ - lsec = xcoff_hash_table (info)->loader_section; - lsec->_raw_size = stoff + ldhdr->l_stlen; - lsec->contents = (bfd_byte *) bfd_zalloc (output_bfd, lsec->_raw_size); - if (lsec->contents == NULL) - goto error_return; - - /* Set up the header. */ - xcoff_swap_ldhdr_out (output_bfd, ldhdr, - (struct external_ldhdr *) lsec->contents); - - /* Set up the import file names. */ - out = (char *) lsec->contents + ldhdr->l_impoff; - strcpy (out, libpath); - out += strlen (libpath) + 1; - *out++ = '\0'; - *out++ = '\0'; - for (fl = xcoff_hash_table (info)->imports; fl != NULL; fl = fl->next) - { - register const char *s; - - s = fl->path; - while ((*out++ = *s++) != '\0') - ; - s = fl->file; - while ((*out++ = *s++) != '\0') - ; - s = fl->member; - while ((*out++ = *s++) != '\0') - ; - } - - BFD_ASSERT ((bfd_size_type) ((bfd_byte *) out - lsec->contents) == stoff); - - /* Set up the symbol string table. */ - if (ldinfo.string_size > 0) - { - memcpy (out, ldinfo.strings, ldinfo.string_size); - free (ldinfo.strings); - ldinfo.strings = NULL; - } - - /* We can't set up the symbol table or the relocs yet, because we - don't yet know the final position of the various sections. The - .loader symbols are written out when the corresponding normal - symbols are written out in xcoff_link_input_bfd or - xcoff_write_global_symbol. The .loader relocs are written out - when the corresponding normal relocs are handled in - xcoff_link_input_bfd. */ - - /* Allocate space for the magic sections. */ - sec = xcoff_hash_table (info)->linkage_section; - if (sec->_raw_size > 0) - { - sec->contents = (bfd_byte *) bfd_zalloc (output_bfd, sec->_raw_size); - if (sec->contents == NULL) - goto error_return; - } - sec = xcoff_hash_table (info)->toc_section; - if (sec->_raw_size > 0) - { - sec->contents = (bfd_byte *) bfd_zalloc (output_bfd, sec->_raw_size); - if (sec->contents == NULL) - goto error_return; - } - sec = xcoff_hash_table (info)->descriptor_section; - if (sec->_raw_size > 0) - { - sec->contents = (bfd_byte *) bfd_zalloc (output_bfd, sec->_raw_size); - if (sec->contents == NULL) - goto error_return; - } - - /* Now that we've done garbage collection, figure out the contents - of the .debug section. */ - debug_strtab = xcoff_hash_table (info)->debug_strtab; - - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - asection *subdeb; - bfd_size_type symcount; - unsigned long *debug_index; - asection **csectpp; - bfd_byte *esym, *esymend; - bfd_size_type symesz; - - if (sub->xvec != info->hash->creator) - continue; - subdeb = bfd_get_section_by_name (sub, ".debug"); - if (subdeb == NULL || subdeb->_raw_size == 0) - continue; - - if (info->strip == strip_all - || info->strip == strip_debugger - || info->discard == discard_all) - { - subdeb->_raw_size = 0; - continue; - } - - if (! _bfd_coff_get_external_symbols (sub)) - goto error_return; - - symcount = obj_raw_syment_count (sub); - debug_index = ((unsigned long *) - bfd_zalloc (sub, symcount * sizeof (unsigned long))); - if (debug_index == NULL) - goto error_return; - xcoff_data (sub)->debug_indices = debug_index; - - /* Grab the contents of the .debug section. We use malloc and - copy the neams into the debug stringtab, rather than - bfd_alloc, because I expect that, when linking many files - together, many of the strings will be the same. Storing the - strings in the hash table should save space in this case. */ - debug_contents = (bfd_byte *) bfd_malloc (subdeb->_raw_size); - if (debug_contents == NULL) - goto error_return; - if (! bfd_get_section_contents (sub, subdeb, (PTR) debug_contents, - (file_ptr) 0, subdeb->_raw_size)) - goto error_return; - - csectpp = xcoff_data (sub)->csects; - - symesz = bfd_coff_symesz (sub); - esym = (bfd_byte *) obj_coff_external_syms (sub); - esymend = esym + symcount * symesz; - while (esym < esymend) - { - struct internal_syment sym; - - bfd_coff_swap_sym_in (sub, (PTR) esym, (PTR) &sym); - - *debug_index = (unsigned long) -1; - - if (sym._n._n_n._n_zeroes == 0 - && *csectpp != NULL - && (! gc - || ((*csectpp)->flags & SEC_MARK) != 0 - || *csectpp == bfd_abs_section_ptr) - && bfd_coff_symname_in_debug (sub, &sym)) - { - char *name; - bfd_size_type indx; - - name = (char *) debug_contents + sym._n._n_n._n_offset; - indx = _bfd_stringtab_add (debug_strtab, name, true, true); - if (indx == (bfd_size_type) -1) - goto error_return; - *debug_index = indx; - } - - esym += (sym.n_numaux + 1) * symesz; - csectpp += sym.n_numaux + 1; - debug_index += sym.n_numaux + 1; - } - - free (debug_contents); - debug_contents = NULL; - - /* Clear the size of subdeb, so that it is not included directly - in the output file. */ - subdeb->_raw_size = 0; - - if (! info->keep_memory) - { - if (! _bfd_coff_free_symbols (sub)) - goto error_return; - } - } - - xcoff_hash_table (info)->debug_section->_raw_size = - _bfd_stringtab_size (debug_strtab); - - return true; - - error_return: - if (ldinfo.strings != NULL) - free (ldinfo.strings); - if (debug_contents != NULL) - free (debug_contents); - return false; -} - -/* Add a symbol to the .loader symbols, if necessary. */ - -static boolean -xcoff_build_ldsyms (h, p) - struct xcoff_link_hash_entry *h; - PTR p; -{ - struct xcoff_loader_info *ldinfo = (struct xcoff_loader_info *) p; - size_t len; - - /* If all defined symbols should be exported, mark them now. */ - if (ldinfo->export_defineds - && (h->flags & XCOFF_DEF_REGULAR) != 0) - h->flags |= XCOFF_EXPORT; - - /* We don't want to garbage collect symbols which are not defined in - XCOFF files. This is a convenient place to mark them. */ - if (xcoff_hash_table (ldinfo->info)->gc - && (h->flags & XCOFF_MARK) == 0 - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && (h->root.u.def.section->owner == NULL - || (h->root.u.def.section->owner->xvec - != ldinfo->info->hash->creator))) - h->flags |= XCOFF_MARK; - - /* If this symbol is called and defined in a dynamic object, or not - defined at all when building a shared object, or imported, then - we need to set up global linkage code for it. (Unless we did - garbage collection and we didn't need this symbol.) */ - if ((h->flags & XCOFF_CALLED) != 0 - && (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - && h->root.root.string[0] == '.' - && h->descriptor != NULL - && ((h->descriptor->flags & XCOFF_DEF_DYNAMIC) != 0 - || ldinfo->info->shared - || ((h->descriptor->flags & XCOFF_IMPORT) != 0 - && (h->descriptor->flags & XCOFF_DEF_REGULAR) == 0)) - && (! xcoff_hash_table (ldinfo->info)->gc - || (h->flags & XCOFF_MARK) != 0)) - { - asection *sec; - struct xcoff_link_hash_entry *hds; - - sec = xcoff_hash_table (ldinfo->info)->linkage_section; - h->root.type = bfd_link_hash_defined; - h->root.u.def.section = sec; - h->root.u.def.value = sec->_raw_size; - h->smclas = XMC_GL; - h->flags |= XCOFF_DEF_REGULAR; - sec->_raw_size += XCOFF_GLINK_SIZE; - - /* The global linkage code requires a TOC entry for the - descriptor. */ - hds = h->descriptor; - BFD_ASSERT ((hds->root.type == bfd_link_hash_undefined - || hds->root.type == bfd_link_hash_undefweak) - && (hds->flags & XCOFF_DEF_REGULAR) == 0); - hds->flags |= XCOFF_MARK; - if (hds->toc_section == NULL) - { - hds->toc_section = xcoff_hash_table (ldinfo->info)->toc_section; - hds->u.toc_offset = hds->toc_section->_raw_size; - hds->toc_section->_raw_size += 4; - ++xcoff_hash_table (ldinfo->info)->ldrel_count; - ++hds->toc_section->reloc_count; - hds->indx = -2; - hds->flags |= XCOFF_SET_TOC | XCOFF_LDREL; - - /* We need to call xcoff_build_ldsyms recursively here, - because we may already have passed hds on the traversal. */ - xcoff_build_ldsyms (hds, p); - } - } - - /* If this symbol is exported, but not defined, we need to try to - define it. */ - if ((h->flags & XCOFF_EXPORT) != 0 - && (h->flags & XCOFF_IMPORT) == 0 - && (h->flags & XCOFF_DEF_REGULAR) == 0 - && (h->flags & XCOFF_DEF_DYNAMIC) == 0 - && (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak)) - { - if ((h->flags & XCOFF_DESCRIPTOR) != 0 - && (h->descriptor->root.type == bfd_link_hash_defined - || h->descriptor->root.type == bfd_link_hash_defweak)) - { - asection *sec; - - /* This is an undefined function descriptor associated with - a defined entry point. We can build up a function - descriptor ourselves. Believe it or not, the AIX linker - actually does this, and there are cases where we need to - do it as well. */ - sec = xcoff_hash_table (ldinfo->info)->descriptor_section; - h->root.type = bfd_link_hash_defined; - h->root.u.def.section = sec; - h->root.u.def.value = sec->_raw_size; - h->smclas = XMC_DS; - h->flags |= XCOFF_DEF_REGULAR; - sec->_raw_size += 12; - - /* A function descriptor uses two relocs: one for the - associated code, and one for the TOC address. */ - xcoff_hash_table (ldinfo->info)->ldrel_count += 2; - sec->reloc_count += 2; - - /* We handle writing out the contents of the descriptor in - xcoff_write_global_symbol. */ - } - else - { - (*_bfd_error_handler) - ("attempt to export undefined symbol `%s'", - h->root.root.string); - ldinfo->failed = true; - bfd_set_error (bfd_error_invalid_operation); - return false; - } - } - - /* If this is still a common symbol, and it wasn't garbage - collected, we need to actually allocate space for it in the .bss - section. */ - if (h->root.type == bfd_link_hash_common - && (! xcoff_hash_table (ldinfo->info)->gc - || (h->flags & XCOFF_MARK) != 0) - && h->root.u.c.p->section->_raw_size == 0) - { - BFD_ASSERT (bfd_is_com_section (h->root.u.c.p->section)); - h->root.u.c.p->section->_raw_size = h->root.u.c.size; - } - - /* We need to add a symbol to the .loader section if it is mentioned - in a reloc which we are copying to the .loader section and it was - not defined or common, or if it is the entry point, or if it is - being exported. */ - - if (((h->flags & XCOFF_LDREL) == 0 - || h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak - || h->root.type == bfd_link_hash_common) - && (h->flags & XCOFF_ENTRY) == 0 - && (h->flags & XCOFF_EXPORT) == 0) - { - h->ldsym = NULL; - return true; - } - - /* We don't need to add this symbol if we did garbage collection and - we did not mark this symbol. */ - if (xcoff_hash_table (ldinfo->info)->gc - && (h->flags & XCOFF_MARK) == 0) - { - h->ldsym = NULL; - return true; - } - - /* We may have already processed this symbol due to the recursive - call above. */ - if ((h->flags & XCOFF_BUILT_LDSYM) != 0) - return true; - - /* We need to add this symbol to the .loader symbols. */ - - /* h->ldsym will already have been allocated for an explicitly - imported symbol. */ - if (h->ldsym == NULL) - { - h->ldsym = ((struct internal_ldsym *) - bfd_zalloc (ldinfo->output_bfd, - sizeof (struct internal_ldsym))); - if (h->ldsym == NULL) - { - ldinfo->failed = true; - return false; - } - } - - /* The first 3 symbol table indices are reserved to indicate the - sections. */ - h->ldindx = ldinfo->ldsym_count + 3; - - ++ldinfo->ldsym_count; - - len = strlen (h->root.root.string); - if (len <= SYMNMLEN) - strncpy (h->ldsym->_l._l_name, h->root.root.string, SYMNMLEN); - else - { - if (ldinfo->string_size + len + 3 > ldinfo->string_alc) - { - size_t newalc; - bfd_byte *newstrings; - - newalc = ldinfo->string_alc * 2; - if (newalc == 0) - newalc = 32; - while (ldinfo->string_size + len + 3 > newalc) - newalc *= 2; - - newstrings = ((bfd_byte *) - bfd_realloc ((PTR) ldinfo->strings, newalc)); - if (newstrings == NULL) - { - ldinfo->failed = true; - return false; - } - ldinfo->string_alc = newalc; - ldinfo->strings = newstrings; - } - - bfd_put_16 (ldinfo->output_bfd, len + 1, - ldinfo->strings + ldinfo->string_size); - strcpy (ldinfo->strings + ldinfo->string_size + 2, h->root.root.string); - h->ldsym->_l._l_l._l_zeroes = 0; - h->ldsym->_l._l_l._l_offset = ldinfo->string_size + 2; - ldinfo->string_size += len + 3; - } - - h->flags |= XCOFF_BUILT_LDSYM; - - return true; -} - -/* Do the final link step. */ - -boolean -_bfd_xcoff_bfd_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - bfd_size_type symesz; - struct xcoff_final_link_info finfo; - asection *o; - struct bfd_link_order *p; - size_t max_contents_size; - size_t max_sym_count; - size_t max_lineno_count; - size_t max_reloc_count; - size_t max_output_reloc_count; - file_ptr rel_filepos; - unsigned int relsz; - file_ptr line_filepos; - unsigned int linesz; - bfd *sub; - bfd_byte *external_relocs = NULL; - char strbuf[STRING_SIZE_SIZE]; - - if (info->shared) - abfd->flags |= DYNAMIC; - - symesz = bfd_coff_symesz (abfd); - - finfo.info = info; - finfo.output_bfd = abfd; - finfo.strtab = NULL; - finfo.section_info = NULL; - finfo.last_file_index = -1; - finfo.toc_symindx = -1; - finfo.internal_syms = NULL; - finfo.sym_indices = NULL; - finfo.outsyms = NULL; - finfo.linenos = NULL; - finfo.contents = NULL; - finfo.external_relocs = NULL; - - finfo.ldsym = ((struct external_ldsym *) - (xcoff_hash_table (info)->loader_section->contents - + LDHDRSZ)); - finfo.ldrel = ((struct external_ldrel *) - (xcoff_hash_table (info)->loader_section->contents - + LDHDRSZ - + xcoff_hash_table (info)->ldhdr.l_nsyms * LDSYMSZ)); - - xcoff_data (abfd)->coff.link_info = info; - - finfo.strtab = _bfd_stringtab_init (); - if (finfo.strtab == NULL) - goto error_return; - - /* Count the line number and relocation entries required for the - output file. Determine a few maximum sizes. */ - max_contents_size = 0; - max_lineno_count = 0; - max_reloc_count = 0; - for (o = abfd->sections; o != NULL; o = o->next) - { - o->reloc_count = 0; - o->lineno_count = 0; - for (p = o->link_order_head; p != NULL; p = p->next) - { - if (p->type == bfd_indirect_link_order) - { - asection *sec; - - sec = p->u.indirect.section; - - if (info->strip == strip_none - || info->strip == strip_some) - o->lineno_count += sec->lineno_count; - - o->reloc_count += sec->reloc_count; - - if (sec->_raw_size > max_contents_size) - max_contents_size = sec->_raw_size; - if (sec->lineno_count > max_lineno_count) - max_lineno_count = sec->lineno_count; - if (coff_section_data (sec->owner, sec) != NULL - && xcoff_section_data (sec->owner, sec) != NULL - && (xcoff_section_data (sec->owner, sec)->lineno_count - > max_lineno_count)) - max_lineno_count = - xcoff_section_data (sec->owner, sec)->lineno_count; - if (sec->reloc_count > max_reloc_count) - max_reloc_count = sec->reloc_count; - } - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - ++o->reloc_count; - } - } - - /* Compute the file positions for all the sections. */ - if (abfd->output_has_begun) - { - if (xcoff_hash_table (info)->file_align != 0) - abort (); - } - else - { - bfd_vma file_align; - - file_align = xcoff_hash_table (info)->file_align; - if (file_align != 0) - { - boolean saw_contents; - int indx; - asection **op; - file_ptr sofar; - - /* Insert .pad sections before every section which has - contents and is loaded, if it is preceded by some other - section which has contents and is loaded. */ - saw_contents = true; - for (op = &abfd->sections; *op != NULL; op = &(*op)->next) - { - (*op)->target_index = indx; - if (strcmp ((*op)->name, ".pad") == 0) - saw_contents = false; - else if (((*op)->flags & SEC_HAS_CONTENTS) != 0 - && ((*op)->flags & SEC_LOAD) != 0) - { - if (! saw_contents) - saw_contents = true; - else - { - asection *n, *hold; - - hold = *op; - *op = NULL; - n = bfd_make_section_anyway (abfd, ".pad"); - BFD_ASSERT (*op == n); - n->next = hold; - n->flags = SEC_HAS_CONTENTS; - n->alignment_power = 0; - saw_contents = false; - } - } - } - - /* Reset the section indices after inserting the new - sections. */ - indx = 0; - for (o = abfd->sections; o != NULL; o = o->next) - { - ++indx; - o->target_index = indx; - } - BFD_ASSERT ((unsigned int) indx == abfd->section_count); - - /* Work out appropriate sizes for the .pad sections to force - each section to land on a page boundary. This bit of - code knows what compute_section_file_positions is going - to do. */ - sofar = bfd_coff_filhsz (abfd); - sofar += bfd_coff_aoutsz (abfd); - sofar += abfd->section_count * bfd_coff_scnhsz (abfd); - for (o = abfd->sections; o != NULL; o = o->next) - if (o->reloc_count >= 0xffff || o->lineno_count >= 0xffff) - sofar += bfd_coff_scnhsz (abfd); - - for (o = abfd->sections; o != NULL; o = o->next) - { - if (strcmp (o->name, ".pad") == 0) - { - bfd_vma pageoff; - - BFD_ASSERT (o->_raw_size == 0); - pageoff = sofar & (file_align - 1); - if (pageoff != 0) - { - o->_raw_size = file_align - pageoff; - sofar += file_align - pageoff; - o->flags |= SEC_HAS_CONTENTS; - } - } - else - { - if ((o->flags & SEC_HAS_CONTENTS) != 0) - sofar += BFD_ALIGN (o->_raw_size, - 1 << o->alignment_power); - } - } - } - - bfd_coff_compute_section_file_positions (abfd); - } - - /* Allocate space for the pointers we need to keep for the relocs. */ - { - unsigned int i; - - /* We use section_count + 1, rather than section_count, because - the target_index fields are 1 based. */ - finfo.section_info = - ((struct xcoff_link_section_info *) - bfd_malloc ((abfd->section_count + 1) - * sizeof (struct xcoff_link_section_info))); - if (finfo.section_info == NULL) - goto error_return; - for (i = 0; i <= abfd->section_count; i++) - { - finfo.section_info[i].relocs = NULL; - finfo.section_info[i].rel_hashes = NULL; - finfo.section_info[i].toc_rel_hashes = NULL; - } - } - - /* Set the file positions for the relocs. */ - rel_filepos = obj_relocbase (abfd); - relsz = bfd_coff_relsz (abfd); - max_output_reloc_count = 0; - for (o = abfd->sections; o != NULL; o = o->next) - { - if (o->reloc_count == 0) - o->rel_filepos = 0; - else - { - o->flags |= SEC_RELOC; - o->rel_filepos = rel_filepos; - rel_filepos += o->reloc_count * relsz; - - /* We don't know the indices of global symbols until we have - written out all the local symbols. For each section in - the output file, we keep an array of pointers to hash - table entries. Each entry in the array corresponds to a - reloc. When we find a reloc against a global symbol, we - set the corresponding entry in this array so that we can - fix up the symbol index after we have written out all the - local symbols. - - Because of this problem, we also keep the relocs in - memory until the end of the link. This wastes memory. - We could backpatch the file later, I suppose, although it - would be slow. */ - finfo.section_info[o->target_index].relocs = - ((struct internal_reloc *) - bfd_malloc (o->reloc_count * sizeof (struct internal_reloc))); - finfo.section_info[o->target_index].rel_hashes = - ((struct xcoff_link_hash_entry **) - bfd_malloc (o->reloc_count - * sizeof (struct xcoff_link_hash_entry *))); - if (finfo.section_info[o->target_index].relocs == NULL - || finfo.section_info[o->target_index].rel_hashes == NULL) - goto error_return; - - if (o->reloc_count > max_output_reloc_count) - max_output_reloc_count = o->reloc_count; - } - } - - /* We now know the size of the relocs, so we can determine the file - positions of the line numbers. */ - line_filepos = rel_filepos; - finfo.line_filepos = line_filepos; - linesz = bfd_coff_linesz (abfd); - for (o = abfd->sections; o != NULL; o = o->next) - { - if (o->lineno_count == 0) - o->line_filepos = 0; - else - { - o->line_filepos = line_filepos; - line_filepos += o->lineno_count * linesz; - } - - /* Reset the reloc and lineno counts, so that we can use them to - count the number of entries we have output so far. */ - o->reloc_count = 0; - o->lineno_count = 0; - } - - obj_sym_filepos (abfd) = line_filepos; - - /* Figure out the largest number of symbols in an input BFD. Take - the opportunity to clear the output_has_begun fields of all the - input BFD's. We want at least 4 symbols, since that is the - number which xcoff_write_global_symbol may need. */ - max_sym_count = 4; - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - size_t sz; - - sub->output_has_begun = false; - sz = obj_raw_syment_count (sub); - if (sz > max_sym_count) - max_sym_count = sz; - } - - /* Allocate some buffers used while linking. */ - finfo.internal_syms = ((struct internal_syment *) - bfd_malloc (max_sym_count - * sizeof (struct internal_syment))); - finfo.sym_indices = (long *) bfd_malloc (max_sym_count * sizeof (long)); - finfo.outsyms = ((bfd_byte *) - bfd_malloc ((size_t) ((max_sym_count + 1) * symesz))); - finfo.linenos = (bfd_byte *) bfd_malloc (max_lineno_count - * bfd_coff_linesz (abfd)); - finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size); - finfo.external_relocs = (bfd_byte *) bfd_malloc (max_reloc_count * relsz); - if ((finfo.internal_syms == NULL && max_sym_count > 0) - || (finfo.sym_indices == NULL && max_sym_count > 0) - || finfo.outsyms == NULL - || (finfo.linenos == NULL && max_lineno_count > 0) - || (finfo.contents == NULL && max_contents_size > 0) - || (finfo.external_relocs == NULL && max_reloc_count > 0)) - goto error_return; - - obj_raw_syment_count (abfd) = 0; - xcoff_data (abfd)->toc = (bfd_vma) -1; - - /* We now know the position of everything in the file, except that - we don't know the size of the symbol table and therefore we don't - know where the string table starts. We just build the string - table in memory as we go along. We process all the relocations - for a single input file at once. */ - for (o = abfd->sections; o != NULL; o = o->next) - { - for (p = o->link_order_head; p != NULL; p = p->next) - { - if (p->type == bfd_indirect_link_order - && p->u.indirect.section->owner->xvec == abfd->xvec) - { - sub = p->u.indirect.section->owner; - if (! sub->output_has_begun) - { - if (! xcoff_link_input_bfd (&finfo, sub)) - goto error_return; - sub->output_has_begun = true; - } - } - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - { - if (! xcoff_reloc_link_order (abfd, &finfo, o, p)) - goto error_return; - } - else - { - if (! _bfd_default_link_order (abfd, info, o, p)) - goto error_return; - } - } - } - - /* Free up the buffers used by xcoff_link_input_bfd. */ - - if (finfo.internal_syms != NULL) - { - free (finfo.internal_syms); - finfo.internal_syms = NULL; - } - if (finfo.sym_indices != NULL) - { - free (finfo.sym_indices); - finfo.sym_indices = NULL; - } - if (finfo.linenos != NULL) - { - free (finfo.linenos); - finfo.linenos = NULL; - } - if (finfo.contents != NULL) - { - free (finfo.contents); - finfo.contents = NULL; - } - if (finfo.external_relocs != NULL) - { - free (finfo.external_relocs); - finfo.external_relocs = NULL; - } - - /* The value of the last C_FILE symbol is supposed to be -1. Write - it out again. */ - if (finfo.last_file_index != -1) - { - finfo.last_file.n_value = -1; - bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file, - (PTR) finfo.outsyms); - if (bfd_seek (abfd, - (obj_sym_filepos (abfd) - + finfo.last_file_index * symesz), - SEEK_SET) != 0 - || bfd_write (finfo.outsyms, symesz, 1, abfd) != symesz) - goto error_return; - } - - /* Write out all the global symbols which do not come from XCOFF - input files. */ - xcoff_link_hash_traverse (xcoff_hash_table (info), - xcoff_write_global_symbol, - (PTR) &finfo); - - if (finfo.outsyms != NULL) - { - free (finfo.outsyms); - finfo.outsyms = NULL; - } - - /* Now that we have written out all the global symbols, we know the - symbol indices to use for relocs against them, and we can finally - write out the relocs. */ - external_relocs = (bfd_byte *) malloc (max_output_reloc_count * relsz); - if (external_relocs == NULL && max_output_reloc_count != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - for (o = abfd->sections; o != NULL; o = o->next) - { - struct internal_reloc *irel; - struct internal_reloc *irelend; - struct xcoff_link_hash_entry **rel_hash; - struct xcoff_toc_rel_hash *toc_rel_hash; - bfd_byte *erel; - - if (o->reloc_count == 0) - continue; - - irel = finfo.section_info[o->target_index].relocs; - irelend = irel + o->reloc_count; - rel_hash = finfo.section_info[o->target_index].rel_hashes; - for (; irel < irelend; irel++, rel_hash++, erel += relsz) - { - if (*rel_hash != NULL) - { - if ((*rel_hash)->indx < 0) - { - if (! ((*info->callbacks->unattached_reloc) - (info, (*rel_hash)->root.root.string, - (bfd *) NULL, o, irel->r_vaddr))) - goto error_return; - (*rel_hash)->indx = 0; - } - irel->r_symndx = (*rel_hash)->indx; - } - } - - for (toc_rel_hash = finfo.section_info[o->target_index].toc_rel_hashes; - toc_rel_hash != NULL; - toc_rel_hash = toc_rel_hash->next) - { - if (toc_rel_hash->h->u.toc_indx < 0) - { - if (! ((*info->callbacks->unattached_reloc) - (info, toc_rel_hash->h->root.root.string, - (bfd *) NULL, o, toc_rel_hash->rel->r_vaddr))) - goto error_return; - toc_rel_hash->h->u.toc_indx = 0; - } - toc_rel_hash->rel->r_symndx = toc_rel_hash->h->u.toc_indx; - } - - /* XCOFF requires that the relocs be sorted by address. We tend - to produce them in the order in which their containing csects - appear in the symbol table, which is not necessarily by - address. So we sort them here. There may be a better way to - do this. */ - qsort ((PTR) finfo.section_info[o->target_index].relocs, - o->reloc_count, sizeof (struct internal_reloc), - xcoff_sort_relocs); - - irel = finfo.section_info[o->target_index].relocs; - irelend = irel + o->reloc_count; - erel = external_relocs; - for (; irel < irelend; irel++, rel_hash++, erel += relsz) - bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel); - - if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0 - || bfd_write ((PTR) external_relocs, relsz, o->reloc_count, - abfd) != relsz * o->reloc_count) - goto error_return; - } - - if (external_relocs != NULL) - { - free (external_relocs); - external_relocs = NULL; - } - - /* Free up the section information. */ - if (finfo.section_info != NULL) - { - unsigned int i; - - for (i = 0; i < abfd->section_count; i++) - { - if (finfo.section_info[i].relocs != NULL) - free (finfo.section_info[i].relocs); - if (finfo.section_info[i].rel_hashes != NULL) - free (finfo.section_info[i].rel_hashes); - } - free (finfo.section_info); - finfo.section_info = NULL; - } - - /* Write out the loader section contents. */ - BFD_ASSERT ((bfd_byte *) finfo.ldrel - == (xcoff_hash_table (info)->loader_section->contents - + xcoff_hash_table (info)->ldhdr.l_impoff)); - o = xcoff_hash_table (info)->loader_section; - if (! bfd_set_section_contents (abfd, o->output_section, - o->contents, o->output_offset, - o->_raw_size)) - goto error_return; - - /* Write out the magic sections. */ - o = xcoff_hash_table (info)->linkage_section; - if (o->_raw_size > 0 - && ! bfd_set_section_contents (abfd, o->output_section, o->contents, - o->output_offset, o->_raw_size)) - goto error_return; - o = xcoff_hash_table (info)->toc_section; - if (o->_raw_size > 0 - && ! bfd_set_section_contents (abfd, o->output_section, o->contents, - o->output_offset, o->_raw_size)) - goto error_return; - o = xcoff_hash_table (info)->descriptor_section; - if (o->_raw_size > 0 - && ! bfd_set_section_contents (abfd, o->output_section, o->contents, - o->output_offset, o->_raw_size)) - goto error_return; - - /* Write out the string table. */ - if (bfd_seek (abfd, - (obj_sym_filepos (abfd) - + obj_raw_syment_count (abfd) * symesz), - SEEK_SET) != 0) - goto error_return; - bfd_h_put_32 (abfd, - _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE, - (bfd_byte *) strbuf); - if (bfd_write (strbuf, 1, STRING_SIZE_SIZE, abfd) != STRING_SIZE_SIZE) - goto error_return; - if (! _bfd_stringtab_emit (abfd, finfo.strtab)) - goto error_return; - - _bfd_stringtab_free (finfo.strtab); - - /* Write out the debugging string table. */ - o = xcoff_hash_table (info)->debug_section; - if (o != NULL) - { - struct bfd_strtab_hash *debug_strtab; - - debug_strtab = xcoff_hash_table (info)->debug_strtab; - BFD_ASSERT (o->output_section->_raw_size - o->output_offset - >= _bfd_stringtab_size (debug_strtab)); - if (bfd_seek (abfd, - o->output_section->filepos + o->output_offset, - SEEK_SET) != 0) - goto error_return; - if (! _bfd_stringtab_emit (abfd, debug_strtab)) - goto error_return; - } - - /* Setting bfd_get_symcount to 0 will cause write_object_contents to - not try to write out the symbols. */ - bfd_get_symcount (abfd) = 0; - - return true; - - error_return: - if (finfo.strtab != NULL) - _bfd_stringtab_free (finfo.strtab); - if (finfo.section_info != NULL) - { - unsigned int i; - - for (i = 0; i < abfd->section_count; i++) - { - if (finfo.section_info[i].relocs != NULL) - free (finfo.section_info[i].relocs); - if (finfo.section_info[i].rel_hashes != NULL) - free (finfo.section_info[i].rel_hashes); - } - free (finfo.section_info); - } - if (finfo.internal_syms != NULL) - free (finfo.internal_syms); - if (finfo.sym_indices != NULL) - free (finfo.sym_indices); - if (finfo.outsyms != NULL) - free (finfo.outsyms); - if (finfo.linenos != NULL) - free (finfo.linenos); - if (finfo.contents != NULL) - free (finfo.contents); - if (finfo.external_relocs != NULL) - free (finfo.external_relocs); - if (external_relocs != NULL) - free (external_relocs); - return false; -} - -/* Link an input file into the linker output file. This function - handles all the sections and relocations of the input file at once. */ - -static boolean -xcoff_link_input_bfd (finfo, input_bfd) - struct xcoff_final_link_info *finfo; - bfd *input_bfd; -{ - bfd *output_bfd; - const char *strings; - bfd_size_type syment_base; - unsigned int n_tmask; - unsigned int n_btshft; - boolean copy, hash; - bfd_size_type isymesz; - bfd_size_type osymesz; - bfd_size_type linesz; - bfd_byte *esym; - bfd_byte *esym_end; - struct xcoff_link_hash_entry **sym_hash; - struct internal_syment *isymp; - asection **csectpp; - unsigned long *debug_index; - long *indexp; - unsigned long output_index; - bfd_byte *outsym; - unsigned int incls; - asection *oline; - boolean keep_syms; - asection *o; - - /* We can just skip DYNAMIC files, unless this is a static link. */ - if ((input_bfd->flags & DYNAMIC) != 0 - && ! finfo->info->static_link) - return true; - - /* Move all the symbols to the output file. */ - - output_bfd = finfo->output_bfd; - strings = NULL; - syment_base = obj_raw_syment_count (output_bfd); - isymesz = bfd_coff_symesz (input_bfd); - osymesz = bfd_coff_symesz (output_bfd); - linesz = bfd_coff_linesz (input_bfd); - BFD_ASSERT (linesz == bfd_coff_linesz (output_bfd)); - - n_tmask = coff_data (input_bfd)->local_n_tmask; - n_btshft = coff_data (input_bfd)->local_n_btshft; - - /* Define macros so that ISFCN, et. al., macros work correctly. */ -#define N_TMASK n_tmask -#define N_BTSHFT n_btshft - - copy = false; - if (! finfo->info->keep_memory) - copy = true; - hash = true; - if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0) - hash = false; - - if (! _bfd_coff_get_external_symbols (input_bfd)) - return false; - - esym = (bfd_byte *) obj_coff_external_syms (input_bfd); - esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz; - sym_hash = obj_xcoff_sym_hashes (input_bfd); - csectpp = xcoff_data (input_bfd)->csects; - debug_index = xcoff_data (input_bfd)->debug_indices; - isymp = finfo->internal_syms; - indexp = finfo->sym_indices; - output_index = syment_base; - outsym = finfo->outsyms; - incls = 0; - oline = NULL; - - while (esym < esym_end) - { - struct internal_syment isym; - union internal_auxent aux; - int smtyp = 0; - boolean skip; - boolean require; - int add; - - bfd_coff_swap_sym_in (input_bfd, (PTR) esym, (PTR) isymp); - - /* If this is a C_EXT or C_HIDEXT symbol, we need the csect - information. */ - if (isymp->n_sclass == C_EXT || isymp->n_sclass == C_HIDEXT) - { - BFD_ASSERT (isymp->n_numaux > 0); - bfd_coff_swap_aux_in (input_bfd, - (PTR) (esym + isymesz * isymp->n_numaux), - isymp->n_type, isymp->n_sclass, - isymp->n_numaux - 1, isymp->n_numaux, - (PTR) &aux); - smtyp = SMTYP_SMTYP (aux.x_csect.x_smtyp); - } - - /* Make a copy of *isymp so that the relocate_section function - always sees the original values. This is more reliable than - always recomputing the symbol value even if we are stripping - the symbol. */ - isym = *isymp; - - /* If this symbol is in the .loader section, swap out the - .loader symbol information. If this is an external symbol - reference to a defined symbol, though, then wait until we get - to the definition. */ - if (isym.n_sclass == C_EXT - && *sym_hash != NULL - && (*sym_hash)->ldsym != NULL - && (smtyp != XTY_ER - || (*sym_hash)->root.type == bfd_link_hash_undefined)) - { - struct xcoff_link_hash_entry *h; - struct internal_ldsym *ldsym; - - h = *sym_hash; - ldsym = h->ldsym; - if (isym.n_scnum > 0) - { - ldsym->l_scnum = (*csectpp)->output_section->target_index; - ldsym->l_value = (isym.n_value - + (*csectpp)->output_section->vma - + (*csectpp)->output_offset - - (*csectpp)->vma); - } - else - { - ldsym->l_scnum = isym.n_scnum; - ldsym->l_value = isym.n_value; - } - - ldsym->l_smtype = smtyp; - if (((h->flags & XCOFF_DEF_REGULAR) == 0 - && (h->flags & XCOFF_DEF_DYNAMIC) != 0) - || (h->flags & XCOFF_IMPORT) != 0) - ldsym->l_smtype |= L_IMPORT; - if (((h->flags & XCOFF_DEF_REGULAR) != 0 - && (h->flags & XCOFF_DEF_DYNAMIC) != 0) - || (h->flags & XCOFF_EXPORT) != 0) - ldsym->l_smtype |= L_EXPORT; - if ((h->flags & XCOFF_ENTRY) != 0) - ldsym->l_smtype |= L_ENTRY; - - ldsym->l_smclas = aux.x_csect.x_smclas; - - if (ldsym->l_ifile == (bfd_size_type) -1) - ldsym->l_ifile = 0; - else if (ldsym->l_ifile == 0) - { - if ((ldsym->l_smtype & L_IMPORT) == 0) - ldsym->l_ifile = 0; - else - { - bfd *impbfd; - - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - impbfd = h->root.u.def.section->owner; - else if (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - impbfd = h->root.u.undef.abfd; - else - impbfd = NULL; - - if (impbfd == NULL) - ldsym->l_ifile = 0; - else - { - BFD_ASSERT (impbfd->xvec == finfo->output_bfd->xvec); - ldsym->l_ifile = xcoff_data (impbfd)->import_file_id; - } - } - } - - ldsym->l_parm = 0; - - BFD_ASSERT (h->ldindx >= 0); - BFD_ASSERT (LDSYMSZ == sizeof (struct external_ldsym)); - xcoff_swap_ldsym_out (finfo->output_bfd, ldsym, - finfo->ldsym + h->ldindx - 3); - h->ldsym = NULL; - - /* Fill in snentry now that we know the target_index. */ - if ((h->flags & XCOFF_ENTRY) != 0 - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)) - xcoff_data (output_bfd)->snentry = - h->root.u.def.section->output_section->target_index; - } - - *indexp = -1; - - skip = false; - require = false; - add = 1 + isym.n_numaux; - - /* If we are skipping this csect, we want to skip this symbol. */ - if (*csectpp == NULL) - skip = true; - - /* If we garbage collected this csect, we want to skip this - symbol. */ - if (! skip - && xcoff_hash_table (finfo->info)->gc - && ((*csectpp)->flags & SEC_MARK) == 0 - && *csectpp != bfd_abs_section_ptr) - skip = true; - - /* An XCOFF linker always skips C_STAT symbols. */ - if (! skip - && isymp->n_sclass == C_STAT) - skip = true; - - /* We skip all but the first TOC anchor. */ - if (! skip - && isymp->n_sclass == C_HIDEXT - && aux.x_csect.x_smclas == XMC_TC0) - { - if (finfo->toc_symindx != -1) - skip = true; - else - { - bfd_vma tocval, tocend; - - tocval = ((*csectpp)->output_section->vma - + (*csectpp)->output_offset - + isym.n_value - - (*csectpp)->vma); - /* We want to find out if tocval is a good value to use - as the TOC anchor--that is, whether we can access all - of the TOC using a 16 bit offset from tocval. This - test assumes that the TOC comes at the end of the - output section, as it does in the default linker - script. If the TOC anchor is too far into the .toc - section, the relocation routine will report - overflows. */ - tocend = ((*csectpp)->output_section->vma - + (*csectpp)->output_section->_raw_size); - if (tocval + 0x8000 < tocend) - { - bfd_vma tocadd; - - tocadd = tocend - (tocval + 0x8000); - tocval += tocadd; - isym.n_value += tocadd; - } - - finfo->toc_symindx = output_index; - xcoff_data (finfo->output_bfd)->toc = tocval; - xcoff_data (finfo->output_bfd)->sntoc = - (*csectpp)->output_section->target_index; - require = true; - } - } - - /* If we are stripping all symbols, we want to skip this one. */ - if (! skip - && finfo->info->strip == strip_all) - skip = true; - - /* We can skip resolved external references. */ - if (! skip - && isym.n_sclass == C_EXT - && smtyp == XTY_ER - && (*sym_hash)->root.type != bfd_link_hash_undefined) - skip = true; - - /* We can skip common symbols if they got defined somewhere - else. */ - if (! skip - && isym.n_sclass == C_EXT - && smtyp == XTY_CM - && ((*sym_hash)->root.type != bfd_link_hash_common - || (*sym_hash)->root.u.c.p->section != *csectpp) - && ((*sym_hash)->root.type != bfd_link_hash_defined - || (*sym_hash)->root.u.def.section != *csectpp)) - skip = true; - - /* Skip local symbols if we are discarding them. */ - if (! skip - && finfo->info->discard == discard_all - && isym.n_sclass != C_EXT - && (isym.n_sclass != C_HIDEXT - || smtyp != XTY_SD)) - skip = true; - - /* If we stripping debugging symbols, and this is a debugging - symbol, then skip it. */ - if (! skip - && finfo->info->strip == strip_debugger - && isym.n_scnum == N_DEBUG) - skip = true; - - /* If some symbols are stripped based on the name, work out the - name and decide whether to skip this symbol. We don't handle - this correctly for symbols whose names are in the .debug - section; to get it right we would need a new bfd_strtab_hash - function to return the string given the index. */ - if (! skip - && (finfo->info->strip == strip_some - || finfo->info->discard == discard_l) - && (debug_index == NULL || *debug_index == (unsigned long) -1)) - { - const char *name; - char buf[SYMNMLEN + 1]; - - name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf); - if (name == NULL) - return false; - - if ((finfo->info->strip == strip_some - && (bfd_hash_lookup (finfo->info->keep_hash, name, false, - false) == NULL)) - || (finfo->info->discard == discard_l - && (isym.n_sclass != C_EXT - && (isym.n_sclass != C_HIDEXT - || smtyp != XTY_SD)) - && strncmp (name, finfo->info->lprefix, - finfo->info->lprefix_len) == 0)) - skip = true; - } - - /* We can not skip the first TOC anchor. */ - if (skip - && require - && finfo->info->strip != strip_all) - skip = false; - - /* We now know whether we are to skip this symbol or not. */ - if (! skip) - { - /* Adjust the symbol in order to output it. */ - - if (isym._n._n_n._n_zeroes == 0 - && isym._n._n_n._n_offset != 0) - { - /* This symbol has a long name. Enter it in the string - table we are building. If *debug_index != -1, the - name has already been entered in the .debug section. */ - if (debug_index != NULL && *debug_index != (unsigned long) -1) - isym._n._n_n._n_offset = *debug_index; - else - { - const char *name; - bfd_size_type indx; - - name = _bfd_coff_internal_syment_name (input_bfd, &isym, - (char *) NULL); - if (name == NULL) - return false; - indx = _bfd_stringtab_add (finfo->strtab, name, hash, copy); - if (indx == (bfd_size_type) -1) - return false; - isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx; - } - } - - if (isym.n_sclass != C_BSTAT - && isym.n_sclass != C_ESTAT - && isym.n_sclass != C_DECL - && isym.n_scnum > 0) - { - isym.n_scnum = (*csectpp)->output_section->target_index; - isym.n_value += ((*csectpp)->output_section->vma - + (*csectpp)->output_offset - - (*csectpp)->vma); - } - - /* The value of a C_FILE symbol is the symbol index of the - next C_FILE symbol. The value of the last C_FILE symbol - is -1. We try to get this right, below, just before we - write the symbols out, but in the general case we may - have to write the symbol out twice. */ - if (isym.n_sclass == C_FILE) - { - if (finfo->last_file_index != -1 - && finfo->last_file.n_value != (long) output_index) - { - /* We must correct the value of the last C_FILE entry. */ - finfo->last_file.n_value = output_index; - if ((bfd_size_type) finfo->last_file_index >= syment_base) - { - /* The last C_FILE symbol is in this input file. */ - bfd_coff_swap_sym_out (output_bfd, - (PTR) &finfo->last_file, - (PTR) (finfo->outsyms - + ((finfo->last_file_index - - syment_base) - * osymesz))); - } - else - { - /* We have already written out the last C_FILE - symbol. We need to write it out again. We - borrow *outsym temporarily. */ - bfd_coff_swap_sym_out (output_bfd, - (PTR) &finfo->last_file, - (PTR) outsym); - if (bfd_seek (output_bfd, - (obj_sym_filepos (output_bfd) - + finfo->last_file_index * osymesz), - SEEK_SET) != 0 - || (bfd_write (outsym, osymesz, 1, output_bfd) - != osymesz)) - return false; - } - } - - finfo->last_file_index = output_index; - finfo->last_file = isym; - } - - /* The value of a C_BINCL or C_EINCL symbol is a file offset - into the line numbers. We update the symbol values when - we handle the line numbers. */ - if (isym.n_sclass == C_BINCL - || isym.n_sclass == C_EINCL) - { - isym.n_value = finfo->line_filepos; - ++incls; - } - - /* Output the symbol. */ - - bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym); - - *indexp = output_index; - - if (isym.n_sclass == C_EXT) - { - long indx; - struct xcoff_link_hash_entry *h; - - indx = ((esym - (bfd_byte *) obj_coff_external_syms (input_bfd)) - / isymesz); - h = obj_xcoff_sym_hashes (input_bfd)[indx]; - BFD_ASSERT (h != NULL); - h->indx = output_index; - } - - /* If this is a symbol in the TOC which we may have merged - (class XMC_TC), remember the symbol index of the TOC - symbol. */ - if (isym.n_sclass == C_HIDEXT - && aux.x_csect.x_smclas == XMC_TC - && *sym_hash != NULL) - { - BFD_ASSERT (((*sym_hash)->flags & XCOFF_SET_TOC) == 0); - BFD_ASSERT ((*sym_hash)->toc_section != NULL); - (*sym_hash)->u.toc_indx = output_index; - } - - output_index += add; - outsym += add * osymesz; - } - - esym += add * isymesz; - isymp += add; - csectpp += add; - sym_hash += add; - if (debug_index != NULL) - debug_index += add; - ++indexp; - for (--add; add > 0; --add) - *indexp++ = -1; - } - - /* Fix up the aux entries and the C_BSTAT symbols. This must be - done in a separate pass, because we don't know the correct symbol - indices until we have already decided which symbols we are going - to keep. */ - - esym = (bfd_byte *) obj_coff_external_syms (input_bfd); - esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz; - isymp = finfo->internal_syms; - indexp = finfo->sym_indices; - csectpp = xcoff_data (input_bfd)->csects; - outsym = finfo->outsyms; - while (esym < esym_end) - { - int add; - - add = 1 + isymp->n_numaux; - - if (*indexp < 0) - esym += add * isymesz; - else - { - int i; - - if (isymp->n_sclass == C_BSTAT) - { - struct internal_syment isym; - unsigned long indx; - - /* The value of a C_BSTAT symbol is the symbol table - index of the containing csect. */ - bfd_coff_swap_sym_in (output_bfd, (PTR) outsym, (PTR) &isym); - indx = isym.n_value; - if (indx < obj_raw_syment_count (input_bfd)) - { - long symindx; - - symindx = finfo->sym_indices[indx]; - if (symindx < 0) - isym.n_value = 0; - else - isym.n_value = symindx; - bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, - (PTR) outsym); - } - } - - esym += isymesz; - outsym += osymesz; - - for (i = 0; i < isymp->n_numaux && esym < esym_end; i++) - { - union internal_auxent aux; - - bfd_coff_swap_aux_in (input_bfd, (PTR) esym, isymp->n_type, - isymp->n_sclass, i, isymp->n_numaux, - (PTR) &aux); - - if (isymp->n_sclass == C_FILE) - { - /* This is the file name (or some comment put in by - the compiler). If it is long, we must put it in - the string table. */ - if (aux.x_file.x_n.x_zeroes == 0 - && aux.x_file.x_n.x_offset != 0) - { - const char *filename; - bfd_size_type indx; - - BFD_ASSERT (aux.x_file.x_n.x_offset - >= STRING_SIZE_SIZE); - if (strings == NULL) - { - strings = _bfd_coff_read_string_table (input_bfd); - if (strings == NULL) - return false; - } - filename = strings + aux.x_file.x_n.x_offset; - indx = _bfd_stringtab_add (finfo->strtab, filename, - hash, copy); - if (indx == (bfd_size_type) -1) - return false; - aux.x_file.x_n.x_offset = STRING_SIZE_SIZE + indx; - } - } - else if ((isymp->n_sclass == C_EXT - || isymp->n_sclass == C_HIDEXT) - && i + 1 == isymp->n_numaux) - { - /* We don't support type checking. I don't know if - anybody does. */ - aux.x_csect.x_parmhash = 0; - /* I don't think anybody uses these fields, but we'd - better clobber them just in case. */ - aux.x_csect.x_stab = 0; - aux.x_csect.x_snstab = 0; - if (SMTYP_SMTYP (aux.x_csect.x_smtyp) == XTY_LD) - { - unsigned long indx; - - indx = aux.x_csect.x_scnlen.l; - if (indx < obj_raw_syment_count (input_bfd)) - { - long symindx; - - symindx = finfo->sym_indices[indx]; - if (symindx < 0) - aux.x_sym.x_tagndx.l = 0; - else - aux.x_sym.x_tagndx.l = symindx; - } - } - } - else if (isymp->n_sclass != C_STAT || isymp->n_type != T_NULL) - { - unsigned long indx; - - if (ISFCN (isymp->n_type) - || ISTAG (isymp->n_sclass) - || isymp->n_sclass == C_BLOCK) - { - indx = aux.x_sym.x_fcnary.x_fcn.x_endndx.l; - if (indx > 0 - && indx < obj_raw_syment_count (input_bfd)) - { - /* We look forward through the symbol for - the index of the next symbol we are going - to include. I don't know if this is - entirely right. */ - while (finfo->sym_indices[indx] < 0 - && indx < obj_raw_syment_count (input_bfd)) - ++indx; - if (indx >= obj_raw_syment_count (input_bfd)) - indx = output_index; - else - indx = finfo->sym_indices[indx]; - aux.x_sym.x_fcnary.x_fcn.x_endndx.l = indx; - } - } - - indx = aux.x_sym.x_tagndx.l; - if (indx > 0 && indx < obj_raw_syment_count (input_bfd)) - { - long symindx; - - symindx = finfo->sym_indices[indx]; - if (symindx < 0) - aux.x_sym.x_tagndx.l = 0; - else - aux.x_sym.x_tagndx.l = symindx; - } - } - - /* Copy over the line numbers, unless we are stripping - them. We do this on a symbol by symbol basis in - order to more easily handle garbage collection. */ - if ((isymp->n_sclass == C_EXT - || isymp->n_sclass == C_HIDEXT) - && i == 0 - && isymp->n_numaux > 1 - && ISFCN (isymp->n_type) - && aux.x_sym.x_fcnary.x_fcn.x_lnnoptr != 0) - { - if (finfo->info->strip != strip_none - && finfo->info->strip != strip_some) - aux.x_sym.x_fcnary.x_fcn.x_lnnoptr = 0; - else - { - asection *enclosing; - unsigned int enc_count; - bfd_size_type linoff; - struct internal_lineno lin; - - o = *csectpp; - enclosing = xcoff_section_data (abfd, o)->enclosing; - enc_count = xcoff_section_data (abfd, o)->lineno_count; - if (oline != enclosing) - { - if (bfd_seek (input_bfd, - enclosing->line_filepos, - SEEK_SET) != 0 - || (bfd_read (finfo->linenos, linesz, - enc_count, input_bfd) - != linesz * enc_count)) - return false; - oline = enclosing; - } - - linoff = (aux.x_sym.x_fcnary.x_fcn.x_lnnoptr - - enclosing->line_filepos); - - bfd_coff_swap_lineno_in (input_bfd, - (PTR) (finfo->linenos + linoff), - (PTR) &lin); - if (lin.l_lnno != 0 - || ((bfd_size_type) lin.l_addr.l_symndx - != ((esym - - isymesz - - ((bfd_byte *) - obj_coff_external_syms (input_bfd))) - / isymesz))) - aux.x_sym.x_fcnary.x_fcn.x_lnnoptr = 0; - else - { - bfd_byte *linpend, *linp; - bfd_vma offset; - bfd_size_type count; - - lin.l_addr.l_symndx = *indexp; - bfd_coff_swap_lineno_out (output_bfd, (PTR) &lin, - (PTR) (finfo->linenos - + linoff)); - - linpend = (finfo->linenos - + enc_count * linesz); - offset = (o->output_section->vma - + o->output_offset - - o->vma); - for (linp = finfo->linenos + linoff + linesz; - linp < linpend; - linp += linesz) - { - bfd_coff_swap_lineno_in (input_bfd, (PTR) linp, - (PTR) &lin); - if (lin.l_lnno == 0) - break; - lin.l_addr.l_paddr += offset; - bfd_coff_swap_lineno_out (output_bfd, - (PTR) &lin, - (PTR) linp); - } - - count = (linp - (finfo->linenos + linoff)) / linesz; - - aux.x_sym.x_fcnary.x_fcn.x_lnnoptr = - (o->output_section->line_filepos - + o->output_section->lineno_count * linesz); - - if (bfd_seek (output_bfd, - aux.x_sym.x_fcnary.x_fcn.x_lnnoptr, - SEEK_SET) != 0 - || (bfd_write (finfo->linenos + linoff, - linesz, count, output_bfd) - != linesz * count)) - return false; - - o->output_section->lineno_count += count; - - if (incls > 0) - { - struct internal_syment *iisp, *iispend; - long *iindp; - bfd_byte *oos; - - /* Update any C_BINCL or C_EINCL symbols - that refer to a line number in the - range we just output. */ - iisp = finfo->internal_syms; - iispend = (iisp - + obj_raw_syment_count (input_bfd)); - iindp = finfo->sym_indices; - oos = finfo->outsyms; - while (iisp < iispend) - { - if ((iisp->n_sclass == C_BINCL - || iisp->n_sclass == C_EINCL) - && ((bfd_size_type) iisp->n_value - >= enclosing->line_filepos + linoff) - && ((bfd_size_type) iisp->n_value - < (enclosing->line_filepos - + enc_count * linesz))) - { - struct internal_syment iis; - - bfd_coff_swap_sym_in (output_bfd, - (PTR) oos, - (PTR) &iis); - iis.n_value = - (iisp->n_value - - enclosing->line_filepos - - linoff - + aux.x_sym.x_fcnary.x_fcn.x_lnnoptr); - bfd_coff_swap_sym_out (output_bfd, - (PTR) &iis, - (PTR) oos); - --incls; - } - - iisp += iisp->n_numaux + 1; - iindp += iisp->n_numaux + 1; - oos += (iisp->n_numaux + 1) * osymesz; - } - } - } - } - } - - bfd_coff_swap_aux_out (output_bfd, (PTR) &aux, isymp->n_type, - isymp->n_sclass, i, isymp->n_numaux, - (PTR) outsym); - outsym += osymesz; - esym += isymesz; - } - } - - indexp += add; - isymp += add; - csectpp += add; - } - - /* If we swapped out a C_FILE symbol, guess that the next C_FILE - symbol will be the first symbol in the next input file. In the - normal case, this will save us from writing out the C_FILE symbol - again. */ - if (finfo->last_file_index != -1 - && (bfd_size_type) finfo->last_file_index >= syment_base) - { - finfo->last_file.n_value = output_index; - bfd_coff_swap_sym_out (output_bfd, (PTR) &finfo->last_file, - (PTR) (finfo->outsyms - + ((finfo->last_file_index - syment_base) - * osymesz))); - } - - /* Write the modified symbols to the output file. */ - if (outsym > finfo->outsyms) - { - if (bfd_seek (output_bfd, - obj_sym_filepos (output_bfd) + syment_base * osymesz, - SEEK_SET) != 0 - || (bfd_write (finfo->outsyms, outsym - finfo->outsyms, 1, - output_bfd) - != (bfd_size_type) (outsym - finfo->outsyms))) - return false; - - BFD_ASSERT ((obj_raw_syment_count (output_bfd) - + (outsym - finfo->outsyms) / osymesz) - == output_index); - - obj_raw_syment_count (output_bfd) = output_index; - } - - /* Don't let the linker relocation routines discard the symbols. */ - keep_syms = obj_coff_keep_syms (input_bfd); - obj_coff_keep_syms (input_bfd) = true; - - /* Relocate the contents of each section. */ - for (o = input_bfd->sections; o != NULL; o = o->next) - { - bfd_byte *contents; - - if ((o->flags & SEC_HAS_CONTENTS) == 0 - || o->_raw_size == 0 - || (o->flags & SEC_IN_MEMORY) != 0) - continue; - - /* We have set filepos correctly for the sections we created to - represent csects, so bfd_get_section_contents should work. */ - if (coff_section_data (input_bfd, o) != NULL - && coff_section_data (input_bfd, o)->contents != NULL) - contents = coff_section_data (input_bfd, o)->contents; - else - { - if (! bfd_get_section_contents (input_bfd, o, finfo->contents, - (file_ptr) 0, o->_raw_size)) - return false; - contents = finfo->contents; - } - - if ((o->flags & SEC_RELOC) != 0) - { - int target_index; - struct internal_reloc *internal_relocs; - struct internal_reloc *irel; - bfd_vma offset; - struct internal_reloc *irelend; - struct xcoff_link_hash_entry **rel_hash; - long r_symndx; - - /* Read in the relocs. */ - target_index = o->output_section->target_index; - internal_relocs = (xcoff_read_internal_relocs - (input_bfd, o, false, finfo->external_relocs, - true, - (finfo->section_info[target_index].relocs - + o->output_section->reloc_count))); - if (internal_relocs == NULL) - return false; - - /* Call processor specific code to relocate the section - contents. */ - if (! bfd_coff_relocate_section (output_bfd, finfo->info, - input_bfd, o, - contents, - internal_relocs, - finfo->internal_syms, - xcoff_data (input_bfd)->csects)) - return false; - - offset = o->output_section->vma + o->output_offset - o->vma; - irel = internal_relocs; - irelend = irel + o->reloc_count; - rel_hash = (finfo->section_info[target_index].rel_hashes - + o->output_section->reloc_count); - for (; irel < irelend; irel++, rel_hash++) - { - struct xcoff_link_hash_entry *h = NULL; - struct internal_ldrel ldrel; - - *rel_hash = NULL; - - /* Adjust the reloc address and symbol index. */ - - irel->r_vaddr += offset; - - r_symndx = irel->r_symndx; - - if (r_symndx != -1) - { - h = obj_xcoff_sym_hashes (input_bfd)[r_symndx]; - if (h != NULL - && (irel->r_type == R_TOC - || irel->r_type == R_GL - || irel->r_type == R_TCL - || irel->r_type == R_TRL - || irel->r_type == R_TRLA)) - { - /* This is a TOC relative reloc with a symbol - attached. The symbol should be the one which - this reloc is for. We want to make this - reloc against the TOC address of the symbol, - not the symbol itself. */ - BFD_ASSERT (h->toc_section != NULL); - BFD_ASSERT ((h->flags & XCOFF_SET_TOC) == 0); - if (h->u.toc_indx != -1) - irel->r_symndx = h->u.toc_indx; - else - { - struct xcoff_toc_rel_hash *n; - struct xcoff_link_section_info *si; - - n = ((struct xcoff_toc_rel_hash *) - bfd_alloc (finfo->output_bfd, - sizeof (struct xcoff_toc_rel_hash))); - if (n == NULL) - return false; - si = finfo->section_info + target_index; - n->next = si->toc_rel_hashes; - n->h = h; - n->rel = irel; - si->toc_rel_hashes = n; - } - } - else if (h != NULL) - { - /* This is a global symbol. */ - if (h->indx >= 0) - irel->r_symndx = h->indx; - else - { - /* This symbol is being written at the end - of the file, and we do not yet know the - symbol index. We save the pointer to the - hash table entry in the rel_hash list. - We set the indx field to -2 to indicate - that this symbol must not be stripped. */ - *rel_hash = h; - h->indx = -2; - } - } - else - { - long indx; - - indx = finfo->sym_indices[r_symndx]; - - if (indx == -1) - { - struct internal_syment *is; - - /* Relocations against a TC0 TOC anchor are - automatically transformed to be against - the TOC anchor in the output file. */ - is = finfo->internal_syms + r_symndx; - if (is->n_sclass == C_HIDEXT - && is->n_numaux > 0) - { - PTR auxptr; - union internal_auxent aux; - - auxptr = ((PTR) - (((bfd_byte *) - obj_coff_external_syms (input_bfd)) - + ((r_symndx + is->n_numaux) - * isymesz))); - bfd_coff_swap_aux_in (input_bfd, auxptr, - is->n_type, is->n_sclass, - is->n_numaux - 1, - is->n_numaux, - (PTR) &aux); - if (SMTYP_SMTYP (aux.x_csect.x_smtyp) == XTY_SD - && aux.x_csect.x_smclas == XMC_TC0) - indx = finfo->toc_symindx; - } - } - - if (indx != -1) - irel->r_symndx = indx; - else - { - struct internal_syment *is; - const char *name; - char buf[SYMNMLEN + 1]; - - /* This reloc is against a symbol we are - stripping. It would be possible to handle - this case, but I don't think it's worth it. */ - is = finfo->internal_syms + r_symndx; - - name = (_bfd_coff_internal_syment_name - (input_bfd, is, buf)); - if (name == NULL) - return false; - - if (! ((*finfo->info->callbacks->unattached_reloc) - (finfo->info, name, input_bfd, o, - irel->r_vaddr))) - return false; - } - } - } - - switch (irel->r_type) - { - default: - if (h == NULL - || h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak - || h->root.type == bfd_link_hash_common) - break; - /* Fall through. */ - case R_POS: - case R_NEG: - case R_RL: - case R_RLA: - /* This reloc needs to be copied into the .loader - section. */ - ldrel.l_vaddr = irel->r_vaddr; - if (r_symndx == -1) - ldrel.l_symndx = -1; - else if (h == NULL - || (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak - || h->root.type == bfd_link_hash_common)) - { - asection *sec; - - if (h == NULL) - sec = xcoff_data (input_bfd)->csects[r_symndx]; - else if (h->root.type == bfd_link_hash_common) - sec = h->root.u.c.p->section; - else - sec = h->root.u.def.section; - sec = sec->output_section; - - if (strcmp (sec->name, ".text") == 0) - ldrel.l_symndx = 0; - else if (strcmp (sec->name, ".data") == 0) - ldrel.l_symndx = 1; - else if (strcmp (sec->name, ".bss") == 0) - ldrel.l_symndx = 2; - else - { - (*_bfd_error_handler) - ("%s: loader reloc in unrecognized section `%s'", - bfd_get_filename (input_bfd), - sec->name); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; - } - } - else - { - if (h->ldindx < 0) - { - (*_bfd_error_handler) - ("%s: `%s' in loader reloc but not loader sym", - bfd_get_filename (input_bfd), - h->root.root.string); - bfd_set_error (bfd_error_bad_value); - return false; - } - ldrel.l_symndx = h->ldindx; - } - ldrel.l_rtype = (irel->r_size << 8) | irel->r_type; - ldrel.l_rsecnm = o->output_section->target_index; - if (xcoff_hash_table (finfo->info)->textro - && strcmp (o->output_section->name, ".text") == 0) - { - (*_bfd_error_handler) - ("%s: loader reloc in read-only section %s", - bfd_get_filename (input_bfd), - bfd_get_section_name (finfo->output_bfd, - o->output_section)); - bfd_set_error (bfd_error_invalid_operation); - return false; - } - xcoff_swap_ldrel_out (output_bfd, &ldrel, - finfo->ldrel); - BFD_ASSERT (sizeof (struct external_ldrel) == LDRELSZ); - ++finfo->ldrel; - break; - - case R_TOC: - case R_GL: - case R_TCL: - case R_TRL: - case R_TRLA: - /* We should never need a .loader reloc for a TOC - relative reloc. */ - break; - } - } - - o->output_section->reloc_count += o->reloc_count; - } - - /* Write out the modified section contents. */ - if (! bfd_set_section_contents (output_bfd, o->output_section, - contents, o->output_offset, - (o->_cooked_size != 0 - ? o->_cooked_size - : o->_raw_size))) - return false; - } - - obj_coff_keep_syms (input_bfd) = keep_syms; - - if (! finfo->info->keep_memory) - { - if (! _bfd_coff_free_symbols (input_bfd)) - return false; - } - - return true; -} - -#undef N_TMASK -#undef N_BTSHFT - -/* Write out a non-XCOFF global symbol. */ - -static boolean -xcoff_write_global_symbol (h, p) - struct xcoff_link_hash_entry *h; - PTR p; -{ - struct xcoff_final_link_info *finfo = (struct xcoff_final_link_info *) p; - bfd *output_bfd; - bfd_byte *outsym; - struct internal_syment isym; - union internal_auxent aux; - - output_bfd = finfo->output_bfd; - - /* If this symbol was garbage collected, just skip it. */ - if (xcoff_hash_table (finfo->info)->gc - && (h->flags & XCOFF_MARK) == 0) - return true; - - /* If we need a .loader section entry, write it out. */ - if (h->ldsym != NULL) - { - struct internal_ldsym *ldsym; - bfd *impbfd; - - ldsym = h->ldsym; - - if (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - { - ldsym->l_value = 0; - ldsym->l_scnum = N_UNDEF; - ldsym->l_smtype = XTY_ER; - impbfd = h->root.u.undef.abfd; - } - else if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - asection *sec; - - sec = h->root.u.def.section; - ldsym->l_value = (sec->output_section->vma - + sec->output_offset - + h->root.u.def.value); - ldsym->l_scnum = sec->output_section->target_index; - ldsym->l_smtype = XTY_SD; - impbfd = sec->owner; - } - else - abort (); - - if (((h->flags & XCOFF_DEF_REGULAR) == 0 - && (h->flags & XCOFF_DEF_DYNAMIC) != 0) - || (h->flags & XCOFF_IMPORT) != 0) - ldsym->l_smtype |= L_IMPORT; - if (((h->flags & XCOFF_DEF_REGULAR) != 0 - && (h->flags & XCOFF_DEF_DYNAMIC) != 0) - || (h->flags & XCOFF_EXPORT) != 0) - ldsym->l_smtype |= L_EXPORT; - if ((h->flags & XCOFF_ENTRY) != 0) - ldsym->l_smtype |= L_ENTRY; - - ldsym->l_smclas = h->smclas; - - if (ldsym->l_ifile == (bfd_size_type) -1) - ldsym->l_ifile = 0; - else if (ldsym->l_ifile == 0) - { - if ((ldsym->l_smtype & L_IMPORT) == 0) - ldsym->l_ifile = 0; - else if (impbfd == NULL) - ldsym->l_ifile = 0; - else - { - BFD_ASSERT (impbfd->xvec == output_bfd->xvec); - ldsym->l_ifile = xcoff_data (impbfd)->import_file_id; - } - } - - ldsym->l_parm = 0; - - BFD_ASSERT (h->ldindx >= 0); - BFD_ASSERT (LDSYMSZ == sizeof (struct external_ldsym)); - xcoff_swap_ldsym_out (output_bfd, ldsym, finfo->ldsym + h->ldindx - 3); - h->ldsym = NULL; - } - - /* If this symbol needs global linkage code, write it out. */ - if (h->root.type == bfd_link_hash_defined - && (h->root.u.def.section - == xcoff_hash_table (finfo->info)->linkage_section)) - { - bfd_byte *p; - bfd_vma tocoff; - unsigned int i; - - p = h->root.u.def.section->contents + h->root.u.def.value; - - /* The first instruction in the global linkage code loads a - specific TOC element. */ - tocoff = (h->descriptor->toc_section->output_section->vma - + h->descriptor->toc_section->output_offset - - xcoff_data (output_bfd)->toc); - if ((h->descriptor->flags & XCOFF_SET_TOC) != 0) - tocoff += h->descriptor->u.toc_offset; - bfd_put_32 (output_bfd, XCOFF_GLINK_FIRST | (tocoff & 0xffff), p); - for (i = 0, p += 4; - i < sizeof xcoff_glink_code / sizeof xcoff_glink_code[0]; - i++, p += 4) - bfd_put_32 (output_bfd, xcoff_glink_code[i], p); - } - - /* If we created a TOC entry for this symbol, write out the required - relocs. */ - if ((h->flags & XCOFF_SET_TOC) != 0) - { - asection *tocsec; - asection *osec; - int oindx; - struct internal_reloc *irel; - struct internal_ldrel ldrel; - - tocsec = h->toc_section; - osec = tocsec->output_section; - oindx = osec->target_index; - irel = finfo->section_info[oindx].relocs + osec->reloc_count; - irel->r_vaddr = (osec->vma - + tocsec->output_offset - + h->u.toc_offset); - if (h->indx >= 0) - irel->r_symndx = h->indx; - else - { - h->indx = -2; - irel->r_symndx = obj_raw_syment_count (output_bfd); - } - irel->r_type = R_POS; - irel->r_size = 31; - finfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL; - ++osec->reloc_count; - - BFD_ASSERT (h->ldindx >= 0); - ldrel.l_vaddr = irel->r_vaddr; - ldrel.l_symndx = h->ldindx; - ldrel.l_rtype = (31 << 8) | R_POS; - ldrel.l_rsecnm = oindx; - xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel); - ++finfo->ldrel; - } - - /* If this symbol is a specially defined function descriptor, write - it out. The first word is the address of the function code - itself, the second word is the address of the TOC, and the third - word is zero. */ - if ((h->flags & XCOFF_DESCRIPTOR) != 0 - && h->root.type == bfd_link_hash_defined - && (h->root.u.def.section - == xcoff_hash_table (finfo->info)->descriptor_section)) - { - asection *sec; - asection *osec; - int oindx; - bfd_byte *p; - struct xcoff_link_hash_entry *hentry; - asection *esec; - struct internal_reloc *irel; - struct internal_ldrel ldrel; - asection *tsec; - - sec = h->root.u.def.section; - osec = sec->output_section; - oindx = osec->target_index; - p = sec->contents + h->root.u.def.value; - - hentry = h->descriptor; - BFD_ASSERT (hentry != NULL - && (hentry->root.type == bfd_link_hash_defined - || hentry->root.type == bfd_link_hash_defweak)); - esec = hentry->root.u.def.section; - bfd_put_32 (output_bfd, - (esec->output_section->vma - + esec->output_offset - + hentry->root.u.def.value), - p); - - irel = finfo->section_info[oindx].relocs + osec->reloc_count; - irel->r_vaddr = (osec->vma - + sec->output_offset - + h->root.u.def.value); - irel->r_symndx = esec->output_section->target_index; - irel->r_type = R_POS; - irel->r_size = 31; - finfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL; - ++osec->reloc_count; - - ldrel.l_vaddr = irel->r_vaddr; - if (strcmp (esec->output_section->name, ".text") == 0) - ldrel.l_symndx = 0; - else if (strcmp (esec->output_section->name, ".data") == 0) - ldrel.l_symndx = 1; - else if (strcmp (esec->output_section->name, ".bss") == 0) - ldrel.l_symndx = 2; - else - { - (*_bfd_error_handler) - ("%s: loader reloc in unrecognized section `%s'", - bfd_get_filename (output_bfd), - esec->output_section->name); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; - } - ldrel.l_rtype = (31 << 8) | R_POS; - ldrel.l_rsecnm = oindx; - xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel); - ++finfo->ldrel; - - bfd_put_32 (output_bfd, xcoff_data (output_bfd)->toc, p + 4); - - tsec = coff_section_from_bfd_index (output_bfd, - xcoff_data (output_bfd)->sntoc); - - ++irel; - irel->r_vaddr = (osec->vma - + sec->output_offset - + h->root.u.def.value - + 4); - irel->r_symndx = tsec->output_section->target_index; - irel->r_type = R_POS; - irel->r_size = 31; - finfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL; - ++osec->reloc_count; - - ldrel.l_vaddr = irel->r_vaddr; - if (strcmp (tsec->output_section->name, ".text") == 0) - ldrel.l_symndx = 0; - else if (strcmp (tsec->output_section->name, ".data") == 0) - ldrel.l_symndx = 1; - else if (strcmp (tsec->output_section->name, ".bss") == 0) - ldrel.l_symndx = 2; - else - { - (*_bfd_error_handler) - ("%s: loader reloc in unrecognized section `%s'", - bfd_get_filename (output_bfd), - tsec->output_section->name); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; - } - ldrel.l_rtype = (31 << 8) | R_POS; - ldrel.l_rsecnm = oindx; - xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel); - ++finfo->ldrel; - } - - if (h->indx >= 0) - return true; - - if (h->indx != -2 - && (finfo->info->strip == strip_all - || (finfo->info->strip == strip_some - && (bfd_hash_lookup (finfo->info->keep_hash, - h->root.root.string, false, false) - == NULL)))) - return true; - - if (h->indx != -2 - && (h->flags & (XCOFF_REF_REGULAR | XCOFF_DEF_REGULAR)) == 0) - return true; - - outsym = finfo->outsyms; - - memset (&aux, 0, sizeof aux); - - h->indx = obj_raw_syment_count (output_bfd); - - if (strlen (h->root.root.string) <= SYMNMLEN) - strncpy (isym._n._n_name, h->root.root.string, SYMNMLEN); - else - { - boolean hash; - bfd_size_type indx; - - hash = true; - if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0) - hash = false; - indx = _bfd_stringtab_add (finfo->strtab, h->root.root.string, hash, - false); - if (indx == (bfd_size_type) -1) - return false; - isym._n._n_n._n_zeroes = 0; - isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx; - } - - if (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak) - { - isym.n_value = 0; - isym.n_scnum = N_UNDEF; - isym.n_sclass = C_EXT; - aux.x_csect.x_smtyp = XTY_ER; - } - else if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - struct xcoff_link_size_list *l; - - isym.n_value = (h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset - + h->root.u.def.value); - isym.n_scnum = h->root.u.def.section->output_section->target_index; - isym.n_sclass = C_HIDEXT; - aux.x_csect.x_smtyp = XTY_SD; - - if ((h->flags & XCOFF_HAS_SIZE) != 0) - { - for (l = xcoff_hash_table (finfo->info)->size_list; - l != NULL; - l = l->next) - { - if (l->h == h) - { - aux.x_csect.x_scnlen.l = l->size; - break; - } - } - } - } - else if (h->root.type == bfd_link_hash_common) - { - isym.n_value = (h->root.u.c.p->section->output_section->vma - + h->root.u.c.p->section->output_offset); - isym.n_scnum = h->root.u.c.p->section->output_section->target_index; - isym.n_sclass = C_EXT; - aux.x_csect.x_smtyp = XTY_CM; - aux.x_csect.x_scnlen.l = h->root.u.c.size; - } - else - abort (); - - isym.n_type = T_NULL; - isym.n_numaux = 1; - - bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym); - outsym += bfd_coff_symesz (output_bfd); - - aux.x_csect.x_smclas = h->smclas; - - bfd_coff_swap_aux_out (output_bfd, (PTR) &aux, T_NULL, isym.n_sclass, 0, 1, - (PTR) outsym); - outsym += bfd_coff_auxesz (output_bfd); - - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - /* We just output an SD symbol. Now output an LD symbol. */ - - h->indx += 2; - - isym.n_sclass = C_EXT; - bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym); - outsym += bfd_coff_symesz (output_bfd); - - aux.x_csect.x_smtyp = XTY_LD; - aux.x_csect.x_scnlen.l = obj_raw_syment_count (output_bfd); - - bfd_coff_swap_aux_out (output_bfd, (PTR) &aux, T_NULL, C_EXT, 0, 1, - (PTR) outsym); - outsym += bfd_coff_auxesz (output_bfd); - } - - if (bfd_seek (output_bfd, - (obj_sym_filepos (output_bfd) - + (obj_raw_syment_count (output_bfd) - * bfd_coff_symesz (output_bfd))), - SEEK_SET) != 0 - || (bfd_write (finfo->outsyms, outsym - finfo->outsyms, 1, output_bfd) - != (bfd_size_type) (outsym - finfo->outsyms))) - return false; - obj_raw_syment_count (output_bfd) += - (outsym - finfo->outsyms) / bfd_coff_symesz (output_bfd); - - return true; -} - -/* Handle a link order which is supposed to generate a reloc. */ - -static boolean -xcoff_reloc_link_order (output_bfd, finfo, output_section, link_order) - bfd *output_bfd; - struct xcoff_final_link_info *finfo; - asection *output_section; - struct bfd_link_order *link_order; -{ - reloc_howto_type *howto; - struct xcoff_link_hash_entry *h; - asection *hsec; - bfd_vma hval; - bfd_vma addend; - struct internal_reloc *irel; - struct xcoff_link_hash_entry **rel_hash_ptr; - struct internal_ldrel ldrel; - - if (link_order->type == bfd_section_reloc_link_order) - { - /* We need to somehow locate a symbol in the right section. The - symbol must either have a value of zero, or we must adjust - the addend by the value of the symbol. FIXME: Write this - when we need it. The old linker couldn't handle this anyhow. */ - abort (); - } - - howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); - if (howto == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - h = ((struct xcoff_link_hash_entry *) - bfd_wrapped_link_hash_lookup (output_bfd, finfo->info, - link_order->u.reloc.p->u.name, - false, false, true)); - if (h == NULL) - { - if (! ((*finfo->info->callbacks->unattached_reloc) - (finfo->info, link_order->u.reloc.p->u.name, (bfd *) NULL, - (asection *) NULL, (bfd_vma) 0))) - return false; - return true; - } - - if (h->root.type == bfd_link_hash_common) - { - hsec = h->root.u.c.p->section; - hval = 0; - } - else if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - hsec = h->root.u.def.section; - hval = h->root.u.def.value; - } - else - { - hsec = NULL; - hval = 0; - } - - addend = link_order->u.reloc.p->addend; - if (hsec != NULL) - addend += (hsec->output_section->vma - + hsec->output_offset - + hval); - - if (addend != 0) - { - bfd_size_type size; - bfd_byte *buf; - bfd_reloc_status_type rstat; - boolean ok; - - size = bfd_get_reloc_size (howto); - buf = (bfd_byte *) bfd_zmalloc (size); - if (buf == NULL) - return false; - - rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf); - switch (rstat) - { - case bfd_reloc_ok: - break; - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - if (! ((*finfo->info->callbacks->reloc_overflow) - (finfo->info, link_order->u.reloc.p->u.name, - howto->name, addend, (bfd *) NULL, (asection *) NULL, - (bfd_vma) 0))) - { - free (buf); - return false; - } - break; - } - ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf, - (file_ptr) link_order->offset, size); - free (buf); - if (! ok) - return false; - } - - /* Store the reloc information in the right place. It will get - swapped and written out at the end of the final_link routine. */ - - irel = (finfo->section_info[output_section->target_index].relocs - + output_section->reloc_count); - rel_hash_ptr = (finfo->section_info[output_section->target_index].rel_hashes - + output_section->reloc_count); - - memset (irel, 0, sizeof (struct internal_reloc)); - *rel_hash_ptr = NULL; - - irel->r_vaddr = output_section->vma + link_order->offset; - - if (h->indx >= 0) - irel->r_symndx = h->indx; - else - { - /* Set the index to -2 to force this symbol to get written out. */ - h->indx = -2; - *rel_hash_ptr = h; - irel->r_symndx = 0; - } - - irel->r_type = howto->type; - irel->r_size = howto->bitsize - 1; - if (howto->complain_on_overflow == complain_overflow_signed) - irel->r_size |= 0x80; - - ++output_section->reloc_count; - - /* Now output the reloc to the .loader section. */ - - ldrel.l_vaddr = irel->r_vaddr; - - if (hsec != NULL) - { - const char *secname; - - secname = hsec->output_section->name; - - if (strcmp (secname, ".text") == 0) - ldrel.l_symndx = 0; - else if (strcmp (secname, ".data") == 0) - ldrel.l_symndx = 1; - else if (strcmp (secname, ".bss") == 0) - ldrel.l_symndx = 2; - else - { - (*_bfd_error_handler) - ("%s: loader reloc in unrecognized section `%s'", - bfd_get_filename (output_bfd), secname); - bfd_set_error (bfd_error_nonrepresentable_section); - return false; - } - } - else - { - if (h->ldindx < 0) - { - (*_bfd_error_handler) - ("%s: `%s' in loader reloc but not loader sym", - bfd_get_filename (output_bfd), - h->root.root.string); - bfd_set_error (bfd_error_bad_value); - return false; - } - ldrel.l_symndx = h->ldindx; - } - - ldrel.l_rtype = (irel->r_size << 8) | irel->r_type; - ldrel.l_rsecnm = output_section->target_index; - xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel); - ++finfo->ldrel; - - return true; -} - -/* Sort relocs by VMA. This is called via qsort. */ - -static int -xcoff_sort_relocs (p1, p2) - const PTR p1; - const PTR p2; -{ - const struct internal_reloc *r1 = (const struct internal_reloc *) p1; - const struct internal_reloc *r2 = (const struct internal_reloc *) p2; - - if (r1->r_vaddr > r2->r_vaddr) - return 1; - else if (r1->r_vaddr < r2->r_vaddr) - return -1; - else - return 0; -} - -/* This is the relocation function for the RS/6000/POWER/PowerPC. - This is currently the only processor which uses XCOFF; I hope that - will never change. */ - -boolean -_bfd_ppc_xcoff_relocate_section (output_bfd, info, input_bfd, - input_section, contents, relocs, syms, - sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - struct internal_reloc *relocs; - struct internal_syment *syms; - asection **sections; -{ - struct internal_reloc *rel; - struct internal_reloc *relend; - - rel = relocs; - relend = rel + input_section->reloc_count; - for (; rel < relend; rel++) - { - long symndx; - struct xcoff_link_hash_entry *h; - struct internal_syment *sym; - bfd_vma addend; - bfd_vma val; - struct reloc_howto_struct howto; - bfd_reloc_status_type rstat; - - /* Relocation type R_REF is a special relocation type which is - merely used to prevent garbage collection from occurring for - the csect including the symbol which it references. */ - if (rel->r_type == R_REF) - continue; - - symndx = rel->r_symndx; - - if (symndx == -1) - { - h = NULL; - sym = NULL; - addend = 0; - } - else - { - h = obj_xcoff_sym_hashes (input_bfd)[symndx]; - sym = syms + symndx; - addend = - sym->n_value; - } - - /* We build the howto information on the fly. */ - - howto.type = rel->r_type; - howto.rightshift = 0; - howto.size = 2; - howto.bitsize = (rel->r_size & 0x1f) + 1; - howto.pc_relative = false; - howto.bitpos = 0; - if ((rel->r_size & 0x80) != 0) - howto.complain_on_overflow = complain_overflow_signed; - else - howto.complain_on_overflow = complain_overflow_bitfield; - howto.special_function = NULL; - howto.name = "internal"; - howto.partial_inplace = true; - if (howto.bitsize == 32) - howto.src_mask = howto.dst_mask = 0xffffffff; - else - { - howto.src_mask = howto.dst_mask = (1 << howto.bitsize) - 1; - if (howto.bitsize == 16) - howto.size = 1; - } - howto.pcrel_offset = false; - - val = 0; - - if (h == NULL) - { - asection *sec; - - if (symndx == -1) - { - sec = bfd_abs_section_ptr; - val = 0; - } - else - { - sec = sections[symndx]; - /* Hack to make sure we use the right TOC anchor value - if this reloc is against the TOC anchor. */ - if (sec->name[3] == '0' - && strcmp (sec->name, ".tc0") == 0) - val = xcoff_data (output_bfd)->toc; - else - val = (sec->output_section->vma - + sec->output_offset - + sym->n_value - - sec->vma); - } - } - else - { - if (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - { - asection *sec; - - sec = h->root.u.def.section; - val = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_common) - { - asection *sec; - - sec = h->root.u.c.p->section; - val = (sec->output_section->vma - + sec->output_offset); - } - else if ((h->flags & XCOFF_DEF_DYNAMIC) != 0 - || (h->flags & XCOFF_IMPORT) != 0) - { - /* Every symbol in a shared object is defined somewhere. */ - val = 0; - } - else if (! info->relocateable - && ! info->shared) - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, input_section, - rel->r_vaddr - input_section->vma))) - return false; - } - } - - /* I took the relocation type definitions from two documents: - the PowerPC AIX Version 4 Application Binary Interface, First - Edition (April 1992), and the PowerOpen ABI, Big-Endian - 32-Bit Hardware Implementation (June 30, 1994). Differences - between the documents are noted below. */ - - switch (rel->r_type) - { - case R_RTB: - case R_RRTBI: - case R_RRTBA: - /* These relocs are defined by the PowerPC ABI to be - relative branches which use half of the difference - between the symbol and the program counter. I can't - quite figure out when this is useful. These relocs are - not defined by the PowerOpen ABI. */ - default: - (*_bfd_error_handler) - ("%s: unsupported relocation type 0x%02x", - bfd_get_filename (input_bfd), (unsigned int) rel->r_type); - bfd_set_error (bfd_error_bad_value); - return false; - case R_POS: - /* Simple positive relocation. */ - break; - case R_NEG: - /* Simple negative relocation. */ - val = - val; - break; - case R_REL: - /* Simple PC relative relocation. */ - howto.pc_relative = true; - break; - case R_TOC: - /* TOC relative relocation. The value in the instruction in - the input file is the offset from the input file TOC to - the desired location. We want the offset from the final - TOC to the desired location. We have: - isym = iTOC + in - iinsn = in + o - osym = oTOC + on - oinsn = on + o - so we must change insn by on - in. - */ - case R_GL: - /* Global linkage relocation. The value of this relocation - is the address of the entry in the TOC section. */ - case R_TCL: - /* Local object TOC address. I can't figure out the - difference between this and case R_GL. */ - case R_TRL: - /* TOC relative relocation. A TOC relative load instruction - which may be changed to a load address instruction. - FIXME: We don't currently implement this optimization. */ - case R_TRLA: - /* TOC relative relocation. This is a TOC relative load - address instruction which may be changed to a load - instruction. FIXME: I don't know if this is the correct - implementation. */ - if (h != NULL && h->toc_section == NULL) - { - (*_bfd_error_handler) - ("%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry", - bfd_get_filename (input_bfd), rel->r_vaddr, - h->root.root.string); - bfd_set_error (bfd_error_bad_value); - return false; - } - if (h != NULL) - { - BFD_ASSERT ((h->flags & XCOFF_SET_TOC) == 0); - val = (h->toc_section->output_section->vma - + h->toc_section->output_offset); - } - val = ((val - xcoff_data (output_bfd)->toc) - - (sym->n_value - xcoff_data (input_bfd)->toc)); - addend = 0; - break; - case R_BA: - /* Absolute branch. We don't want to mess with the lower - two bits of the instruction. */ - case R_CAI: - /* The PowerPC ABI defines this as an absolute call which - may be modified to become a relative call. The PowerOpen - ABI does not define this relocation type. */ - case R_RBA: - /* Absolute branch which may be modified to become a - relative branch. */ - case R_RBAC: - /* The PowerPC ABI defines this as an absolute branch to a - fixed address which may be modified to an absolute branch - to a symbol. The PowerOpen ABI does not define this - relocation type. */ - case R_RBRC: - /* The PowerPC ABI defines this as an absolute branch to a - fixed address which may be modified to a relative branch. - The PowerOpen ABI does not define this relocation type. */ - howto.src_mask &= ~3; - howto.dst_mask = howto.src_mask; - break; - case R_BR: - /* Relative branch. We don't want to mess with the lower - two bits of the instruction. */ - case R_CREL: - /* The PowerPC ABI defines this as a relative call which may - be modified to become an absolute call. The PowerOpen - ABI does not define this relocation type. */ - case R_RBR: - /* A relative branch which may be modified to become an - absolute branch. FIXME: We don't implement this, - although we should for symbols of storage mapping class - XMC_XO. */ - howto.pc_relative = true; - howto.src_mask &= ~3; - howto.dst_mask = howto.src_mask; - break; - case R_RL: - /* The PowerPC AIX ABI describes this as a load which may be - changed to a load address. The PowerOpen ABI says this - is the same as case R_POS. */ - break; - case R_RLA: - /* The PowerPC AIX ABI describes this as a load address - which may be changed to a load. The PowerOpen ABI says - this is the same as R_POS. */ - break; - } - - /* If we see an R_BR or R_RBR reloc which is jumping to global - linkage code, and it is followed by an appropriate cror nop - instruction, we replace the cror with lwz r2,20(r1). This - restores the TOC after the glink code. Contrariwise, if the - call is followed by a lwz r2,20(r1), but the call is not - going to global linkage code, we can replace the load with a - cror. */ - if ((rel->r_type == R_BR || rel->r_type == R_RBR) - && h != NULL - && h->root.type == bfd_link_hash_defined - && (rel->r_vaddr - input_section->vma + 8 - <= input_section->_cooked_size)) - { - bfd_byte *pnext; - unsigned long next; - - pnext = contents + (rel->r_vaddr - input_section->vma) + 4; - next = bfd_get_32 (input_bfd, pnext); - if (h->smclas == XMC_GL) - { - if (next == 0x4def7b82 /* cror 15,15,15 */ - || next == 0x4ffffb82) /* cror 31,31,31 */ - bfd_put_32 (input_bfd, 0x80410014, pnext); /* lwz r1,20(r1) */ - } - else - { - if (next == 0x80410014) /* lwz r1,20(r1) */ - bfd_put_32 (input_bfd, 0x4ffffb82, pnext); /* cror 31,31,31 */ - } - } - - /* A PC relative reloc includes the section address. */ - if (howto.pc_relative) - addend += input_section->vma; - - rstat = _bfd_final_link_relocate (&howto, input_bfd, input_section, - contents, - rel->r_vaddr - input_section->vma, - val, addend); - - switch (rstat) - { - default: - abort (); - case bfd_reloc_ok: - break; - case bfd_reloc_overflow: - { - const char *name; - char buf[SYMNMLEN + 1]; - char howto_name[10]; - - if (symndx == -1) - name = "*ABS*"; - else if (h != NULL) - name = h->root.root.string; - else - { - name = _bfd_coff_internal_syment_name (input_bfd, sym, buf); - if (name == NULL) - return false; - } - sprintf (howto_name, "0x%02x", rel->r_type); - - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto_name, (bfd_vma) 0, input_bfd, - input_section, rel->r_vaddr - input_section->vma))) - return false; - } - } - } - - return true; -} |