Upgrade to gdb version 4.11

This commit is contained in:
pk 1994-01-28 12:37:29 +00:00
parent e6e5bff5d5
commit 1b943a732e
45 changed files with 23169 additions and 0 deletions

View File

@ -0,0 +1,24 @@
# $Id: Makefile,v 1.1 1994/01/28 12:37:29 pk Exp $
LIB= bfd
NOPROFILE=
NOPIC=
CFLAGS+= -I$(.CURDIR)/arch/$(MACHINE_ARCH) -I$(.CURDIR) \
-I$(.CURDIR)/../include
.PATH: $(.CURDIR)/arch/$(MACHINE_ARCH)
SRCS= archive.c archures.c bfd.c cache.c coffgen.c core.c ctor.c \
format.c init.c libbfd.c opncls.c reloc.c seclet.c section.c \
syms.c targets.c ecoff.c elf.c srec.c aout32.c \
stab-syms.c trad-core.c
.include "arch/$(MACHINE_ARCH)/Makefile.inc"
targets.o archures.o: $(.CURDIR)/$(.TARGET:S/.o$/.c/)
$(CC) $(CFLAGS) $(VECTORS) -c -o $(.TARGET) $(.IMPSRC)
install:
.include <bsd.lib.mk>

View File

@ -0,0 +1,432 @@
/* Define a target vector and some small routines for a variant of a.out.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: aout-target.h,v 1.1 1994/01/28 12:37:31 pk Exp $
*/
#include "aout/aout64.h"
#include "aout/stab_gnu.h"
#include "aout/ar.h"
/*#include "libaout.h"*/
extern CONST struct reloc_howto_struct * NAME(aout,reloc_type_lookup) ();
/* Set parameters about this a.out file that are machine-dependent.
This routine is called from some_aout_object_p just before it returns. */
#ifndef MY_callback
static bfd_target *
DEFUN(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);
/* 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
/* Don't set sizes now -- can't be sure until we know arch & mach.
Sizes get set in set_sizes callback, later. */
#if 0
adata(abfd).page_size = PAGE_SIZE;
#ifdef SEGMENT_SIZE
adata(abfd).segment_size = SEGMENT_SIZE;
#else
adata(abfd).segment_size = PAGE_SIZE;
#endif
adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE;
#endif
return abfd->xvec;
}
#endif
#ifndef MY_object_p
/* Finish up the reading of an a.out file header */
static bfd_target *
DEFUN(MY(object_p),(abfd),
bfd *abfd)
{
struct external_exec exec_bytes; /* Raw exec header from file */
struct internal_exec exec; /* Cleaned-up exec header */
bfd_target *target;
if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
!= EXEC_BYTES_SIZE) {
bfd_error = wrong_format;
return 0;
}
#ifdef NO_SWAP_MAGIC
memcpy (&exec.a_info, exec_bytes.e_info, sizeof(exec.a_info));
#else
exec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
#endif /* NO_SWAP_MAGIC */
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 = NAME(aout,some_aout_object_p) (abfd, &exec, MY(callback));
#ifdef ENTRY_CAN_BE_ZERO
/* The NEWSOS3 entry-point is/was 0, which (amongst other lossage)
* means that it isn't obvious if EXEC_P should be set.
* All of the following must be true for an executable:
* There must be no relocations, the bfd can be neither an
* archive nor an archive element, and the file must be executable. */
if (exec.a_trsize + exec.a_drsize == 0
&& bfd_get_format(abfd) == bfd_object && abfd->my_archive == NULL)
{
struct stat buf;
#ifndef S_IXUSR
#define S_IXUSR 0100 /* Execute by owner. */
#endif
if (stat(abfd->filename, &buf) == 0 && (buf.st_mode & S_IXUSR))
abfd->flags |= EXEC_P;
}
#endif /* ENTRY_CAN_BE_ZERO */
return target;
}
#define MY_object_p MY(object_p)
#endif
#ifndef MY_mkobject
static boolean
DEFUN(MY(mkobject),(abfd),
bfd *abfd)
{
if (NAME(aout,mkobject)(abfd) == false)
return false;
#if 0 /* Sizes get set in set_sizes callback, later, after we know
the architecture and machine. */
adata(abfd).page_size = PAGE_SIZE;
#ifdef SEGMENT_SIZE
adata(abfd).segment_size = SEGMENT_SIZE;
#else
adata(abfd).segment_size = PAGE_SIZE;
#endif
adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE;
#endif
return true;
}
#define MY_mkobject MY(mkobject)
#endif
/* Write an object file.
Section contents have already been written. We write the
file header, symbols, and relocation. */
#ifndef MY_write_object_contents
static boolean
DEFUN(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
WRITE_HEADERS(abfd, execp);
return true;
}
#define MY_write_object_contents MY(write_object_contents)
#endif
#ifndef MY_set_sizes
static boolean
DEFUN(MY(set_sizes),(abfd), bfd *abfd)
{
adata(abfd).page_size = PAGE_SIZE;
#ifdef SEGMENT_SIZE
adata(abfd).segment_size = SEGMENT_SIZE;
#else
adata(abfd).segment_size = PAGE_SIZE;
#endif
adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE;
return true;
}
#define MY_set_sizes MY(set_sizes)
#endif
#ifndef MY_backend_data
static CONST struct aout_backend_data MY(backend_data) = {
0, /* zmagic contiguous */
0, /* text incl header */
0, /* text vma? */
MY_set_sizes,
0, /* exec header is counted */
};
#define MY_backend_data &MY(backend_data)
#endif
/* We assume BFD generic archive files. */
#ifndef MY_openr_next_archived_file
#define MY_openr_next_archived_file bfd_generic_openr_next_archived_file
#endif
#ifndef MY_generic_stat_arch_elt
#define MY_generic_stat_arch_elt bfd_generic_stat_arch_elt
#endif
#ifndef MY_slurp_armap
#define MY_slurp_armap bfd_slurp_bsd_armap
#endif
#ifndef MY_slurp_extended_name_table
#define MY_slurp_extended_name_table _bfd_slurp_extended_name_table
#endif
#ifndef MY_write_armap
#define MY_write_armap bsd_write_armap
#endif
#ifndef MY_truncate_arname
#define MY_truncate_arname bfd_bsd_truncate_arname
#endif
/* No core file defined here -- configure in trad-core.c separately. */
#ifndef MY_core_file_failing_command
#define MY_core_file_failing_command _bfd_dummy_core_file_failing_command
#endif
#ifndef MY_core_file_failing_signal
#define MY_core_file_failing_signal _bfd_dummy_core_file_failing_signal
#endif
#ifndef MY_core_file_matches_executable_p
#define MY_core_file_matches_executable_p \
_bfd_dummy_core_file_matches_executable_p
#endif
#ifndef MY_core_file_p
#define MY_core_file_p _bfd_dummy_target
#endif
#ifndef MY_bfd_debug_info_start
#define MY_bfd_debug_info_start bfd_void
#endif
#ifndef MY_bfd_debug_info_end
#define MY_bfd_debug_info_end bfd_void
#endif
#ifndef MY_bfd_debug_info_accumulate
#define MY_bfd_debug_info_accumulate \
(void (*) PARAMS ((bfd*, struct sec *))) bfd_void
#endif
#ifndef MY_core_file_failing_command
#define MY_core_file_failing_command NAME(aout,core_file_failing_command)
#endif
#ifndef MY_core_file_failing_signal
#define MY_core_file_failing_signal NAME(aout,core_file_failing_signal)
#endif
#ifndef MY_core_file_matches_executable_p
#define MY_core_file_matches_executable_p NAME(aout,core_file_matches_executable_p)
#endif
#ifndef MY_slurp_armap
#define MY_slurp_armap NAME(aout,slurp_armap)
#endif
#ifndef MY_slurp_extended_name_table
#define MY_slurp_extended_name_table NAME(aout,slurp_extended_name_table)
#endif
#ifndef MY_truncate_arname
#define MY_truncate_arname NAME(aout,truncate_arname)
#endif
#ifndef MY_write_armap
#define MY_write_armap NAME(aout,write_armap)
#endif
#ifndef MY_close_and_cleanup
#define MY_close_and_cleanup NAME(aout,close_and_cleanup)
#endif
#ifndef MY_set_section_contents
#define MY_set_section_contents NAME(aout,set_section_contents)
#endif
#ifndef MY_get_section_contents
#define MY_get_section_contents NAME(aout,get_section_contents)
#endif
#ifndef MY_new_section_hook
#define MY_new_section_hook NAME(aout,new_section_hook)
#endif
#ifndef MY_get_symtab_upper_bound
#define MY_get_symtab_upper_bound NAME(aout,get_symtab_upper_bound)
#endif
#ifndef MY_get_symtab
#define MY_get_symtab NAME(aout,get_symtab)
#endif
#ifndef MY_get_reloc_upper_bound
#define MY_get_reloc_upper_bound NAME(aout,get_reloc_upper_bound)
#endif
#ifndef MY_canonicalize_reloc
#define MY_canonicalize_reloc NAME(aout,canonicalize_reloc)
#endif
#ifndef MY_make_empty_symbol
#define MY_make_empty_symbol NAME(aout,make_empty_symbol)
#endif
#ifndef MY_print_symbol
#define MY_print_symbol NAME(aout,print_symbol)
#endif
#ifndef MY_get_symbol_info
#define MY_get_symbol_info NAME(aout,get_symbol_info)
#endif
#ifndef MY_get_lineno
#define MY_get_lineno NAME(aout,get_lineno)
#endif
#ifndef MY_set_arch_mach
#define MY_set_arch_mach NAME(aout,set_arch_mach)
#endif
#ifndef MY_openr_next_archived_file
#define MY_openr_next_archived_file NAME(aout,openr_next_archived_file)
#endif
#ifndef MY_find_nearest_line
#define MY_find_nearest_line NAME(aout,find_nearest_line)
#endif
#ifndef MY_generic_stat_arch_elt
#define MY_generic_stat_arch_elt NAME(aout,generic_stat_arch_elt)
#endif
#ifndef MY_sizeof_headers
#define MY_sizeof_headers NAME(aout,sizeof_headers)
#endif
#ifndef MY_bfd_debug_info_start
#define MY_bfd_debug_info_start NAME(aout,bfd_debug_info_start)
#endif
#ifndef MY_bfd_debug_info_end
#define MY_bfd_debug_info_end NAME(aout,bfd_debug_info_end)
#endif
#ifndef MY_bfd_debug_info_accumulat
#define MY_bfd_debug_info_accumulat NAME(aout,bfd_debug_info_accumulat)
#endif
#ifndef MY_reloc_howto_type_lookup
#define MY_reloc_howto_type_lookup NAME(aout,reloc_type_lookup)
#endif
#ifndef MY_make_debug_symbol
#define MY_make_debug_symbol 0
#endif
/* Aout symbols normally have leading underscores */
#ifndef MY_symbol_leading_char
#define MY_symbol_leading_char '_'
#endif
/* Aout archives normally use spaces for padding */
#ifndef AR_PAD_CHAR
#define AR_PAD_CHAR ' '
#endif
#ifndef MY_BFD_TARGET
bfd_target MY(vec) =
{
TARGETNAME, /* name */
bfd_target_aout_flavour,
#ifdef TARGET_IS_BIG_ENDIAN_P
true, /* target byte order (big) */
true, /* target headers byte order (big) */
#else
false, /* target byte order (little) */
false, /* target headers byte order (little) */
#endif
(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 */
3, /* minimum alignment */
#ifdef TARGET_IS_BIG_ENDIAN_P
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 */
#else
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 */
#endif
{_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},
MY_core_file_failing_command,
MY_core_file_failing_signal,
MY_core_file_matches_executable_p,
MY_slurp_armap,
MY_slurp_extended_name_table,
MY_truncate_arname,
MY_write_armap,
MY_close_and_cleanup,
MY_set_section_contents,
MY_get_section_contents,
MY_new_section_hook,
MY_get_symtab_upper_bound,
MY_get_symtab,
MY_get_reloc_upper_bound,
MY_canonicalize_reloc,
MY_make_empty_symbol,
MY_print_symbol,
MY_get_symbol_info,
MY_get_lineno,
MY_set_arch_mach,
MY_openr_next_archived_file,
MY_find_nearest_line,
MY_generic_stat_arch_elt,
MY_sizeof_headers,
MY_bfd_debug_info_start,
MY_bfd_debug_info_end,
MY_bfd_debug_info_accumulate,
bfd_generic_get_relocated_section_contents,
bfd_generic_relax_section,
bfd_generic_seclet_link,
MY_reloc_howto_type_lookup,
MY_make_debug_symbol,
(PTR) MY_backend_data,
};
#endif /* MY_BFD_TARGET */

View File

@ -0,0 +1,26 @@
/* BFD back-end for 32-bit a.out files.
Copyright (C) 1990-1991 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: aout32.c,v 1.1 1994/01/28 12:37:32 pk Exp $
*/
#define ARCH_SIZE 32
#include "aoutx.h"

2571
gnu/usr.bin/gdb/bfd/aoutx.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
# $Id: Makefile.inc,v 1.1 1994/01/28 12:38:17 pk Exp $
SRCS+= netbsd386.c cpu-i386.c
CFLAGS+= -DTRAD_CORE
VECTORS= -DDEFAULT_VECTOR=netbsd_386_vec \
-DSELECT_ARCHITECTURES=bfd_i386_arch \
-DSELECT_VECS='&netbsd_386_vec'

View File

@ -0,0 +1,46 @@
/* BFD support for the Intel 386 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: cpu-i386.c,v 1.1 1994/01/28 12:38:19 pk Exp $
*/
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
static 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_i386,
0, /* only 1 machine */
"i386",
"i386",
3,
true, /* the one and only */
bfd_default_compatible,
bfd_default_scan ,
0,
};
void DEFUN_VOID(bfd_i386_arch)
{
bfd_arch_linkin(&arch_info_struct);
}

View File

@ -0,0 +1,40 @@
/* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: netbsd386.c,v 1.1 1994/01/28 12:38:20 pk Exp $
*/
#define BYTES_IN_WORD 4
#define ARCH 32
#undef TARGET_IS_BIG_ENDIAN_P
#undef HOST_BIG_ENDIAN_P
#define PAGE_SIZE 4096
#define SEGMENT_SIZE PAGE_SIZE
#define __LDPGSZ 4096
#define DEFAULT_ARCH bfd_arch_i386
#define MACHTYPE_OK(mtype) ((mtype) == M_386 || (mtype) == M_386_NETBSD || (mtype) == M_UNKNOWN)
#define MY(OP) CAT(netbsd_386_,OP)
/* This needs to start with a.out so GDB knows it is an a.out variant. */
#define TARGETNAME "a.out-netbsd-386"
#include "netbsd.h"

View File

@ -0,0 +1,47 @@
/* $Id: sysdep.h,v 1.1 1994/01/28 12:38:21 pk Exp $ */
#ifndef hosts_i386bsd_H
/* Intel 386 running any BSD Unix */
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <string.h>
#include <sys/file.h>
#include <machine/param.h>
#include <machine/vmparam.h>
#ifndef O_ACCMODE
#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
#endif
#define SEEK_SET 0
#define SEEK_CUR 1
#define HOST_PAGE_SIZE NBPG
#define HOST_MACHINE_ARCH bfd_arch_i386
#define HOST_TEXT_START_ADDR USRTEXT
/* Jolitz suggested defining HOST_STACK_END_ADDR to
(u.u_kproc.kp_eproc.e_vm.vm_maxsaddr + MAXSSIZ), which should work on
both BSDI and 386BSD, but that is believed not to work for BSD 4.4. */
#if defined(__bsdi__) || defined(__NetBSD__)
/* This seems to be the right thing for BSDI. */
#define HOST_STACK_END_ADDR USRSTACK
#define HOST_DATA_START_ADDR ((bfd_vma)u.u_kproc.kp_eproc.e_vm.vm_daddr)
#else
/* This seems to be the right thing for 386BSD release 0.1. */
#define HOST_STACK_END_ADDR (USRSTACK - MAXSSIZ)
#endif
#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(core_bfd) \
((core_bfd)->tdata.trad_core_data->u.u_sig)
#define u_comm u_kproc.kp_proc.p_comm
#include "fopen-same.h"
#define hosts_i386bsd_H
#endif

View File

@ -0,0 +1,11 @@
# $Id: Makefile.inc,v 1.1 1994/01/28 12:38:23 pk Exp $
SRCS+= netbsdm68k.c cpu-m68k.c
CFLAGS+= -DTRAD_CORE
VECTORS= -DDEFAULT_VECTOR=netbsd_m68k_vec \
-DSELECT_ARCHITECTURES=bfd_m68k_arch \
-DSELECT_VECS='&netbsd_m68k_vec'

View File

@ -0,0 +1,55 @@
/* BFD library support routines for architectures.
Copyright (C) 1990-1991 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: cpu-m68k.c,v 1.1 1994/01/28 12:38:24 pk Exp $
*/
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
int bfd_default_scan_num_mach();
#define N(name, print,d) \
{ 32, 32, 8, bfd_arch_m68k, name, "m68k",print,2,d,bfd_default_compatible,bfd_default_scan, 0, }
static bfd_arch_info_type arch_info_struct[] =
{
N(68000,"m68k:68000",false),
N(68008,"m68k:68008",false),
N(68010,"m68k:68010",false),
N(68020,"m68k:68020",true), /* the word m68k will match this too */
N(68030,"m68k:68030",false),
N(68040,"m68k:68040",false),
N(68070,"m68k:68070",false),
{ 0 },
}
;
void DEFUN_VOID(bfd_m68k_arch)
{
unsigned int i;
for (i = 0; arch_info_struct[i].bits_per_word; i++)
{
bfd_arch_linkin(&arch_info_struct[i]);
}
}

View File

@ -0,0 +1,40 @@
/* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: netbsdm68k.c,v 1.1 1994/01/28 12:38:25 pk Exp $
*/
#define BYTES_IN_WORD 4
#define ARCH 32
#define HOST_BIG_ENDIAN_P
#define TARGET_BIG_ENDIAN_P
#define PAGE_SIZE 4096
#define SEGMENT_SIZE PAGE_SIZE
#define __LDPGSZ 4096
#define DEFAULT_ARCH bfd_arch_m68k
#define MACHTYPE_OK(mtype) ((mtype) == M_HP300 || (mtype) == M_M68K_NETBSD || (mtype) == M_UNKNOWN)
#define MY(OP) CAT(netbsd_m68k_,OP)
/* This needs to start with a.out so GDB knows it is an a.out variant. */
#define TARGETNAME "a.out-netbsd-m68k"
#include "netbsd.h"

View File

@ -0,0 +1,31 @@
/* $Id: sysdep.h,v 1.1 1994/01/28 12:38:26 pk Exp $ */
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <string.h>
#include <sys/file.h>
#include <machine/param.h> /* BSD 4.4 alpha or better */
#ifndef O_ACCMODE
#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
#endif
#define SEEK_SET 0
#define SEEK_CUR 1
#define NO_CORE_COMMAND /* Core files don't have command name */
#define HOST_PAGE_SIZE NBPG
#define HOST_SEGMENT_SIZE NBPG /* Data seg start addr rounds to NBPG */
#define HOST_MACHINE_ARCH bfd_arch_m68k
/* #define HOST_MACHINE_MACHINE */
#define HOST_TEXT_START_ADDR 0
#define HOST_STACK_END_ADDR 0xfff00000
#include "fopen-same.h"

View File

@ -0,0 +1,11 @@
# $Id: Makefile.inc,v 1.1 1994/01/28 12:38:28 pk Exp $
SRCS+= netbsd_sparc.c cpu-sparc.c
CFLAGS+= -DTRAD_CORE
VECTORS= -DDEFAULT_VECTOR=netbsd_sparc_vec \
-DSELECT_ARCHITECTURES=bfd_sparc_arch \
-DSELECT_VECS='&netbsd_sparc_vec'

View File

@ -0,0 +1,46 @@
/* BFD support for the SPARC 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: cpu-sparc.c,v 1.1 1994/01/28 12:38:29 pk Exp $
*/
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
static 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_sparc,
0, /* only 1 machine */
"sparc",
"sparc",
3,
true, /* the one and only */
bfd_default_compatible,
bfd_default_scan ,
0,
};
void DEFUN_VOID(bfd_sparc_arch)
{
bfd_arch_linkin(&arch_info_struct);
}

View File

@ -0,0 +1,21 @@
/* $Id: netbsd_sparc.c,v 1.1 1994/01/28 12:38:30 pk Exp $ */
#define TARGET_IS_BIG_ENDIAN_P
#define HOST_BIG_ENDIAN_P
#define BYTES_IN_WORD 4
#define ARCH 32
#define PAGE_SIZE 4096
#define SEGMENT_SIZE PAGE_SIZE
#define __LDPGSZ 8192
#define MID_SPARC 138
#define DEFAULT_ARCH bfd_arch_sparc
#define MACHTYPE_OK(mtype) ((mtype) == MID_SPARC || (mtype) == M_UNKNOWN)
#define MY(OP) CAT(netbsd_sparc_,OP)
/* This needs to start with a.out so GDB knows it is an a.out variant. */
#define TARGETNAME "a.out-netbsd-sparc"
#include "netbsd.h"

View File

@ -0,0 +1,39 @@
/* $Id: sysdep.h,v 1.1 1994/01/28 12:38:31 pk Exp $ */
#ifndef hosts_sparc_H
#define hosts_sparc_H
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <string.h>
#include <sys/file.h>
#include <machine/param.h>
#include <machine/vmparam.h>
#ifndef O_ACCMODE
#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
#endif
#define SEEK_SET 0
#define SEEK_CUR 1
#include "fopen-same.h"
#define HOST_PAGE_SIZE NBPG
#define HOST_MACHINE_ARCH bfd_arch_sparc
#define HOST_TEXT_START_ADDR USRTEXT
#define HOST_STACK_END_ADDR USRSTACK
#define HOST_DATA_START_ADDR ((bfd_vma)u.u_kproc.kp_eproc.e_vm.vm_daddr)
#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(core_bfd) \
((core_bfd)->tdata.trad_core_data->u.u_sig)
#define u_comm u_kproc.kp_proc.p_comm
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,734 @@
/* BFD library support routines for architectures.
Copyright (C) 1990-1991 Free Software Foundation, Inc.
Hacked by John Gilmore and 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: archures.c,v 1.1 1994/01/28 12:37:37 pk Exp $
*/
/*
SECTION
Architectures
BFD's idea of an architecture is implimented in
<<archures.c>>. BFD keeps one atom in a BFD describing the
architecture of the data attached to the BFD; a pointer to a
<<bfd_arch_info_type>>.
Pointers to structures can be requested independently of a bfd
so that an architecture's information can be interrogated
without access to an open bfd.
The arch information is provided by each architecture package.
The set of default architectures is selected by the #define
<<SELECT_ARCHITECTURES>>. This is normally set up in the
<<config/target.mt>> file of your choice. If the name is not
defined, then all the architectures supported are included.
When BFD starts up, all the architectures are called with an
initialize method. It is up to the architecture back end to
insert as many items into the list of architectures as it wants to;
generally this would be one for each machine and one for the
default case (an item with a machine field of 0).
*/
/*
SUBSECTION
bfd_architecture
DESCRIPTION
This enum gives the object file's CPU architecture, in a
global sense --- i.e., what processor family does it belong to?
There is another field, which indicates what processor within
the family is in use. The machine gives a number which
distingushes different versions of the architecture,
containing for example 2 and 3 for Intel i960 KA and i960 KB,
and 68020 and 68030 for Motorola 68020 and 68030.
.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
.
. bfd_arch_a29k, {* AMD 29000 *}
. bfd_arch_sparc, {* 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_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_last
. };
*/
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
/*
SUBSECTION
bfd_arch_info
DESCRIPTION
This structure contains information on architectures for use
within BFD.
.
.typedef struct bfd_arch_info
.{
. int bits_per_word;
. int bits_per_address;
. int bits_per_byte;
. enum bfd_architecture arch;
. long mach;
. 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 *));
. {* How to disassemble an instruction, producing a printable
. representation on a specified stdio stream. This isn't
. defined for most processors at present, because of the size
. of the additional tables it would drag in, and because gdb
. wants to use a different interface. *}
. unsigned int (*disassemble) PARAMS ((bfd_vma addr, CONST char *data,
. PTR stream));
.
. struct bfd_arch_info *next;
.} bfd_arch_info_type;
*/
bfd_arch_info_type *bfd_arch_info_list;
/*
FUNCTION
bfd_printable_name
SYNOPSIS
CONST char *bfd_printable_name(bfd *abfd);
DESCRIPTION
Return a printable string representing the architecture and machine
from the pointer to the arch info structure
*/
CONST char *
DEFUN(bfd_printable_name, (abfd),
bfd *abfd)
{
return abfd->arch_info->printable_name;
}
/*
FUNCTION
bfd_scan_arch
SYNOPSIS
bfd_arch_info_type *bfd_scan_arch(CONST char *);
DESCRIPTION
This routine is provided with a string and tries to work out
if bfd supports any cpu which could be described with the name
provided. The routine returns a pointer to an arch_info
structure if a machine is found, otherwise NULL.
*/
bfd_arch_info_type *
DEFUN(bfd_scan_arch,(string),
CONST char *string)
{
struct bfd_arch_info *ap;
/* Look through all the installed architectures */
for (ap = bfd_arch_info_list;
ap != (bfd_arch_info_type *)NULL;
ap = ap->next) {
if (ap->scan(ap, string))
return ap;
}
return (bfd_arch_info_type *)NULL;
}
/*
FUNCTION
bfd_arch_get_compatible
SYNOPSIS
CONST bfd_arch_info_type *bfd_arch_get_compatible(
CONST bfd *abfd,
CONST bfd *bbfd);
DESCRIPTION
This routine is used to determine whether two BFDs'
architectures and achine types are compatible. It calculates
the lowest common denominator between the two architectures
and machine types implied by the BFDs and returns a pointer to
an arch_info structure describing the compatible machine.
*/
CONST bfd_arch_info_type *
DEFUN(bfd_arch_get_compatible,(abfd, bbfd),
CONST bfd *abfd AND
CONST bfd *bbfd)
{
return abfd->arch_info->compatible(abfd->arch_info,bbfd->arch_info);
}
/*
INTERNAL_DEFINITION
bfd_default_arch_struct
DESCRIPTION
The <<bfd_default_arch_struct>> is an item of
<<bfd_arch_info_type>> which has been initialized to a fairly
generic state. A BFD starts life by pointing to this
structure, until the correct back end has determined the real
architecture of the file.
.extern bfd_arch_info_type bfd_default_arch_struct;
*/
bfd_arch_info_type bfd_default_arch_struct =
{
32,32,8,bfd_arch_unknown,0,"unknown","unknown",2,true,
bfd_default_compatible,
bfd_default_scan,
0,
};
/*
FUNCTION
bfd_set_arch_info
SYNOPSIS
void bfd_set_arch_info(bfd *, bfd_arch_info_type *);
*/
void DEFUN(bfd_set_arch_info,(abfd, arg),
bfd *abfd AND
bfd_arch_info_type *arg)
{
abfd->arch_info = arg;
}
/*
INTERNAL_FUNCTION
bfd_default_set_arch_mach
SYNOPSIS
boolean bfd_default_set_arch_mach(bfd *abfd,
enum bfd_architecture arch,
unsigned long mach);
DESCRIPTION
Set the architecture and machine type in a bfd. This finds the
correct pointer to structure and inserts it into the arch_info
pointer.
*/
boolean DEFUN(bfd_default_set_arch_mach,(abfd, arch, mach),
bfd *abfd AND
enum bfd_architecture arch AND
unsigned long mach)
{
static struct bfd_arch_info *old_ptr = &bfd_default_arch_struct;
boolean found = false;
/* run through the table to find the one we want, we keep a little
cache to speed things up */
if (old_ptr == 0 || arch != old_ptr->arch || mach != old_ptr->mach) {
bfd_arch_info_type *ptr;
old_ptr = (bfd_arch_info_type *)NULL;
for (ptr = bfd_arch_info_list;
ptr != (bfd_arch_info_type *)NULL;
ptr= ptr->next) {
if (ptr->arch == arch &&
((ptr->mach == mach) || (ptr->the_default && mach == 0))) {
old_ptr = ptr;
found = true;
break;
}
}
if (found==false) {
/*looked for it and it wasn't there, so put in the default */
old_ptr = &bfd_default_arch_struct;
bfd_error = bad_value;
}
}
else {
/* it was in the cache */
found = true;
}
abfd->arch_info = old_ptr;
return found;
}
/*
FUNCTION
bfd_get_arch
SYNOPSIS
enum bfd_architecture bfd_get_arch(bfd *abfd);
DESCRIPTION
Returns the enumerated type which describes the supplied bfd's
architecture
*/
enum bfd_architecture DEFUN(bfd_get_arch, (abfd), bfd *abfd)
{
return abfd->arch_info->arch;
}
/*
FUNCTION
bfd_get_mach
SYNOPSIS
unsigned long bfd_get_mach(bfd *abfd);
DESCRIPTION
Returns the long type which describes the supplied bfd's
machine
*/
unsigned long
DEFUN(bfd_get_mach, (abfd), bfd *abfd)
{
return abfd->arch_info->mach;
}
/*
FUNCTION
bfd_arch_bits_per_byte
SYNOPSIS
unsigned int bfd_arch_bits_per_byte(bfd *abfd);
DESCRIPTION
Returns the number of bits in one of the architectures bytes
*/
unsigned int DEFUN(bfd_arch_bits_per_byte, (abfd), bfd *abfd)
{
return abfd->arch_info->bits_per_byte;
}
/*
FUNCTION
bfd_arch_bits_per_address
SYNOPSIS
unsigned int bfd_arch_bits_per_address(bfd *abfd);
DESCRIPTION
Returns the number of bits in one of the architectures addresses
*/
unsigned int DEFUN(bfd_arch_bits_per_address, (abfd), bfd *abfd)
{
return abfd->arch_info->bits_per_address;
}
extern void bfd_a29k_arch PARAMS ((void));
extern void bfd_alpha_arch PARAMS ((void));
extern void bfd_h8300_arch PARAMS ((void));
extern void bfd_h8500_arch PARAMS ((void));
extern void bfd_hppa_arch PARAMS ((void));
extern void bfd_i386_arch PARAMS ((void));
extern void bfd_i960_arch PARAMS ((void));
extern void bfd_m68k_arch PARAMS ((void));
extern void bfd_m88k_arch PARAMS ((void));
extern void bfd_mips_arch PARAMS ((void));
extern void bfd_rs6000_arch PARAMS ((void));
extern void bfd_sh_arch PARAMS ((void));
extern void bfd_sparc_arch PARAMS ((void));
extern void bfd_vax_arch PARAMS ((void));
extern void bfd_we32k_arch PARAMS ((void));
extern void bfd_z8k_arch PARAMS ((void));
static void (*archures_init_table[]) PARAMS ((void)) =
{
#ifdef SELECT_ARCHITECTURES
SELECT_ARCHITECTURES,
#else
bfd_a29k_arch,
bfd_alpha_arch,
bfd_h8300_arch,
bfd_h8500_arch,
bfd_hppa_arch,
bfd_i386_arch,
bfd_i960_arch,
bfd_m68k_arch,
bfd_m88k_arch,
bfd_mips_arch,
bfd_rs6000_arch,
bfd_sh_arch,
bfd_sparc_arch,
bfd_vax_arch,
bfd_we32k_arch,
bfd_z8k_arch,
#endif
0
};
/*
INTERNAL_FUNCTION
bfd_arch_init
SYNOPSIS
void bfd_arch_init(void);
DESCRIPTION
This routine initializes the architecture dispatch table by
calling all installed architecture packages and getting them
to poke around.
*/
void
DEFUN_VOID(bfd_arch_init)
{
void (**ptable) PARAMS ((void));
for (ptable = archures_init_table;
*ptable ;
ptable++)
{
(*ptable)();
}
}
/*
INTERNAL_FUNCTION
bfd_arch_linkin
SYNOPSIS
void bfd_arch_linkin(bfd_arch_info_type *);
DESCRIPTION
Link the provided arch info structure into the list
*/
void DEFUN(bfd_arch_linkin,(ptr),
bfd_arch_info_type *ptr)
{
ptr->next = bfd_arch_info_list;
bfd_arch_info_list = ptr;
}
/*
INTERNAL_FUNCTION
bfd_default_compatible
SYNOPSIS
CONST bfd_arch_info_type *bfd_default_compatible
(CONST bfd_arch_info_type *a,
CONST bfd_arch_info_type *b);
DESCRIPTION
The default function for testing for compatibility.
*/
CONST bfd_arch_info_type *
DEFUN(bfd_default_compatible,(a,b),
CONST bfd_arch_info_type *a AND
CONST bfd_arch_info_type *b)
{
if(a->arch != b->arch) return NULL;
if (a->mach > b->mach) {
return a;
}
if (b->mach > a->mach) {
return b;
}
return a;
}
/*
INTERNAL_FUNCTION
bfd_default_scan
SYNOPSIS
boolean bfd_default_scan(CONST struct bfd_arch_info *, CONST char *);
DESCRIPTION
The default function for working out whether this is an
architecture hit and a machine hit.
*/
boolean
DEFUN(bfd_default_scan,(info, string),
CONST struct bfd_arch_info *info AND
CONST char *string)
{
CONST char *ptr_src;
CONST char *ptr_tst;
unsigned long number;
enum bfd_architecture arch;
/* First test for an exact match */
if (strcmp(string, info->printable_name) == 0) return true;
/* See how much of the supplied string matches with the
architecture, eg the string m68k:68020 would match the 68k entry
up to the :, then we get left with the machine number */
for (ptr_src = string,
ptr_tst = info->arch_name;
*ptr_src && *ptr_tst;
ptr_src++,
ptr_tst++)
{
if (*ptr_src != *ptr_tst) break;
}
/* Chewed up as much of the architecture as will match, skip any
colons */
if (*ptr_src == ':') ptr_src++;
if (*ptr_src == 0) {
/* nothing more, then only keep this one if it is the default
machine for this architecture */
return info->the_default;
}
number = 0;
while (isdigit(*ptr_src)) {
number = number * 10 + *ptr_src - '0';
ptr_src++;
}
switch (number)
{
case 300:
arch = bfd_arch_h8300;
break;
case 500:
arch = bfd_arch_h8500;
break;
case 68010:
case 68020:
case 68030:
case 68040:
case 68332:
case 68050:
case 68000:
arch = bfd_arch_m68k;
break;
case 386:
case 80386:
case 486:
case 80486:
arch = bfd_arch_i386;
break;
case 29000:
arch = bfd_arch_a29k;
break;
case 8000:
arch = bfd_arch_z8k;
break;
case 32000:
arch = bfd_arch_we32k;
break;
case 860:
case 80860:
arch = bfd_arch_i860;
break;
case 960:
case 80960:
arch = bfd_arch_i960;
break;
case 2000:
case 3000:
case 4000:
case 4400:
arch = bfd_arch_mips;
break;
case 6000:
arch = bfd_arch_rs6000;
break;
default:
return false;
}
if (arch != info->arch)
return false;
if (number != info->mach)
return false;
return true;
}
/*
FUNCTION
bfd_get_arch_info
SYNOPSIS
bfd_arch_info_type * bfd_get_arch_info(bfd *);
*/
bfd_arch_info_type *
DEFUN(bfd_get_arch_info,(abfd),
bfd *abfd)
{
return abfd->arch_info;
}
/*
FUNCTION
bfd_lookup_arch
SYNOPSIS
bfd_arch_info_type *bfd_lookup_arch
(enum bfd_architecture
arch,
long machine);
DESCRIPTION
Look for the architecure info struct which matches the
arguments given. A machine of 0 will match the
machine/architecture structure which marks itself as the
default.
*/
bfd_arch_info_type *
DEFUN(bfd_lookup_arch,(arch, machine),
enum bfd_architecture arch AND
long machine)
{
bfd_arch_info_type *ap;
bfd_check_init();
for (ap = bfd_arch_info_list;
ap != (bfd_arch_info_type *)NULL;
ap = ap->next) {
if (ap->arch == arch &&
((ap->mach == machine)
|| (ap->the_default && machine == 0))) {
return ap;
}
}
return (bfd_arch_info_type *)NULL;
}
/*
FUNCTION
bfd_printable_arch_mach
SYNOPSIS
CONST char * bfd_printable_arch_mach
(enum bfd_architecture arch, unsigned long machine);
DESCRIPTION
Return a printable string representing the architecture and
machine type.
NB. The use of this routine is depreciated.
*/
CONST char *
DEFUN(bfd_printable_arch_mach,(arch, machine),
enum bfd_architecture arch AND
unsigned long machine)
{
bfd_arch_info_type *ap = bfd_lookup_arch(arch, machine);
if(ap) return ap->printable_name;
return "UNKNOWN!";
}

736
gnu/usr.bin/gdb/bfd/bfd.c Normal file
View File

@ -0,0 +1,736 @@
/* Generic BFD library interface and support routines.
Copyright (C) 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: bfd.c,v 1.1 1994/01/28 12:37:38 pk Exp $
*/
/*
SECTION
<<typedef bfd>>
A BFD is has type <<bfd>>; objects of this type are the
cornerstone of any application using <<libbfd>>. References
though the BFD and to data in the BFD give the entire BFD
functionality.
Here is the struct used to define the type <<bfd>>. This
contains the major data about the file, and contains pointers
to the rest of the data.
CODE_FRAGMENT
.
.struct _bfd
.{
. {* The filename the application opened the BFD with. *}
. CONST char *filename;
.
. {* A pointer to the target jump table. *}
. 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. *}
. char *iostream;
.
. {* Is the file being cached *}
.
. boolean cacheable;
.
. {* Marks whether there was a default target specified when the
. BFD was opened. This is used to select what matching algorithm
. to use to chose 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:*}
.
. 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.*}
.
. 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
. 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*}
. struct symbol_cache_entry **outsymbols;
.
. {* Pointer to structure which contains architecture information*}
. struct bfd_arch_info *arch_info;
.
. {* Stuff only useful for archives:*}
. PTR arelt_data;
. struct _bfd *my_archive;
. struct _bfd *next;
. struct _bfd *archive_head;
. boolean has_armap;
.
. {* 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 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 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 hppa_data_struct *hppa_data;
. struct hpux_core_struct *hpux_core_data;
. struct sgi_core_struct *sgi_core_data;
. struct lynx_core_struct *lynx_core_data;
. struct osf_core_struct *osf_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;
.
. {* Is this really needed in addition to usrdata? *}
. asymbol **ld_symbols;
.};
.
*/
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#include "coff/internal.h"
#include "coff/sym.h"
#include "libcoff.h"
#include "libecoff.h"
#undef obj_symbols
#include "libelf.h"
#undef strerror
extern char *strerror();
/** Error handling
o - Most functions return nonzero on success (check doc for
precise semantics); 0 or NULL on error.
o - Internal errors are documented by the value of bfd_error.
If that is system_call_error then check errno.
o - The easiest way to report this to the user is to use bfd_perror.
*/
bfd_ec bfd_error = no_error;
CONST char *CONST bfd_errmsgs[] = {
"No error",
"System call error",
"Invalid target",
"File in wrong format",
"Invalid operation",
"Memory exhausted",
"No symbols",
"No relocation info",
"No more archived files",
"Malformed archive",
"Symbol not found",
"File format not recognized",
"File format is ambiguous",
"Section has no contents",
"Nonrepresentable section on output",
"Symbol needs debug section which does not exist",
"Bad value",
"File truncated",
"#<Invalid error code>"
};
static
void
DEFUN(bfd_nonrepresentable_section,(abfd, name),
CONST bfd * CONST abfd AND
CONST char * CONST name)
{
fprintf(stderr,
"bfd error writing file %s, format %s can't represent section %s\n",
abfd->filename,
abfd->xvec->name,
name);
exit(1);
}
/*ARGSUSED*/
static
void
DEFUN(bfd_undefined_symbol,(relent, seclet),
CONST arelent *relent AND
CONST struct bfd_seclet *seclet)
{
asymbol *symbol = *(relent->sym_ptr_ptr);
fprintf(stderr, "bfd error relocating, symbol %s is undefined\n",
symbol->name);
exit(1);
}
/*ARGSUSED*/
static
void
DEFUN(bfd_reloc_value_truncated,(relent, seclet),
CONST arelent *relent AND
struct bfd_seclet *seclet)
{
fprintf(stderr, "bfd error relocating, value truncated\n");
exit(1);
}
/*ARGSUSED*/
static
void
DEFUN(bfd_reloc_is_dangerous,(relent, seclet),
CONST arelent *relent AND
CONST struct bfd_seclet *seclet)
{
fprintf(stderr, "bfd error relocating, dangerous\n");
exit(1);
}
bfd_error_vector_type bfd_error_vector =
{
bfd_nonrepresentable_section ,
bfd_undefined_symbol,
bfd_reloc_value_truncated,
bfd_reloc_is_dangerous,
};
CONST char *
bfd_errmsg (error_tag)
bfd_ec error_tag;
{
#ifndef errno
extern int errno;
#endif
if (error_tag == system_call_error)
return strerror (errno);
if ((((int)error_tag <(int) no_error) ||
((int)error_tag > (int)invalid_error_code)))
error_tag = invalid_error_code;/* sanity check */
return bfd_errmsgs [(int)error_tag];
}
void
DEFUN (bfd_default_error_trap, (error_tag),
bfd_ec error_tag)
{
fprintf(stderr, "bfd assert fail (%s)\n", bfd_errmsg(error_tag));
}
void (*bfd_error_trap) PARAMS ((bfd_ec)) = bfd_default_error_trap;
void (*bfd_error_nonrepresentabltrap) PARAMS ((bfd_ec)) = bfd_default_error_trap;
void
DEFUN(bfd_perror,(message),
CONST char *message)
{
if (bfd_error == system_call_error)
perror((char *)message); /* must be system error then... */
else {
if (message == NULL || *message == '\0')
fprintf (stderr, "%s\n", bfd_errmsg (bfd_error));
else
fprintf (stderr, "%s: %s\n", message, bfd_errmsg (bfd_error));
}
}
/** Symbols */
/*
FUNCTION
bfd_get_reloc_upper_bound
SYNOPSIS
unsigned int bfd_get_reloc_upper_bound(bfd *abfd, asection *sect);
DESCRIPTION
This function return the number of bytes required to store the
relocation information associated with section <<sect>>
attached to bfd <<abfd>>
*/
unsigned int
DEFUN(bfd_get_reloc_upper_bound,(abfd, asect),
bfd *abfd AND
sec_ptr asect)
{
if (abfd->format != bfd_object) {
bfd_error = invalid_operation;
return 0;
}
return BFD_SEND (abfd, _get_reloc_upper_bound, (abfd, asect));
}
/*
FUNCTION
bfd_canonicalize_reloc
SYNOPSIS
unsigned int bfd_canonicalize_reloc
(bfd *abfd,
asection *sec,
arelent **loc,
asymbol **syms);
DESCRIPTION
This function calls the back end associated with the open
<<abfd>> and translates the external form of the relocation
information attached to <<sec>> into the internal canonical
form. The table is placed into memory at <<loc>>, which has
been preallocated, usually by a call to
<<bfd_get_reloc_upper_bound>>.
The <<syms>> table is also needed for horrible internal magic
reasons.
*/
unsigned int
DEFUN(bfd_canonicalize_reloc,(abfd, asect, location, symbols),
bfd *abfd AND
sec_ptr asect AND
arelent **location AND
asymbol **symbols)
{
if (abfd->format != bfd_object) {
bfd_error = invalid_operation;
return 0;
}
return BFD_SEND (abfd, _bfd_canonicalize_reloc,
(abfd, asect, location, symbols));
}
/*
FUNCTION
bfd_set_file_flags
SYNOPSIS
boolean bfd_set_file_flags(bfd *abfd, flagword flags);
DESCRIPTION
This function attempts to set the flag word in the referenced
BFD structure to the value supplied.
Possible errors are:
o wrong_format - The target bfd was not of object format.
o invalid_operation - The target bfd was open for reading.
o invalid_operation -
The flag word contained a bit which was not applicable to the
type of file. eg, an attempt was made to set the D_PAGED bit
on a bfd format which does not support demand paging
*/
boolean
bfd_set_file_flags (abfd, flags)
bfd *abfd;
flagword flags;
{
if (abfd->format != bfd_object) {
bfd_error = wrong_format;
return false;
}
if (bfd_read_p (abfd)) {
bfd_error = invalid_operation;
return false;
}
bfd_get_file_flags (abfd) = flags;
if ((flags & bfd_applicable_file_flags (abfd)) != flags) {
bfd_error = invalid_operation;
return false;
}
return true;
}
/*
FUNCTION
bfd_set_reloc
SYNOPSIS
void bfd_set_reloc
(bfd *abfd, asection *sec, arelent **rel, unsigned int count)
DESCRIPTION
This function sets the relocation pointer and count within a
section to the supplied values.
*/
/*ARGSUSED*/
void
bfd_set_reloc (ignore_abfd, asect, location, count)
bfd *ignore_abfd;
sec_ptr asect;
arelent **location;
unsigned int count;
{
asect->orelocation = location;
asect->reloc_count = count;
}
void
bfd_assert(file, line)
char *file;
int line;
{
fprintf(stderr, "bfd assertion fail %s:%d\n",file,line);
}
/*
FUNCTION
bfd_set_start_address
DESCRIPTION
Marks the entry point of an output BFD.
RETURNS
Returns <<true>> on success, <<false>> otherwise.
SYNOPSIS
boolean bfd_set_start_address(bfd *, bfd_vma);
*/
boolean
bfd_set_start_address(abfd, vma)
bfd *abfd;
bfd_vma vma;
{
abfd->start_address = vma;
return true;
}
/*
FUNCTION
The bfd_get_mtime function
SYNOPSIS
long bfd_get_mtime(bfd *);
DESCRIPTION
Return file modification time (as read from file system, or
from archive header for archive members).
*/
long
bfd_get_mtime (abfd)
bfd *abfd;
{
FILE *fp;
struct stat buf;
if (abfd->mtime_set)
return abfd->mtime;
fp = bfd_cache_lookup (abfd);
if (0 != fstat (fileno (fp), &buf))
return 0;
abfd->mtime = buf.st_mtime; /* Save value in case anyone wants it */
return buf.st_mtime;
}
/*
FUNCTION
The bfd_get_size function
SYNOPSIS
long bfd_get_size(bfd *);
DESCRIPTION
Return file size (as read from file system) for the file
associated with a bfd.
Note that the initial motivation for, and use of, this routine is not
so we can get the exact size of the object the bfd applies to, since
that might not be generally possible (archive members for example?).
Although it would be ideal if someone could eventually modify
it so that such results were guaranteed.
Instead, we want to ask questions like "is this NNN byte sized
object I'm about to try read from file offset YYY reasonable?"
As as example of where we might want to do this, some object formats
use string tables for which the first sizeof(long) bytes of the table
contain the size of the table itself, including the size bytes.
If an application tries to read what it thinks is one of these
string tables, without some way to validate the size, and for
some reason the size is wrong (byte swapping error, wrong location
for the string table, etc), the only clue is likely to be a read
error when it tries to read the table, or a "virtual memory
exhausted" error when it tries to allocated 15 bazillon bytes
of space for the 15 bazillon byte table it is about to read.
This function at least allows us to answer the quesion, "is the
size reasonable?".
*/
long
bfd_get_size (abfd)
bfd *abfd;
{
FILE *fp;
struct stat buf;
fp = bfd_cache_lookup (abfd);
if (0 != fstat (fileno (fp), &buf))
return 0;
return buf.st_size;
}
/*
FUNCTION
The bfd_get_gp_size function
SYNOPSIS
int bfd_get_gp_size(bfd *);
DESCRIPTION
Get the maximum size of objects to be optimized using the GP
register under MIPS ECOFF. This is typically set by the -G
argument to the compiler, assembler or linker.
*/
int
bfd_get_gp_size (abfd)
bfd *abfd;
{
if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
return ecoff_data (abfd)->gp_size;
return 0;
}
/*
FUNCTION
The bfd_set_gp_size function
SYNOPSIS
void bfd_set_gp_size(bfd *, int);
DESCRIPTION
Set the maximum size of objects to be optimized using the GP
register under ECOFF or MIPS ELF. This is typically set by
the -G argument to the compiler, assembler or linker.
*/
void
bfd_set_gp_size (abfd, i)
bfd *abfd;
int i;
{
if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
ecoff_data (abfd)->gp_size = i;
else if (abfd->xvec->flavour == bfd_target_elf_flavour)
elf_gp_size (abfd) = i;
}
/*
FUNCTION
bfd_scan_vma
DESCRIPTION
Converts, like strtoul, a numerical expression as a
string into a bfd_vma integer, and returns that integer.
(Though without as many bells and whistles as strtoul.)
The expression is assumed to be unsigned (i.e. positive).
If given a base, it is used as the base for conversion.
A base of 0 causes the function to interpret the string
in hex if a leading "0x" or "0X" is found, otherwise
in octal if a leading zero is found, otherwise in decimal.
Overflow is not detected.
SYNOPSIS
bfd_vma bfd_scan_vma(CONST char *string, CONST char **end, int base);
*/
bfd_vma
DEFUN(bfd_scan_vma,(string, end, base),
CONST char *string AND
CONST char **end AND
int base)
{
bfd_vma value;
int digit;
/* Let the host do it if possible. */
if (sizeof(bfd_vma) <= sizeof(unsigned long))
return (bfd_vma) strtoul (string, 0, base);
/* A negative base makes no sense, and we only need to go as high as hex. */
if ((base < 0) || (base > 16))
return (bfd_vma) 0;
if (base == 0)
{
if (string[0] == '0')
{
if ((string[1] == 'x') || (string[1] == 'X'))
base = 16;
/* XXX should we also allow "0b" or "0B" to set base to 2? */
else
base = 8;
}
else
base = 10;
}
if ((base == 16) &&
(string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X')))
string += 2;
/* XXX should we also skip over "0b" or "0B" if base is 2? */
/* Speed could be improved with a table like hex_value[] in gas. */
#define HEX_VALUE(c) \
(isxdigit(c) ? \
(isdigit(c) ? \
(c - '0') : \
(10 + c - (islower(c) ? 'a' : 'A'))) : \
42)
for (value = 0; (digit = HEX_VALUE(*string)) < base; string++)
{
value = value * base + digit;
}
if (end)
*end = string;
return value;
}
/*
FUNCTION
stuff
DESCRIPTION
stuff which should be documented
.#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_set_arch_mach(abfd, arch, mach)\
. BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach))
.
.#define bfd_get_relocated_section_contents(abfd, seclet, data, relocateable) \
. BFD_SEND (abfd, _bfd_get_relocated_section_contents, (abfd, seclet, data, relocateable))
.
.#define bfd_relax_section(abfd, section, symbols) \
. BFD_SEND (abfd, _bfd_relax_section, (abfd, section, symbols))
.
.#define bfd_seclet_link(abfd, data, relocateable) \
. BFD_SEND (abfd, _bfd_seclet_link, (abfd, data, relocateable))
*/

1806
gnu/usr.bin/gdb/bfd/bfd.h Normal file

File diff suppressed because it is too large Load Diff

314
gnu/usr.bin/gdb/bfd/cache.c Normal file
View File

@ -0,0 +1,314 @@
/* BFD library -- caching of file descriptors.
Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
Hacked by Steve Chamberlain of Cygnus Support (steve@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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: cache.c,v 1.1 1994/01/28 12:37:42 pk Exp $
*/
/*
SECTION
File Caching
The file caching mechanism is embedded within BFD and allows
the application to open as many BFDs as it wants without
regard to the underlying operating system's file descriptor
limit (often as low as 20 open files). The module in
<<cache.c>> maintains a least recently used list of
<<BFD_CACHE_MAX_OPEN>> files, and exports the name
<<bfd_cache_lookup>> which runs around and makes sure that
the required BFD is open. If not, then it chooses a file to
close, closes it and opens the one wanted, returning its file
handle.
*/
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
/*
INTERNAL_FUNCTION
BFD_CACHE_MAX_OPEN macro
DESCRIPTION
The maximum number of files which the cache will keep open at
one time.
.#define BFD_CACHE_MAX_OPEN 10
*/
static boolean
bfd_cache_delete PARAMS ((bfd *));
/* Number of bfds on the chain. All such bfds have their file open;
if it closed, they get snipd()d from the chain. */
static int open_files;
static bfd *cache_sentinel; /* Chain of BFDs with active fds we've
opened */
/*
INTERNAL_FUNCTION
bfd_last_cache
SYNOPSIS
extern bfd *bfd_last_cache;
DESCRIPTION
Zero, or a pointer to the topmost BFD on the chain. This is
used by the <<bfd_cache_lookup>> macro in @file{libbfd.h} to
determine when it can avoid a function call.
*/
bfd *bfd_last_cache;
/*
* INTERNAL_FUNCTION
* bfd_cache_lookup
*
* DESCRIPTION
* Checks to see if the required BFD is the same as the last one
* looked up. If so then it can use the iostream in the BFD with
* impunity, since it can't have changed since the last lookup,
* otherwise it has to perform the complicated lookup function
*
* .#define bfd_cache_lookup(x) \
* . ((x)==bfd_last_cache? \
* . (FILE*)(bfd_last_cache->iostream): \
* . bfd_cache_lookup_worker(x))
*
*
*/
static void
DEFUN_VOID(close_one)
{
bfd *kill = cache_sentinel;
if (kill == 0) /* Nothing in the cache */
return ;
/* We can only close files that want to play this game. */
while (!kill->cacheable) {
kill = kill->lru_prev;
if (kill == cache_sentinel) /* Nobody wants to play */
return ;
}
kill->where = ftell((FILE *)(kill->iostream));
(void) bfd_cache_delete(kill);
}
/* Cuts the BFD abfd out of the chain in the cache */
static void
DEFUN(snip,(abfd),
bfd *abfd)
{
abfd->lru_prev->lru_next = abfd->lru_next;
abfd->lru_next->lru_prev = abfd->lru_prev;
if (cache_sentinel == abfd) cache_sentinel = (bfd *)NULL;
}
static boolean
DEFUN(bfd_cache_delete,(abfd),
bfd *abfd)
{
boolean ret;
if (fclose ((FILE *)(abfd->iostream)) == 0)
ret = true;
else
{
ret = false;
bfd_error = system_call_error;
}
snip (abfd);
abfd->iostream = NULL;
open_files--;
bfd_last_cache = 0;
return ret;
}
static bfd *
DEFUN(insert,(x,y),
bfd *x AND
bfd *y)
{
if (y) {
x->lru_next = y;
x->lru_prev = y->lru_prev;
y->lru_prev->lru_next = x;
y->lru_prev = x;
}
else {
x->lru_prev = x;
x->lru_next = x;
}
return x;
}
/* Initialize a BFD by putting it on the cache LRU. */
void
DEFUN(bfd_cache_init,(abfd),
bfd *abfd)
{
if (open_files >= BFD_CACHE_MAX_OPEN)
close_one ();
cache_sentinel = insert(abfd, cache_sentinel);
++open_files;
}
/*
INTERNAL_FUNCTION
bfd_cache_close
DESCRIPTION
Remove the BFD from the cache. If the attached file is open,
then close it too.
SYNOPSIS
boolean bfd_cache_close (bfd *);
RETURNS
<<false>> is returned if closing the file fails, <<true>> is
returned if all is well.
*/
boolean
DEFUN(bfd_cache_close,(abfd),
bfd *abfd)
{
/* If this file is open then remove from the chain */
if (abfd->iostream)
{
return bfd_cache_delete(abfd);
}
else
{
return true;
}
}
/*
INTERNAL_FUNCTION
bfd_open_file
DESCRIPTION
Call the OS to open a file for this BFD. Returns the FILE *
(possibly null) that results from this operation. Sets up the
BFD so that future accesses know the file is open. If the FILE
* returned is null, then there is won't have been put in the
cache, so it won't have to be removed from it.
SYNOPSIS
FILE* bfd_open_file(bfd *);
*/
FILE *
DEFUN(bfd_open_file, (abfd),
bfd *abfd)
{
abfd->cacheable = true; /* Allow it to be closed later. */
if(open_files >= BFD_CACHE_MAX_OPEN) {
close_one();
}
switch (abfd->direction) {
case read_direction:
case no_direction:
abfd->iostream = (char *) fopen(abfd->filename, FOPEN_RB);
break;
case both_direction:
case write_direction:
if (abfd->opened_once == true) {
abfd->iostream = (char *) fopen(abfd->filename, FOPEN_RUB);
if (!abfd->iostream) {
abfd->iostream = (char *) fopen(abfd->filename, FOPEN_WUB);
}
} else {
/*open for creat */
abfd->iostream = (char *) fopen(abfd->filename, FOPEN_WB);
abfd->opened_once = true;
}
break;
}
if (abfd->iostream) {
bfd_cache_init (abfd);
}
return (FILE *)(abfd->iostream);
}
/*
INTERNAL_FUNCTION
bfd_cache_lookup_worker
DESCRIPTION
Called when the macro <<bfd_cache_lookup>> fails to find a
quick answer. Finds a file descriptor for this BFD. If
necessary, it open it. If there are already more than
BFD_CACHE_MAX_OPEN files open, it trys to close one first, to
avoid running out of file descriptors.
SYNOPSIS
FILE *bfd_cache_lookup_worker(bfd *);
*/
FILE *
DEFUN(bfd_cache_lookup_worker,(abfd),
bfd *abfd)
{
if (abfd->my_archive)
{
abfd = abfd->my_archive;
}
/* Is this file already open .. if so then quick exit */
if (abfd->iostream)
{
if (abfd != cache_sentinel) {
/* Place onto head of lru chain */
snip (abfd);
cache_sentinel = insert(abfd, cache_sentinel);
}
}
/* This is a BFD without a stream -
so it must have been closed or never opened.
find an empty cache entry and use it. */
else
{
if (open_files >= BFD_CACHE_MAX_OPEN)
{
close_one();
}
BFD_ASSERT(bfd_open_file (abfd) != (FILE *)NULL) ;
fseek((FILE *)(abfd->iostream), abfd->where, false);
}
bfd_last_cache = abfd;
return (FILE *)(abfd->iostream);
}

File diff suppressed because it is too large Load Diff

109
gnu/usr.bin/gdb/bfd/core.c Normal file
View File

@ -0,0 +1,109 @@
/* Core file generic interface routines for BFD.
Copyright (C) 1990-1991 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: core.c,v 1.1 1994/01/28 12:37:47 pk Exp $
*/
/*
SECTION
Core files
DESCRIPTION
Buff output this facinating topic
*/
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
/*
FUNCTION
bfd_core_file_failing_command
SYNOPSIS
CONST char *bfd_core_file_failing_command(bfd *);
DESCRIPTION
Returns a read-only string explaining what program was running
when it failed and produced the core file being read
*/
CONST char *
DEFUN(bfd_core_file_failing_command,(abfd),
bfd *abfd)
{
if (abfd->format != bfd_core) {
bfd_error = invalid_operation;
return NULL;
}
return BFD_SEND (abfd, _core_file_failing_command, (abfd));
}
/*
FUNCTION
bfd_core_file_failing_signal
SYNOPSIS
int bfd_core_file_failing_signal(bfd *);
DESCRIPTION
Returns the signal number which caused the core dump which
generated the file the BFD is attached to.
*/
int
bfd_core_file_failing_signal (abfd)
bfd *abfd;
{
if (abfd->format != bfd_core) {
bfd_error = invalid_operation;
return 0;
}
return BFD_SEND (abfd, _core_file_failing_signal, (abfd));
}
/*
FUNCTION
core_file_matches_executable_p
SYNOPSIS
boolean core_file_matches_executable_p
(bfd *core_bfd, bfd *exec_bfd);
DESCRIPTION
Returns <<true>> if the core file attached to @var{core_bfd}
was generated by a run of the executable file attached to
@var{exec_bfd}, or else <<false>>.
*/
boolean
core_file_matches_executable_p (core_bfd, exec_bfd)
bfd *core_bfd, *exec_bfd;
{
if ((core_bfd->format != bfd_core) || (exec_bfd->format != bfd_object)) {
bfd_error = wrong_format;
return false;
}
return BFD_SEND (core_bfd, _core_file_matches_executable_p,
(core_bfd, exec_bfd));
}

151
gnu/usr.bin/gdb/bfd/ctor.c Normal file
View File

@ -0,0 +1,151 @@
/* BFD library support routines for constructors
Copyright (C) 1990-1991 Free Software Foundation, Inc.
Hacked by Steve Chamberlain of Cygnus Support. With some help from
Judy Chamberlain too.
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.
$Id: ctor.c,v 1.1 1994/01/28 12:37:49 pk Exp $
*/
/*
SECTION
Constructors
Classes in C++ have `constructors' and `destructors'. These
are functions which are called automatically by the language
whenever data of a class is created or destroyed. Class data
which is static data may also be have a type which requires
`construction', the contructor must be called before the data
can be referenced, so the contructor must be called before the
program begins.
The common solution to this problem is for the compiler to
call a magic function as the first statement <<main>>.
This magic function, (often called <<__main>>) runs around
calling the constructors for all the things needing it.
With COFF the compile has a bargain with the linker et al.
All constructors are given strange names, for example
<<__GLOBAL__$I$foo>> might be the label of a contructor for
the class @var{foo}. The solution on unfortunate systems
(most system V machines) is to perform a partial link on all
the <<.o>> files, do an <<nm>> on the result, run <<awk>> or some
such over the result looking for strange <<__GLOBAL__$>>
symbols, generate a C program from this, compile it and link
with the partially linked input. This process is usually
called <<collect>>.
Some versions of <<a.out>> use something called the
<<set_vector>> mechanism. The constructor symbols are output
from the compiler with a special stab code saying that they
are constructors, and the linker can deal with them directly.
BFD allows applications (ie the linker) to deal with
constructor information independently of their external
implimentation by providing a set of entry points for the
indiviual object back ends to call which maintains a database
of the contructor information. The application can
interrogate the database to find out what it wants. The
construction data essential for the linker to be able to
perform its job are:
o asymbol -
The asymbol of the contructor entry point contains all the
information necessary to call the function.
o table id -
The type of symbol, i.e., is it a constructor, a destructor or
something else someone dreamed up to make our lives difficult.
This module takes this information and then builds extra
sections attached to the bfds which own the entry points. It
creates these sections as if they were tables of pointers to
the entry points, and builds relocation entries to go with
them so that the tables can be relocated along with the data
they reference.
These sections are marked with a special bit
(<<SEC_CONSTRUCTOR>>) which the linker notices and do with
what it wants.
*/
#include <bfd.h>
#include <sysdep.h>
#include <libbfd.h>
/*
INTERNAL_FUNCTION
bfd_constructor_entry
SYNOPSIS
void bfd_constructor_entry(bfd *abfd,
asymbol **symbol_ptr_ptr,
CONST char*type);
DESCRIPTION
This function is called with an a symbol describing the
function to be called, an string which descibes the xtor type,
e.g., something like "CTOR" or "DTOR" would be fine. And the bfd
which owns the function. Its duty is to create a section
called "CTOR" or "DTOR" or whatever if the bfd doesn't already
have one, and grow a relocation table for the entry points as
they accumulate.
*/
void DEFUN(bfd_constructor_entry,(abfd, symbol_ptr_ptr, type),
bfd *abfd AND
asymbol **symbol_ptr_ptr AND
CONST char *type)
{
/* Look up the section we're using to store the table in */
asection *rel_section = bfd_get_section_by_name (abfd, type);
if (rel_section == (asection *)NULL) {
rel_section = bfd_make_section (abfd, type);
rel_section->flags = SEC_CONSTRUCTOR;
rel_section->alignment_power = 2;
}
/* Create a relocation into the section which references the entry
point */
{
arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd,
sizeof(arelent_chain));
/* reloc->relent.section = (asection *)NULL;*/
reloc->relent.addend = 0;
reloc->relent.sym_ptr_ptr = symbol_ptr_ptr;
reloc->next = rel_section->constructor_chain;
rel_section->constructor_chain = reloc;
reloc->relent.address = rel_section->_cooked_size;
/* ask the cpu which howto to use */
reloc->relent.howto = bfd_reloc_type_lookup(abfd, BFD_RELOC_CTOR);
rel_section->_cooked_size += sizeof(int *);
rel_section->reloc_count++;
}
}

3997
gnu/usr.bin/gdb/bfd/ecoff.c Normal file

File diff suppressed because it is too large Load Diff

251
gnu/usr.bin/gdb/bfd/elf.c Normal file
View File

@ -0,0 +1,251 @@
/* ELF 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: elf.c,v 1.1 1994/01/28 12:37:52 pk Exp $
*/
/*
SECTION
ELF backends
BFD support for ELF formats is being worked on.
Currently, the best supported back ends are for sparc and i386
(running svr4 or Solaris 2).
Documentation of the internals of the support code still needs
to be written. The code is changing quickly enough that we
haven't bothered yet.
*/
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#define ARCH_SIZE 0
#include "libelf.h"
/* Standard ELF hash function. Do not change this function; you will
cause invalid hash tables to be generated. (Well, you would if this
were being used yet.) */
unsigned long
DEFUN (bfd_elf_hash, (name),
CONST unsigned char *name)
{
unsigned long h = 0;
unsigned long g;
int ch;
while ((ch = *name++) != '\0')
{
h = (h << 4) + ch;
if ((g = (h & 0xf0000000)) != 0)
{
h ^= g >> 24;
h &= ~g;
}
}
return h;
}
/* Read a specified number of bytes at a specified offset in an ELF
file, into a newly allocated buffer, and return a pointer to the
buffer. */
static char *
DEFUN (elf_read, (abfd, offset, size),
bfd * abfd AND
long offset AND
int size)
{
char *buf;
if ((buf = bfd_alloc (abfd, size)) == NULL)
{
bfd_error = no_memory;
return NULL;
}
if (bfd_seek (abfd, offset, SEEK_SET) == -1)
{
bfd_error = system_call_error;
return NULL;
}
if (bfd_read ((PTR) buf, size, 1, abfd) != size)
{
bfd_error = system_call_error;
return NULL;
}
return buf;
}
boolean
DEFUN (elf_mkobject, (abfd), bfd * abfd)
{
/* this just does initialization */
/* coff_mkobject zalloc's space for tdata.coff_obj_data ... */
elf_tdata (abfd) = (struct elf_obj_tdata *)
bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
if (elf_tdata (abfd) == 0)
{
bfd_error = no_memory;
return false;
}
/* since everything is done at close time, do we need any
initialization? */
return true;
}
char *
DEFUN (elf_get_str_section, (abfd, shindex),
bfd * abfd AND
unsigned int shindex)
{
Elf_Internal_Shdr **i_shdrp;
char *shstrtab = NULL;
unsigned int offset;
unsigned int shstrtabsize;
i_shdrp = elf_elfsections (abfd);
if (i_shdrp == 0 || i_shdrp[shindex] == 0)
return 0;
shstrtab = i_shdrp[shindex]->rawdata;
if (shstrtab == NULL)
{
/* No cached one, attempt to read, and cache what we read. */
offset = i_shdrp[shindex]->sh_offset;
shstrtabsize = i_shdrp[shindex]->sh_size;
shstrtab = elf_read (abfd, offset, shstrtabsize);
i_shdrp[shindex]->rawdata = (void *) shstrtab;
}
return shstrtab;
}
char *
DEFUN (elf_string_from_elf_section, (abfd, shindex, strindex),
bfd * abfd AND
unsigned int shindex AND
unsigned int strindex)
{
Elf_Internal_Shdr *hdr;
if (strindex == 0)
return "";
hdr = elf_elfsections (abfd)[shindex];
if (!hdr->rawdata
&& elf_get_str_section (abfd, shindex) == NULL)
return NULL;
return ((char *) hdr->rawdata) + strindex;
}
/*
INTERNAL_FUNCTION
bfd_elf_find_section
SYNOPSIS
struct elf_internal_shdr *bfd_elf_find_section (bfd *abfd, char *name);
DESCRIPTION
Helper functions for GDB to locate the string tables.
Since BFD hides string tables from callers, GDB needs to use an
internal hook to find them. Sun's .stabstr, in particular,
isn't even pointed to by the .stab section, so ordinary
mechanisms wouldn't work to find it, even if we had some.
*/
struct elf_internal_shdr *
DEFUN (bfd_elf_find_section, (abfd, name),
bfd * abfd AND
char *name)
{
Elf_Internal_Shdr **i_shdrp;
char *shstrtab;
unsigned int max;
unsigned int i;
i_shdrp = elf_elfsections (abfd);
if (i_shdrp != NULL)
{
shstrtab = elf_get_str_section (abfd, elf_elfheader (abfd)->e_shstrndx);
if (shstrtab != NULL)
{
max = elf_elfheader (abfd)->e_shnum;
for (i = 1; i < max; i++)
if (!strcmp (&shstrtab[i_shdrp[i]->sh_name], name))
return i_shdrp[i];
}
}
return 0;
}
const struct bfd_elf_arch_map bfd_elf_arch_map[] = {
{ bfd_arch_sparc, EM_SPARC },
{ bfd_arch_i386, EM_386 },
{ bfd_arch_m68k, EM_68K },
{ bfd_arch_m88k, EM_88K },
{ bfd_arch_i860, EM_860 },
{ bfd_arch_mips, EM_MIPS },
{ bfd_arch_hppa, EM_HPPA },
};
const int bfd_elf_arch_map_size = sizeof (bfd_elf_arch_map) / sizeof (bfd_elf_arch_map[0]);
const char *const bfd_elf_section_type_names[] = {
"SHT_NULL", "SHT_PROGBITS", "SHT_SYMTAB", "SHT_STRTAB",
"SHT_RELA", "SHT_HASH", "SHT_DYNAMIC", "SHT_NOTE",
"SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM",
};
/* ELF relocs are against symbols. 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. */
bfd_reloc_status_type
bfd_elf_generic_reloc (abfd,
reloc_entry,
symbol,
data,
input_section,
output_bfd)
bfd *abfd;
arelent *reloc_entry;
asymbol *symbol;
PTR data;
asection *input_section;
bfd *output_bfd;
{
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;
}

View File

@ -0,0 +1,261 @@
/* Generic BFD support for file formats.
Copyright (C) 1990-1991 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: format.c,v 1.1 1994/01/28 12:37:53 pk Exp $
*/
/*
SECTION
File Formats
A format is a BFD concept of high level file contents. The
formats supported by BFD are:
o bfd_object
The BFD may contain data, symbols, relocations and debug info.
o bfd_archive
The BFD contains other BFDs and an optional index.
o bfd_core
The BFD contains the result of an executable core dump.
*/
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
extern bfd_target *target_vector[];
extern bfd_target *default_vector[];
/*
FUNCTION
bfd_check_format
SYNOPSIS
boolean bfd_check_format(bfd *abfd, bfd_format format);
DESCRIPTION
This routine is supplied a BFD and a format. It attempts to
verify if the file attached to the BFD is indeed compatible
with the format specified (ie, one of <<bfd_object>>,
<<bfd_archive>> or <<bfd_core>>).
If the BFD has been set to a specific @var{target} before the
call, only the named target and format combination will be
checked. If the target has not been set, or has been set to
<<default>> then all the known target backends will be
interrogated to determine a match. If the default target
matches, it is used. If not, exactly one target must recognize
the file, or an error results.
The function returns <<true>> on success, otherwise <<false>>
with one of the following error codes:
o invalid_operation -
if <<format>> is not one of <<bfd_object>>, <<bfd_archive>> or
<<bfd_core>>.
o system_call_error -
if an error occured during a read - even some file mismatches
can cause system_call_errors
o file_not_recognised -
none of the backends recognised the file format
o file_ambiguously_recognized -
more than one backend recognised the file format.
*/
boolean
DEFUN(bfd_check_format,(abfd, format),
bfd *abfd AND
bfd_format format)
{
bfd_target **target, *save_targ, *right_targ;
int match_count;
if (!bfd_read_p (abfd) ||
((int)(abfd->format) < (int)bfd_unknown) ||
((int)(abfd->format) >= (int)bfd_type_end)) {
bfd_error = invalid_operation;
return false;
}
if (abfd->format != bfd_unknown)
return (abfd->format == format)? true: false;
/* Since the target type was defaulted, check them
all in the hope that one will be uniquely recognized. */
save_targ = abfd->xvec;
match_count = 0;
right_targ = 0;
/* presume the answer is yes */
abfd->format = format;
/* If the target type was explicitly specified, just check that target. */
if (!abfd->target_defaulted) {
bfd_seek (abfd, (file_ptr)0, SEEK_SET); /* rewind! */
right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
if (right_targ) {
abfd->xvec = right_targ; /* Set the target as returned */
return true; /* File position has moved, BTW */
}
}
for (target = target_vector; *target != NULL; target++) {
bfd_target *temp;
abfd->xvec = *target; /* Change BFD's target temporarily */
bfd_seek (abfd, (file_ptr)0, SEEK_SET);
/* If _bfd_check_format neglects to set bfd_error, assume wrong_format.
We didn't used to even pay any attention to bfd_error, so I suspect
that some _bfd_check_format might have this problem. */
bfd_error = wrong_format;
temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
if (temp) { /* This format checks out as ok! */
right_targ = temp;
match_count++;
/* If this is the default target, accept it, even if other targets
might match. People who want those other targets have to set
the GNUTARGET variable. */
if (temp == default_vector[0])
{
match_count = 1;
break;
}
#ifdef GNU960
/* Big- and little-endian b.out archives look the same, but it doesn't
* matter: there is no difference in their headers, and member file byte
* orders will (I hope) be handled appropriately by bfd. Ditto for big
* and little coff archives. And the 4 coff/b.out object formats are
* unambiguous. So accept the first match we find.
*/
break;
#endif
} else if (bfd_error != wrong_format) {
abfd->xvec = save_targ;
abfd->format = bfd_unknown;
return false;
}
}
if (match_count == 1) {
abfd->xvec = right_targ; /* Change BFD's target permanently */
return true; /* File position has moved, BTW */
}
abfd->xvec = save_targ; /* Restore original target type */
abfd->format = bfd_unknown; /* Restore original format */
bfd_error = ((match_count == 0) ? file_not_recognized :
file_ambiguously_recognized);
return false;
}
/*
FUNCTION
bfd_set_format
SYNOPSIS
boolean bfd_set_format(bfd *, bfd_format);
DESCRIPTION
This function sets the file format of the supplied BFD to the
format requested. If the target set in the BFD does not
support the format requested, the format is illegal or the BFD
is not open for writing than an error occurs.
*/
boolean
DEFUN(bfd_set_format,(abfd, format),
bfd *abfd AND
bfd_format format)
{
if (bfd_read_p (abfd) ||
((int)abfd->format < (int)bfd_unknown) ||
((int)abfd->format >= (int)bfd_type_end)) {
bfd_error = invalid_operation;
return false;
}
if (abfd->format != bfd_unknown)
return (abfd->format == format) ? true:false;
/* presume the answer is yes */
abfd->format = format;
if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd))) {
abfd->format = bfd_unknown;
return false;
}
return true;
}
/*
FUNCTION
bfd_format_string
SYNOPSIS
CONST char *bfd_format_string(bfd_format);
DESCRIPTION
This function takes one argument, and enumerated type
(bfd_format) and returns a pointer to a const string
<<invalid>>, <<object>>, <<archive>>, <<core>> or <<unknown>>
depending upon the value of the enumeration.
*/
CONST char *
DEFUN(bfd_format_string,(format),
bfd_format format)
{
if (((int)format <(int) bfd_unknown)
|| ((int)format >=(int) bfd_type_end))
return "invalid";
switch (format) {
case bfd_object:
return "object"; /* linker/assember/compiler output */
case bfd_archive:
return "archive"; /* object archive file */
case bfd_core:
return "core"; /* core dump */
default:
return "unknown";
}
}

View File

@ -0,0 +1,81 @@
/* bfd initialization stuff
Copyright (C) 1990-1991 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: init.c,v 1.1 1994/01/28 12:37:54 pk Exp $
*/
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
extern void DEFUN_VOID (bfd_section_init);
static boolean initialized = false;
/*
SECTION
Initialization
This is the initialization section
*/
/*
FUNCTION
bfd_init
SYNOPSIS
void bfd_init(void);
DESCRIPTION
This routine must be called before any other bfd function to
initialize magical internal data structures.
*/
void DEFUN_VOID(bfd_init)
{
if (initialized == false) {
initialized = true;
bfd_arch_init();
}
}
/*
INTERNAL_FUNCTION
bfd_check_init
DESCRIPTION
This routine is called before any other bfd function using
initialized data is used to ensure that the structures have
been initialized. Soon this function will go away, and the bfd
library will assume that bfd_init has been called.
SYNOPSIS
void bfd_check_init(void);
*/
void DEFUN_VOID(bfd_check_init)
{
if (initialized == false) {
bfd_init();
}
}

View File

@ -0,0 +1,397 @@
/* BFD back-end data structures for a.out (and similar) 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: libaout.h,v 1.1 1994/01/28 12:37:55 pk Exp $
*/
/* We try to encapsulate the differences in the various a.out file
variants in a few routines, and otherwise share large masses of code.
This means we only have to fix bugs in one place, most of the time. */
/* Parameterize the a.out code based on whether it is being built
for a 32-bit architecture or a 64-bit architecture. */
#if ARCH_SIZE==64
#define GET_WORD bfd_h_get_64
#define GET_SWORD bfd_h_get_signed_64
#define PUT_WORD bfd_h_put_64
#ifndef NAME
#define NAME(x,y) CAT3(x,_64_,y)
#endif
#define JNAME(x) CAT(x,_64)
#define BYTES_IN_WORD 8
#else /* ARCH_SIZE == 32 */
#define GET_WORD bfd_h_get_32
#define GET_SWORD bfd_h_get_signed_32
#define PUT_WORD bfd_h_put_32
#ifndef NAME
#define NAME(x,y) CAT3(x,_32_,y)
#endif
#define JNAME(x) CAT(x,_32)
#define BYTES_IN_WORD 4
#endif /* ARCH_SIZE==32 */
/* Declare these types at file level, since they are used in parameter
lists, which have wierd scope. */
struct external_exec;
struct internal_exec;
/* Back-end information for various a.out targets. */
struct aout_backend_data
{
/* Are ZMAGIC files mapped contiguously? If so, the text section may
need more padding, if the segment size (granularity for memory access
control) is larger than the page size. */
unsigned char zmagic_mapped_contiguous;
/* If this flag is set, ZMAGIC/NMAGIC file headers get mapped in with the
text section, which starts immediately after the file header.
If not, the text section starts on the next page. */
unsigned char text_includes_header;
/* If the text section VMA isn't specified, and we need an absolute
address, use this as the default. If we're producing a relocatable
file, zero is always used. */
/* ?? Perhaps a callback would be a better choice? Will this do anything
reasonable for a format that handles multiple CPUs with different
load addresses for each? */
bfd_vma default_text_vma;
/* Callback for setting the page and segment sizes, if they can't be
trivially determined from the architecture. */
boolean (*set_sizes) PARAMS ((bfd *));
/* zmagic files only. For go32, the length of the exec header contributes
to the size of the text section in the file for alignment purposes but
does *not* get counted in the length of the text section. */
unsigned char exec_header_not_counted;
};
#define aout_backend_info(abfd) \
((CONST struct aout_backend_data *)((abfd)->xvec->backend_data))
/* This is the layout in memory of a "struct exec" while we process it.
All 'lengths' are given as a number of bytes.
All 'alignments' are for relinkable files only; an alignment of
'n' indicates the corresponding segment must begin at an
address that is a multiple of (2**n). */
struct internal_exec
{
long a_info; /* Magic number and flags, packed */
bfd_vma a_text; /* length of text, in bytes */
bfd_vma a_data; /* length of data, in bytes */
bfd_vma a_bss; /* length of uninitialized data area in mem */
bfd_vma a_syms; /* length of symbol table data in file */
bfd_vma a_entry; /* start address */
bfd_vma a_trsize; /* length of text's relocation info, in bytes */
bfd_vma a_drsize; /* length of data's relocation info, in bytes */
/* Added for i960 */
bfd_vma a_tload; /* Text runtime load address */
bfd_vma a_dload; /* Data runtime load address */
unsigned char a_talign; /* Alignment of text segment */
unsigned char a_dalign; /* Alignment of data segment */
unsigned char a_balign; /* Alignment of bss segment */
char a_relaxable; /* Enough info for linker relax */
};
/* Magic number is written
< MSB >
3130292827262524232221201918171615141312111009080706050403020100
< FLAGS >< MACHINE TYPE >< MAGIC NUMBER >
*/
/* Magic number for NetBSD is
<MSB >
3130292827262524232221201918171615141312111009080706050403020100
< FLAGS >< >< MAGIC NUMBER >
*/
enum machine_type {
M_UNKNOWN = 0,
M_68010 = 1,
M_68020 = 2,
M_SPARC = 3,
/* skip a bunch so we don't run into any of suns numbers */
M_386 = 100,
M_29K = 101, /* AMD 29000 */
M_386_DYNIX = 102, /* Sequent running dynix */
M_386_NETBSD = 134, /* NetBSD/386 binary */
M_M68K_NETBSD = 135, /* NetBSD/m68k binary */
M_MIPS1 = 151, /* MIPS R2000/R3000 binary */
M_MIPS2 = 152, /* MIPS R4000/R6000 binary */
M_HP200 = 200, /* HP 200 (68010) BSD binary */
M_HP300 = (300 % 256), /* HP 300 (68020+68881) BSD binary */
M_HPUX = (0x20c % 256)/* HP 200/300 HPUX binary */
};
#define N_DYNAMIC(exec) ((exec).a_info & 0x8000000)
#ifndef N_MAGIC
# define N_MAGIC(exec) ((exec).a_info & 0xffff)
#endif
#ifndef N_MACHTYPE
# define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
#endif
#ifndef N_FLAGS
# define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
#endif
#ifndef N_SET_INFO
# define N_SET_INFO(exec, magic, type, flags) \
((exec).a_info = ((magic) & 0xffff) \
| (((int)(type) & 0xff) << 16) \
| (((flags) & 0xff) << 24))
#endif
#ifndef N_SET_MAGIC
# define N_SET_MAGIC(exec, magic) \
((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff)))
#endif
#ifndef N_SET_MACHTYPE
# define N_SET_MACHTYPE(exec, machtype) \
((exec).a_info = \
((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16))
#endif
#ifndef N_SET_FLAGS
# define N_SET_FLAGS(exec, flags) \
((exec).a_info = \
((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
#endif
typedef struct aout_symbol {
asymbol symbol;
short desc;
char other;
unsigned char type;
} aout_symbol_type;
/* The `tdata' struct for all a.out-like object file formats.
Various things depend on this struct being around any time an a.out
file is being handled. An example is dbxread.c in GDB. */
struct aoutdata {
struct internal_exec *hdr; /* exec file header */
aout_symbol_type *symbols; /* symtab for input bfd */
/* For ease, we do this */
asection *textsec;
asection *datasec;
asection *bsssec;
/* We remember these offsets so that after check_file_format, we have
no dependencies on the particular format of the exec_hdr. */
file_ptr sym_filepos;
file_ptr str_filepos;
/* Size of a relocation entry in external form */
unsigned reloc_entry_size;
/* Size of a symbol table entry in external form */
unsigned symbol_entry_size;
/* Page size - needed for alignment of demand paged files. */
unsigned long page_size;
/* Segment size - needed for alignment of demand paged files. */
unsigned long segment_size;
unsigned exec_bytes_size;
unsigned vma_adjusted : 1;
/* used when a bfd supports several highly similar formats */
enum {
default_format = 0,
gnu_encap_format } subformat;
enum {
undecided_magic = 0,
z_magic,
o_magic,
n_magic } magic;
};
struct aout_data_struct {
struct aoutdata a;
struct internal_exec e;
};
#define adata(bfd) ((bfd)->tdata.aout_data->a)
#define exec_hdr(bfd) (adata(bfd).hdr)
#define obj_aout_symbols(bfd) (adata(bfd).symbols)
#define obj_textsec(bfd) (adata(bfd).textsec)
#define obj_datasec(bfd) (adata(bfd).datasec)
#define obj_bsssec(bfd) (adata(bfd).bsssec)
#define obj_sym_filepos(bfd) (adata(bfd).sym_filepos)
#define obj_str_filepos(bfd) (adata(bfd).str_filepos)
#define obj_reloc_entry_size(bfd) (adata(bfd).reloc_entry_size)
#define obj_symbol_entry_size(bfd) (adata(bfd).symbol_entry_size)
#define obj_aout_subformat(bfd) (adata(bfd).subformat)
/* We take the address of the first element of an asymbol to ensure that the
macro is only ever applied to an asymbol */
#define aout_symbol(asymbol) ((aout_symbol_type *)(&(asymbol)->the_bfd))
/* Prototype declarations for functions defined in aoutx.h */
boolean
NAME(aout,squirt_out_relocs) PARAMS ((bfd *abfd, asection *section));
bfd_target *
NAME(aout,some_aout_object_p) PARAMS ((bfd *abfd,
struct internal_exec *execp,
bfd_target * (*callback)(bfd *)));
boolean
NAME(aout,mkobject) PARAMS ((bfd *abfd));
enum machine_type
NAME(aout,machine_type) PARAMS ((enum bfd_architecture arch,
unsigned long machine));
boolean
NAME(aout,set_arch_mach) PARAMS ((bfd *abfd, enum bfd_architecture arch,
unsigned long machine));
boolean
NAME(aout,new_section_hook) PARAMS ((bfd *abfd, asection *newsect));
boolean
NAME(aout,set_section_contents) PARAMS ((bfd *abfd, sec_ptr section,
PTR location, file_ptr offset, bfd_size_type count));
asymbol *
NAME(aout,make_empty_symbol) PARAMS ((bfd *abfd));
boolean
NAME(aout,slurp_symbol_table) PARAMS ((bfd *abfd));
void
NAME(aout,write_syms) PARAMS ((bfd *abfd));
void
NAME(aout,reclaim_symbol_table) PARAMS ((bfd *abfd));
unsigned int
NAME(aout,get_symtab_upper_bound) PARAMS ((bfd *abfd));
unsigned int
NAME(aout,get_symtab) PARAMS ((bfd *abfd, asymbol **location));
boolean
NAME(aout,slurp_reloc_table) PARAMS ((bfd *abfd, sec_ptr asect,
asymbol **symbols));
unsigned int
NAME(aout,canonicalize_reloc) PARAMS ((bfd *abfd, sec_ptr section,
arelent **relptr, asymbol **symbols));
unsigned int
NAME(aout,get_reloc_upper_bound) PARAMS ((bfd *abfd, sec_ptr asect));
void
NAME(aout,reclaim_reloc) PARAMS ((bfd *ignore_abfd, sec_ptr ignore));
alent *
NAME(aout,get_lineno) PARAMS ((bfd *ignore_abfd, asymbol *ignore_symbol));
void
NAME(aout,print_symbol) PARAMS ((bfd *ignore_abfd, PTR file,
asymbol *symbol, bfd_print_symbol_type how));
void
NAME(aout,get_symbol_info) PARAMS ((bfd *ignore_abfd,
asymbol *symbol, symbol_info *ret));
boolean
NAME(aout,close_and_cleanup) PARAMS ((bfd *abfd));
boolean
NAME(aout,find_nearest_line) PARAMS ((bfd *abfd, asection *section,
asymbol **symbols, bfd_vma offset, CONST char **filename_ptr,
CONST char **functionname_ptr, unsigned int *line_ptr));
int
NAME(aout,sizeof_headers) PARAMS ((bfd *abfd, boolean exec));
boolean
NAME(aout,adjust_sizes_and_vmas) PARAMS ((bfd *abfd,
bfd_size_type *text_size, file_ptr *text_end));
void
NAME(aout,swap_exec_header_in) PARAMS ((bfd *abfd,
struct external_exec *raw_bytes, struct internal_exec *execp));
void
NAME(aout,swap_exec_header_out) PARAMS ((bfd *abfd,
struct internal_exec *execp, struct external_exec *raw_bytes));
/* Prototypes for functions in stab-syms.c. */
CONST char *
aout_stab_name PARAMS ((int code));
/* A.out uses the generic versions of these routines... */
#define aout_32_get_section_contents bfd_generic_get_section_contents
#define aout_32_close_and_cleanup bfd_generic_close_and_cleanup
#define aout_64_get_section_contents bfd_generic_get_section_contents
#define aout_64_close_and_cleanup bfd_generic_close_and_cleanup
#ifndef NO_WRITE_HEADER_KLUDGE
#define NO_WRITE_HEADER_KLUDGE 0
#endif
#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); \
\
bfd_seek (abfd, (file_ptr) 0, SEEK_SET); \
bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd); \
/* Now write out reloc info, followed by syms and strings */ \
\
if (bfd_get_symcount (abfd) != 0) \
{ \
bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET); \
\
NAME(aout,write_syms)(abfd); \
\
bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET); \
\
if (!NAME(aout,squirt_out_relocs) (abfd, obj_textsec (abfd))) return false; \
bfd_seek (abfd, (file_ptr)(N_DRELOFF(*execp)), SEEK_SET); \
\
if (!NAME(aout,squirt_out_relocs)(abfd, obj_datasec (abfd))) return false; \
} \
}
#endif

View File

@ -0,0 +1,853 @@
/* Assorted BFD support routines, only used internally.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: libbfd.c,v 1.1 1994/01/28 12:37:56 pk Exp $
*/
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
/*
SECTION
libbfd
DESCRIPTION
This file contains various routines which are used within BFD.
They are not intended for export, but are documented here for
completeness.
*/
boolean
DEFUN(_bfd_dummy_new_section_hook,(ignore, ignore_newsect),
bfd *ignore AND
asection *ignore_newsect)
{
return true;
}
boolean
DEFUN(bfd_false ,(ignore),
bfd *ignore)
{
return false;
}
boolean
DEFUN(bfd_true,(ignore),
bfd *ignore)
{
return true;
}
PTR
DEFUN(bfd_nullvoidptr,(ignore),
bfd *ignore)
{
return (PTR)NULL;
}
int
DEFUN(bfd_0,(ignore),
bfd *ignore)
{
return 0;
}
unsigned int
DEFUN(bfd_0u,(ignore),
bfd *ignore)
{
return 0;
}
void
DEFUN(bfd_void,(ignore),
bfd *ignore)
{
}
boolean
DEFUN(_bfd_dummy_core_file_matches_executable_p,(ignore_core_bfd, ignore_exec_bfd),
bfd *ignore_core_bfd AND
bfd *ignore_exec_bfd)
{
bfd_error = invalid_operation;
return false;
}
/* of course you can't initialize a function to be the same as another, grr */
char *
DEFUN(_bfd_dummy_core_file_failing_command,(ignore_abfd),
bfd *ignore_abfd)
{
return (char *)NULL;
}
int
DEFUN(_bfd_dummy_core_file_failing_signal,(ignore_abfd),
bfd *ignore_abfd)
{
return 0;
}
bfd_target *
DEFUN(_bfd_dummy_target,(ignore_abfd),
bfd *ignore_abfd)
{
return 0;
}
/** zalloc -- allocate and clear storage */
#ifndef zalloc
char *
DEFUN(zalloc,(size),
bfd_size_type size)
{
char *ptr = (char *) malloc ((size_t)size);
if ((ptr != NULL) && (size != 0))
memset(ptr,0, (size_t) size);
return ptr;
}
#endif
/*
INTERNAL_FUNCTION
bfd_xmalloc
SYNOPSIS
PTR bfd_xmalloc( bfd_size_type size);
DESCRIPTION
Like malloc, but exit if no more memory.
*/
/** There is major inconsistency in how running out of memory is handled.
Some routines return a NULL, and set bfd_error to no_memory.
However, obstack routines can't do this ... */
DEFUN(PTR bfd_xmalloc,(size),
bfd_size_type size)
{
static CONST char no_memory_message[] = "Virtual memory exhausted!\n";
PTR ptr;
if (size == 0) size = 1;
ptr = (PTR)malloc((size_t) size);
if (!ptr)
{
write (2, no_memory_message, sizeof(no_memory_message)-1);
exit (-1);
}
return ptr;
}
/*
INTERNAL_FUNCTION
bfd_xmalloc_by_size_t
SYNOPSIS
PTR bfd_xmalloc_by_size_t ( size_t size);
DESCRIPTION
Like malloc, but exit if no more memory.
Uses size_t, so it's suitable for use as obstack_chunk_alloc.
*/
PTR
DEFUN(bfd_xmalloc_by_size_t, (size),
size_t size)
{
return bfd_xmalloc ((bfd_size_type) size);
}
/* Some IO code */
/* Note that archive entries don't have streams; they share their parent's.
This allows someone to play with the iostream behind BFD's back.
Also, note that the origin pointer points to the beginning of a file's
contents (0 for non-archive elements). For archive entries this is the
first octet in the file, NOT the beginning of the archive header. */
static
int DEFUN(real_read,(where, a,b, file),
PTR where AND
int a AND
int b AND
FILE *file)
{
return fread(where, a,b,file);
}
bfd_size_type
DEFUN(bfd_read,(ptr, size, nitems, abfd),
PTR ptr AND
bfd_size_type size AND
bfd_size_type nitems AND
bfd *abfd)
{
int nread;
nread = real_read (ptr, 1, (int)(size*nitems), bfd_cache_lookup(abfd));
#ifdef FILE_OFFSET_IS_CHAR_INDEX
if (nread > 0)
abfd->where += nread;
#endif
return nread;
}
bfd_size_type
DEFUN(bfd_write,(ptr, size, nitems, abfd),
CONST PTR ptr AND
bfd_size_type size AND
bfd_size_type nitems AND
bfd *abfd)
{
int nwrote = fwrite (ptr, 1, (int)(size*nitems), bfd_cache_lookup(abfd));
#ifdef FILE_OFFSET_IS_CHAR_INDEX
if (nwrote > 0)
abfd->where += nwrote;
#endif
return nwrote;
}
/*
INTERNAL_FUNCTION
bfd_write_bigendian_4byte_int
SYNOPSIS
void bfd_write_bigendian_4byte_int(bfd *abfd, int i);
DESCRIPTION
Writes a 4 byte integer to the outputing bfd, in big endian
mode regardless of what else is going on. This is useful in
archives.
*/
void
DEFUN(bfd_write_bigendian_4byte_int,(abfd, i),
bfd *abfd AND
int i)
{
bfd_byte buffer[4];
bfd_putb32(i, buffer);
bfd_write((PTR)buffer, 4, 1, abfd);
}
long
DEFUN(bfd_tell,(abfd),
bfd *abfd)
{
file_ptr ptr;
ptr = ftell (bfd_cache_lookup(abfd));
if (abfd->my_archive)
ptr -= abfd->origin;
abfd->where = ptr;
return ptr;
}
int
DEFUN(bfd_flush,(abfd),
bfd *abfd)
{
return fflush (bfd_cache_lookup(abfd));
}
int
DEFUN(bfd_stat,(abfd, statbuf),
bfd *abfd AND
struct stat *statbuf)
{
return fstat (fileno(bfd_cache_lookup(abfd)), statbuf);
}
int
DEFUN(bfd_seek,(abfd, position, direction),
bfd * CONST abfd AND
CONST file_ptr position AND
CONST int direction)
{
int result;
FILE *f;
file_ptr file_position;
/* For the time being, a BFD may not seek to it's end. The problem
is that we don't easily have a way to recognize the end of an
element in an archive. */
BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR);
if (direction == SEEK_CUR && position == 0)
return 0;
#ifdef FILE_OFFSET_IS_CHAR_INDEX
if (abfd->format != bfd_archive && abfd->my_archive == 0)
{
#ifndef NDEBUG
/* Explanation for this code: I'm only about 95+% sure that the above
conditions are sufficient and that all i/o calls are properly
adjusting the `where' field. So this is sort of an `assert'
that the `where' field is correct. If we can go a while without
tripping the abort, we can probably safely disable this code,
so that the real optimizations happen. */
file_ptr where_am_i_now;
where_am_i_now = ftell (bfd_cache_lookup (abfd));
if (abfd->my_archive)
where_am_i_now -= abfd->origin;
if (where_am_i_now != abfd->where)
abort ();
#endif
if (direction == SEEK_SET && position == abfd->where)
return 0;
}
else
{
/* We need something smarter to optimize access to archives.
Currently, anything inside an archive is read via the file
handle for the archive. Which means that a bfd_seek on one
component affects the `current position' in the archive, as
well as in any other component.
It might be sufficient to put a spike through the cache
abstraction, and look to the archive for the file position,
but I think we should try for something cleaner.
In the meantime, no optimization for archives. */
}
#endif
f = bfd_cache_lookup (abfd);
file_position = position;
if (direction == SEEK_SET && abfd->my_archive != NULL)
file_position += abfd->origin;
result = fseek (f, file_position, direction);
if (result != 0)
/* Force redetermination of `where' field. */
bfd_tell (abfd);
else
{
#ifdef FILE_OFFSET_IS_CHAR_INDEX
/* Adjust `where' field. */
if (direction == SEEK_SET)
abfd->where = position;
else
abfd->where += position;
#endif
}
return result;
}
/** Make a string table */
/*>bfd.h<
Add string to table pointed to by table, at location starting with free_ptr.
resizes the table if necessary (if it's NULL, creates it, ignoring
table_length). Updates free_ptr, table, table_length */
boolean
DEFUN(bfd_add_to_string_table,(table, new_string, table_length, free_ptr),
char **table AND
char *new_string AND
unsigned int *table_length AND
char **free_ptr)
{
size_t string_length = strlen (new_string) + 1; /* include null here */
char *base = *table;
size_t space_length = *table_length;
unsigned int offset = (base ? *free_ptr - base : 0);
if (base == NULL) {
/* Avoid a useless regrow if we can (but of course we still
take it next time */
space_length = (string_length < DEFAULT_STRING_SPACE_SIZE ?
DEFAULT_STRING_SPACE_SIZE : string_length+1);
base = zalloc ((bfd_size_type) space_length);
if (base == NULL) {
bfd_error = no_memory;
return false;
}
}
if ((size_t)(offset + string_length) >= space_length) {
/* Make sure we will have enough space */
while ((size_t)(offset + string_length) >= space_length)
space_length += space_length/2; /* grow by 50% */
base = (char *) realloc (base, space_length);
if (base == NULL) {
bfd_error = no_memory;
return false;
}
}
memcpy (base + offset, new_string, string_length);
*table = base;
*table_length = space_length;
*free_ptr = base + offset + string_length;
return true;
}
/** The do-it-yourself (byte) sex-change kit */
/* The middle letter e.g. get<b>short indicates Big or Little endian
target machine. It doesn't matter what the byte order of the host
machine is; these routines work for either. */
/* FIXME: Should these take a count argument?
Answer (gnu@cygnus.com): No, but perhaps they should be inline
functions in swap.h #ifdef __GNUC__.
Gprof them later and find out. */
/*
FUNCTION
bfd_put_size
FUNCTION
bfd_get_size
DESCRIPTION
These macros as used for reading and writing raw data in
sections; each access (except for bytes) is vectored through
the target format of the BFD and mangled accordingly. The
mangling performs any necessary endian translations and
removes alignment restrictions. Note that types accepted and
returned by these macros are identical so they can be swapped
around in macros--for example libaout.h defines GET_WORD to
either bfd_get_32 or bfd_get_64.
In the put routines, val must be a bfd_vma. If we are on a
system without prototypes, the caller is responsible for making
sure that is true, with a cast if necessary. We don't cast
them in the macro definitions because that would prevent lint
or gcc -Wall from detecting sins such as passing a pointer.
To detect calling these with less than a bfd_vma, use gcc
-Wconversion on a host with 64 bit bfd_vma's.
.
.{* 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))
.
*/
/*
FUNCTION
bfd_h_put_size
FUNCTION
bfd_h_get_size
DESCRIPTION
These macros have the same function as their <<bfd_get_x>>
bretherin, except that they are used for removing information
for the header records of object files. Believe it or not,
some object files keep their header records in big endian
order, and their data in little endian order.
.
.{* 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))
.
*/
/* Sign extension to bfd_signed_vma. */
#define COERCE16(x) (((bfd_signed_vma) (x) ^ 0x8000) - 0x8000)
#define COERCE32(x) (((bfd_signed_vma) (x) ^ 0x80000000) - 0x80000000)
#define EIGHT_GAZILLION (((HOST_64_BIT)0x80000000) << 32)
#define COERCE64(x) \
(((bfd_signed_vma) (x) ^ EIGHT_GAZILLION) - EIGHT_GAZILLION)
bfd_vma
DEFUN(bfd_getb16,(addr),
register bfd_byte *addr)
{
return (addr[0] << 8) | addr[1];
}
bfd_vma
DEFUN(bfd_getl16,(addr),
register bfd_byte *addr)
{
return (addr[1] << 8) | addr[0];
}
bfd_signed_vma
DEFUN(bfd_getb_signed_16,(addr),
register bfd_byte *addr)
{
return COERCE16((addr[0] << 8) | addr[1]);
}
bfd_signed_vma
DEFUN(bfd_getl_signed_16,(addr),
register bfd_byte *addr)
{
return COERCE16((addr[1] << 8) | addr[0]);
}
void
DEFUN(bfd_putb16,(data, addr),
bfd_vma data AND
register bfd_byte *addr)
{
addr[0] = (bfd_byte)(data >> 8);
addr[1] = (bfd_byte )data;
}
void
DEFUN(bfd_putl16,(data, addr),
bfd_vma data AND
register bfd_byte *addr)
{
addr[0] = (bfd_byte )data;
addr[1] = (bfd_byte)(data >> 8);
}
bfd_vma
bfd_getb32 (addr)
register bfd_byte *addr;
{
return (((((bfd_vma)addr[0] << 8) | addr[1]) << 8)
| addr[2]) << 8 | addr[3];
}
bfd_vma
bfd_getl32 (addr)
register bfd_byte *addr;
{
return (((((bfd_vma)addr[3] << 8) | addr[2]) << 8)
| addr[1]) << 8 | addr[0];
}
bfd_signed_vma
bfd_getb_signed_32 (addr)
register bfd_byte *addr;
{
return COERCE32((((((bfd_vma)addr[0] << 8) | addr[1]) << 8)
| addr[2]) << 8 | addr[3]);
}
bfd_signed_vma
bfd_getl_signed_32 (addr)
register bfd_byte *addr;
{
return COERCE32((((((bfd_vma)addr[3] << 8) | addr[2]) << 8)
| addr[1]) << 8 | addr[0]);
}
bfd_vma
DEFUN(bfd_getb64,(addr),
register bfd_byte *addr)
{
#ifdef BFD64
bfd_vma low, high;
high= ((((((((addr[0]) << 8) |
addr[1]) << 8) |
addr[2]) << 8) |
addr[3]) );
low = (((((((((bfd_vma)addr[4]) << 8) |
addr[5]) << 8) |
addr[6]) << 8) |
addr[7]));
return high << 32 | low;
#else
BFD_FAIL();
return 0;
#endif
}
bfd_vma
DEFUN(bfd_getl64,(addr),
register bfd_byte *addr)
{
#ifdef BFD64
bfd_vma low, high;
high= (((((((addr[7] << 8) |
addr[6]) << 8) |
addr[5]) << 8) |
addr[4]));
low = ((((((((bfd_vma)addr[3] << 8) |
addr[2]) << 8) |
addr[1]) << 8) |
addr[0]) );
return high << 32 | low;
#else
BFD_FAIL();
return 0;
#endif
}
bfd_signed_vma
DEFUN(bfd_getb_signed_64,(addr),
register bfd_byte *addr)
{
#ifdef BFD64
bfd_vma low, high;
high= ((((((((addr[0]) << 8) |
addr[1]) << 8) |
addr[2]) << 8) |
addr[3]) );
low = (((((((((bfd_vma)addr[4]) << 8) |
addr[5]) << 8) |
addr[6]) << 8) |
addr[7]));
return COERCE64(high << 32 | low);
#else
BFD_FAIL();
return 0;
#endif
}
bfd_signed_vma
DEFUN(bfd_getl_signed_64,(addr),
register bfd_byte *addr)
{
#ifdef BFD64
bfd_vma low, high;
high= (((((((addr[7] << 8) |
addr[6]) << 8) |
addr[5]) << 8) |
addr[4]));
low = ((((((((bfd_vma)addr[3] << 8) |
addr[2]) << 8) |
addr[1]) << 8) |
addr[0]) );
return COERCE64(high << 32 | low);
#else
BFD_FAIL();
return 0;
#endif
}
void
DEFUN(bfd_putb32,(data, addr),
bfd_vma data AND
register bfd_byte *addr)
{
addr[0] = (bfd_byte)(data >> 24);
addr[1] = (bfd_byte)(data >> 16);
addr[2] = (bfd_byte)(data >> 8);
addr[3] = (bfd_byte)data;
}
void
DEFUN(bfd_putl32,(data, addr),
bfd_vma data AND
register bfd_byte *addr)
{
addr[0] = (bfd_byte)data;
addr[1] = (bfd_byte)(data >> 8);
addr[2] = (bfd_byte)(data >> 16);
addr[3] = (bfd_byte)(data >> 24);
}
void
DEFUN(bfd_putb64,(data, addr),
bfd_vma data AND
register bfd_byte *addr)
{
#ifdef BFD64
addr[0] = (bfd_byte)(data >> (7*8));
addr[1] = (bfd_byte)(data >> (6*8));
addr[2] = (bfd_byte)(data >> (5*8));
addr[3] = (bfd_byte)(data >> (4*8));
addr[4] = (bfd_byte)(data >> (3*8));
addr[5] = (bfd_byte)(data >> (2*8));
addr[6] = (bfd_byte)(data >> (1*8));
addr[7] = (bfd_byte)(data >> (0*8));
#else
BFD_FAIL();
#endif
}
void
DEFUN(bfd_putl64,(data, addr),
bfd_vma data AND
register bfd_byte *addr)
{
#ifdef BFD64
addr[7] = (bfd_byte)(data >> (7*8));
addr[6] = (bfd_byte)(data >> (6*8));
addr[5] = (bfd_byte)(data >> (5*8));
addr[4] = (bfd_byte)(data >> (4*8));
addr[3] = (bfd_byte)(data >> (3*8));
addr[2] = (bfd_byte)(data >> (2*8));
addr[1] = (bfd_byte)(data >> (1*8));
addr[0] = (bfd_byte)(data >> (0*8));
#else
BFD_FAIL();
#endif
}
/* Default implementation */
boolean
DEFUN(bfd_generic_get_section_contents, (abfd, section, location, offset, count),
bfd *abfd AND
sec_ptr section AND
PTR location AND
file_ptr offset AND
bfd_size_type count)
{
if (count == 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);
}
/* This generic function can only be used in implementations where creating
NEW sections is disallowed. It is useful in patching existing sections
in read-write files, though. See other set_section_contents functions
to see why it doesn't work for new sections. */
boolean
DEFUN(bfd_generic_set_section_contents, (abfd, section, location, offset, count),
bfd *abfd AND
sec_ptr section AND
PTR location AND
file_ptr offset AND
bfd_size_type count)
{
if (count == 0)
return true;
if ((bfd_size_type)(offset+count) > bfd_get_section_size_after_reloc(section)
|| bfd_seek(abfd, (file_ptr)(section->filepos + offset), SEEK_SET) == -1
|| bfd_write(location, (bfd_size_type)1, count, abfd) != count)
return (false); /* on error */
return (true);
}
/*
INTERNAL_FUNCTION
bfd_log2
DESCRIPTION
Return the log base 2 of the value supplied, rounded up. eg an
arg of 1025 would return 11.
SYNOPSIS
unsigned int bfd_log2(bfd_vma x);
*/
unsigned
bfd_log2(x)
bfd_vma x;
{
unsigned result = 0;
while ( (bfd_vma)(1<< result) < x)
result++;
return result;
}

View File

@ -0,0 +1,276 @@
/* libbfd.h -- Declarations used by bfd library *implementation*.
(This include file is not for users of the library.)
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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: libbfd.h,v 1.1 1994/01/28 12:37:57 pk Exp $
*/
/* 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))
/* 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 */
time_t 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. */
};
#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)
char *zalloc PARAMS ((bfd_size_type size));
/* These routines allocate and free things on the BFD's obstack. Note
that realloc can never occur in place. */
PTR bfd_alloc PARAMS ((bfd *abfd, size_t size));
PTR bfd_zalloc PARAMS ((bfd *abfd, size_t size));
PTR bfd_realloc PARAMS ((bfd *abfd, PTR orig, size_t new));
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_size_type bfd_read PARAMS ((PTR ptr, bfd_size_type size,
bfd_size_type nitems, bfd *abfd));
bfd_size_type bfd_write PARAMS ((CONST PTR ptr, bfd_size_type size,
bfd_size_type nitems, bfd *abfd));
int bfd_seek PARAMS ((bfd* CONST abfd, CONST file_ptr fp,
CONST int direction));
long bfd_tell PARAMS ((bfd *abfd));
int bfd_flush PARAMS ((bfd *abfd));
int bfd_stat PARAMS ((bfd *abfd, struct stat *));
bfd * _bfd_create_empty_archive_element_shell PARAMS ((bfd *obfd));
bfd * look_for_bfd_in_cache PARAMS ((bfd *arch_bfd, file_ptr index));
boolean _bfd_generic_mkarchive PARAMS ((bfd *abfd));
struct areltdata * snarf_ar_hdr PARAMS ((bfd *abfd));
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));
boolean _bfd_write_archive_contents PARAMS ((bfd *abfd));
bfd * new_bfd PARAMS (());
#define DEFAULT_STRING_SPACE_SIZE 0x2000
boolean bfd_add_to_string_table PARAMS ((char **table, char *new_string,
unsigned int *table_length,
char **free_ptr));
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));
void bfd_void PARAMS ((bfd *ignore));
bfd * new_bfd_contained_in PARAMS ((bfd *));
boolean _bfd_dummy_new_section_hook PARAMS ((bfd *ignore, asection *newsect));
char * _bfd_dummy_core_file_failing_command PARAMS ((bfd *abfd));
int _bfd_dummy_core_file_failing_signal PARAMS ((bfd *abfd));
boolean _bfd_dummy_core_file_matches_executable_p PARAMS ((bfd *core_bfd,
bfd *exec_bfd));
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));
bfd * bfd_generic_openr_next_archived_file PARAMS ((bfd *archive,
bfd *last_file));
int bfd_generic_stat_arch_elt PARAMS ((bfd *, struct stat *));
boolean bfd_generic_get_section_contents PARAMS ((bfd *abfd, sec_ptr section,
PTR location, file_ptr offset,
bfd_size_type count));
boolean bfd_generic_set_section_contents PARAMS ((bfd *abfd, sec_ptr section,
PTR location, file_ptr offset,
bfd_size_type count));
/* 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 ((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
/* Generic routine for close_and_cleanup is really just bfd_true. */
#define bfd_generic_close_and_cleanup bfd_true
/* And more follows */
void
bfd_check_init PARAMS ((void));
PTR
bfd_xmalloc PARAMS (( bfd_size_type size));
PTR
bfd_xmalloc_by_size_t PARAMS (( size_t size));
void
bfd_write_bigendian_4byte_int PARAMS ((bfd *abfd, int i));
unsigned int
bfd_log2 PARAMS ((bfd_vma x));
#define BFD_CACHE_MAX_OPEN 10
extern bfd *bfd_last_cache;
#define bfd_cache_lookup(x) \
((x)==bfd_last_cache? \
(FILE*)(bfd_last_cache->iostream): \
bfd_cache_lookup_worker(x))
boolean
bfd_cache_close PARAMS ((bfd *));
FILE*
bfd_open_file PARAMS ((bfd *));
FILE *
bfd_cache_lookup_worker PARAMS ((bfd *));
void
bfd_constructor_entry PARAMS ((bfd *abfd,
asymbol **symbol_ptr_ptr,
CONST char*type));
CONST struct reloc_howto_struct *
bfd_default_reloc_type_lookup
PARAMS ((bfd *abfd AND
bfd_reloc_code_real_type code));
boolean
bfd_generic_relax_section
PARAMS ((bfd *abfd,
asection *section,
asymbol **symbols));
bfd_byte *
bfd_generic_get_relocated_section_contents PARAMS ((bfd *abfd,
struct bfd_seclet *seclet,
bfd_byte *data,
boolean relocateable));
boolean
bfd_generic_seclet_link
PARAMS ((bfd *abfd,
PTR data,
boolean relocateable));
extern bfd_arch_info_type bfd_default_arch_struct;
boolean
bfd_default_set_arch_mach PARAMS ((bfd *abfd,
enum bfd_architecture arch,
unsigned long mach));
void
bfd_arch_init PARAMS ((void));
void
bfd_arch_linkin PARAMS ((bfd_arch_info_type *));
CONST bfd_arch_info_type *
bfd_default_compatible
PARAMS ((CONST bfd_arch_info_type *a,
CONST bfd_arch_info_type *b));
boolean
bfd_default_scan PARAMS ((CONST struct bfd_arch_info *, CONST char *));
struct elf_internal_shdr *
bfd_elf_find_section PARAMS ((bfd *abfd, char *name));

View File

@ -0,0 +1,355 @@
/* BFD COFF object file private structure.
Copyright (C) 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: libcoff.h,v 1.1 1994/01/28 12:37:59 pk Exp $
*/
/* Object file tdata; access macros */
#define coff_data(bfd) ((bfd)->tdata.coff_obj_data)
#define exec_hdr(bfd) (coff_data(bfd)->hdr)
#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)
#if CFILE_STUFF
#define obj_symbol_slew(bfd) (coff_data(bfd)->symbol_index_slew)
#else
#define obj_symbol_slew(bfd) 0
#endif
/* `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;
long symbol_index_slew; /* used during read to mark whether a
C_FILE symbol as been added. */
struct coff_ptr_struct *raw_syments;
struct lineno *raw_linenos;
unsigned int raw_syment_count;
unsigned short flags;
/* 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;
} coff_data_type;
/* 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)))
/* Functions in coffgen.c. */
extern bfd_target *coff_object_p PARAMS ((bfd *));
extern struct sec *coff_section_from_bfd_index PARAMS ((bfd *, int));
extern unsigned int coff_get_symtab_upper_bound PARAMS ((bfd *));
extern unsigned int 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 void coff_renumber_symbols PARAMS ((bfd *));
extern void coff_mangle_symbols PARAMS ((bfd *));
extern void coff_write_symbols PARAMS ((bfd *));
extern void coff_write_linenumbers PARAMS ((bfd *));
extern alent *coff_get_lineno PARAMS ((bfd *, asymbol *));
extern asymbol *coff_section_symbol PARAMS ((bfd *, char *));
extern struct coff_ptr_struct *coff_get_normalized_symtab PARAMS ((bfd *));
extern unsigned int 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 *,
asymbol **));
extern bfd_byte *bfd_coff_reloc16_get_relocated_section_contents
PARAMS ((bfd *, struct bfd_seclet *, bfd_byte *, boolean relocateable));
extern bfd_vma bfd_coff_reloc16_get_value PARAMS ((arelent *,
struct bfd_seclet *));
/* And more taken from the source .. */
typedef struct coff_ptr_struct
{
/* Remembers the offset from the first symbol in the file for
this symbol. Generated by coff_renumber_symbols. */
unsigned int offset;
/* Should the tag field of this symbol be renumbered.
Created by coff_pointerize_aux. */
char fix_tag;
/* Should the endidx field of this symbol be renumbered.
Created by coff_pointerize_aux. */
char fix_end;
/* The container for the symbol structure as read and translated
from the file. */
union {
union internal_auxent auxent;
struct internal_syment syment;
} u;
} combined_entry_type;
/* Each canonical asymbol really looks like this: */
typedef struct coff_symbol_struct
{
/* The actual symbol which the rest of BFD works with */
asymbol symbol;
/* A pointer to the hidden information for this symbol */
combined_entry_type *native;
/* A pointer to the linenumber information for this symbol */
struct lineno_cache_entry *lineno;
/* Have the line numbers been relocated yet ? */
boolean done_lineno;
} coff_symbol_type;
typedef struct
{
void (*_bfd_coff_swap_aux_in) PARAMS ((
bfd *abfd ,
PTR ext,
int type,
int class ,
PTR in));
void (*_bfd_coff_swap_sym_in) PARAMS ((
bfd *abfd ,
PTR ext,
PTR in));
void (*_bfd_coff_swap_lineno_in) PARAMS ((
bfd *abfd,
PTR ext,
PTR in));
unsigned int (*_bfd_coff_swap_aux_out) PARAMS ((
bfd *abfd,
PTR in,
int type,
int class,
PTR ext));
unsigned int (*_bfd_coff_swap_sym_out) PARAMS ((
bfd *abfd,
PTR in,
PTR ext));
unsigned int (*_bfd_coff_swap_lineno_out) PARAMS ((
bfd *abfd,
PTR in,
PTR ext));
unsigned int (*_bfd_coff_swap_reloc_out) PARAMS ((
bfd *abfd,
PTR src,
PTR dst));
unsigned int (*_bfd_coff_swap_filehdr_out) PARAMS ((
bfd *abfd,
PTR in,
PTR out));
unsigned int (*_bfd_coff_swap_aouthdr_out) PARAMS ((
bfd *abfd,
PTR in,
PTR out));
unsigned int (*_bfd_coff_swap_scnhdr_out) PARAMS ((
bfd *abfd,
PTR in,
PTR out));
unsigned int _bfd_filhsz;
unsigned int _bfd_aoutsz;
unsigned int _bfd_scnhsz;
unsigned int _bfd_symesz;
unsigned int _bfd_auxesz;
unsigned int _bfd_linesz;
boolean _bfd_coff_long_filenames;
void (*_bfd_coff_swap_filehdr_in) PARAMS ((
bfd *abfd,
PTR ext,
PTR in));
void (*_bfd_coff_swap_aouthdr_in) PARAMS ((
bfd *abfd,
PTR ext,
PTR in));
void (*_bfd_coff_swap_scnhdr_in) PARAMS ((
bfd *abfd,
PTR ext,
PTR in));
boolean (*_bfd_coff_bad_format_hook) PARAMS ((
bfd *abfd,
PTR internal_filehdr));
boolean (*_bfd_coff_set_arch_mach_hook) PARAMS ((
bfd *abfd,
PTR internal_filehdr));
PTR (*_bfd_coff_mkobject_hook) PARAMS ((
bfd *abfd,
PTR internal_filehdr,
PTR internal_aouthdr));
flagword (*_bfd_styp_to_sec_flags_hook) PARAMS ((
bfd *abfd,
PTR internal_scnhdr));
asection *(*_bfd_make_section_hook) PARAMS ((
bfd *abfd,
char *name));
void (*_bfd_set_alignment_hook) PARAMS ((
bfd *abfd,
asection *sec,
PTR internal_scnhdr));
boolean (*_bfd_coff_slurp_symbol_table) PARAMS ((
bfd *abfd));
boolean (*_bfd_coff_symname_in_debug) PARAMS ((
bfd *abfd,
struct internal_syment *sym));
void (*_bfd_coff_reloc16_extra_cases) PARAMS ((
bfd *abfd,
struct bfd_seclet *seclet,
arelent *reloc,
bfd_byte *data,
unsigned int *src_ptr,
unsigned int *dst_ptr));
int (*_bfd_coff_reloc16_estimate) PARAMS ((
asection *input_section,
asymbol **symbols,
arelent *r,
unsigned int shrink));
} bfd_coff_backend_data;
#define coff_backend_info(abfd) ((bfd_coff_backend_data *) (abfd)->xvec->backend_data)
#define bfd_coff_swap_aux_in(a,e,t,c,i) \
((coff_backend_info (a)->_bfd_coff_swap_aux_in) (a,e,t,c,i))
#define bfd_coff_swap_sym_in(a,e,i) \
((coff_backend_info (a)->_bfd_coff_swap_sym_in) (a,e,i))
#define bfd_coff_swap_lineno_in(a,e,i) \
((coff_backend_info ( a)->_bfd_coff_swap_lineno_in) (a,e,i))
#define bfd_coff_swap_reloc_out(abfd, i, o) \
((coff_backend_info (abfd)->_bfd_coff_swap_reloc_out) (abfd, i, o))
#define bfd_coff_swap_lineno_out(abfd, i, o) \
((coff_backend_info (abfd)->_bfd_coff_swap_lineno_out) (abfd, i, o))
#define bfd_coff_swap_aux_out(abfd, i, t,c,o) \
((coff_backend_info (abfd)->_bfd_coff_swap_aux_out) (abfd, i,t,c, o))
#define bfd_coff_swap_sym_out(abfd, i,o) \
((coff_backend_info (abfd)->_bfd_coff_swap_sym_out) (abfd, i, o))
#define bfd_coff_swap_scnhdr_out(abfd, i,o) \
((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_out) (abfd, i, o))
#define bfd_coff_swap_filehdr_out(abfd, i,o) \
((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_out) (abfd, i, o))
#define bfd_coff_swap_aouthdr_out(abfd, i,o) \
((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_out) (abfd, i, o))
#define bfd_coff_filhsz(abfd) (coff_backend_info (abfd)->_bfd_filhsz)
#define bfd_coff_aoutsz(abfd) (coff_backend_info (abfd)->_bfd_aoutsz)
#define bfd_coff_scnhsz(abfd) (coff_backend_info (abfd)->_bfd_scnhsz)
#define bfd_coff_symesz(abfd) (coff_backend_info (abfd)->_bfd_symesz)
#define bfd_coff_auxesz(abfd) (coff_backend_info (abfd)->_bfd_auxesz)
#define bfd_coff_linesz(abfd) (coff_backend_info (abfd)->_bfd_linesz)
#define bfd_coff_long_filenames(abfd) (coff_backend_info (abfd)->_bfd_coff_long_filenames)
#define bfd_coff_swap_filehdr_in(abfd, i,o) \
((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_in) (abfd, i, o))
#define bfd_coff_swap_aouthdr_in(abfd, i,o) \
((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_in) (abfd, i, o))
#define bfd_coff_swap_scnhdr_in(abfd, i,o) \
((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_in) (abfd, i, o))
#define bfd_coff_bad_format_hook(abfd, filehdr) \
((coff_backend_info (abfd)->_bfd_coff_bad_format_hook) (abfd, filehdr))
#define bfd_coff_set_arch_mach_hook(abfd, filehdr)\
((coff_backend_info (abfd)->_bfd_coff_set_arch_mach_hook) (abfd, filehdr))
#define bfd_coff_mkobject_hook(abfd, filehdr, aouthdr)\
((coff_backend_info (abfd)->_bfd_coff_mkobject_hook) (abfd, filehdr, aouthdr))
#define bfd_coff_styp_to_sec_flags_hook(abfd, scnhdr)\
((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook) (abfd, scnhdr))
#define bfd_coff_make_section_hook(abfd, name)\
((coff_backend_info (abfd)->_bfd_make_section_hook) (abfd, name))
#define bfd_coff_set_alignment_hook(abfd, sec, scnhdr)\
((coff_backend_info (abfd)->_bfd_set_alignment_hook) (abfd, sec, scnhdr))
#define bfd_coff_slurp_symbol_table(abfd)\
((coff_backend_info (abfd)->_bfd_coff_slurp_symbol_table) (abfd))
#define bfd_coff_symname_in_debug(abfd, sym)\
((coff_backend_info (abfd)->_bfd_coff_symname_in_debug) (abfd, sym))
#define bfd_coff_reloc16_extra_cases(abfd, seclet, reloc, data, src_ptr, dst_ptr)\
((coff_backend_info (abfd)->_bfd_coff_reloc16_extra_cases)\
(abfd, seclet, reloc, data, src_ptr, dst_ptr))
#define bfd_coff_reloc16_estimate(abfd, section, symbols, reloc, shrink)\
((coff_backend_info (abfd)->_bfd_coff_reloc16_estimate)\
(section, symbols, reloc, shrink))

View File

@ -0,0 +1,268 @@
/* BFD ECOFF object file private structure.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: libecoff.h,v 1.1 1994/01/28 12:38:00 pk Exp $
*/
/* This is the backend information kept for ECOFF files. This
structure is constant for a particular backend. The first element
is the COFF backend data structure, so that ECOFF targets can use
the generic COFF code. */
#define ecoff_backend(abfd) \
((struct ecoff_backend_data *) (abfd)->xvec->backend_data)
struct ecoff_backend_data
{
/* COFF backend information. This must be the first field. */
bfd_coff_backend_data coff;
/* Supported architecture. */
enum bfd_architecture arch;
/* Symbol table magic number. */
int sym_magic;
/* Initial portion of armap string. */
const char *armap_start;
/* Alignment of debugging information. E.g., 4. */
bfd_size_type debug_align;
/* The page boundary used to align sections in a demand-paged
executable file. E.g., 0x1000. */
bfd_vma round;
/* Bitsize of constructor entries. */
unsigned int constructor_bitsize;
/* Reloc to use for constructor entries. */
CONST struct reloc_howto_struct *constructor_reloc;
/* Sizes of external symbolic information. */
bfd_size_type external_hdr_size;
bfd_size_type external_dnr_size;
bfd_size_type external_pdr_size;
bfd_size_type external_sym_size;
bfd_size_type external_opt_size;
bfd_size_type external_fdr_size;
bfd_size_type external_rfd_size;
bfd_size_type external_ext_size;
/* Functions to swap in external symbolic data. */
void (*swap_hdr_in) PARAMS ((bfd *, PTR, HDRR *));
void (*swap_dnr_in) PARAMS ((bfd *, PTR, DNR *));
void (*swap_pdr_in) PARAMS ((bfd *, PTR, PDR *));
void (*swap_sym_in) PARAMS ((bfd *, PTR, SYMR *));
void (*swap_opt_in) PARAMS ((bfd *, PTR, OPTR *));
void (*swap_fdr_in) PARAMS ((bfd *, PTR, FDR *));
void (*swap_rfd_in) PARAMS ((bfd *, PTR, RFDT *));
void (*swap_ext_in) PARAMS ((bfd *, PTR, EXTR *));
/* Functions to swap out external symbolic data. */
void (*swap_hdr_out) PARAMS ((bfd *, const HDRR *, PTR));
void (*swap_dnr_out) PARAMS ((bfd *, const DNR *, PTR));
void (*swap_pdr_out) PARAMS ((bfd *, const PDR *, PTR));
void (*swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR));
void (*swap_opt_out) PARAMS ((bfd *, const OPTR *, PTR));
void (*swap_fdr_out) PARAMS ((bfd *, const FDR *, PTR));
void (*swap_rfd_out) PARAMS ((bfd *, const RFDT *, PTR));
void (*swap_ext_out) PARAMS ((bfd *, const EXTR *, PTR));
/* It so happens that the auxiliary type information has the same
type and format for all known ECOFF targets. I don't see any
reason that that should change, so at least for now the auxiliary
swapping information is not in this table. */
/* External reloc size. */
bfd_size_type external_reloc_size;
/* Reloc swapping functions. */
void (*swap_reloc_in) PARAMS ((bfd *, PTR, struct internal_reloc *));
void (*swap_reloc_out) PARAMS ((bfd *, const struct internal_reloc *, PTR));
/* Backend reloc tweaking. */
void (*finish_reloc) PARAMS ((bfd *, struct internal_reloc *, arelent *));
};
/* This is the target specific information kept for ECOFF files. */
#define ecoff_data(abfd) ((abfd)->tdata.ecoff_obj_data)
typedef struct ecoff_tdata
{
/* The reloc file position, set by
ecoff_compute_section_file_positions. */
file_ptr reloc_filepos;
/* The symbol table file position, set by ecoff_mkobject_hook. */
file_ptr sym_filepos;
/* The start and end of the text segment. Only valid for an
existing file, not for one we are creating. */
unsigned long text_start;
unsigned long text_end;
/* The cached gp value. This is used when relocating. */
bfd_vma gp;
/* The maximum size of objects to optimize using gp. This is
typically set by the -G option to the compiler, assembler or
linker. */
int gp_size;
/* The register masks. When linking, all the masks found in the
input files are combined into the masks of the output file.
These are not all used for all targets, but that's OK, because
the relevant ones are the only ones swapped in and out. */
unsigned long gprmask;
unsigned long fprmask;
unsigned long cprmask[4];
/* The size of the unswapped ECOFF symbolic information. */
bfd_size_type raw_size;
/* The unswapped ECOFF symbolic information. */
PTR raw_syments;
/* The swapped ECOFF symbolic header. */
HDRR symbolic_header;
/* Pointers to the unswapped symbolic information. */
unsigned char *line;
PTR external_dnr; /* struct dnr_ext */
PTR external_pdr; /* struct pdr_ext */
PTR external_sym; /* struct sym_ext */
PTR external_opt; /* struct opt_ext */
union aux_ext *external_aux;
char *ss;
char *ssext;
PTR external_fdr; /* struct fdr_ext */
PTR external_rfd; /* struct rfd_ext */
PTR external_ext; /* struct ext_ext */
/* The swapped FDR information. */
FDR *fdr;
/* The FDR index. This is set for an input BFD to a link so that
the external symbols can set their FDR index correctly. */
unsigned int ifdbase;
/* The canonical BFD symbols. */
struct ecoff_symbol_struct *canonical_symbols;
} ecoff_data_type;
/* Each canonical asymbol really looks like this. */
typedef struct ecoff_symbol_struct
{
/* The actual symbol which the rest of BFD works with */
asymbol symbol;
/* The fdr for this symbol. */
FDR *fdr;
/* true if this is a local symbol rather than an external one. */
boolean local;
/* A pointer to the unswapped hidden information for this symbol.
This is either a struct sym_ext or a struct ext_ext, depending on
the value of the local field above. */
PTR native;
} ecoff_symbol_type;
/* We take the address of the first element of a asymbol to ensure that the
macro is only ever applied to an asymbol. */
#define ecoffsymbol(asymbol) ((ecoff_symbol_type *) (&((asymbol)->the_bfd)))
/* This is a hack borrowed from coffcode.h; we need to save the index
of an external symbol when we write it out so that can set the
symbol index correctly when we write out the relocs. */
#define ecoff_get_sym_index(symbol) ((unsigned long) (symbol)->udata)
#define ecoff_set_sym_index(symbol, idx) ((symbol)->udata = (PTR) (idx))
/* Make an ECOFF object. */
extern boolean ecoff_mkobject PARAMS ((bfd *));
/* Read in the ECOFF symbolic debugging information. */
extern boolean ecoff_slurp_symbolic_info PARAMS ((bfd *));
/* Generic ECOFF BFD backend vectors. */
extern asymbol *ecoff_make_empty_symbol PARAMS ((bfd *abfd));
extern unsigned int ecoff_get_symtab_upper_bound PARAMS ((bfd *abfd));
extern unsigned int ecoff_get_symtab PARAMS ((bfd *abfd,
asymbol **alocation));
extern void ecoff_get_symbol_info PARAMS ((bfd *abfd,
asymbol *symbol,
symbol_info *ret));
extern void ecoff_print_symbol PARAMS ((bfd *abfd, PTR filep,
asymbol *symbol,
bfd_print_symbol_type how));
extern unsigned int ecoff_canonicalize_reloc PARAMS ((bfd *abfd,
asection *section,
arelent **relptr,
asymbol **symbols));
extern boolean ecoff_find_nearest_line PARAMS ((bfd *abfd,
asection *section,
asymbol **symbols,
bfd_vma offset,
CONST char **filename_ptr,
CONST char **fnname_ptr,
unsigned int *retline_ptr));
extern boolean ecoff_bfd_seclet_link PARAMS ((bfd *abfd, PTR data,
boolean relocateable));
extern boolean ecoff_set_arch_mach PARAMS ((bfd *abfd,
enum bfd_architecture arch,
unsigned long machine));
extern int ecoff_sizeof_headers PARAMS ((bfd *abfd, boolean reloc));
extern boolean ecoff_set_section_contents PARAMS ((bfd *abfd,
asection *section,
PTR location,
file_ptr offset,
bfd_size_type count));
extern boolean ecoff_get_section_contents PARAMS ((bfd *abfd,
asection *section,
PTR location,
file_ptr offset,
bfd_size_type count));
extern boolean ecoff_write_object_contents PARAMS ((bfd *abfd));
extern boolean ecoff_slurp_armap PARAMS ((bfd *abfd));
extern boolean ecoff_write_armap PARAMS ((bfd *abfd, unsigned int elength,
struct orl *map,
unsigned int orl_count,
int stridx));
#define ecoff_slurp_extended_name_table _bfd_slurp_extended_name_table
extern bfd_target *ecoff_archive_p PARAMS ((bfd *abfd));
#define ecoff_get_lineno \
((alent *(*) PARAMS ((bfd *, asymbol *))) bfd_nullvoidptr)
#define ecoff_truncate_arname bfd_dont_truncate_arname
#define ecoff_openr_next_archived_file bfd_generic_openr_next_archived_file
#define ecoff_generic_stat_arch_elt bfd_generic_stat_arch_elt
#define ecoff_get_reloc_upper_bound coff_get_reloc_upper_bound
#define ecoff_close_and_cleanup bfd_generic_close_and_cleanup
#define ecoff_bfd_debug_info_start bfd_void
#define ecoff_bfd_debug_info_end bfd_void
#define ecoff_bfd_debug_info_accumulate \
((void (*) PARAMS ((bfd *, struct sec *))) bfd_void)
#define ecoff_bfd_get_relocated_section_contents \
bfd_generic_get_relocated_section_contents
#define ecoff_bfd_relax_section bfd_generic_relax_section
#define ecoff_bfd_make_debug_symbol \
((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
/* Hook functions for the generic COFF section reading code. */
extern PTR ecoff_mkobject_hook PARAMS ((bfd *, PTR filehdr, PTR aouthdr));
extern asection *ecoff_make_section_hook PARAMS ((bfd *abfd, char *name));
extern boolean ecoff_new_section_hook PARAMS ((bfd *abfd,
asection *section));
#define ecoff_set_alignment_hook \
((void (*) PARAMS ((bfd *, asection *, PTR))) bfd_void)
extern boolean ecoff_set_arch_mach_hook PARAMS ((bfd *abfd, PTR filehdr));
extern long ecoff_sec_to_styp_flags PARAMS ((CONST char *name,
flagword flags));
extern flagword ecoff_styp_to_sec_flags PARAMS ((bfd *abfd, PTR hdr));
extern boolean ecoff_slurp_symbol_table PARAMS ((bfd *abfd));

View File

@ -0,0 +1,252 @@
/* BFD back-end data structures for ELF files.
Copyright (C) 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: libelf.h,v 1.1 1994/01/28 12:38:01 pk Exp $
*/
#ifndef _LIBELF_H_
#define _LIBELF_H_ 1
#include "elf/common.h"
#include "elf/internal.h"
#include "elf/external.h"
/* If size isn't specified as 64 or 32, NAME macro should fail. */
#ifndef NAME
#if ARCH_SIZE==64
#define NAME(x,y) CAT4(x,64,_,y)
#endif
#if ARCH_SIZE==32
#define NAME(x,y) CAT4(x,32,_,y)
#endif
#endif
#ifndef NAME
#define NAME(x,y) CAT4(x,NOSIZE,_,y)
#endif
#define ElfNAME(X) NAME(Elf,X)
#define elfNAME(X) NAME(elf,X)
typedef struct
{
asymbol symbol;
Elf_Internal_Sym internal_elf_sym;
union
{
unsigned int hppa_arg_reloc;
PTR any;
}
tc_data;
} elf_symbol_type;
struct elf_backend_data
{
int use_rela_p;
int elf_64_p;
enum bfd_architecture arch;
void (*elf_info_to_howto) PARAMS ((bfd *, arelent *,
Elf_Internal_Rela *));
void (*elf_info_to_howto_rel) PARAMS ((bfd *, arelent *,
Elf_Internal_Rel *));
bfd_vma maxpagesize;
void (*write_relocs) PARAMS ((bfd *, asection *, PTR));
void (*elf_backend_symbol_processing) PARAMS ((bfd *, asymbol *));
boolean (*elf_backend_symbol_table_processing) PARAMS ((bfd *, elf_symbol_type *, int));
boolean (*elf_backend_section_processing) PARAMS ((bfd *, Elf32_Internal_Shdr *));
boolean (*elf_backend_section_from_shdr) PARAMS ((bfd *, Elf32_Internal_Shdr *, char *));
boolean (*elf_backend_fake_sections) PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *));
boolean (*elf_backend_section_from_bfd_section) PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *, int *));
};
struct elf_sym_extra
{
int elf_sym_num; /* sym# after locals/globals are reordered */
};
typedef struct elf_sym_extra Elf_Sym_Extra;
struct bfd_elf_arch_map {
enum bfd_architecture bfd_arch;
int elf_arch;
};
extern const struct bfd_elf_arch_map bfd_elf_arch_map[];
extern const int bfd_elf_arch_map_size;
struct bfd_elf_section_data {
Elf_Internal_Shdr this_hdr;
Elf_Internal_Shdr rel_hdr;
int this_idx, rel_idx;
};
#define elf_section_data(sec) ((struct bfd_elf_section_data*)sec->used_by_bfd)
#define shdr_name(abfd,shdr) (elf_shstrtab (abfd)->tab + (shdr)->sh_name)
#define get_elf_backend_data(abfd) \
((struct elf_backend_data *) (abfd)->xvec->backend_data)
struct strtab
{
char *tab;
int nentries;
int length;
};
/* Some private data is stashed away for future use using the tdata pointer
in the bfd structure. */
struct elf_obj_tdata
{
Elf_Internal_Ehdr elf_header[1]; /* Actual data, but ref like ptr */
Elf_Internal_Shdr **elf_sect_ptr;
Elf_Internal_Phdr *phdr;
struct strtab *strtab_ptr;
int num_locals;
int num_globals;
Elf_Internal_Sym *internal_syms;
elf_symbol_type *symbols; /* elf_symbol_type */
Elf_Sym_Extra *sym_extra;
asymbol **section_syms; /* STT_SECTION symbols for each section */
int num_section_syms; /* number of section_syms allocated */
Elf_Internal_Shdr symtab_hdr;
Elf_Internal_Shdr shstrtab_hdr;
Elf_Internal_Shdr strtab_hdr;
int symtab_section, shstrtab_section, strtab_section;
file_ptr next_file_pos;
void *prstatus; /* The raw /proc prstatus structure */
void *prpsinfo; /* The raw /proc prpsinfo structure */
bfd_vma gp; /* The gp value (MIPS only, for now) */
int gp_size; /* The gp size (MIPS only, for now) */
};
#define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data)
#define elf_elfheader(bfd) (elf_tdata(bfd) -> elf_header)
#define elf_elfsections(bfd) (elf_tdata(bfd) -> elf_sect_ptr)
#define elf_shstrtab(bfd) (elf_tdata(bfd) -> strtab_ptr)
#define elf_onesymtab(bfd) (elf_tdata(bfd) -> symtab_section)
#define elf_num_locals(bfd) (elf_tdata(bfd) -> num_locals)
#define elf_num_globals(bfd) (elf_tdata(bfd) -> num_globals)
#define elf_sym_extra(bfd) (elf_tdata(bfd) -> sym_extra)
#define elf_section_syms(bfd) (elf_tdata(bfd) -> section_syms)
#define elf_num_section_syms(bfd) (elf_tdata(bfd) -> num_section_syms)
#define core_prpsinfo(bfd) (elf_tdata(bfd) -> prpsinfo)
#define core_prstatus(bfd) (elf_tdata(bfd) -> prstatus)
#define obj_symbols(bfd) (elf_tdata(bfd) -> symbols)
#define obj_internal_syms(bfd) (elf_tdata(bfd) -> internal_syms)
#define elf_gp(bfd) (elf_tdata(bfd) -> gp)
#define elf_gp_size(bfd) (elf_tdata(bfd) -> gp_size)
extern char * elf_string_from_elf_section PARAMS ((bfd *, unsigned, unsigned));
extern char * elf_get_str_section PARAMS ((bfd *, unsigned));
#define bfd_elf32_mkobject bfd_elf_mkobject
#define bfd_elf64_mkobject bfd_elf_mkobject
#define elf_mkobject bfd_elf_mkobject
extern unsigned long bfd_elf_hash PARAMS ((CONST unsigned char *));
extern bfd_reloc_status_type bfd_elf_generic_reloc PARAMS ((bfd *,
arelent *,
asymbol *,
PTR,
asection *,
bfd *));
extern boolean bfd_elf_mkobject PARAMS ((bfd *));
extern Elf_Internal_Shdr *bfd_elf_find_section PARAMS ((bfd *, char *));
extern boolean bfd_elf32_write_object_contents PARAMS ((bfd *));
extern boolean bfd_elf64_write_object_contents PARAMS ((bfd *));
extern bfd_target *bfd_elf32_object_p PARAMS ((bfd *));
extern bfd_target *bfd_elf32_core_file_p PARAMS ((bfd *));
extern char *bfd_elf32_core_file_failing_command PARAMS ((bfd *));
extern int bfd_elf32_core_file_failing_signal PARAMS ((bfd *));
extern boolean bfd_elf32_core_file_matches_executable_p PARAMS ((bfd *,
bfd *));
extern boolean bfd_elf32_set_section_contents PARAMS ((bfd *, sec_ptr, PTR,
file_ptr,
bfd_size_type));
extern unsigned int bfd_elf32_get_symtab_upper_bound PARAMS ((bfd *));
extern unsigned int bfd_elf32_get_symtab PARAMS ((bfd *, asymbol **));
extern unsigned int bfd_elf32_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
extern unsigned int bfd_elf32_canonicalize_reloc PARAMS ((bfd *, sec_ptr,
arelent **,
asymbol **));
extern asymbol *bfd_elf32_make_empty_symbol PARAMS ((bfd *));
extern void bfd_elf32_print_symbol PARAMS ((bfd *, PTR, asymbol *,
bfd_print_symbol_type));
extern void bfd_elf32_get_symbol_info PARAMS ((bfd *, asymbol *,
symbol_info *));
extern alent *bfd_elf32_get_lineno PARAMS ((bfd *, asymbol *));
extern boolean bfd_elf32_set_arch_mach PARAMS ((bfd *, enum bfd_architecture,
unsigned long));
extern boolean bfd_elf32_find_nearest_line PARAMS ((bfd *, asection *,
asymbol **,
bfd_vma, CONST char **,
CONST char **,
unsigned int *));
extern int bfd_elf32_sizeof_headers PARAMS ((bfd *, boolean));
extern void bfd_elf32__write_relocs PARAMS ((bfd *, asection *, PTR));
extern boolean bfd_elf32_new_section_hook PARAMS ((bfd *, asection *));
/* If the target doesn't have reloc handling written yet: */
extern void bfd_elf32_no_info_to_howto PARAMS ((bfd *, arelent *,
Elf32_Internal_Rela *));
extern bfd_target *bfd_elf64_object_p PARAMS ((bfd *));
extern bfd_target *bfd_elf64_core_file_p PARAMS ((bfd *));
extern char *bfd_elf64_core_file_failing_command PARAMS ((bfd *));
extern int bfd_elf64_core_file_failing_signal PARAMS ((bfd *));
extern boolean bfd_elf64_core_file_matches_executable_p PARAMS ((bfd *,
bfd *));
extern boolean bfd_elf64_set_section_contents PARAMS ((bfd *, sec_ptr, PTR,
file_ptr,
bfd_size_type));
extern unsigned int bfd_elf64_get_symtab_upper_bound PARAMS ((bfd *));
extern unsigned int bfd_elf64_get_symtab PARAMS ((bfd *, asymbol **));
extern unsigned int bfd_elf64_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
extern unsigned int bfd_elf64_canonicalize_reloc PARAMS ((bfd *, sec_ptr,
arelent **,
asymbol **));
extern asymbol *bfd_elf64_make_empty_symbol PARAMS ((bfd *));
extern void bfd_elf64_print_symbol PARAMS ((bfd *, PTR, asymbol *,
bfd_print_symbol_type));
extern void bfd_elf64_get_symbol_info PARAMS ((bfd *, asymbol *,
symbol_info *));
extern alent *bfd_elf64_get_lineno PARAMS ((bfd *, asymbol *));
extern boolean bfd_elf64_set_arch_mach PARAMS ((bfd *, enum bfd_architecture,
unsigned long));
extern boolean bfd_elf64_find_nearest_line PARAMS ((bfd *, asection *,
asymbol **,
bfd_vma, CONST char **,
CONST char **,
unsigned int *));
extern int bfd_elf64_sizeof_headers PARAMS ((bfd *, boolean));
extern void bfd_elf64__write_relocs PARAMS ((bfd *, asection *, PTR));
extern boolean bfd_elf64_new_section_hook PARAMS ((bfd *, asection *));
/* If the target doesn't have reloc handling written yet: */
extern void bfd_elf64_no_info_to_howto PARAMS ((bfd *, arelent *,
Elf64_Internal_Rela *));
#endif /* _LIBELF_H_ */

View File

@ -0,0 +1,55 @@
/* $Id: netbsd.h,v 1.1 1994/01/28 12:38:02 pk Exp $ */
/* ZMAGIC files never have the header in the text. */
#define N_HEADER_IN_TEXT(x) 0
/* ZMAGIC files start at address 0. This does not apply to QMAGIC. */
#define TEXT_START_ADDR 0
#define N_MAGIC(ex) \
( (((ex).a_info)&0xffff0000) ? (ntohl(((ex).a_info))&0xffff) : ((ex).a_info))
#define N_MACHTYPE(ex) \
( (((ex).a_info)&0xffff0000) ? ((ntohl(((ex).a_info))>>16)&0x03ff) : 0 )
# define N_FLAGS(ex) \
( (((ex).a_info)&0xffff0000) ? ((ntohl(((ex).a_info))>>26)&0x3f) : 0 )
#define N_SET_INFO(ex, mag,mid,flag) \
( (ex).a_info = htonl( (((flag)&0x3f)<<26) | (((mid)&0x03ff)<<16) | \
(((mag)&0xffff)) ) )
#define N_SET_MAGIC(exec,magic) \
((exec).a_info = (((exec).a_info & ~0xffff) | ((magic) & 0xffff)))
#define N_SET_MACHTYPE(exec,machtype) \
((exec).a_info = \
(((exec).a_info & ~(0x3ff<<16)) | (((machtype)&0xff) << 16)))
#define N_SET_FLAGS(exec, flags) \
((exec).a_info = ((exec).a_info & 0xffff) | (flags & 0xffff))
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#include "libaout.h"
#define N_GETMAGIC(ex) \
( (((ex).a_info)&0xffff0000) ? (ntohl(((ex).a_info))&0xffff) : ((ex).a_info))
#define N_GETMAGIC2(ex) \
( (((ex).a_info)&0xffff0000) ? (ntohl(((ex).a_info))&0xffff) : \
(((ex).a_info) | 0x10000) )
#define N_TXTADDR(ex) (N_GETMAGIC2(ex) == (ZMAGIC|0x10000) ? 0 : __LDPGSZ)
#define N_TXTOFF(ex) \
( N_GETMAGIC2(ex)==ZMAGIC || N_GETMAGIC2(ex)==(QMAGIC|0x10000) ? \
0 : (N_GETMAGIC2(ex)==(ZMAGIC|0x10000) ? __LDPGSZ : EXEC_BYTES_SIZE ))
#define N_ALIGN(ex,x) \
(N_MAGIC(ex) == ZMAGIC || N_MAGIC(ex) == QMAGIC ? \
((x) + __LDPGSZ - 1) & ~(__LDPGSZ - 1) : (x))
#define N_DATADDR(ex) \
(N_GETMAGIC(ex) == OMAGIC ? N_TXTADDR(ex) + (ex).a_text : \
(N_TXTADDR(ex) + (ex).a_text + __LDPGSZ - 1) & ~(__LDPGSZ - 1))
/* Data segment offset. */
#define N_DATOFF(ex) \
N_ALIGN(ex, N_TXTOFF(ex) + (ex).a_text)
#define NO_SWAP_MAGIC /* magic number already in correct endian format */
#include "aout-target.h"

View File

@ -0,0 +1,537 @@
/* opncls.c -- open and close a BFD.
Copyright (C) 1990-1991 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: opncls.c,v 1.1 1994/01/28 12:38:03 pk Exp $
*/
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#include "obstack.h"
extern void bfd_cache_init PARAMS ((bfd *));
FILE *bfd_open_file PARAMS ((bfd *));
/* fdopen is a loser -- we should use stdio exclusively. Unfortunately
if we do that we can't use fcntl. */
#define obstack_chunk_alloc bfd_xmalloc_by_size_t
#define obstack_chunk_free free
/* Return a new BFD. All BFD's are allocated through this routine. */
bfd *
new_bfd PARAMS ((void))
{
bfd *nbfd;
nbfd = (bfd *)zalloc (sizeof (bfd));
if (!nbfd)
return 0;
bfd_check_init();
obstack_begin((PTR)&nbfd->memory, 128);
nbfd->arch_info = &bfd_default_arch_struct;
nbfd->direction = no_direction;
nbfd->iostream = NULL;
nbfd->where = 0;
nbfd->sections = (asection *)NULL;
nbfd->format = bfd_unknown;
nbfd->my_archive = (bfd *)NULL;
nbfd->origin = 0;
nbfd->opened_once = false;
nbfd->output_has_begun = false;
nbfd->section_count = 0;
nbfd->usrdata = (PTR)NULL;
nbfd->cacheable = false;
nbfd->flags = NO_FLAGS;
nbfd->mtime_set = false;
return nbfd;
}
/* Allocate a new BFD as a member of archive OBFD. */
bfd *
new_bfd_contained_in (obfd)
bfd *obfd;
{
bfd *nbfd;
nbfd = new_bfd();
nbfd->xvec = obfd->xvec;
nbfd->my_archive = obfd;
nbfd->direction = read_direction;
nbfd->target_defaulted = obfd->target_defaulted;
return nbfd;
}
/*
SECTION
Opening and Closing BFDs
*/
/*
FUNCTION
bfd_openr
SYNOPSIS
bfd *bfd_openr(CONST char *filename, CONST char*target);
DESCRIPTION
This function opens the file supplied (using <<fopen>>) with the target
supplied, it returns a pointer to the created BFD.
If NULL is returned then an error has occured. Possible errors
are <<no_memory>>, <<invalid_target>> or <<system_call>> error.
*/
bfd *
DEFUN(bfd_openr, (filename, target),
CONST char *filename AND
CONST char *target)
{
bfd *nbfd;
bfd_target *target_vec;
nbfd = new_bfd();
if (nbfd == NULL) {
bfd_error = no_memory;
return NULL;
}
target_vec = bfd_find_target (target, nbfd);
if (target_vec == NULL) {
bfd_error = invalid_target;
return NULL;
}
nbfd->filename = filename;
nbfd->direction = read_direction;
if (bfd_open_file (nbfd) == NULL) {
bfd_error = system_call_error; /* File didn't exist, or some such */
bfd_release(nbfd,0);
return NULL;
}
return nbfd;
}
/* Don't try to `optimize' this function:
o - We lock using stack space so that interrupting the locking
won't cause a storage leak.
o - We open the file stream last, since we don't want to have to
close it if anything goes wrong. Closing the stream means closing
the file descriptor too, even though we didn't open it.
*/
/*
FUNCTION
bfd_fdopenr
SYNOPSIS
bfd *bfd_fdopenr(CONST char *filename, CONST char *target, int fd);
DESCRIPTION
bfd_fdopenr is to bfd_fopenr much like fdopen is to fopen.
It opens a BFD on a file already described by the @var{fd}
supplied.
When the file is later bfd_closed, the file descriptor will be closed.
If the caller desires that this file descriptor be cached by BFD
(opened as needed, closed as needed to free descriptors for
other opens), with the supplied @var{fd} used as an initial
file descriptor (but subject to closure at any time), set
bfd->cacheable nonzero in the returned BFD. The default is to
assume no cacheing; the file descriptor will remain open until
bfd_close, and will not be affected by BFD operations on other
files.
Possible errors are no_memory, invalid_target and system_call
error.
*/
bfd *
DEFUN(bfd_fdopenr,(filename, target, fd),
CONST char *filename AND
CONST char *target AND
int fd)
{
bfd *nbfd;
bfd_target *target_vec;
int fdflags;
bfd_error = system_call_error;
#ifdef NO_FCNTL
fdflags = O_RDWR; /* Assume full access */
#else
fdflags = fcntl (fd, F_GETFL, NULL);
#endif
if (fdflags == -1) return NULL;
nbfd = new_bfd();
if (nbfd == NULL) {
bfd_error = no_memory;
return NULL;
}
target_vec = bfd_find_target (target, nbfd);
if (target_vec == NULL) {
bfd_error = invalid_target;
return NULL;
}
#if defined(VMS) || defined(__GO32__)
nbfd->iostream = (char *)fopen(filename, FOPEN_RB);
#else
/* (O_ACCMODE) parens are to avoid Ultrix header file bug */
switch (fdflags & (O_ACCMODE)) {
case O_RDONLY: nbfd->iostream = (char *) fdopen (fd, FOPEN_RB); break;
case O_WRONLY: nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB); break;
case O_RDWR: nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB); break;
default: abort ();
}
#endif
if (nbfd->iostream == NULL) {
(void) obstack_free (&nbfd->memory, (PTR)0);
return NULL;
}
/* OK, put everything where it belongs */
nbfd->filename = filename;
/* As a special case we allow a FD open for read/write to
be written through, although doing so requires that we end
the previous clause with a preposition. */
/* (O_ACCMODE) parens are to avoid Ultrix header file bug */
switch (fdflags & (O_ACCMODE)) {
case O_RDONLY: nbfd->direction = read_direction; break;
case O_WRONLY: nbfd->direction = write_direction; break;
case O_RDWR: nbfd->direction = both_direction; break;
default: abort ();
}
bfd_cache_init (nbfd);
return nbfd;
}
/** bfd_openw -- open for writing.
Returns a pointer to a freshly-allocated BFD on success, or NULL.
See comment by bfd_fdopenr before you try to modify this function. */
/*
FUNCTION
bfd_openw
SYNOPSIS
bfd *bfd_openw(CONST char *filename, CONST char *target);
DESCRIPTION
Creates a BFD, associated with file @var{filename}, using the
file format @var{target}, and returns a pointer to it.
Possible errors are system_call_error, no_memory,
invalid_target.
*/
bfd *
DEFUN(bfd_openw,(filename, target),
CONST char *filename AND
CONST char *target)
{
bfd *nbfd;
bfd_target *target_vec;
bfd_error = system_call_error;
/* nbfd has to point to head of malloc'ed block so that bfd_close may
reclaim it correctly. */
nbfd = new_bfd();
if (nbfd == NULL) {
bfd_error = no_memory;
return NULL;
}
target_vec = bfd_find_target (target, nbfd);
if (target_vec == NULL) return NULL;
nbfd->filename = filename;
nbfd->direction = write_direction;
if (bfd_open_file (nbfd) == NULL) {
bfd_error = system_call_error; /* File not writeable, etc */
(void) obstack_free (&nbfd->memory, (PTR)0);
return NULL;
}
return nbfd;
}
/*
FUNCTION
bfd_close
SYNOPSIS
boolean bfd_close(bfd *);
DESCRIPTION
This function closes a BFD. If the BFD was open for writing,
then pending operations are completed and the file written out
and closed. If the created file is executable, then
<<chmod>> is called to mark it as such.
All memory attached to the BFD's obstacks is released.
The file descriptor associated with the BFD is closed (even
if it was passed in to BFD by bfd_fdopenr).
RETURNS
<<true>> is returned if all is ok, otherwise <<false>>.
*/
boolean
DEFUN(bfd_close,(abfd),
bfd *abfd)
{
boolean ret;
if (!bfd_read_p(abfd))
if (BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)) != true)
return false;
if (BFD_SEND (abfd, _close_and_cleanup, (abfd)) != true) return false;
ret = bfd_cache_close(abfd);
/* If the file was open for writing and is now executable,
make it so */
if (ret == true
&& abfd->direction == write_direction
&& abfd->flags & EXEC_P) {
struct stat buf;
stat(abfd->filename, &buf);
#ifndef S_IXUSR
#define S_IXUSR 0100 /* Execute by owner. */
#endif
#ifndef S_IXGRP
#define S_IXGRP 0010 /* Execute by group. */
#endif
#ifndef S_IXOTH
#define S_IXOTH 0001 /* Execute by others. */
#endif
chmod(abfd->filename, 0777 & (buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH));
}
(void) obstack_free (&abfd->memory, (PTR)0);
(void) free(abfd);
return ret;
}
/*
FUNCTION
bfd_close_all_done
SYNOPSIS
boolean bfd_close_all_done(bfd *);
DESCRIPTION
This function closes a BFD. It differs from <<bfd_close>>
since it does not complete any pending operations. This
routine would be used if the application had just used BFD for
swapping and didn't want to use any of the writing code.
If the created file is executable, then <<chmod>> is called
to mark it as such.
All memory attached to the BFD's obstacks is released.
RETURNS
<<true>> is returned if all is ok, otherwise <<false>>.
*/
boolean
DEFUN(bfd_close_all_done,(abfd),
bfd *abfd)
{
boolean ret;
ret = bfd_cache_close(abfd);
/* If the file was open for writing and is now executable,
make it so */
if (ret == true
&& abfd->direction == write_direction
&& abfd->flags & EXEC_P) {
struct stat buf;
stat(abfd->filename, &buf);
#ifndef S_IXUSR
#define S_IXUSR 0100 /* Execute by owner. */
#endif
#ifndef S_IXGRP
#define S_IXGRP 0010 /* Execute by group. */
#endif
#ifndef S_IXOTH
#define S_IXOTH 0001 /* Execute by others. */
#endif
chmod(abfd->filename, 0x777 &(buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH));
}
(void) obstack_free (&abfd->memory, (PTR)0);
(void) free(abfd);
return ret;
}
/*
FUNCTION
bfd_alloc_size
SYNOPSIS
bfd_size_type bfd_alloc_size(bfd *abfd);
DESCRIPTION
Return the number of bytes in the obstacks connected to the
supplied BFD.
*/
bfd_size_type
DEFUN(bfd_alloc_size,(abfd),
bfd *abfd)
{
struct _obstack_chunk *chunk = abfd->memory.chunk;
size_t size = 0;
while (chunk) {
size += chunk->limit - &(chunk->contents[0]);
chunk = chunk->prev;
}
return size;
}
/*
FUNCTION
bfd_create
SYNOPSIS
bfd *bfd_create(CONST char *filename, bfd *templ);
DESCRIPTION
This routine creates a new BFD in the manner of
<<bfd_openw>>, but without opening a file. The new BFD
takes the target from the target used by @var{template}. The
format is always set to <<bfd_object>>.
*/
bfd *
DEFUN(bfd_create,(filename, templ),
CONST char *filename AND
bfd *templ)
{
bfd *nbfd = new_bfd();
if (nbfd == (bfd *)NULL) {
bfd_error = no_memory;
return (bfd *)NULL;
}
nbfd->filename = filename;
if(templ) {
nbfd->xvec = templ->xvec;
}
nbfd->direction = no_direction;
bfd_set_format(nbfd, bfd_object);
return nbfd;
}
/*
INTERNAL_FUNCTION
bfd_alloc_by_size_t
SYNOPSIS
PTR bfd_alloc_by_size_t(bfd *abfd, size_t wanted);
DESCRIPTION
This function allocates a block of memory in the obstack
attatched to <<abfd>> and returns a pointer to it.
*/
PTR
DEFUN(bfd_alloc_by_size_t,(abfd, size),
bfd *abfd AND
size_t size)
{
PTR res = obstack_alloc(&(abfd->memory), size);
return res;
}
DEFUN(void bfd_alloc_grow,(abfd, ptr, size),
bfd *abfd AND
PTR ptr AND
size_t size)
{
(void) obstack_grow(&(abfd->memory), ptr, size);
}
DEFUN(PTR bfd_alloc_finish,(abfd),
bfd *abfd)
{
return obstack_finish(&(abfd->memory));
}
DEFUN(PTR bfd_alloc, (abfd, size),
bfd *abfd AND
size_t size)
{
return bfd_alloc_by_size_t(abfd, (size_t)size);
}
DEFUN(PTR bfd_zalloc,(abfd, size),
bfd *abfd AND
size_t size)
{
PTR res;
res = bfd_alloc(abfd, size);
memset(res, 0, (size_t)size);
return res;
}
DEFUN(PTR bfd_realloc,(abfd, old, size),
bfd *abfd AND
PTR old AND
size_t size)
{
PTR res = bfd_alloc(abfd, size);
memcpy(res, old, (size_t)size);
return res;
}

1228
gnu/usr.bin/gdb/bfd/reloc.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,188 @@
/* seclet.c
Copyright (C) 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: seclet.c,v 1.1 1994/01/28 12:38:06 pk Exp $
*/
/* This module is part of BFD */
/* The intention is that one day, all the code which uses sections
will change and use seclets instead - maybe seglet would have been
a better name..
Anyway, a seclet contains enough info to be able to describe an
area of output memory in one go.
The only description so far catered for is that of the
<<bfd_indirect_seclet>>, which is a select which points to a
<<section>> and the <<asymbols>> associated with the section, so
that relocation can be done when needed.
One day there will be more types - they will at least migrate from
the linker's data structures - also there could be extra stuff,
like a bss seclet, which descibes a lump of memory as containing
zeros compactly, without the horrible SEC_* flag cruft.
*/
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#include "seclet.h"
#include "coff/internal.h"
/* Create a new seclet and attach it to a section. */
bfd_seclet_type *
DEFUN(bfd_new_seclet,(abfd, section),
bfd *abfd AND
asection *section)
{
bfd_seclet_type *n = (bfd_seclet_type *)bfd_alloc(abfd, sizeof(bfd_seclet_type));
if (section->seclets_tail != (bfd_seclet_type *)NULL) {
section->seclets_tail->next = n;
}
else
{
section->seclets_head = n;
}
section->seclets_tail = n;
return n;
}
/* Given an indirect seclet which points to an input section, relocate
the contents of the seclet and put the data in its final
destination. */
static boolean
DEFUN(rel,(abfd, seclet, output_section, data, relocateable),
bfd *abfd AND
bfd_seclet_type *seclet AND
asection *output_section AND
PTR data AND
boolean relocateable)
{
if ((output_section->flags & SEC_HAS_CONTENTS) != 0
&& seclet->size)
{
data = (PTR) bfd_get_relocated_section_contents(abfd, seclet, data,
relocateable);
if(bfd_set_section_contents(abfd,
output_section,
data,
seclet->offset,
seclet->size) == false)
{
abort();
}
}
return true;
}
/* Put the contents of a seclet in its final destination. */
static boolean
DEFUN(seclet_dump_seclet,(abfd, seclet, section, data, relocateable),
bfd *abfd AND
bfd_seclet_type *seclet AND
asection *section AND
PTR data AND
boolean relocateable)
{
switch (seclet->type)
{
case bfd_indirect_seclet:
/* The contents of this section come from another one somewhere
else */
return rel(abfd, seclet, section, data, relocateable);
case bfd_fill_seclet:
/* Fill in the section with us */
{
char *d = bfd_xmalloc(seclet->size);
unsigned int i;
for (i =0; i < seclet->size; i+=2) {
d[i] = seclet->u.fill.value >> 8;
}
for (i = 1; i < seclet->size; i+=2) {
d[i] = seclet->u.fill.value ;
}
/* Don't bother to fill in empty sections */
if (!(bfd_get_section_flags(abfd, section) & SEC_HAS_CONTENTS))
{
return true;
}
return bfd_set_section_contents(abfd, section, d, seclet->offset,
seclet->size);
}
default:
abort();
}
return true;
}
/*
INTERNAL_FUNCTION
bfd_generic_seclet_link
SYNOPSIS
boolean bfd_generic_seclet_link
(bfd *abfd,
PTR data,
boolean relocateable);
DESCRIPTION
The generic seclet linking routine. The caller should have
set up seclets for all the output sections. The DATA argument
should point to a memory area large enough to hold the largest
section. This function looks through the seclets and moves
the contents into the output sections. If RELOCATEABLE is
true, the orelocation fields of the output sections must
already be initialized.
*/
boolean
DEFUN(bfd_generic_seclet_link,(abfd, data, relocateable),
bfd *abfd AND
PTR data AND
boolean relocateable)
{
asection *o = abfd->sections;
while (o != (asection *)NULL)
{
bfd_seclet_type *p = o->seclets_head;
while (p != (bfd_seclet_type *)NULL)
{
if (seclet_dump_seclet(abfd, p, o, data, relocateable) == false)
return false;
p = p ->next;
}
o = o->next;
}
return true;
}

View File

@ -0,0 +1,58 @@
/* Definitions of little sections (seclets) for BFD.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: seclet.h,v 1.1 1994/01/28 12:38:07 pk Exp $
*/
#ifndef _SECLET_H
#define _SECLET_H
enum bfd_seclet_enum
{
bfd_indirect_seclet,
bfd_fill_seclet
};
struct bfd_seclet
{
struct bfd_seclet *next;
enum bfd_seclet_enum type;
unsigned int offset;
unsigned int size;
union
{
struct
{
asection *section;
asymbol **symbols;
} indirect;
struct {
int value;
} fill;
}
u;
};
typedef struct bfd_seclet bfd_seclet_type;
bfd_seclet_type *
bfd_new_seclet PARAMS ((bfd *, asection *));
#endif

View File

@ -0,0 +1,902 @@
/* Object file "section" support for the BFD library.
Copyright (C) 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: section.c,v 1.1 1994/01/28 12:38:08 pk Exp $
*/
/*
SECTION
Sections
Sections are supported in BFD in <<section.c>>.
The raw data contained within a BFD is maintained through the
section abstraction. A single BFD may have any number of
sections, and keeps hold of them by pointing to the first,
each one points to the next in the list.
@menu
@* Section Input::
@* Section Output::
@* typedef asection::
@* section prototypes::
@end menu
INODE
Section Input, Section Output, Sections, Sections
SUBSECTION
Section Input
When a BFD is opened for reading, the section structures are
created and attached to the BFD.
Each section has a name which describes the section in the
outside world - for example, <<a.out>> would contain at least
three sections, called <<.text>>, <<.data>> and <<.bss>>.
Names need not be unique; for example a COFF file may have several
sections named .data.
Sometimes a BFD will contain more than the 'natural' number of
sections. A back end may attach other sections containing
constructor data, or an application may add a section (using
bfd_make_section) to the sections attached to an already open
BFD. For example, the linker creates a supernumary section
<<COMMON>> for each input file's BFD to hold information about
common storage.
The raw data is not necessarily read in at the same time as
the section descriptor is created. Some targets may leave the
data in place until a <<bfd_get_section_contents>> call is
made. Other back ends may read in all the data at once - For
example; an S-record file has to be read once to determine the
size of the data. An IEEE-695 file doesn't contain raw data in
sections, but data and relocation expressions intermixed, so
the data area has to be parsed to get out the data and
relocations.
INODE
Section Output, typedef asection, Section Input, Sections
SUBSECTION
Section Output
To write a new object style BFD, the various sections to be
written have to be created. They are attached to the BFD in
the same way as input sections, data is written to the
sections using <<bfd_set_section_contents>>.
Any program that creates or combines sections (e.g., the assembler
and linker) must use the fields <<output_section>> and
<<output_offset>> to indicate the file sections to which each
section must be written. (If the section is being created from
scratch, <<output_section>> should probably point to the section
itself, and <<output_offset>> should probably be zero.)
The data to be written comes from input sections attached to
the output sections. The output section structure can be
considered a filter for the input section, the output section
determines the vma of the output data and the name, but the
input section determines the offset into the output section of
the data to be written.
E.g., to create a section "O", starting at 0x100, 0x123 long,
containing two subsections, "A" at offset 0x0 (ie at vma
0x100) and "B" at offset 0x20 (ie at vma 0x120) the structures
would look like:
| section name "A"
| output_offset 0x00
| size 0x20
| output_section -----------> section name "O"
| | vma 0x100
| section name "B" | size 0x123
| output_offset 0x20 |
| size 0x103 |
| output_section --------|
SUBSECTION
Seglets
The data within a section is stored in a <<seglet>>. These
are much like the fixups in <<gas>>. The seglet abstraction
allows the a section to grow and shrink within itself.
A seglet knows how big it is, and which is the next seglet and
where the raw data for it is, and also points to a list of
relocations which apply to it.
The seglet is used by the linker to perform relaxing on final
code. The application creates code which is as big as
necessary to make it work without relaxing, and the user can
select whether to relax. Sometimes relaxing takes a lot of
time. The linker runs around the relocations to see if any
are attached to data which can be shrunk, if so it does it on
a seglet by seglet basis.
*/
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
/*
DOCDD
INODE
typedef asection, section prototypes, Section Output, Sections
SUBSECTION
typedef asection
The shape of a section struct:
CODE_FRAGMENT
.
.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 of
. 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 loaded.
. This would 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 would be clear for a .bss section *}
.#define SEC_LOAD 0x002
.
. {* The section contains data still to be relocated, so there will
. be 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 (eg <<__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 relocte 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 not to output sections
. containing this flag even if they have information which
. would normally be written. *}
.#define SEC_NEVER_LOAD 0x400
.
. {* The section is a shared library section. The linker must leave
. these completely alone, as the vma and size are used when
. the executable is loaded. *}
.#define SEC_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), 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
.
. {* 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 (eg, the
. size of <<.bss>>). This will be filled in after relocation *}
.
. bfd_size_type _cooked_size;
.
. {* The size on disk of the section in bytes originally. 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. Eg, 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 - eg
. 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;
.
. struct lang_output_section *otheruserdata;
.
. {* 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_seclet *seclets_head;
. struct bfd_seclet *seclets_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. *}
.#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 asection bfd_abs_section;
. {* Pointer to the undefined section *}
.extern asection bfd_und_section;
. {* Pointer to the common section *}
.extern asection bfd_com_section;
. {* Pointer to the indirect section *}
.extern asection bfd_ind_section;
.
.extern struct symbol_cache_entry *bfd_abs_symbol;
.extern struct symbol_cache_entry *bfd_com_symbol;
.extern struct symbol_cache_entry *bfd_und_symbol;
.extern struct symbol_cache_entry *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))
*/
/* These symbols are global, not specific to any BFD. Therefore, anything
that tries to change them is broken, and should be repaired. */
static CONST asymbol global_syms[] = {
/* the_bfd, name, value, attr, section [, udata] */
{ 0, BFD_COM_SECTION_NAME, 0, BSF_SECTION_SYM, &bfd_com_section },
{ 0, BFD_UND_SECTION_NAME, 0, BSF_SECTION_SYM, &bfd_und_section },
{ 0, BFD_ABS_SECTION_NAME, 0, BSF_SECTION_SYM, &bfd_abs_section },
{ 0, BFD_IND_SECTION_NAME, 0, BSF_SECTION_SYM, &bfd_ind_section },
};
#define STD_SECTION(SEC, FLAGS, SYM, NAME, IDX) \
asymbol *SYM = (asymbol *) &global_syms[IDX]; \
asection SEC = { NAME, 0, 0, FLAGS, 0, 0, (boolean) 0, 0, 0, 0, &SEC,\
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (boolean) 0, \
(asymbol *) &global_syms[IDX], &SYM, }
STD_SECTION (bfd_com_section, SEC_IS_COMMON, bfd_com_symbol, BFD_COM_SECTION_NAME, 0);
STD_SECTION (bfd_und_section, 0, bfd_und_symbol, BFD_UND_SECTION_NAME, 1);
STD_SECTION (bfd_abs_section, 0, bfd_abs_symbol, BFD_ABS_SECTION_NAME, 2);
STD_SECTION (bfd_ind_section, 0, bfd_ind_symbol, BFD_IND_SECTION_NAME, 3);
#undef STD_SECTION
/*
DOCDD
INODE
section prototypes, , typedef asection, Sections
SUBSECTION
section prototypes
These are the functions exported by the section handling part of
<<libbfd>.
*/
/*
FUNCTION
bfd_get_section_by_name
SYNOPSIS
asection *bfd_get_section_by_name(bfd *abfd, CONST char *name);
DESCRIPTION
Runs through the provided @var{abfd} and returns the one of the
<<asection>>s who's name matches that provided, otherwise NULL.
@xref{Sections}, for more information.
This should only be used in special cases; the normal way to process
all sections of a given name is to use bfd_map_over_sections and
strcmp on the name (or better yet, base it on the section flags
or something else) for each section.
*/
asection *
DEFUN(bfd_get_section_by_name,(abfd, name),
bfd *abfd AND
CONST char *name)
{
asection *sect;
for (sect = abfd->sections; sect != NULL; sect = sect->next)
if (!strcmp (sect->name, name)) return sect;
return NULL;
}
/*
FUNCTION
bfd_make_section_old_way
SYNOPSIS
asection *bfd_make_section_old_way(bfd *, CONST char *name);
DESCRIPTION
This function creates a new empty section called @var{name}
and attaches it to the end of the chain of sections for the
BFD supplied. An attempt to create a section with a name which
is already in use, returns its pointer without changing the
section chain.
It has the funny name since this is the way it used to be
before is was rewritten...
Possible errors are:
o invalid_operation -
If output has already started for this BFD.
o no_memory -
If obstack alloc fails.
*/
asection *
DEFUN(bfd_make_section_old_way,(abfd, name),
bfd *abfd AND
CONST char * name)
{
asection *sec = bfd_get_section_by_name(abfd, name);
if (sec == (asection *)NULL)
{
sec = bfd_make_section(abfd, name);
}
return sec;
}
/*
FUNCTION
bfd_make_section_anyway
SYNOPSIS
asection *bfd_make_section_anyway(bfd *, CONST char *name);
DESCRIPTION
Create a new empty section called @var{name} and attach it to the end of
the chain of sections for @var{abfd}. Create a new section even if there
is already a section with that name.
Returns NULL and sets bfd_error on error; possible errors are:
o invalid_operation - If output has already started for @var{abfd}.
o no_memory - If obstack alloc fails.
*/
sec_ptr
bfd_make_section_anyway (abfd, name)
bfd *abfd;
CONST char *name;
{
asection *newsect;
asection **prev = &abfd->sections;
asection * sect = abfd->sections;
if (abfd->output_has_begun)
{
bfd_error = invalid_operation;
return NULL;
}
while (sect) {
prev = &sect->next;
sect = sect->next;
}
newsect = (asection *) bfd_zalloc(abfd, sizeof (asection));
if (newsect == NULL) {
bfd_error = no_memory;
return NULL;
}
newsect->name = name;
newsect->index = abfd->section_count++;
newsect->flags = SEC_NO_FLAGS;
newsect->userdata = 0;
newsect->next = (asection *)NULL;
newsect->relocation = (arelent *)NULL;
newsect->reloc_count = 0;
newsect->line_filepos =0;
newsect->owner = abfd;
/* Create a symbol whos only job is to point to this section. This is
useful for things like relocs which are relative to the base of a
section. */
newsect->symbol = bfd_make_empty_symbol(abfd);
newsect->symbol->name = name;
newsect->symbol->value = 0;
newsect->symbol->section = newsect;
newsect->symbol->flags = BSF_SECTION_SYM;
newsect->symbol_ptr_ptr = &newsect->symbol;
if (BFD_SEND (abfd, _new_section_hook, (abfd, newsect)) != true) {
free (newsect);
return NULL;
}
*prev = newsect;
return newsect;
}
/*
FUNCTION
bfd_make_section
SYNOPSIS
asection *bfd_make_section(bfd *, CONST char *name);
DESCRIPTION
Like bfd_make_section_anyway, but return NULL (without setting
bfd_error) without changing the section chain if there is already a
section named @var{name}. If there is an error, return NULL and set
bfd_error.
*/
sec_ptr
DEFUN(bfd_make_section,(abfd, name),
bfd *abfd AND
CONST char * name)
{
asection * sect = abfd->sections;
if (strcmp(name, BFD_ABS_SECTION_NAME) == 0)
{
return &bfd_abs_section;
}
if (strcmp(name, BFD_COM_SECTION_NAME) == 0)
{
return &bfd_com_section;
}
if (strcmp(name, BFD_UND_SECTION_NAME) == 0)
{
return &bfd_und_section;
}
if (strcmp(name, BFD_IND_SECTION_NAME) == 0)
{
return &bfd_ind_section;
}
while (sect) {
if (!strcmp(sect->name, name)) return NULL;
sect = sect->next;
}
/* The name is not already used; go ahead and make a new section. */
return bfd_make_section_anyway (abfd, name);
}
/*
FUNCTION
bfd_set_section_flags
SYNOPSIS
boolean bfd_set_section_flags(bfd *, asection *, flagword);
DESCRIPTION
Attempts to set the attributes of the section named in the BFD
supplied to the value. Returns true on success, false on
error. Possible error returns are:
o invalid operation -
The section cannot have one or more of the attributes
requested. For example, a .bss section in <<a.out>> may not
have the <<SEC_HAS_CONTENTS>> field set.
*/
boolean
DEFUN(bfd_set_section_flags,(abfd, section, flags),
bfd *abfd AND
sec_ptr section AND
flagword flags)
{
#if 0
/* If you try to copy a text section from an input file (where it
has the SEC_CODE flag set) to an output file, this loses big if
the bfd_applicable_section_flags (abfd) doesn't have the SEC_CODE
set - which it doesn't, at least not for a.out. FIXME */
if ((flags & bfd_applicable_section_flags (abfd)) != flags) {
bfd_error = invalid_operation;
return false;
}
#endif
section->flags = flags;
return true;
}
/*
FUNCTION
bfd_map_over_sections
SYNOPSIS
void bfd_map_over_sections(bfd *abfd,
void (*func)(bfd *abfd,
asection *sect,
PTR obj),
PTR obj);
DESCRIPTION
Calls the provided function @var{func} for each section
attached to the BFD @var{abfd}, passing @var{obj} as an
argument. The function will be called as if by
| func(abfd, the_section, obj);
This is the prefered method for iterating over sections, an
alternative would be to use a loop:
| section *p;
| for (p = abfd->sections; p != NULL; p = p->next)
| func(abfd, p, ...)
*/
/*VARARGS2*/
void
DEFUN(bfd_map_over_sections,(abfd, operation, user_storage),
bfd *abfd AND
void (*operation) PARAMS ((bfd *abfd, asection *sect, PTR obj)) AND
PTR user_storage)
{
asection *sect;
int i = 0;
for (sect = abfd->sections; sect != NULL; i++, sect = sect->next)
(*operation) (abfd, sect, user_storage);
if (i != abfd->section_count) /* Debugging */
abort();
}
/*
FUNCTION
bfd_set_section_size
SYNOPSIS
boolean bfd_set_section_size(bfd *, asection *, bfd_size_type val);
DESCRIPTION
Sets @var{section} to the size @var{val}. If the operation is
ok, then <<true>> is returned, else <<false>>.
Possible error returns:
o invalid_operation -
Writing has started to the BFD, so setting the size is invalid
*/
boolean
DEFUN(bfd_set_section_size,(abfd, ptr, val),
bfd *abfd AND
sec_ptr ptr AND
bfd_size_type val)
{
/* Once you've started writing to any section you cannot create or change
the size of any others. */
if (abfd->output_has_begun) {
bfd_error = invalid_operation;
return false;
}
ptr->_cooked_size = val;
ptr->_raw_size = val;
return true;
}
/*
FUNCTION
bfd_set_section_contents
SYNOPSIS
boolean bfd_set_section_contents
(bfd *abfd,
asection *section,
PTR data,
file_ptr offset,
bfd_size_type count);
DESCRIPTION
Sets the contents of the section @var{section} in BFD
@var{abfd} to the data starting in memory at @var{data}. The
data is written to the output section starting at offset
@var{offset} for @var{count} bytes.
Normally <<true>> is returned, else <<false>>. Possible error
returns are:
o no_contents -
The output section does not have the <<SEC_HAS_CONTENTS>>
attribute, so nothing can be written to it.
o and some more too
This routine is front end to the back end function
<<_bfd_set_section_contents>>.
*/
#define bfd_get_section_size_now(abfd,sec) \
(sec->reloc_done \
? bfd_get_section_size_after_reloc (sec) \
: bfd_get_section_size_before_reloc (sec))
boolean
DEFUN(bfd_set_section_contents,(abfd, section, location, offset, count),
bfd *abfd AND
sec_ptr section AND
PTR location AND
file_ptr offset AND
bfd_size_type count)
{
bfd_size_type sz;
if (!bfd_get_section_flags(abfd, section) & SEC_HAS_CONTENTS)
{
bfd_error = no_contents;
return(false);
}
if (offset < 0)
{
bad_val:
bfd_error = bad_value;
return false;
}
sz = bfd_get_section_size_now (abfd, section);
if (offset > sz
|| count > sz
|| offset + count > sz)
goto bad_val;
switch (abfd->direction)
{
case read_direction:
case no_direction:
bfd_error = invalid_operation;
return false;
case write_direction:
break;
case both_direction:
/* File is opened for update. `output_has_begun' some time ago when
the file was created. Do not recompute sections sizes or alignments
in _bfd_set_section_content. */
abfd->output_has_begun = true;
break;
}
if (BFD_SEND (abfd, _bfd_set_section_contents,
(abfd, section, location, offset, count)))
{
abfd->output_has_begun = true;
return true;
}
return false;
}
/*
FUNCTION
bfd_get_section_contents
SYNOPSIS
boolean bfd_get_section_contents
(bfd *abfd, asection *section, PTR location,
file_ptr offset, bfd_size_type count);
DESCRIPTION
This function reads data from @var{section} in BFD @var{abfd}
into memory starting at @var{location}. The data is read at an
offset of @var{offset} from the start of the input section,
and is read for @var{count} bytes.
If the contents of a constuctor with the <<SEC_CONSTUCTOR>>
flag set are requested, then the @var{location} is filled with
zeroes. If no errors occur, <<true>> is returned, else
<<false>>.
*/
boolean
DEFUN(bfd_get_section_contents,(abfd, section, location, offset, count),
bfd *abfd AND
sec_ptr section AND
PTR location AND
file_ptr offset AND
bfd_size_type count)
{
bfd_size_type sz;
if (section->flags & SEC_CONSTRUCTOR)
{
memset(location, 0, (unsigned)count);
return true;
}
if (offset < 0)
{
bad_val:
bfd_error = bad_value;
return false;
}
sz = bfd_get_section_size_now (abfd, section);
if (offset > sz
|| count > sz
|| offset + count > sz)
goto bad_val;
if (count == 0)
/* Don't bother. */
return true;
return BFD_SEND (abfd, _bfd_get_section_contents,
(abfd, section, location, offset, count));
}

1004
gnu/usr.bin/gdb/bfd/srec.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,62 @@
/* Table of stab names for the BFD library.
Copyright (C) 1990-1991 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: stab-syms.c,v 1.1 1994/01/28 12:38:10 pk Exp $
*/
#include "bfd.h"
#define ARCH_SIZE 32 /* Value doesn't matter. */
#include "libaout.h"
#include "aout/aout64.h"
/* Create a table of debugging stab-codes and corresponding names. */
#define __define_name(CODE, STRING) {(int)CODE, STRING},
#define __define_stab(NAME, CODE, STRING) __define_name(CODE, STRING)
CONST struct {short code; char string[10];} aout_stab_names[]
= {
#include "aout/stab.def"
/* These are not really stab symbols, but it is
convenient to have them here for the sake of nm.
For completeness, we could also add N_TEXT etc, but those
are never needed, since nm treats those specially. */
__define_name (N_SETA, "SETA") /* Absolute set element symbol */
__define_name (N_SETT, "SETT") /* Text set element symbol */
__define_name (N_SETD, "SETD") /* Data set element symbol */
__define_name (N_SETB, "SETB") /* Bss set element symbol */
__define_name (N_SETV, "SETV") /* Pointer to set vector in data area. */
__define_name (N_INDR, "INDR")
__define_name (N_WARNING, "WARNING")
};
#undef __define_stab
#undef GNU_EXTRA_STABS
CONST char *
DEFUN(aout_stab_name,(code),
int code)
{
register int i = sizeof(aout_stab_names) / sizeof(aout_stab_names[0]);
while (--i >= 0)
if (aout_stab_names[i].code == code)
return aout_stab_names[i].string;
return 0;
}

530
gnu/usr.bin/gdb/bfd/syms.c Normal file
View File

@ -0,0 +1,530 @@
/* Generic symbol-table support for the BFD library.
Copyright (C) 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: syms.c,v 1.1 1994/01/28 12:38:12 pk Exp $
*/
/*
SECTION
Symbols
BFD trys to maintain as much symbol information as it can when
it moves information from file to file. BFD passes information
to applications though the <<asymbol>> structure. When the
application requests the symbol table, BFD reads the table in
the native form and translates parts of it into the internal
format. To maintain more than the infomation passed to
applications some targets keep some information `behind the
scenes', in a structure only the particular back end knows
about. For example, the coff back end keeps the original
symbol table structure as well as the canonical structure when
a BFD is read in. On output, the coff back end can reconstruct
the output symbol table so that no information is lost, even
information unique to coff which BFD doesn't know or
understand. If a coff symbol table was read, but was written
through an a.out back end, all the coff specific information
would be lost. The symbol table of a BFD
is not necessarily read in until a canonicalize request is
made. Then the BFD back end fills in a table provided by the
application with pointers to the canonical information. To
output symbols, the application provides BFD with a table of
pointers to pointers to <<asymbol>>s. This allows applications
like the linker to output a symbol as read, since the `behind
the scenes' information will be still available.
@menu
@* Reading Symbols::
@* Writing Symbols::
@* typedef asymbol::
@* symbol handling functions::
@end menu
INODE
Reading Symbols, Writing Symbols, Symbols, Symbols
SUBSECTION
Reading Symbols
There are two stages to reading a symbol table from a BFD;
allocating storage, and the actual reading process. This is an
excerpt from an appliction which reads the symbol table:
| unsigned int storage_needed;
| asymbol **symbol_table;
| unsigned int number_of_symbols;
| unsigned int i;
|
| storage_needed = get_symtab_upper_bound (abfd);
|
| if (storage_needed == 0) {
| return ;
| }
| symbol_table = (asymbol **) bfd_xmalloc (storage_needed);
| ...
| number_of_symbols =
| bfd_canonicalize_symtab (abfd, symbol_table);
|
| for (i = 0; i < number_of_symbols; i++) {
| process_symbol (symbol_table[i]);
| }
All storage for the symbols themselves is in an obstack
connected to the BFD, and is freed when the BFD is closed.
INODE
Writing Symbols, typedef asymbol, Reading Symbols, Symbols
SUBSECTION
Writing Symbols
Writing of a symbol table is automatic when a BFD open for
writing is closed. The application attaches a vector of
pointers to pointers to symbols to the BFD being written, and
fills in the symbol count. The close and cleanup code reads
through the table provided and performs all the necessary
operations. The outputing code must always be provided with an
'owned' symbol; one which has come from another BFD, or one
which has been created using <<bfd_make_empty_symbol>>. An
example showing the creation of a symbol table with only one element:
| #include "bfd.h"
| main()
| {
| bfd *abfd;
| asymbol *ptrs[2];
| asymbol *new;
|
| abfd = bfd_openw("foo","a.out-sunos-big");
| bfd_set_format(abfd, bfd_object);
| new = bfd_make_empty_symbol(abfd);
| new->name = "dummy_symbol";
| new->section = bfd_make_section_old_way(abfd, ".text");
| new->flags = BSF_GLOBAL;
| new->value = 0x12345;
|
| ptrs[0] = new;
| ptrs[1] = (asymbol *)0;
|
| bfd_set_symtab(abfd, ptrs, 1);
| bfd_close(abfd);
| }
|
| ./makesym
| nm foo
| 00012345 A dummy_symbol
Many formats cannot represent arbitary symbol information; for
instance the <<a.out>> object format does not allow an
arbitary number of sections. A symbol pointing to a section
which is not one of <<.text>>, <<.data>> or <<.bss>> cannot
be described.
*/
/*
DOCDD
INODE
typedef asymbol, symbol handling functions, Writing Symbols, Symbols
*/
/*
SUBSECTION
typedef asymbol
An <<asymbol>> has the form:
*/
/*
CODE_FRAGMENT
.
.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. If the symbol
. is a warning symbol, then the value field (I know this is
. tacky) will point to the asymbol which when referenced will
. cause the warning. *}
.#define BSF_WARNING 0x1000
.
. {* Signal that the symbol is indirect. The value of the symbol
. is a pointer to an undefined asymbol which contains the
. name to use instead. *}
.#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
.
. 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. This is being phased out in favour
. of making this a union. *}
. PTR udata;
.
.} asymbol;
*/
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#include "aout/stab_gnu.h"
/*
DOCDD
INODE
symbol handling functions, , typedef asymbol, Symbols
SUBSECTION
Symbol Handling Functions
*/
/*
FUNCTION
get_symtab_upper_bound
DESCRIPTION
Returns the number of bytes required in a vector of pointers
to <<asymbols>> for all the symbols in the supplied BFD,
including a terminal NULL pointer. If there are no symbols in
the BFD, then 0 is returned.
.#define get_symtab_upper_bound(abfd) \
. BFD_SEND (abfd, _get_symtab_upper_bound, (abfd))
*/
/*
FUNCTION
bfd_canonicalize_symtab
DESCRIPTION
Supplied a BFD and a pointer to an uninitialized vector of
pointers. This reads in the symbols from the BFD, and fills in
the table with pointers to the symbols, and a trailing NULL.
The routine returns the actual number of symbol pointers not
including the NULL.
.#define bfd_canonicalize_symtab(abfd, location) \
. BFD_SEND (abfd, _bfd_canonicalize_symtab,\
. (abfd, location))
*/
/*
FUNCTION
bfd_set_symtab
DESCRIPTION
Provided a table of pointers to symbols and a count, writes to
the output BFD the symbols when closed.
SYNOPSIS
boolean bfd_set_symtab (bfd *, asymbol **, unsigned int );
*/
boolean
bfd_set_symtab (abfd, location, symcount)
bfd *abfd;
asymbol **location;
unsigned int symcount;
{
if ((abfd->format != bfd_object) || (bfd_read_p (abfd))) {
bfd_error = invalid_operation;
return false;
}
bfd_get_outsymbols (abfd) = location;
bfd_get_symcount (abfd) = symcount;
return true;
}
/*
FUNCTION
bfd_print_symbol_vandf
DESCRIPTION
Prints the value and flags of the symbol supplied to the stream file.
SYNOPSIS
void bfd_print_symbol_vandf(PTR file, asymbol *symbol);
*/
void
DEFUN(bfd_print_symbol_vandf,(file, symbol),
PTR file AND
asymbol *symbol)
{
flagword type = symbol->flags;
if (symbol->section != (asection *)NULL)
{
fprintf_vma(file, symbol->value+symbol->section->vma);
}
else
{
fprintf_vma(file, symbol->value);
}
fprintf(file," %c%c%c%c%c%c%c",
(type & BSF_LOCAL) ? 'l':' ',
(type & BSF_GLOBAL) ? 'g' : ' ',
(type & BSF_WEAK) ? 'w' : ' ',
(type & BSF_CONSTRUCTOR) ? 'C' : ' ',
(type & BSF_WARNING) ? 'W' : ' ',
(type & BSF_INDIRECT) ? 'I' : ' ',
(type & BSF_DEBUGGING) ? 'd' :' ');
}
/*
FUNCTION
bfd_make_empty_symbol
DESCRIPTION
This function creates a new <<asymbol>> structure for the BFD,
and returns a pointer to it.
This routine is necessary, since each back end has private
information surrounding the <<asymbol>>. Building your own
<<asymbol>> and pointing to it will not create the private
information, and will cause problems later on.
.#define bfd_make_empty_symbol(abfd) \
. BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd))
*/
/*
FUNCTION
bfd_make_debug_symbol
DESCRIPTION
This function creates a new <<asymbol>> structure for the BFD,
to be used as a debugging symbol. Further details of its use have
yet to be worked out.
.#define bfd_make_debug_symbol(abfd,ptr,size) \
. BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size))
*/
struct section_to_type
{
CONST char *section;
char type;
};
/* Map COFF section names to POSIX/BSD single-character symbol types.
This table is probably incomplete. It is sorted for convenience of
adding entries. Since it is so short, a linear search is used. */
static CONST struct section_to_type stt[] = {
{"*DEBUG*", 'N'},
{".bss", 'b'},
{".data", 'd'},
{".sbss", 's'}, /* Small BSS (uninitialized data) */
{".scommon", 'c'}, /* Small common */
{".sdata", 'g'}, /* Small initialized data */
{".text", 't'},
{0, 0}
};
/* Return the single-character symbol type corresponding to
COFF section S, or '?' for an unknown COFF section. */
static char
coff_section_type (s)
char *s;
{
CONST struct section_to_type *t;
for (t = &stt[0]; t->section; t++)
if (!strcmp (s, t->section))
return t->type;
return '?';
}
#ifndef islower
#define islower(c) ((c) >= 'a' && (c) <= 'z')
#endif
#ifndef toupper
#define toupper(c) (islower(c) ? ((c) & ~0x20) : (c))
#endif
/*
FUNCTION
bfd_decode_symclass
DESCRIPTION
Return a character corresponding to the symbol
class of symbol, or '?' for an unknown class.
SYNOPSIS
int bfd_decode_symclass(asymbol *symbol);
*/
int
DEFUN(bfd_decode_symclass,(symbol),
asymbol *symbol)
{
char c;
if (bfd_is_com_section (symbol->section))
return 'C';
if (symbol->section == &bfd_und_section)
return 'U';
if (symbol->section == &bfd_ind_section)
return 'I';
if (!(symbol->flags & (BSF_GLOBAL|BSF_LOCAL)))
return '?';
if (symbol->section == &bfd_abs_section)
c = 'a';
else if (symbol->section)
c = coff_section_type (symbol->section->name);
else
return '?';
if (symbol->flags & BSF_GLOBAL)
c = toupper (c);
return c;
/* We don't have to handle these cases just yet, but we will soon:
N_SETV: 'v';
N_SETA: 'l';
N_SETT: 'x';
N_SETD: 'z';
N_SETB: 's';
N_INDR: 'i';
*/
}
/*
FUNCTION
bfd_symbol_info
DESCRIPTION
Fill in the basic info about symbol that nm needs.
Additional info may be added by the back-ends after
calling this function.
SYNOPSIS
void bfd_symbol_info(asymbol *symbol, symbol_info *ret);
*/
void
DEFUN(bfd_symbol_info,(symbol, ret),
asymbol *symbol AND
symbol_info *ret)
{
ret->type = bfd_decode_symclass (symbol);
if (ret->type != 'U')
ret->value = symbol->value+symbol->section->vma;
else
ret->value = 0;
ret->name = symbol->name;
}
void
bfd_symbol_is_absolute()
{
abort();
}

View File

@ -0,0 +1,638 @@
/* Generic target-file-type support for the BFD library.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: targets.c,v 1.1 1994/01/28 12:38:13 pk Exp $
*/
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
/*
SECTION
Targets
DESCRIPTION
Each port of BFD to a different machine requries the creation
of a target back end. All the back end provides to the root
part of BFD is a structure containing pointers to functions
which perform certain low level operations on files. BFD
translates the applications's requests through a pointer into
calls to the back end routines.
When a file is opened with <<bfd_openr>>, its format and
target are unknown. BFD uses various mechanisms to determine
how to interpret the file. The operations performed are:
o First a BFD is created by calling the internal routine
<<new_bfd>>, then <<bfd_find_target>> is called with the
target string supplied to <<bfd_openr>> and the new BFD pointer.
o If a null target string was provided to <<bfd_find_target>>,
it looks up the environment variable <<GNUTARGET>> and uses
that as the target string.
o If the target string is still NULL, or the target string is
<<default>>, then the first item in the target vector is used
as the target type, and <<target_defaulted>> is set to
cause <<bfd_check_format>> to loop through all the targets.
@xref{bfd_target}. @xref{Formats}.
o Otherwise, the elements in the target vector are inspected
one by one, until a match on target name is found. When found,
that is used.
o Otherwise the error <<invalid_target>> is returned to
<<bfd_openr>>.
o <<bfd_openr>> attempts to open the file using
<<bfd_open_file>>, and returns the BFD.
Once the BFD has been opened and the target selected, the file
format may be determined. This is done by calling
<<bfd_check_format>> on the BFD with a suggested format.
If <<target_defaulted>> has been set, each possible target
type is tried to see if it recognizes the specified format. The
routine returns <<true>> when the application guesses right.
@menu
@* bfd_target::
@end menu
*/
/*
INODE
bfd_target, , Targets, Targets
DOCDD
SUBSECTION
bfd_target
DESCRIPTION
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.
These macros are used to dispatch to functions through the
bfd_target vector. They are used in a number of macros further
down in @file{bfd.h}, and are also used when calling various
routines by hand inside the BFD implementation. The "arglist"
argument must be parenthesized; it contains all the arguments
to the called function.
They make the documentation (more) unpleasant to read, so if
someone wants to fix this and not break the above, please do.
.#define BFD_SEND(bfd, message, arglist) \
. ((*((bfd)->xvec->message)) arglist)
For operations which index on the BFD format
.#define BFD_SEND_FMT(bfd, message, arglist) \
. (((bfd)->xvec->message[(int)((bfd)->format)]) arglist)
This is the struct which defines the type of BFD this is. The
<<xvec>> member of the struct <<bfd>> itself points here. Each
module that implements access to a different target under BFD,
defines one of these.
FIXME, these names should be rationalised with the names of
the entry points which call them. Too bad we can't have one
macro to define them both!
.typedef struct bfd_target
.{
Identifies the kind of target, eg SunOS4, Ultrix, etc.
. char *name;
The "flavour" of a back end is a general indication about the contents
of a file.
. enum target_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_hppa_flavour} flavour;
The order of bytes within the data area of a file.
. boolean byteorder_big_p;
The order of bytes within the header parts of a file.
. boolean header_byteorder_big_p;
This is a mask of all the flags which an executable may have set -
from the set <<NO_FLAGS>>, <<HAS_RELOC>>, ...<<D_PAGED>>.
. flagword object_flags;
This is a mask of all the flags which a section may have set - from
the set <<SEC_NO_FLAGS>>, <<SEC_ALLOC>>, ...<<SET_NEVER_LOAD>>.
. flagword section_flags;
The character normally found at the front of a symbol
(if any), perhaps _.
. char symbol_leading_char;
The pad character for filenames within an archive header.
. char ar_pad_char;
The maximum number of characters in an archive header.
. unsigned short ar_max_namelen;
The minimum alignment restriction for any section.
. unsigned int align_power_min;
Entries for byte swapping for data. These are different to the other
entry points, since they don't take BFD as first arg. Certain other handlers
could do the same.
. bfd_vma (*bfd_getx64) PARAMS ((bfd_byte *));
. bfd_signed_vma (*bfd_getx_signed_64) PARAMS ((bfd_byte *));
. void (*bfd_putx64) PARAMS ((bfd_vma, bfd_byte *));
. bfd_vma (*bfd_getx32) PARAMS ((bfd_byte *));
. bfd_signed_vma (*bfd_getx_signed_32) PARAMS ((bfd_byte *));
. void (*bfd_putx32) PARAMS ((bfd_vma, bfd_byte *));
. bfd_vma (*bfd_getx16) PARAMS ((bfd_byte *));
. bfd_signed_vma (*bfd_getx_signed_16) PARAMS ((bfd_byte *));
. void (*bfd_putx16) PARAMS ((bfd_vma, bfd_byte *));
Byte swapping for the headers
. bfd_vma (*bfd_h_getx64) PARAMS ((bfd_byte *));
. bfd_signed_vma (*bfd_h_getx_signed_64) PARAMS ((bfd_byte *));
. void (*bfd_h_putx64) PARAMS ((bfd_vma, bfd_byte *));
. bfd_vma (*bfd_h_getx32) PARAMS ((bfd_byte *));
. bfd_signed_vma (*bfd_h_getx_signed_32) PARAMS ((bfd_byte *));
. void (*bfd_h_putx32) PARAMS ((bfd_vma, bfd_byte *));
. bfd_vma (*bfd_h_getx16) PARAMS ((bfd_byte *));
. bfd_signed_vma (*bfd_h_getx_signed_16) PARAMS ((bfd_byte *));
. void (*bfd_h_putx16) PARAMS ((bfd_vma, bfd_byte *));
Format dependent routines: these are vectors of entry points
within the target vector structure, one for each format to check.
Check the format of a file being read. Return bfd_target * or zero.
. struct bfd_target * (*_bfd_check_format[bfd_type_end]) PARAMS ((bfd *));
Set the format of a file being written.
. boolean (*_bfd_set_format[bfd_type_end]) PARAMS ((bfd *));
Write cached information into a file being written, at bfd_close.
. boolean (*_bfd_write_contents[bfd_type_end]) PARAMS ((bfd *));
The following functions are defined in <<JUMP_TABLE>>. The idea is
that the back end writer of <<foo>> names all the routines
<<foo_>>@var{entry_point}, <<JUMP_TABLE>> will built the entries
in this structure in the right order.
Core file entry points
. 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
. boolean (*_bfd_slurp_armap) PARAMS ((bfd *));
. boolean (*_bfd_slurp_extended_name_table) PARAMS ((bfd *));
. 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));
Standard stuff.
. boolean (*_close_and_cleanup) PARAMS ((bfd *));
. boolean (*_bfd_set_section_contents) PARAMS ((bfd *, sec_ptr, PTR,
. file_ptr, bfd_size_type));
. boolean (*_bfd_get_section_contents) PARAMS ((bfd *, sec_ptr, PTR,
. file_ptr, bfd_size_type));
. boolean (*_new_section_hook) PARAMS ((bfd *, sec_ptr));
Symbols and relocations
. unsigned int (*_get_symtab_upper_bound) PARAMS ((bfd *));
. unsigned int (*_bfd_canonicalize_symtab) PARAMS ((bfd *,
. struct symbol_cache_entry **));
. unsigned int (*_get_reloc_upper_bound) PARAMS ((bfd *, sec_ptr));
. unsigned int (*_bfd_canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **,
. 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))
. alent * (*_get_lineno) PARAMS ((bfd *, struct symbol_cache_entry *));
.
. boolean (*_bfd_set_arch_mach) PARAMS ((bfd *, enum bfd_architecture,
. unsigned long));
.
. bfd * (*openr_next_archived_file) PARAMS ((bfd *arch, bfd *prev));
.
. 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));
.
. int (*_bfd_stat_arch_elt) PARAMS ((bfd *, struct stat *));
.
. int (*_bfd_sizeof_headers) PARAMS ((bfd *, boolean));
.
. void (*_bfd_debug_info_start) PARAMS ((bfd *));
. void (*_bfd_debug_info_end) PARAMS ((bfd *));
. void (*_bfd_debug_info_accumulate) PARAMS ((bfd *, struct sec *));
.
. bfd_byte * (*_bfd_get_relocated_section_contents) PARAMS ((bfd *,
. struct bfd_seclet *, bfd_byte *data,
. boolean relocateable));
.
. boolean (*_bfd_relax_section) PARAMS ((bfd *, struct sec *,
. struct symbol_cache_entry **));
.
. boolean (*_bfd_seclet_link) PARAMS ((bfd *, PTR data,
. boolean relocateable));
. {* See documentation on reloc types. *}
. CONST struct reloc_howto_struct *
. (*reloc_type_lookup) PARAMS ((bfd *abfd,
. bfd_reloc_code_real_type code));
.
. {* 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));
Data for use by back-end routines, which isn't generic enough to belong
in this structure.
. PTR backend_data;
.} bfd_target;
*/
/* All known xvecs (even those that don't compile on all systems).
Alphabetized for easy reference.
They are listed a second time below, since
we can't intermix extern's and initializers. */
extern bfd_target a29kcoff_big_vec;
extern bfd_target a_out_adobe_vec;
extern bfd_target aout_mips_big_vec;
extern bfd_target aout_mips_little_vec;
extern bfd_target apollocoff_vec;
extern bfd_target b_out_vec_big_host;
extern bfd_target b_out_vec_little_host;
extern bfd_target bfd_elf32_big_generic_vec;
extern bfd_target bfd_elf32_bigmips_vec;
extern bfd_target bfd_elf32_hppa_vec;
extern bfd_target bfd_elf32_i386_vec;
extern bfd_target bfd_elf32_i860_vec;
extern bfd_target bfd_elf32_little_generic_vec;
extern bfd_target bfd_elf32_littlemips_vec;
extern bfd_target bfd_elf32_m68k_vec;
extern bfd_target bfd_elf32_m88k_vec;
extern bfd_target bfd_elf32_sparc_vec;
extern bfd_target bfd_elf64_big_generic_vec;
extern bfd_target bfd_elf64_little_generic_vec;
extern bfd_target demo_64_vec;
extern bfd_target ecoff_big_vec;
extern bfd_target ecoff_little_vec;
extern bfd_target ecoffalpha_little_vec;
extern bfd_target h8300coff_vec;
extern bfd_target h8500coff_vec;
extern bfd_target host_aout_vec;
extern bfd_target hp300bsd_vec;
extern bfd_target hp300hpux_vec;
extern bfd_target hppa_vec;
extern bfd_target i386aout_vec;
extern bfd_target i386bsd_vec;
extern bfd_target i386coff_vec;
extern bfd_target i386linux_vec;
extern bfd_target i386lynx_aout_vec;
extern bfd_target i386lynx_coff_vec;
extern bfd_target icoff_big_vec;
extern bfd_target icoff_little_vec;
extern bfd_target ieee_vec;
extern bfd_target m68kcoff_vec;
extern bfd_target m68kcoffun_vec;
extern bfd_target m68klynx_aout_vec;
extern bfd_target m68klynx_coff_vec;
extern bfd_target m88kbcs_vec;
extern bfd_target newsos3_vec;
extern bfd_target nlm32_big_generic_vec;
extern bfd_target nlm32_i386_vec;
extern bfd_target nlm32_little_generic_vec;
extern bfd_target nlm64_big_generic_vec;
extern bfd_target nlm64_little_generic_vec;
extern bfd_target oasys_vec;
extern bfd_target rs6000coff_vec;
extern bfd_target shcoff_vec;
extern bfd_target sunos_big_vec;
extern bfd_target tekhex_vec;
extern bfd_target we32kcoff_vec;
extern bfd_target z8kcoff_vec;
extern bfd_target netbsd_386_vec;
extern bfd_target netbsd_sparc_vec;
extern bfd_target netbsd_m68k_vec;
/* srec is always included. */
extern bfd_target srec_vec;
extern bfd_target symbolsrec_vec;
/* All of the xvecs for core files. */
extern bfd_target aix386_core_vec;
extern bfd_target hpux_core_vec;
extern bfd_target osf_core_vec;
extern bfd_target sco_core_vec;
extern bfd_target trad_core_vec;
bfd_target *target_vector[] = {
#ifdef SELECT_VECS
SELECT_VECS,
#else /* not SELECT_VECS */
#ifdef DEFAULT_VECTOR
&DEFAULT_VECTOR,
#endif
/* This list is alphabetized to make it easy to compare
with other vector lists -- the decls above and
the case statement in configure.in.
Vectors that don't compile on all systems, or aren't finished,
should have an entry here with #if 0 around it, to show that
it wasn't omitted by mistake. */
&a29kcoff_big_vec,
&a_out_adobe_vec,
#if 0 /* No one seems to use this. */
&aout_mips_big_vec,
#endif
&aout_mips_little_vec,
&b_out_vec_big_host,
&b_out_vec_little_host,
#if 0 /* No one seems to use this. */
&bfd_elf32_big_generic_vec,
&bfd_elf32_bigmips_vec,
#endif
#if 0
&bfd_elf32_hppa_vec,
#endif
&bfd_elf32_i386_vec,
&bfd_elf32_i860_vec,
#if 0 /* No one seems to use this. */
&bfd_elf32_little_generic_vec,
&bfd_elf32_littlemips_vec,
#endif
&bfd_elf32_m68k_vec,
&bfd_elf32_m88k_vec,
&bfd_elf32_sparc_vec,
#ifdef BFD64 /* No one seems to use this. */
&bfd_elf64_big_generic_vec,
&bfd_elf64_little_generic_vec,
#endif
#ifdef BFD64
&demo_64_vec, /* Only compiled if host has long-long support */
#endif
&ecoff_big_vec,
&ecoff_little_vec,
#if 0
&ecoffalpha_little_vec,
#endif
&h8300coff_vec,
&h8500coff_vec,
#if 0
&host_aout_vec,
#endif
#if 0 /* Clashes with sunos_big_vec magic no. */
&hp300bsd_vec,
#endif
&hp300hpux_vec,
#if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD)
&hppa_vec,
#endif
&i386aout_vec,
&i386bsd_vec,
&netbsd386_vec,
&i386coff_vec,
#if 0
&i386linux_vec,
#endif
&i386lynx_aout_vec,
&i386lynx_coff_vec,
&icoff_big_vec,
&icoff_little_vec,
&ieee_vec,
&m68kcoff_vec,
&m68kcoffun_vec,
&m68klynx_aout_vec,
&m68klynx_coff_vec,
&m88kbcs_vec,
&newsos3_vec,
#if 0 /* No one seems to use this. */
&nlm32_big_generic_vec,
#endif
&nlm32_i386_vec,
#if 0 /* No one seems to use this. */
&nlm32_little_generic_vec,
#endif
#ifdef BFD64
&nlm64_big_generic_vec,
&nlm64_little_generic_vec,
#endif
#if 0
/* We have no oasys tools anymore, so we can't test any of this
anymore. If you want to test the stuff yourself, go ahead...
steve@cygnus.com
Worse, since there is no magic number for archives, there
can be annoying target mis-matches. */
&oasys_vec,
#endif
&rs6000coff_vec,
&shcoff_vec,
&sunos_big_vec,
#if 0
&tekhex_vec,
#endif
&we32kcoff_vec,
&z8kcoff_vec,
#endif /* not SELECT_VECS */
/* Always support S-records, for convenience. */
&srec_vec,
&symbolsrec_vec,
/* Add any required traditional-core-file-handler. */
#ifdef AIX386_CORE
&aix386_core_vec,
#endif
#ifdef HPUX_CORE
&hpux_core_vec,
#endif
#ifdef OSF_CORE
&osf_core_vec,
#endif
#ifdef SCO_CORE
&sco_core_vec,
#endif
#ifdef TRAD_CORE
&trad_core_vec,
#endif
NULL /* end of list marker */
};
/* default_vector[0] contains either the address of the default vector,
if there is one, or zero if there isn't. */
bfd_target *default_vector[] = {
#ifdef DEFAULT_VECTOR
&DEFAULT_VECTOR,
#endif
NULL
};
/*
FUNCTION
bfd_find_target
DESCRIPTION
Returns a pointer to the transfer vector for the object target
named target_name. If target_name is NULL, chooses the one in
the environment variable GNUTARGET; if that is null or not
defined thenthe first entry in the target list is chosen.
Passing in the string "default" or setting the environment
variable to "default" will cause the first entry in the target
list to be returned, and "target_defaulted" will be set in the
BFD. This causes <<bfd_check_format>> to loop over all the
targets to find the one that matches the file being read.
SYNOPSIS
bfd_target *bfd_find_target(CONST char *, bfd *);
*/
bfd_target *
DEFUN(bfd_find_target,(target_name, abfd),
CONST char *target_name AND
bfd *abfd)
{
bfd_target **target;
extern char *getenv ();
CONST char *targname = (target_name ? target_name :
(CONST char *) getenv ("GNUTARGET"));
/* This is safe; the vector cannot be null */
if (targname == NULL || !strcmp (targname, "default")) {
abfd->target_defaulted = true;
return abfd->xvec = target_vector[0];
}
abfd->target_defaulted = false;
for (target = &target_vector[0]; *target != NULL; target++) {
if (!strcmp (targname, (*target)->name))
return abfd->xvec = *target;
}
bfd_error = invalid_target;
return NULL;
}
/*
FUNCTION
bfd_target_list
DESCRIPTION
This function returns a freshly malloced NULL-terminated
vector of the names of all the valid BFD targets. Do not
modify the names
SYNOPSIS
CONST char **bfd_target_list(void);
*/
CONST char **
DEFUN_VOID(bfd_target_list)
{
int vec_length= 0;
#ifdef NATIVE_HPPAHPUX_COMPILER
/* The native compiler on the HP9000/700 has a bug which causes it
to loop endlessly when compiling this file. This avoids it. */
volatile
#endif
bfd_target **target;
CONST char **name_list, **name_ptr;
for (target = &target_vector[0]; *target != NULL; target++)
vec_length++;
name_ptr =
name_list = (CONST char **) zalloc ((vec_length + 1) * sizeof (char **));
if (name_list == NULL) {
bfd_error = no_memory;
return NULL;
}
for (target = &target_vector[0]; *target != NULL; target++)
*(name_ptr++) = (*target)->name;
return name_list;
}

View File

@ -0,0 +1,380 @@
/* BFD back end for traditional Unix core files (U-area and raw sections)
Copyright 1988, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
Written by 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: trad-core.c,v 1.1 1994/01/28 12:38:14 pk Exp $
*/
/* To use this file on a particular host, configure the host with these
parameters in the config/h-HOST file:
HDEFINES=-DTRAD_CORE
HDEPFILES=trad-core.o
*/
#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/user.h> /* After a.out.h */
#if 0
/* file.h is included by std-host.h. So we better not try to include it
twice; on some systems (dpx2) it is not protected against multiple
inclusion. I have checked that all the hosts which use this file
include sys/file.h in the hosts file. */
#include <sys/file.h>
#endif
#include <errno.h>
struct trad_core_struct
{
asection *data_section;
asection *stack_section;
asection *reg_section;
struct user u;
} *rawptr;
#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 */
bfd_target * trad_unix_core_file_p PARAMS ((bfd *abfd));
char * trad_unix_core_file_failing_command PARAMS ((bfd *abfd));
int trad_unix_core_file_failing_signal PARAMS ((bfd *abfd));
boolean trad_unix_core_file_matches_executable_p
PARAMS ((bfd *core_bfd, bfd *exec_bfd));
/* Handle 4.2-style (and perhaps also sysV-style) core dump file. */
/* ARGSUSED */
bfd_target *
trad_unix_core_file_p (abfd)
bfd *abfd;
{
int val;
struct user u;
#ifdef TRAD_CORE_USER_OFFSET
/* If defined, this macro is the file position of the user struct. */
if (bfd_seek (abfd, TRAD_CORE_USER_OFFSET, SEEK_SET) == 0)
return 0;
#endif
val = bfd_read ((void *)&u, 1, sizeof u, abfd);
if (val != sizeof u)
{
/* Too small to be a core file */
bfd_error = wrong_format;
return 0;
}
/* Sanity check perhaps??? */
if (u.u_dsize > 0x1000000) /* Remember, it's in pages... */
{
bfd_error = wrong_format;
return 0;
}
if (u.u_ssize > 0x1000000)
{
bfd_error = wrong_format;
return 0;
}
/* Check that the size claimed is no greater than the file size. */
{
FILE *stream = bfd_cache_lookup (abfd);
struct stat statbuf;
if (stream == NULL)
return 0;
if (fstat (fileno (stream), &statbuf) < 0)
{
bfd_error = system_call_error;
return 0;
}
if (NBPG * (UPAGES + u.u_dsize + u.u_ssize) > statbuf.st_size)
{
bfd_error = file_truncated;
return 0;
}
if (NBPG * (UPAGES + u.u_dsize + u.u_ssize)
#ifdef TRAD_CORE_EXTRA_SIZE_ALLOWED
/* Some systems write the file too big. */
+ TRAD_CORE_EXTRA_SIZE_ALLOWED
#endif
< 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_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) {
bfd_error = no_memory;
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 *) zalloc (sizeof (asection));
if (core_stacksec (abfd) == NULL) {
loser:
bfd_error = no_memory;
free ((void *)rawptr);
return 0;
}
core_datasec (abfd) = (asection *) zalloc (sizeof (asection));
if (core_datasec (abfd) == NULL) {
loser1:
free ((void *)core_stacksec (abfd));
goto loser;
}
core_regsec (abfd) = (asection *) zalloc (sizeof (asection));
if (core_regsec (abfd) == NULL) {
free ((void *)core_datasec (abfd));
goto loser1;
}
core_stacksec (abfd)->name = ".stack";
core_datasec (abfd)->name = ".data";
core_regsec (abfd)->name = ".reg";
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_ALLOC + SEC_HAS_CONTENTS;
core_datasec (abfd)->_raw_size = NBPG * u.u_dsize;
core_stacksec (abfd)->_raw_size = NBPG * u.u_ssize;
core_regsec (abfd)->_raw_size = NBPG * UPAGES; /* Larger than sizeof struct u */
/* What a hack... we'd like to steal it from the exec file,
since the upage does not seem to provide it. FIXME. */
#ifdef HOST_DATA_START_ADDR
core_datasec (abfd)->vma = HOST_DATA_START_ADDR;
#else
core_datasec (abfd)->vma = HOST_TEXT_START_ADDR + (NBPG * u.u_tsize);
#endif
#ifdef HOST_STACK_START_ADDR
core_stacksec (abfd)->vma = HOST_STACK_START_ADDR;
#else
core_stacksec (abfd)->vma = HOST_STACK_END_ADDR - (NBPG * u.u_ssize);
#endif
/* This is tricky. As the "register section", we give them the entire
upage and stack. u.u_ar0 points to where "register 0" is stored.
There are two tricks with this, though. One is that the rest of the
registers might be at positive or negative (or both) displacements
from *u_ar0. The other is that u_ar0 is sometimes an absolute address
in kernel memory, and on other systems it is an offset from the beginning
of the `struct user'.
As a practical matter, we don't know where the registers actually are,
so we have to pass the whole area to GDB. We encode the value of u_ar0
by setting the .regs section up so that its virtual memory address
0 is at the place pointed to by u_ar0 (by setting the vma of the start
of the section to -u_ar0). GDB uses this info to locate the regs,
using minor trickery to get around the offset-or-absolute-addr problem. */
core_regsec (abfd)->vma = 0 - (int) u.u_ar0;
core_datasec (abfd)->filepos = NBPG * UPAGES;
#ifdef TRAD_CORE_STACK_FILEPOS
core_stacksec (abfd)->filepos = TRAD_CORE_STACK_FILEPOS;
#else
core_stacksec (abfd)->filepos = (NBPG * UPAGES) + NBPG * u.u_dsize;
#endif
core_regsec (abfd)->filepos = 0; /* Register segment is the upage */
/* 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 *
trad_unix_core_file_failing_command (abfd)
bfd *abfd;
{
#ifndef NO_CORE_COMMAND
char *com = abfd->tdata.trad_core_data->u.u_comm;
if (*com)
return com;
else
#endif
return 0;
}
/* ARGSUSED */
int
trad_unix_core_file_failing_signal (ignore_abfd)
bfd *ignore_abfd;
{
#ifdef TRAD_UNIX_CORE_FILE_FAILING_SIGNAL
return TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(ignore_abfd);
#else
return -1; /* FIXME, where is it? */
#endif
}
/* ARGSUSED */
boolean
trad_unix_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 trad_unix_openr_next_archived_file bfd_generic_openr_next_archived_file
#define trad_unix_generic_stat_arch_elt bfd_generic_stat_arch_elt
#define trad_unix_slurp_armap bfd_false
#define trad_unix_slurp_extended_name_table bfd_true
#define trad_unix_write_armap (boolean (*) PARAMS \
((bfd *arch, unsigned int elength, struct orl *map, \
unsigned int orl_count, int stridx))) bfd_false
#define trad_unix_truncate_arname bfd_dont_truncate_arname
#define aout_32_openr_next_archived_file bfd_generic_openr_next_archived_file
#define trad_unix_close_and_cleanup bfd_generic_close_and_cleanup
#define trad_unix_set_section_contents (boolean (*) PARAMS \
((bfd *abfd, asection *section, PTR data, file_ptr offset, \
bfd_size_type count))) bfd_false
#define trad_unix_get_section_contents bfd_generic_get_section_contents
#define trad_unix_new_section_hook (boolean (*) PARAMS \
((bfd *, sec_ptr))) bfd_true
#define trad_unix_get_symtab_upper_bound bfd_0u
#define trad_unix_get_symtab (unsigned int (*) PARAMS \
((bfd *, struct symbol_cache_entry **))) bfd_0u
#define trad_unix_get_reloc_upper_bound (unsigned int (*) PARAMS \
((bfd *, sec_ptr))) bfd_0u
#define trad_unix_canonicalize_reloc (unsigned int (*) PARAMS \
((bfd *, sec_ptr, arelent **, struct symbol_cache_entry**))) bfd_0u
#define trad_unix_make_empty_symbol (struct symbol_cache_entry * \
(*) PARAMS ((bfd *))) bfd_false
#define trad_unix_print_symbol (void (*) PARAMS \
((bfd *, PTR, struct symbol_cache_entry *, \
bfd_print_symbol_type))) bfd_false
#define trad_unix_get_symbol_info (void (*) PARAMS \
((bfd *, struct symbol_cache_entry *, \
symbol_info *))) bfd_false
#define trad_unix_get_lineno (alent * (*) PARAMS \
((bfd *, struct symbol_cache_entry *))) bfd_nullvoidptr
#define trad_unix_set_arch_mach (boolean (*) PARAMS \
((bfd *, enum bfd_architecture, unsigned long))) bfd_false
#define trad_unix_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 trad_unix_sizeof_headers (int (*) PARAMS \
((bfd *, boolean))) bfd_0
#define trad_unix_bfd_debug_info_start bfd_void
#define trad_unix_bfd_debug_info_end bfd_void
#define trad_unix_bfd_debug_info_accumulate (void (*) PARAMS \
((bfd *, struct sec *))) bfd_void
#define trad_unix_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
#define trad_unix_bfd_relax_section bfd_generic_relax_section
#define trad_unix_bfd_seclet_link \
((boolean (*) PARAMS ((bfd *, PTR, boolean))) bfd_false)
#define trad_unix_bfd_reloc_type_lookup \
((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
#define trad_unix_bfd_make_debug_symbol \
((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
/* 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 (( bfd_byte *))) swap_abort )
#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
#define NO_SIGNED_GET ((bfd_signed_vma (*) PARAMS ((bfd_byte *))) swap_abort )
bfd_target trad_core_vec =
{
"trad-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 */
trad_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
},
JUMP_TABLE(trad_unix),
(PTR) 0 /* backend_data */
};