Hurrah! Let the champagne flow, the olive oil barrel be opened and

the wild, slippery orgy commence!

Gary Jennejohn, too studly for his own good, has finally come through with
the new, improved gdb 4.13.  This gdb features:

o	kgdb support - if this works (and I urge folks to test it), we can
	finally purge the old and hateful version of kgdb from our source
	tree.

o	attach/detach support.  See comments in README.FreeBSD for more
	details.

o	Well, it's newer.  Our previous version was 4.11.

Comments and flames to gj, of course! :-)

Thanks, Gary.  Much appreciated.  The previous state of gdb/kgdb has been a
thorn in all of our sides for some time..
Submitted by:	gj
This commit is contained in:
jkh 1994-12-30 23:27:33 +00:00
parent 981b2b037a
commit 16d72e1e9b
175 changed files with 26350 additions and 18738 deletions

View File

@ -1,19 +1,23 @@
PROG = gdb
BINDIR= /usr/bin
CLEANFILES+= y.tab.h c-exp.tab.c ch-exp.tab.c m2-exp.tab.c
SRCS = main.c blockframe.c breakpoint.c findvar.c stack.c thread.c \
source.c values.c eval.c valops.c valarith.c valprint.c printcmd.c \
symtab.c symfile.c symmisc.c infcmd.c infrun.c command.c utils.c \
expprint.c environ.c gdbtypes.c copying.c i386-tdep.c i386-pinsn.c \
freebsd-solib.c ser-unix.c exec.c fork-child.c infptrace.c inftarg.c \
corelow.c coredep.c freebsd-nat.c remote.c dcache.c remote-utils.c \
mem-break.c target.c putenv.c parse.c language.c buildsym.c \
objfiles.c minsyms.c maint.c demangle.c dbxread.c coffread.c \
elfread.c dwarfread.c mipsread.c stabsread.c core.c c-lang.c \
ch-lang.c m2-lang.c complaints.c typeprint.c c-typeprint.c \
ch-typeprint.c m2-typeprint.c c-valprint.c cp-valprint.c ch-valprint.c \
m2-valprint.c nlmread.c serial.c inflow.c regex.c init.c \
c-exp.tab.c ch-exp.tab.c m2-exp.tab.c version.c i386-dis.c dis-buf.c
SRCS = annotate.c blockframe.c breakpoint.c buildsym.c c-lang.c \
c-typeprint.c c-valprint.c ch-lang.c ch-typeprint.c \
ch-valprint.c coffread.c command.c complaints.c copying.c core.c \
coredep.c corelow.c cp-valprint.c \
dcache.c dbxread.c demangle.c disassemble.c dis-buf.c dwarfread.c \
elfread.c environ.c eval.c exec.c expprint.c \
findvar.c fork-child.c freebsd-nat.c gdbtypes.c i386-dis.c \
i386-pinsn.c i386-tdep.c infcmd.c inflow.c infptrace.c \
infrun.c inftarg.c init.c kcorelow.c language.c \
m2-lang.c m2-typeprint.c m2-valprint.c main.c maint.c \
mem-break.c minsyms.c objfiles.c parse.c \
printcmd.c regex.c remote.c remote-utils.c solib.c source.c \
stabsread.c stack.c symfile.c symmisc.c \
symtab.c target.c thread.c top.c \
typeprint.c utils.c valarith.c valops.c \
valprint.c values.c version.c serial.c ser-unix.c mdebugread.c\
c-exp.tab.c ch-exp.tab.c m2-exp.tab.c
c-exp.tab.c: $(.CURDIR)/c-exp.y
yacc -d -p c_ $(.CURDIR)/c-exp.y
@ -40,7 +44,6 @@ m2-exp.tab.c: $(.CURDIR)/m2-exp.y
mv m2-exp.new ./m2-exp.tab.c
CFLAGS+= -I$(.CURDIR)/. -I${DESTDIR}/usr/include/readline -I$(.CURDIR)/../bfd
DPADD+= ${LIBREADLINE} ${LIBTERMCAP}
LDADD+= -lreadline -ltermcap

View File

@ -1,6 +1,6 @@
.\" Copyright (c) 1991 Free Software Foundation
.\" See section COPYING for conditions for redistribution
.\" $Id: gdb.1,v 1.1.1.1 1993/10/30 21:59:13 jkh Exp $
.\" $Id: gdb.1,v 1.1 1994/01/28 12:39:43 pk Exp $
.TH gdb 1 "4nov1991" "GNU Tools" "GNU Tools"
.SH NAME
gdb \- The GNU Debugger

View File

@ -15,10 +15,20 @@ 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. */
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: freebsd-nat.c,v 1.3 1994/05/18 12:43:13 pk Exp $
*/
#include <sys/types.h>
#include <sys/param.h>
#include <signal.h>
#include <sys/user.h>
#include <machine/reg.h>
#include <machine/frame.h>
#include <sys/ptrace.h>
#include "defs.h"
#include <machine/reg.h>
/* this table must line up with REGISTER_NAMES in tm-i386.h */
/* symbols like 'tEAX' come from <machine/reg.h> */
@ -28,14 +38,7 @@ static int tregmap[] =
tESP, tEBP, tESI, tEDI,
tEIP, tEFLAGS, tCS, tSS
};
#ifdef sEAX
static int sregmap[] =
{
sEAX, sECX, sEDX, sEBX,
sESP, sEBP, sESI, sEDI,
sEIP, sEFLAGS, sCS, sSS
};
#endif
/* blockend is the value of u.u_ar0, and points to the
place where ES is stored. */
@ -44,45 +47,14 @@ i386_register_u_addr (blockend, regnum)
int blockend;
int regnum;
{
/* The following condition is a kludge to get at the proper register map
depending upon the state of pcb_flag.
The proper condition would be
if (u.u_pcb.pcb_flag & FM_TRAP)
but that would require a ptrace call here and wouldn't work
for corefiles. */
#ifdef sEAX
if (blockend < 0x1fcc)
return (blockend + 4 * tregmap[regnum]);
else
return (blockend + 4 * sregmap[regnum]);
#else
return (blockend + 4 * tregmap[regnum]);
#endif
}
#ifdef FLOAT_INFO
#include <sys/param.h>
#include <sys/dir.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <a.out.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/uio.h>
#define curpcb Xcurpcb /* XXX avoid leaking declaration from pcb.h */
#include <sys/user.h>
#undef curpcb
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/ptrace.h>
#define fpstate save87
#define U_FPSTATE(u) u.u_pcb.pcb_savefpu
static void
i387_to_double (from, to)
char *from;
char *to;
@ -113,6 +85,7 @@ i387_to_double (from, to)
asm ("popl %eax"); /* flush saved copy */
}
static void
double_to_i387 (from, to)
char *from;
char *to;
@ -209,7 +182,7 @@ print_387_status_word (status)
printf ("top %d\n", (status >> 11) & 7);
}
static
static void
print_387_status (status, ep)
unsigned short status;
struct env387 *ep;
@ -271,6 +244,7 @@ print_387_status (status, ep)
}
}
void
i386_float_info ()
{
struct user u; /* just for address computations */
@ -320,4 +294,319 @@ i386_float_info ()
print_387_status (0, (struct env387 *)buf);
}
void
clear_regs()
{
return;
}
#ifdef KERNEL_DEBUG
#include <sys/proc.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <machine/vmparam.h>
#include <machine/pcb.h>
#define KERNOFF ((unsigned)KERNBASE)
#define INKERNEL(x) ((x) >= KERNOFF)
static CORE_ADDR sbr;
static CORE_ADDR curpcb;
static CORE_ADDR kstack;
static int found_pcb;
static int devmem;
static int kfd;
static struct pcb pcb;
int read_pcb (int, CORE_ADDR);
static CORE_ADDR kvtophys (int, CORE_ADDR);
static physrd(int, u_int, char*, int);
extern CORE_ADDR ksym_lookup(const char *);
/* substitutes for the stuff in libkvm which doesn't work */
/* most of this was taken from the old kgdb */
/* we don't need all this stuff, but the call should look the same */
kvm_open (efile, cfile, sfile, perm, errout)
char *efile;
char *cfile;
void *sfile;
int perm;
int errout;
{
struct stat stb;
CORE_ADDR addr;
int cfd;
if ((cfd = open(cfile, perm, 0)) < 0)
return (cfd);
fstat(cfd, &stb);
if ((stb.st_mode & S_IFMT) == S_IFCHR && stb.st_rdev == makedev(2, 0)) {
devmem = 1;
kfd = open ("/dev/kmem", perm, 0);
}
physrd(cfd, ksym_lookup("IdlePTD") - KERNOFF, (char*)&sbr, sizeof sbr);
printf("IdlePTD %x\n", sbr);
curpcb = ksym_lookup("curpcb") - KERNOFF;
physrd(cfd, curpcb, (char*)&curpcb, sizeof curpcb);
kstack = ksym_lookup("kstack");
found_pcb = 1; /* for vtophys */
if (!devmem)
read_pcb(cfd, ksym_lookup("dumppcb") - KERNOFF);
else
read_pcb(cfd, kvtophys(cfd, kstack));
return (cfd);
}
kvm_close (fd)
{
return (close (fd));
}
kvm_write(core_kd, memaddr, myaddr, len)
CORE_ADDR memaddr;
char *myaddr;
{
int cc;
if (devmem) {
if (kfd > 0) {
/*
* Just like kvm_read, only we write.
*/
errno = 0;
if (lseek(kfd, (off_t)memaddr, 0) < 0 && errno != 0) {
error("kvm_write:invalid address (%x)", memaddr);
return (0);
}
cc = write(kfd, myaddr, len);
if (cc < 0) {
error("kvm_write:write failed");
return (0);
} else if (cc < len)
error("kvm_write:short write");
return (cc);
} else
return (0);
} else {
printf("kvm_write not implemented for dead kernels\n");
return (0);
}
/* NOTREACHED */
}
kvm_read(core_kd, memaddr, myaddr, len)
CORE_ADDR memaddr;
char *myaddr;
{
return (kernel_core_file_hook (core_kd, memaddr, myaddr, len));
}
kvm_uread(core_kd, p, memaddr, myaddr, len)
register struct proc *p;
CORE_ADDR memaddr;
char *myaddr;
{
register char *cp;
char procfile[MAXPATHLEN];
ssize_t amount;
int fd;
if (devmem) {
cp = myaddr;
sprintf(procfile, "/proc/%d/mem", p->p_pid);
fd = open(procfile, O_RDONLY, 0);
if (fd < 0) {
error("cannot open %s", procfile);
close(fd);
return (0);
}
while (len > 0) {
if (lseek(fd, memaddr, 0) == -1 && errno != 0) {
error("invalid address (%x) in %s",
memaddr, procfile);
break;
}
amount = read(fd, cp, len);
if (amount < 0) {
error("error reading %s", procfile);
break;
}
cp += amount;
memaddr += amount;
len -= amount;
}
close(fd);
return (ssize_t)(cp - myaddr);
} else {
return (kernel_core_file_hook (core_kd, memaddr, myaddr, len));
}
}
static
physrd(cfd, addr, dat, len)
u_int addr;
char *dat;
{
if (lseek(cfd, (off_t)addr, L_SET) == -1)
return (-1);
return (read(cfd, dat, len));
}
static CORE_ADDR
kvtophys (fd, addr)
CORE_ADDR addr;
{
CORE_ADDR v;
struct pte pte;
static CORE_ADDR PTD = -1;
CORE_ADDR current_ptd;
/*if (devmem && kfd > 0)
return (addr);
/*
* If we're looking at the kernel stack,
* munge the address to refer to the user space mapping instead;
* that way we get the requested process's kstack, not the running one.
*/
if (addr >= kstack && addr < kstack + ctob(UPAGES))
addr = (addr - kstack) + curpcb;
/*
* We may no longer have a linear system page table...
*
* Here's the scoop. IdlePTD contains the physical address
* of a page table directory that always maps the kernel.
* IdlePTD is in memory that is mapped 1-to-1, so we can
* find it easily given its 'virtual' address from ksym_lookup().
* For hysterical reasons, the value of IdlePTD is stored in sbr.
*
* To look up a kernel address, we first convert it to a 1st-level
* address and look it up in IdlePTD. This gives us the physical
* address of a page table page; we extract the 2nd-level part of
* VA and read the 2nd-level pte. Finally, we add the offset part
* of the VA into the physical address from the pte and return it.
*
* User addresses are a little more complicated. If we don't have
* a current PCB from read_pcb(), we use PTD, which is the (fixed)
* virtual address of the current ptd. Since it's NOT in 1-to-1
* kernel space, we must look it up using IdlePTD. If we do have
* a pcb, we get the ptd from pcb_ptd.
*/
if (INKERNEL(addr))
current_ptd = sbr;
else if (found_pcb == 0) {
if (PTD == -1)
PTD = kvtophys(fd, ksym_lookup("PTD"));
current_ptd = PTD;
} else
current_ptd = pcb.pcb_ptd;
/*
* Read the first-level page table (ptd).
*/
v = current_ptd + ((unsigned)addr >> PD_SHIFT) * sizeof pte;
if (physrd(fd, v, (char *)&pte, sizeof pte) < 0 || pte.pg_v == 0)
return (~0);
/*
* Read the second-level page table.
*/
v = i386_ptob(pte.pg_pfnum) + ((addr&PT_MASK) >> PG_SHIFT) * sizeof pte;
if (physrd(fd, v, (char *) &pte, sizeof(pte)) < 0 || pte.pg_v == 0)
return (~0);
addr = i386_ptob(pte.pg_pfnum) + (addr & PGOFSET);
#if 0
printf("vtophys(%x) -> %x\n", oldaddr, addr);
#endif
return (addr);
}
read_pcb (fd, uaddr)
CORE_ADDR uaddr;
{
int i;
int *pcb_regs = (int *)&pcb;
int eip;
if (physrd(fd, uaddr, (char *)&pcb, sizeof pcb) < 0) {
error("cannot read pcb at %x\n", uaddr);
return (-1);
}
printf("current pcb at %x\n", uaddr);
/*
* get the register values out of the sys pcb and
* store them where `read_register' will find them.
*/
for (i = 0; i < 8; ++i)
supply_register(i, &pcb_regs[i+10]);
supply_register(8, &pcb_regs[8]); /* eip */
supply_register(9, &pcb_regs[9]); /* eflags */
for (i = 10; i < 13; ++i) /* cs, ss, ds */
supply_register(i, &pcb_regs[i+9]);
supply_register(13, &pcb_regs[18]); /* es */
for (i = 14; i < 16; ++i) /* fs, gs */
supply_register(i, &pcb_regs[i+8]);
#if 0 /* doesn't work ??? */
/* Hmm... */
if (target_read_memory(pcb_regs[5+10]+4, &eip, sizeof eip, 0))
error("Cannot read PC.");
supply_register(8, &eip); /* eip */
#endif
/* XXX 80387 registers? */
}
/*
* read len bytes from kernel virtual address 'addr' into local
* buffer 'buf'. Return numbert of bytes if read ok, 0 otherwise. On read
* errors, portion of buffer not read is zeroed.
*/
kernel_core_file_hook(fd, addr, buf, len)
CORE_ADDR addr;
char *buf;
int len;
{
int i;
CORE_ADDR paddr;
register char *cp;
int cc;
cp = buf;
while (len > 0) {
paddr = kvtophys(fd, addr);
if (paddr == ~0) {
bzero(buf, len);
break;
}
/* we can't read across a page boundary */
i = min(len, NBPG - (addr & PGOFSET));
if ((cc = physrd(fd, paddr, cp, i)) <= 0) {
bzero(cp, len);
return (cp - buf);
}
cp += cc;
addr += cc;
len -= cc;
}
return (cp - buf);
}
#endif /* KERNEL_DEBUG */

View File

@ -40,5 +40,61 @@ extern int
i386_register_u_addr PARAMS ((int, int));
#define PTRACE_ARG3_TYPE char*
#define ATTACH_DETACH
#define KERNEL_DEBUG
/* make structure definitions match up with those expected in solib.c */
#define link_object sod
#define lo_name sod_name
#define lo_library sod_library
#define lo_unused sod_reserved
#define lo_major sod_major
#define lo_minor sod_minor
#define lo_next sod_next
#define link_map so_map
#define lm_addr som_addr
#define lm_name som_path
#define lm_next som_next
#define lm_lop som_sod
#define lm_lob som_sodbase
#define lm_rwt som_write
#define lm_ld som_dynamic
#define lm_lpd som_spd
#define link_dynamic_2 section_dispatch_table
#define ld_loaded sdt_loaded
#define ld_need sdt_sods
#define ld_rules sdt_filler1
#define ld_got sdt_got
#define ld_plt sdt_plt
#define ld_rel sdt_rel
#define ld_hash sdt_hash
#define ld_stab sdt_nzlist
#define ld_stab_hash sdt_filler2
#define ld_buckets sdt_buckets
#define ld_symbols sdt_strings
#define ld_symb_size sdt_str_sz
#define ld_text sdt_text_sz
#define ld_plt_sz sdt_plt_sz
#define rtc_symb rt_symbol
#define rtc_sp rt_sp
#define rtc_next rt_next
#define ld_debug so_debug
#define ldd_version dd_version
#define ldd_in_debugger dd_in_debugger
#define ldd_sym_loaded dd_sym_loaded
#define ldd_bp_addr dd_bpt_addr
#define ldd_bp_inst dd_bpt_shadow
#define ldd_cp dd_cc
#define link_dynamic _dynamic
#define ld_version d_version
#define ldd d_debug
#define ld_un d_un
#define ld_2 d_sdt
#endif /* NM_FREEBSD_H */

View File

@ -68,7 +68,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Offset to saved PC in sigcontext, from <sys/signal.h>. */
#define SIGCONTEXT_PC_OFFSET 20
#undef FRAME_SAVED_PC(FRAME)
#undef FRAME_SAVED_PC
#define FRAME_SAVED_PC(FRAME) \
(((FRAME)->signal_handler_caller \
? sigtramp_saved_pc (FRAME) \

View File

@ -1,3 +1,3 @@
char *version = "4.11";
char *host_canonical = "i386-unknown-freebsd";
char *target_canonical = "i386-unknown-freebsd";
char *version = "4.13";
char *host_name = "i386-unknown-freebsd";
char *target_name = "i386-unknown-freebsd";

View File

@ -26,8 +26,4 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define PSIGNAL_IN_SIGNAL_H
/* Get rid of any system-imposed stack limit if possible. */
#define SET_STACK_LIMIT_HUGE
#define HAVE_TERMIOS

View File

@ -1,15 +1,24 @@
This is a greatly pared down version of GDB-4.12 for FreeBSD 1.1.5 that
supports debugging of shared executables and the new a.out format.
This is a greatly pared down version of GDB-4.13 for FreeBSD 2.0. It
also has support for kernel debugging a la the dearly beloved kgdb.
Kernel debugging is enabled either using the -k flag or by linking gdb
to kgdb and invoking it as kgdb. Linking is left up to the discretion
of the user.
I've collapsed some of the directories and removed lots of files from others.
All that's included is those necessary to compile on FreeBSD 1.1.5, this was
to keep the replacement for GDB-3 compact since none of the multiple
architecture stuff is used. All the documentation has been put in the doc/
directory.
The kernel debugging needs testing, I didn't have any useful crash dumps
available. The new gdb produced the same output as the old kgdb with
what I had available for testing, though.
A full port of each library will probably be done for FreeBSD 2.0 and
included as system libraries so that other build tools can share them.
At that time a more complete port of GDB-4 will be done that allows
configuration for different systems and uses the full libraries.
There's rudimentary support for attaching to a running process and
debugging (attach/detach commands in gdb). This works best if the
program being debugged was compiled with -g, of course. Be aware that
detaching frequently results in the death of the process being debugged
(Trace/BKPT Trap). Haven't figured what's going on yet. Use this at your
own risk! I had to stop somewhere for the release :-)
paul@freefall.cdrom.com
Note that a plain vanilla gdb-4.13 without kernal debugging or
attach/detach support can be made by removing the
#define ATTACH_DETACH
#define KERNEL_DEBUG
lines from gdb/nm.h.
gj@freebsd.org

View File

@ -1 +1 @@
4.11
4.13

View File

@ -1,8 +1,17 @@
LIB = bfd
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 freebsd386.c aout32.c stab-syms.c \
cpu-i386.c trad-core.c
SRCS = libbfd.c opncls.c bfd.c archive.c targets.c cache.c \
archures.c coff-i386.c aout32.c \
srec.c \
ecoff.c ecofflink.c \
coffgen.c format.c \
section.c core.c syms.c stab-syms.c reloc.c init.c ctor.c \
trad-core.c \
i386aout.c \
freebsd386.c \
cpu-i386.c \
elf.c elf32.c elf32-i386.c \
hash.c linker.c
CFLAGS+= -I$(.CURDIR)/. -I$(.CURDIR)/../gdb/.
CFLAGS+= -DDEFAULT_VECTOR=freebsd386_vec -DSELECT_VECS='&freebsd386_vec' \

View File

@ -1,7 +1,4 @@
This is a greatly pared down libbfd directory. Only what's required to build
gdb-4.12 on FreeBSD was kept.
gdb-4.13 on FreeBSD 2.0 was kept.
This is temporary. In FreeBSD 2.0 a fully ported libbfd will likely appear
as a system library for use by all the build tools.
paul@freefall.cdrom.com
gj@freebsd.org

View File

@ -1 +1 @@
2.2
cygnus-2.3

View File

@ -1,5 +1,5 @@
/* Define a target vector and some small routines for a variant of a.out.
Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@ -27,11 +27,13 @@ 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)
static const bfd_target *
MY(callback) (abfd)
bfd *abfd;
{
struct internal_exec *execp = exec_hdr (abfd);
unsigned int arch_align_power;
unsigned long arch_align;
/* Calculate the file positions of the parts of a newly read aout header */
obj_textsec (abfd)->_raw_size = N_TXTSIZE(*execp);
@ -60,6 +62,26 @@ DEFUN(MY(callback),(abfd),
bfd_default_set_arch_mach(abfd, DEFAULT_ARCH, 0);
#endif
/* Now that we know the architecture, set the alignments of the
sections. This is normally done by NAME(aout,new_section_hook),
but when the initial sections were created the architecture had
not yet been set. However, for backward compatibility, we don't
set the alignment power any higher than as required by the size
of the section. */
arch_align_power = bfd_get_arch_info (abfd)->section_align_power;
arch_align = 1 << arch_align_power;
if ((BFD_ALIGN (obj_textsec (abfd)->_raw_size, arch_align)
== obj_textsec (abfd)->_raw_size)
&& (BFD_ALIGN (obj_datasec (abfd)->_raw_size, arch_align)
== obj_datasec (abfd)->_raw_size)
&& (BFD_ALIGN (obj_bsssec (abfd)->_raw_size, arch_align)
== obj_bsssec (abfd)->_raw_size))
{
obj_textsec (abfd)->alignment_power = arch_align_power;
obj_datasec (abfd)->alignment_power = arch_align_power;
obj_bsssec (abfd)->alignment_power = arch_align_power;
}
/* Don't set sizes now -- can't be sure until we know arch & mach.
Sizes get set in set_sizes callback, later. */
#if 0
@ -79,25 +101,26 @@ DEFUN(MY(callback),(abfd),
#ifndef MY_object_p
/* Finish up the reading of an a.out file header */
static bfd_target *
DEFUN(MY(object_p),(abfd),
bfd *abfd)
static const bfd_target *
MY(object_p) (abfd)
bfd *abfd;
{
struct external_exec exec_bytes; /* Raw exec header from file */
struct internal_exec exec; /* Cleaned-up exec header */
bfd_target *target;
const bfd_target *target;
if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
!= EXEC_BYTES_SIZE) {
bfd_error = wrong_format;
if (bfd_get_error () != bfd_error_system_call)
bfd_set_error (bfd_error_wrong_format);
return 0;
}
#ifdef NO_SWAP_MAGIC
memcpy (&exec.a_info, exec_bytes.e_info, sizeof(exec.a_info));
#ifdef SWAP_MAGIC
exec.a_info = SWAP_MAGIC (exec_bytes.e_info);
#else
exec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
#endif /* NO_SWAP_MAGIC */
#endif /* SWAP_MAGIC */
if (N_BADMAG (exec)) return 0;
#ifdef MACHTYPE_OK
@ -105,6 +128,12 @@ DEFUN(MY(object_p),(abfd),
#endif
NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, &exec);
#ifdef SWAP_MAGIC
/* swap_exec_header_in read in a_info with the wrong byte order */
exec.a_info = SWAP_MAGIC (exec_bytes.e_info);
#endif /* SWAP_MAGIC */
target = NAME(aout,some_aout_object_p) (abfd, &exec, MY(callback));
#ifdef ENTRY_CAN_BE_ZERO
@ -134,8 +163,8 @@ DEFUN(MY(object_p),(abfd),
#ifndef MY_mkobject
static boolean
DEFUN(MY(mkobject),(abfd),
bfd *abfd)
MY(mkobject) (abfd)
bfd *abfd;
{
if (NAME(aout,mkobject)(abfd) == false)
return false;
@ -154,14 +183,36 @@ DEFUN(MY(mkobject),(abfd),
#define MY_mkobject MY(mkobject)
#endif
#ifndef MY_bfd_copy_private_section_data
/* Copy private section data. This actually does nothing with the
sections. It copies the subformat field. We copy it here, because
we need to know whether this is a QMAGIC file before we set the
section contents, and copy_private_bfd_data is not called until
after the section contents have been set. */
/*ARGSUSED*/
static boolean
MY_bfd_copy_private_section_data (ibfd, isec, obfd, osec)
bfd *ibfd;
asection *isec;
bfd *obfd;
asection *osec;
{
obj_aout_subformat (obfd) = obj_aout_subformat (ibfd);
return true;
}
#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)
MY(write_object_contents) (abfd)
bfd *abfd;
{
struct external_exec exec_bytes;
struct internal_exec *execp = exec_hdr (abfd);
@ -181,31 +232,112 @@ DEFUN(MY(write_object_contents),(abfd),
#ifndef MY_set_sizes
static boolean
DEFUN(MY(set_sizes),(abfd), bfd *abfd)
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
#ifdef ZMAGIC_DISK_BLOCK_SIZE
adata(abfd).zmagic_disk_block_size = ZMAGIC_DISK_BLOCK_SIZE;
#else
adata(abfd).zmagic_disk_block_size = PAGE_SIZE;
#endif
adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE;
return true;
}
#define MY_set_sizes MY(set_sizes)
#endif
#ifndef MY_exec_hdr_flags
#define MY_exec_hdr_flags 0
#endif
#ifndef MY_backend_data
#ifndef MY_text_includes_header
#define MY_text_includes_header 0
#endif
#ifndef MY_add_dynamic_symbols
#define MY_add_dynamic_symbols 0
#endif
#ifndef MY_add_one_symbol
#define MY_add_one_symbol 0
#endif
#ifndef MY_link_dynamic_object
#define MY_link_dynamic_object 0
#endif
#ifndef MY_write_dynamic_symbol
#define MY_write_dynamic_symbol 0
#endif
#ifndef MY_check_dynamic_reloc
#define MY_check_dynamic_reloc 0
#endif
#ifndef MY_finish_dynamic_link
#define MY_finish_dynamic_link 0
#endif
static CONST struct aout_backend_data MY(backend_data) = {
0, /* zmagic contiguous */
0, /* text incl header */
MY_text_includes_header,
MY_exec_hdr_flags,
0, /* text vma? */
MY_set_sizes,
0, /* exec header is counted */
MY_add_dynamic_symbols,
MY_add_one_symbol,
MY_link_dynamic_object,
MY_write_dynamic_symbol,
MY_check_dynamic_reloc,
MY_finish_dynamic_link
};
#define MY_backend_data &MY(backend_data)
#endif
#ifndef MY_final_link_callback
/* Callback for the final_link routine to set the section offsets. */
static void MY_final_link_callback
PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
static void
MY_final_link_callback (abfd, ptreloff, pdreloff, psymoff)
bfd *abfd;
file_ptr *ptreloff;
file_ptr *pdreloff;
file_ptr *psymoff;
{
struct internal_exec *execp = exec_hdr (abfd);
*ptreloff = N_TRELOFF (*execp);
*pdreloff = N_DRELOFF (*execp);
*psymoff = N_SYMOFF (*execp);
}
#endif
#ifndef MY_bfd_final_link
/* Final link routine. We need to use a call back to get the correct
offsets in the output file. */
static boolean
MY_bfd_final_link (abfd, info)
bfd *abfd;
struct bfd_link_info *info;
{
return NAME(aout,final_link) (abfd, info, MY_final_link_callback);
}
#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
@ -228,14 +360,14 @@ static CONST struct aout_backend_data MY(backend_data) = {
/* 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
#define MY_core_file_failing_command _bfd_nocore_core_file_failing_command
#endif
#ifndef MY_core_file_failing_signal
#define MY_core_file_failing_signal _bfd_dummy_core_file_failing_signal
#define MY_core_file_failing_signal _bfd_nocore_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
_bfd_nocore_core_file_matches_executable_p
#endif
#ifndef MY_core_file_p
#define MY_core_file_p _bfd_dummy_target
@ -261,21 +393,6 @@ static CONST struct aout_backend_data MY(backend_data) = {
#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
@ -312,32 +429,63 @@ static CONST struct aout_backend_data MY(backend_data) = {
#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)
#ifndef MY_bfd_get_relocated_section_contents
#define MY_bfd_get_relocated_section_contents \
bfd_generic_get_relocated_section_contents
#endif
#ifndef MY_bfd_debug_info_end
#define MY_bfd_debug_info_end NAME(aout,bfd_debug_info_end)
#ifndef MY_bfd_relax_section
#define MY_bfd_relax_section bfd_generic_relax_section
#endif
#ifndef MY_bfd_debug_info_accumulat
#define MY_bfd_debug_info_accumulat NAME(aout,bfd_debug_info_accumulat)
#ifndef MY_bfd_reloc_type_lookup
#define MY_bfd_reloc_type_lookup NAME(aout,reloc_type_lookup)
#endif
#ifndef MY_reloc_howto_type_lookup
#define MY_reloc_howto_type_lookup NAME(aout,reloc_type_lookup)
#ifndef MY_bfd_make_debug_symbol
#define MY_bfd_make_debug_symbol 0
#endif
#ifndef MY_make_debug_symbol
#define MY_make_debug_symbol 0
#ifndef MY_bfd_link_hash_table_create
#define MY_bfd_link_hash_table_create NAME(aout,link_hash_table_create)
#endif
#ifndef MY_bfd_link_add_symbols
#define MY_bfd_link_add_symbols NAME(aout,link_add_symbols)
#endif
#ifndef MY_bfd_copy_private_bfd_data
#define MY_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data
#endif
#ifndef MY_bfd_is_local_label
#define MY_bfd_is_local_label bfd_generic_is_local_label
#endif
#ifndef MY_bfd_free_cached_info
#define MY_bfd_free_cached_info NAME(aout,bfd_free_cached_info)
#endif
#ifndef MY_close_and_cleanup
#define MY_close_and_cleanup MY_bfd_free_cached_info
#endif
#ifndef MY_get_dynamic_symtab_upper_bound
#define MY_get_dynamic_symtab_upper_bound \
_bfd_nodynamic_get_dynamic_symtab_upper_bound
#endif
#ifndef MY_canonicalize_dynamic_symtab
#define MY_canonicalize_dynamic_symtab \
_bfd_nodynamic_canonicalize_dynamic_symtab
#endif
#ifndef MY_get_dynamic_reloc_upper_bound
#define MY_get_dynamic_reloc_upper_bound \
_bfd_nodynamic_get_dynamic_reloc_upper_bound
#endif
#ifndef MY_canonicalize_dynamic_reloc
#define MY_canonicalize_dynamic_reloc \
_bfd_nodynamic_canonicalize_dynamic_reloc
#endif
/* Aout symbols normally have leading underscores */
@ -351,7 +499,7 @@ static CONST struct aout_backend_data MY(backend_data) = {
#endif
#ifndef MY_BFD_TARGET
bfd_target MY(vec) =
const bfd_target MY(vec) =
{
TARGETNAME, /* name */
bfd_target_aout_flavour,
@ -392,38 +540,16 @@ bfd_target MY(vec) =
{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,
BFD_JUMP_TABLE_GENERIC (MY),
BFD_JUMP_TABLE_COPY (MY),
BFD_JUMP_TABLE_CORE (MY),
BFD_JUMP_TABLE_ARCHIVE (MY),
BFD_JUMP_TABLE_SYMBOLS (MY),
BFD_JUMP_TABLE_RELOCS (MY),
BFD_JUMP_TABLE_WRITE (MY),
BFD_JUMP_TABLE_LINK (MY),
BFD_JUMP_TABLE_DYNAMIC (MY),
(PTR) MY_backend_data,
};
#endif /* MY_BFD_TARGET */

View File

@ -1,5 +1,5 @@
/* BFD back-end for 32-bit a.out files.
Copyright (C) 1990-1991 Free Software Foundation, Inc.
Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,7 @@
/* BFD library support routines for architectures.
Copyright (C) 1990-1991 Free Software Foundation, Inc.
Copyright (C) 1990, 91, 92, 93, 94 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
@ -24,19 +23,18 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
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 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
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.
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
The architecture information is provided by each architecture package.
The set of default architectures is selected by the macro
<<SELECT_ARCHITECTURES>>. This is normally set up in the
<<config/target.mt>> file of your choice. If the name is not
@file{config/@var{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
@ -44,6 +42,8 @@ SECTION
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).
BFD's idea of an architecture is implemented in @file{archures.c}.
*/
/*
@ -53,11 +53,11 @@ SUBSECTION
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
global sense---i.e., what processor family does it belong to?
Another field indicates which 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,
distinguishes 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
@ -97,6 +97,7 @@ DESCRIPTION
. bfd_arch_h8300, {* Hitachi H8/300 *}
.#define bfd_mach_h8300 1
.#define bfd_mach_h8300h 2
. bfd_arch_powerpc, {* PowerPC *}
. bfd_arch_rs6000, {* IBM RS/6000 *}
. bfd_arch_hppa, {* HP PA RISC *}
. bfd_arch_z8k, {* Zilog Z8000 *}
@ -105,6 +106,7 @@ DESCRIPTION
. bfd_arch_h8500, {* Hitachi H8/500 *}
. bfd_arch_sh, {* Hitachi SH *}
. bfd_arch_alpha, {* Dec Alpha *}
. bfd_arch_ns32k, {* National Semiconductors ns32000 *}
. bfd_arch_last
. };
@ -166,13 +168,13 @@ SYNOPSIS
DESCRIPTION
Return a printable string representing the architecture and machine
from the pointer to the arch info structure
from the pointer to the architecture info structure.
*/
CONST char *
DEFUN(bfd_printable_name, (abfd),
bfd *abfd)
bfd_printable_name (abfd)
bfd *abfd;
{
return abfd->arch_info->printable_name;
}
@ -184,19 +186,18 @@ FUNCTION
bfd_scan_arch
SYNOPSIS
bfd_arch_info_type *bfd_scan_arch(CONST char *);
bfd_arch_info_type *bfd_scan_arch(CONST char *string);
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
Figure out if BFD supports any cpu which could be described with
the name @var{string}. Return 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)
bfd_scan_arch (string)
CONST char *string;
{
struct bfd_arch_info *ap;
@ -223,18 +224,17 @@ SYNOPSIS
CONST bfd *bbfd);
DESCRIPTION
This routine is used to determine whether two BFDs'
architectures and achine types are compatible. It calculates
Determine whether two BFDs'
architectures and machine types are compatible. 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.
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)
bfd_arch_get_compatible (abfd, bbfd)
CONST bfd *abfd;
CONST bfd *bbfd;
{
return abfd->arch_info->compatible(abfd->arch_info,bbfd->arch_info);
}
@ -268,13 +268,16 @@ FUNCTION
bfd_set_arch_info
SYNOPSIS
void bfd_set_arch_info(bfd *, bfd_arch_info_type *);
void bfd_set_arch_info(bfd *abfd, bfd_arch_info_type *arg);
DESCRIPTION
Set the architecture info of @var{abfd} to @var{arg}.
*/
void DEFUN(bfd_set_arch_info,(abfd, arg),
bfd *abfd AND
bfd_arch_info_type *arg)
void
bfd_set_arch_info (abfd, arg)
bfd *abfd;
bfd_arch_info_type *arg;
{
abfd->arch_info = arg;
}
@ -289,15 +292,17 @@ SYNOPSIS
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
Set the architecture and machine type in BFD @var{abfd}
to @var{arch} and @var{mach}. Find the correct
pointer to a structure and insert 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)
boolean
bfd_default_set_arch_mach (abfd, arch, mach)
bfd *abfd;
enum bfd_architecture arch;
unsigned long mach;
{
static struct bfd_arch_info *old_ptr = &bfd_default_arch_struct;
boolean found = false;
@ -319,7 +324,7 @@ boolean DEFUN(bfd_default_set_arch_mach,(abfd, arch, mach),
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;
bfd_set_error (bfd_error_bad_value);
}
}
else {
@ -333,9 +338,6 @@ boolean DEFUN(bfd_default_set_arch_mach,(abfd, arch, mach),
}
/*
FUNCTION
bfd_get_arch
@ -344,12 +346,14 @@ SYNOPSIS
enum bfd_architecture bfd_get_arch(bfd *abfd);
DESCRIPTION
Returns the enumerated type which describes the supplied bfd's
architecture
Return the enumerated type which describes the BFD @var{abfd}'s
architecture.
*/
enum bfd_architecture DEFUN(bfd_get_arch, (abfd), bfd *abfd)
enum bfd_architecture
bfd_get_arch (abfd)
bfd *abfd;
{
return abfd->arch_info->arch;
}
@ -362,12 +366,13 @@ SYNOPSIS
unsigned long bfd_get_mach(bfd *abfd);
DESCRIPTION
Returns the long type which describes the supplied bfd's
machine
Return the long type which describes the BFD @var{abfd}'s
machine.
*/
unsigned long
DEFUN(bfd_get_mach, (abfd), bfd *abfd)
bfd_get_mach (abfd)
bfd *abfd;
{
return abfd->arch_info->mach;
}
@ -380,14 +385,17 @@ SYNOPSIS
unsigned int bfd_arch_bits_per_byte(bfd *abfd);
DESCRIPTION
Returns the number of bits in one of the architectures bytes
Return the number of bits in one of the BFD @var{abfd}'s
architecture's bytes.
*/
unsigned int DEFUN(bfd_arch_bits_per_byte, (abfd), bfd *abfd)
{
return abfd->arch_info->bits_per_byte;
}
unsigned int
bfd_arch_bits_per_byte (abfd)
bfd *abfd;
{
return abfd->arch_info->bits_per_byte;
}
/*
FUNCTION
@ -397,13 +405,16 @@ SYNOPSIS
unsigned int bfd_arch_bits_per_address(bfd *abfd);
DESCRIPTION
Returns the number of bits in one of the architectures addresses
Return the number of bits in one of the BFD @var{abfd}'s
architecture's addresses.
*/
unsigned int DEFUN(bfd_arch_bits_per_address, (abfd), bfd *abfd)
{
return abfd->arch_info->bits_per_address;
}
unsigned int
bfd_arch_bits_per_address (abfd)
bfd *abfd;
{
return abfd->arch_info->bits_per_address;
}
extern void bfd_a29k_arch PARAMS ((void));
@ -416,12 +427,14 @@ 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_powerpc_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));
extern void bfd_ns32k_arch PARAMS ((void));
static void (*archures_init_table[]) PARAMS ((void)) =
{
@ -438,12 +451,14 @@ static void (*archures_init_table[]) PARAMS ((void)) =
bfd_m68k_arch,
bfd_m88k_arch,
bfd_mips_arch,
bfd_powerpc_arch,
bfd_rs6000_arch,
bfd_sh_arch,
bfd_sparc_arch,
bfd_vax_arch,
bfd_we32k_arch,
bfd_z8k_arch,
bfd_ns32k_arch,
#endif
0
};
@ -455,16 +470,16 @@ INTERNAL_FUNCTION
bfd_arch_init
SYNOPSIS
void bfd_arch_init(void);
void bfd_arch_init(void);
DESCRIPTION
This routine initializes the architecture dispatch table by
Initialize the architecture dispatch table by
calling all installed architecture packages and getting them
to poke around.
*/
void
DEFUN_VOID(bfd_arch_init)
bfd_arch_init ()
{
void (**ptable) PARAMS ((void));
for (ptable = archures_init_table;
@ -481,14 +496,15 @@ INTERNAL_FUNCTION
bfd_arch_linkin
SYNOPSIS
void bfd_arch_linkin(bfd_arch_info_type *);
void bfd_arch_linkin(bfd_arch_info_type *ptr);
DESCRIPTION
Link the provided arch info structure into the list
Link the architecture info structure @var{ptr} into the list.
*/
void DEFUN(bfd_arch_linkin,(ptr),
bfd_arch_info_type *ptr)
void
bfd_arch_linkin (ptr)
bfd_arch_info_type *ptr;
{
ptr->next = bfd_arch_info_list;
bfd_arch_info_list = ptr;
@ -509,9 +525,9 @@ DESCRIPTION
*/
CONST bfd_arch_info_type *
DEFUN(bfd_default_compatible,(a,b),
CONST bfd_arch_info_type *a AND
CONST bfd_arch_info_type *b)
bfd_default_compatible (a,b)
CONST bfd_arch_info_type *a;
CONST bfd_arch_info_type *b;
{
if(a->arch != b->arch) return NULL;
@ -530,7 +546,7 @@ INTERNAL_FUNCTION
bfd_default_scan
SYNOPSIS
boolean bfd_default_scan(CONST struct bfd_arch_info *, CONST char *);
boolean bfd_default_scan(CONST struct bfd_arch_info *info, CONST char *string);
DESCRIPTION
The default function for working out whether this is an
@ -538,9 +554,9 @@ DESCRIPTION
*/
boolean
DEFUN(bfd_default_scan,(info, string),
CONST struct bfd_arch_info *info AND
CONST char *string)
bfd_default_scan (info, string)
CONST struct bfd_arch_info *info;
CONST char *string;
{
CONST char *ptr_src;
CONST char *ptr_tst;
@ -647,21 +663,20 @@ CONST char *string)
}
/*
FUNCTION
bfd_get_arch_info
SYNOPSIS
bfd_arch_info_type * bfd_get_arch_info(bfd *);
bfd_arch_info_type * bfd_get_arch_info(bfd *abfd);
DESCRIPTION
Return the architecture info struct in @var{abfd}.
*/
bfd_arch_info_type *
DEFUN(bfd_get_arch_info,(abfd),
bfd *abfd)
bfd_get_arch_info (abfd)
bfd *abfd;
{
return abfd->arch_info;
}
@ -678,16 +693,16 @@ SYNOPSIS
long machine);
DESCRIPTION
Look for the architecure info struct which matches the
arguments given. A machine of 0 will match the
Look for the architecure info structure which matches the
arguments @var{arch} and @var{machine}. A machine of 0 matches 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_lookup_arch (arch, machine)
enum bfd_architecture arch;
long machine;
{
bfd_arch_info_type *ap;
bfd_check_init();
@ -704,26 +719,25 @@ long machine)
}
/*
FUNCTION
bfd_printable_arch_mach
SYNOPSIS
CONST char * bfd_printable_arch_mach
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.
This routine is depreciated.
*/
CONST char *
DEFUN(bfd_printable_arch_mach,(arch, machine),
enum bfd_architecture arch AND
unsigned long machine)
bfd_printable_arch_mach (arch, machine)
enum bfd_architecture arch;
unsigned long machine;
{
bfd_arch_info_type *ap = bfd_lookup_arch(arch, machine);
if(ap) return ap->printable_name;

View File

@ -1,5 +1,5 @@
/* Generic BFD library interface and support routines.
Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@ -22,13 +22,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
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.
A BFD has type <<bfd>>; objects of this type are the
cornerstone of any application using BFD. Using BFD
consists of making references though the BFD and to data in the BFD.
Here is the struct used to define the type <<bfd>>. This
contains the major data about the file, and contains pointers
Here is the structure that defines the type <<bfd>>. It
contains the major data about the file and pointers
to the rest of the data.
CODE_FRAGMENT
@ -39,7 +38,7 @@ CODE_FRAGMENT
. CONST char *filename;
.
. {* A pointer to the target jump table. *}
. struct bfd_target *xvec;
. const struct bfd_target *xvec;
.
. {* To avoid dragging too many header files into every file that
. includes `<<bfd.h>>', IOSTREAM has been declared as a "char
@ -48,13 +47,14 @@ CODE_FRAGMENT
. is the result of an fopen on the filename. *}
. char *iostream;
.
. {* Is the file being cached *}
. {* Is the file descriptor being cached? That is, can it be closed as
. needed, and re-opened when accessed later? *}
.
. boolean cacheable;
.
. {* Marks whether there was a default target specified when the
. BFD was opened. This is used to select what matching algorithm
. to use to chose the back end. *}
. BFD was opened. This is used to select which matching algorithm
. to use to choose the back end. *}
.
. boolean target_defaulted;
.
@ -64,12 +64,11 @@ CODE_FRAGMENT
. struct _bfd *lru_prev, *lru_next;
.
. {* When a file is closed by the caching routines, BFD retains
. state information on the file here:
. *}
. state information on the file here: *}
.
. file_ptr where;
.
. {* and here:*}
. {* and here: (``once'' means at least once) *}
.
. boolean opened_once;
.
@ -86,7 +85,7 @@ CODE_FRAGMENT
.
. int ifd;
.
. {* The format which belongs to the BFD.*}
. {* The format which belongs to the BFD. (object, core, etc.) *}
.
. bfd_format format;
.
@ -108,7 +107,7 @@ CODE_FRAGMENT
. file_ptr origin;
.
. {* Remember when output has begun, to stop strange things
. happening. *}
. from happening. *}
. boolean output_has_begun;
.
. {* Pointer to linked list of sections*}
@ -124,7 +123,7 @@ CODE_FRAGMENT
. {* Used for input and output*}
. unsigned int symcount;
.
. {* Symbol table for output BFD*}
. {* Symbol table for output BFD (with symcount entries) *}
. struct symbol_cache_entry **outsymbols;
.
. {* Pointer to structure which contains architecture information*}
@ -132,11 +131,18 @@ CODE_FRAGMENT
.
. {* Stuff only useful for archives:*}
. PTR arelt_data;
. struct _bfd *my_archive;
. struct _bfd *next;
. struct _bfd *archive_head;
. struct _bfd *my_archive; {* The containing archive BFD. *}
. struct _bfd *next; {* The next BFD in the archive. *}
. struct _bfd *archive_head; {* The first BFD in the archive. *}
. boolean has_armap;
.
. {* A chain of BFD structures involved in a link. *}
. struct _bfd *link_next;
.
. {* A field used by _bfd_generic_link_add_archive_symbols. This will
. be used only for archive elements. *}
. int archive_pass;
.
. {* Used by the back end to hold private data. *}
.
. union
@ -156,11 +162,13 @@ CODE_FRAGMENT
. 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 som_data_struct *som_data;
. struct hpux_core_struct *hpux_core_data;
. struct hppabsd_core_struct *hppabsd_core_data;
. struct sgi_core_struct *sgi_core_data;
. struct lynx_core_struct *lynx_core_data;
. struct osf_core_struct *osf_core_data;
. struct cisco_core_struct *cisco_core_data;
. PTR any;
. } tdata;
.
@ -169,15 +177,13 @@ CODE_FRAGMENT
.
. {* 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 "bfdlink.h"
#include "libbfd.h"
#include "coff/internal.h"
#include "coff/sym.h"
@ -186,31 +192,67 @@ CODE_FRAGMENT
#undef obj_symbols
#include "libelf.h"
/*
SECTION
Error reporting
Most BFD functions return nonzero on success (check their
individual documentation for precise semantics). On an error,
they call <<bfd_set_error>> to set an error condition that callers
can check by calling <<bfd_get_error>>.
If that returns <<bfd_error_system_call>>, then check
<<errno>>.
The easiest way to report a BFD error to the user is to
use <<bfd_perror>>.
SUBSECTION
Type <<bfd_error_type>>
The values returned by <<bfd_get_error>> are defined by the
enumerated type <<bfd_error_type>>.
CODE_FRAGMENT
.
.typedef enum bfd_error
.{
. bfd_error_no_error = 0,
. bfd_error_system_call,
. bfd_error_invalid_target,
. bfd_error_wrong_format,
. bfd_error_invalid_operation,
. bfd_error_no_memory,
. bfd_error_no_symbols,
. bfd_error_no_more_archived_files,
. bfd_error_malformed_archive,
. bfd_error_file_not_recognized,
. bfd_error_file_ambiguously_recognized,
. bfd_error_no_contents,
. bfd_error_nonrepresentable_section,
. bfd_error_no_debug_section,
. bfd_error_bad_value,
. bfd_error_file_truncated,
. bfd_error_invalid_error_code
.} bfd_error_type;
.
*/
#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;
static bfd_error_type bfd_error = bfd_error_no_error;
CONST char *CONST bfd_errmsgs[] = {
"No error",
"System call error",
"Invalid target",
"Invalid bfd 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",
@ -221,130 +263,128 @@ CONST char *CONST bfd_errmsgs[] = {
"#<Invalid error code>"
};
static
void
DEFUN(bfd_nonrepresentable_section,(abfd, name),
CONST bfd * CONST abfd AND
CONST char * CONST name)
/*
FUNCTION
bfd_get_error
SYNOPSIS
bfd_error_type bfd_get_error (void);
DESCRIPTION
Return the current BFD error condition.
*/
bfd_error_type
bfd_get_error ()
{
fprintf(stderr,
"bfd error writing file %s, format %s can't represent section %s\n",
abfd->filename,
abfd->xvec->name,
name);
exit(1);
return bfd_error;
}
/*ARGSUSED*/
static
void
DEFUN(bfd_undefined_symbol,(relent, seclet),
CONST arelent *relent AND
CONST struct bfd_seclet *seclet)
/*
FUNCTION
bfd_set_error
SYNOPSIS
void bfd_set_error (bfd_error_type error_tag);
DESCRIPTION
Set the BFD error condition to be @var{error_tag}.
*/
void
bfd_set_error (error_tag)
bfd_error_type error_tag;
{
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 = error_tag;
}
bfd_error_vector_type bfd_error_vector =
{
bfd_nonrepresentable_section ,
bfd_undefined_symbol,
bfd_reloc_value_truncated,
bfd_reloc_is_dangerous,
};
/*
FUNCTION
bfd_errmsg
SYNOPSIS
CONST char *bfd_errmsg (bfd_error_type error_tag);
DESCRIPTION
Return a string describing the error @var{error_tag}, or
the system error if @var{error_tag} is <<bfd_error_system_call>>.
*/
CONST char *
bfd_errmsg (error_tag)
bfd_ec error_tag;
bfd_error_type error_tag;
{
#ifndef errno
extern int errno;
#endif
if (error_tag == system_call_error)
if (error_tag == bfd_error_system_call)
return strerror (errno);
if ((((int)error_tag <(int) no_error) ||
((int)error_tag > (int)invalid_error_code)))
error_tag = invalid_error_code;/* sanity check */
if ((((int)error_tag <(int) bfd_error_no_error) ||
((int)error_tag > (int)bfd_error_invalid_error_code)))
error_tag = bfd_error_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));
}
/*
FUNCTION
bfd_perror
void (*bfd_error_trap) PARAMS ((bfd_ec)) = bfd_default_error_trap;
void (*bfd_error_nonrepresentabltrap) PARAMS ((bfd_ec)) = bfd_default_error_trap;
SYNOPSIS
void bfd_perror (CONST char *message);
DESCRIPTION
Print to the standard error stream a string describing the
last BFD error that occurred, or the last system error if
the last BFD error was a system call failure. If @var{message}
is non-NULL and non-empty, the error string printed is preceded
by @var{message}, a colon, and a space. It is followed by a newline.
*/
void
DEFUN(bfd_perror,(message),
CONST char *message)
bfd_perror (message)
CONST char *message;
{
if (bfd_error == system_call_error)
if (bfd_get_error () == bfd_error_system_call)
perror((char *)message); /* must be system error then... */
else {
if (message == NULL || *message == '\0')
fprintf (stderr, "%s\n", bfd_errmsg (bfd_error));
fprintf (stderr, "%s\n", bfd_errmsg (bfd_get_error ()));
else
fprintf (stderr, "%s: %s\n", message, bfd_errmsg (bfd_error));
fprintf (stderr, "%s: %s\n", message, bfd_errmsg (bfd_get_error ()));
}
}
/** Symbols */
/*
SECTION
Symbols
*/
/*
FUNCTION
bfd_get_reloc_upper_bound
SYNOPSIS
unsigned int bfd_get_reloc_upper_bound(bfd *abfd, asection *sect);
long 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>>
Return the number of bytes required to store the
relocation information associated with section @var{sect}
attached to bfd @var{abfd}. If an error occurs, return -1.
*/
unsigned int
DEFUN(bfd_get_reloc_upper_bound,(abfd, asect),
bfd *abfd AND
sec_ptr asect)
long
bfd_get_reloc_upper_bound (abfd, asect)
bfd *abfd;
sec_ptr asect;
{
if (abfd->format != bfd_object) {
bfd_error = invalid_operation;
return 0;
bfd_set_error (bfd_error_invalid_operation);
return -1;
}
return BFD_SEND (abfd, _get_reloc_upper_bound, (abfd, asect));
@ -355,84 +395,39 @@ FUNCTION
bfd_canonicalize_reloc
SYNOPSIS
unsigned int bfd_canonicalize_reloc
long 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
Call the back end associated with the open BFD
@var{abfd} and translate the external form of the relocation
information attached to @var{sec} into the internal canonical
form. Place the table into memory at @var{loc}, which has
been preallocated, usually by a call to
<<bfd_get_reloc_upper_bound>>.
<<bfd_get_reloc_upper_bound>>. Returns the number of relocs, or
-1 on error.
The <<syms>> table is also needed for horrible internal magic
The @var{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)
long
bfd_canonicalize_reloc (abfd, asect, location, symbols)
bfd *abfd;
flagword flags;
sec_ptr asect;
arelent **location;
asymbol **symbols;
{
if (abfd->format != bfd_object) {
bfd_error = wrong_format;
return false;
bfd_set_error (bfd_error_invalid_operation);
return -1;
}
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;
return BFD_SEND (abfd, _bfd_canonicalize_reloc,
(abfd, asect, location, symbols));
}
/*
@ -444,8 +439,9 @@ SYNOPSIS
(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.
Set the relocation pointer and count within
section @var{sec} to the values @var{rel} and @var{count}.
The argument @var{abfd} is ignored.
*/
/*ARGSUSED*/
@ -460,6 +456,50 @@ bfd_set_reloc (ignore_abfd, asect, location, count)
asect->reloc_count = count;
}
/*
FUNCTION
bfd_set_file_flags
SYNOPSIS
boolean bfd_set_file_flags(bfd *abfd, flagword flags);
DESCRIPTION
Set the flag word in the BFD @var{abfd} to the value @var{flags}.
Possible errors are:
o <<bfd_error_wrong_format>> - The target bfd was not of object format.
o <<bfd_error_invalid_operation>> - The target bfd was open for reading.
o <<bfd_error_invalid_operation>> -
The flag word contained a bit which was not applicable to the
type of file. E.g., 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_set_error (bfd_error_wrong_format);
return false;
}
if (bfd_read_p (abfd)) {
bfd_set_error (bfd_error_invalid_operation);
return false;
}
bfd_get_file_flags (abfd) = flags;
if ((flags & bfd_applicable_file_flags (abfd)) != flags) {
bfd_set_error (bfd_error_invalid_operation);
return false;
}
return true;
}
void
bfd_assert(file, line)
char *file;
@ -473,14 +513,14 @@ int line;
FUNCTION
bfd_set_start_address
SYNOPSIS
boolean bfd_set_start_address(bfd *abfd, bfd_vma vma);
DESCRIPTION
Marks the entry point of an output BFD.
Make @var{vma} the entry point of output BFD @var{abfd}.
RETURNS
Returns <<true>> on success, <<false>> otherwise.
SYNOPSIS
boolean bfd_set_start_address(bfd *, bfd_vma);
*/
boolean
@ -495,14 +535,14 @@ bfd_vma vma;
/*
FUNCTION
The bfd_get_mtime function
bfd_get_mtime
SYNOPSIS
long bfd_get_mtime(bfd *);
long bfd_get_mtime(bfd *abfd);
DESCRIPTION
Return file modification time (as read from file system, or
from archive header for archive members).
Return the file modification time (as read from the file system, or
from the archive header for archive members).
*/
@ -526,32 +566,32 @@ bfd_get_mtime (abfd)
/*
FUNCTION
The bfd_get_size function
bfd_get_size
SYNOPSIS
long bfd_get_size(bfd *);
long bfd_get_size(bfd *abfd);
DESCRIPTION
Return file size (as read from file system) for the file
associated with a bfd.
Return the file size (as read from file system) for the file
associated with BFD @var{abfd}.
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
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).
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.
As as example of where we might 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
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
exhausted" error when it tries to allocate 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?".
@ -573,14 +613,14 @@ bfd_get_size (abfd)
/*
FUNCTION
The bfd_get_gp_size function
bfd_get_gp_size
SYNOPSIS
int bfd_get_gp_size(bfd *);
int bfd_get_gp_size(bfd *abfd);
DESCRIPTION
Get the maximum size of objects to be optimized using the GP
register under MIPS ECOFF. This is typically set by the -G
Return 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.
*/
@ -588,22 +628,27 @@ int
bfd_get_gp_size (abfd)
bfd *abfd;
{
if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
return ecoff_data (abfd)->gp_size;
if (abfd->format == bfd_object)
{
if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
return ecoff_data (abfd)->gp_size;
else if (abfd->xvec->flavour == bfd_target_elf_flavour)
return elf_gp_size (abfd);
}
return 0;
}
/*
FUNCTION
The bfd_set_gp_size function
bfd_set_gp_size
SYNOPSIS
void bfd_set_gp_size(bfd *, int);
void bfd_set_gp_size(bfd *abfd, int i);
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.
the <<-G>> argument to the compiler, assembler or linker.
*/
void
@ -611,6 +656,9 @@ bfd_set_gp_size (abfd, i)
bfd *abfd;
int i;
{
/* Don't try to set GP size on an archive or core file! */
if (abfd->format != bfd_object)
return;
if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
ecoff_data (abfd)->gp_size = i;
else if (abfd->xvec->flavour == bfd_target_elf_flavour)
@ -621,27 +669,27 @@ bfd_set_gp_size (abfd, i)
FUNCTION
bfd_scan_vma
SYNOPSIS
bfd_vma bfd_scan_vma(CONST char *string, CONST char **end, int base);
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.
Convert, like <<strtoul>>, a numerical expression
@var{string} into a <<bfd_vma>> integer, and return that integer.
(Though without as many bells and whistles as <<strtoul>>.)
The expression is assumed to be unsigned (i.e., positive).
If given a @var{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_scan_vma (string, end, base)
CONST char *string;
CONST char **end;
int base;
{
bfd_vma value;
int digit;
@ -691,12 +739,33 @@ DEFUN(bfd_scan_vma,(string, end, base),
return value;
}
/*
FUNCTION
bfd_copy_private_bfd_data
SYNOPSIS
boolean bfd_copy_private_bfd_data(bfd *ibfd, bfd *obfd);
DESCRIPTION
Copy private BFD information from the BFD @var{ibfd} to the
the BFD @var{obfd}. Return <<true>> on success, <<false>> on error.
Possible error returns are:
o <<bfd_error_no_memory>> -
Not enough memory exists to create private data for @var{obfd}.
.#define bfd_copy_private_bfd_data(ibfd, obfd) \
. BFD_SEND (ibfd, _bfd_copy_private_bfd_data, \
. (ibfd, obfd))
*/
/*
FUNCTION
stuff
DESCRIPTION
stuff which should be documented
Stuff which should be documented:
.#define bfd_sizeof_headers(abfd, reloc) \
. BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc))
@ -721,13 +790,36 @@ DESCRIPTION
.#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_get_relocated_section_contents(abfd, link_info, link_order, data, relocateable, symbols) \
. BFD_SEND (abfd, _bfd_get_relocated_section_contents, \
. (abfd, link_info, link_order, data, relocateable, symbols))
.
.#define bfd_relax_section(abfd, section, symbols) \
. BFD_SEND (abfd, _bfd_relax_section, (abfd, section, symbols))
.#define bfd_relax_section(abfd, section, link_info, again) \
. BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again))
.
.#define bfd_link_hash_table_create(abfd) \
. BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd))
.
.#define bfd_link_add_symbols(abfd, info) \
. BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info))
.
.#define bfd_final_link(abfd, info) \
. BFD_SEND (abfd, _bfd_final_link, (abfd, info))
.
.#define bfd_free_cached_info(abfd) \
. BFD_SEND (abfd, _bfd_free_cached_info, (abfd))
.
.#define bfd_get_dynamic_symtab_upper_bound(abfd) \
. BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd))
.
.#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \
. BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols))
.
.#define bfd_get_dynamic_reloc_upper_bound(abfd) \
. BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd))
.
.#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \
. BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms))
.
.#define bfd_seclet_link(abfd, data, relocateable) \
. BFD_SEND (abfd, _bfd_seclet_link, (abfd, data, relocateable))
*/

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* BFD library -- caching of file descriptors.
Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
Copyright 1990, 1991, 1992, 1994 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.
@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
SECTION
File Caching
File caching
The file caching mechanism is embedded within BFD and allows
the application to open as many BFDs as it wants without
@ -28,7 +28,7 @@ SECTION
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
<<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.
@ -39,6 +39,11 @@ SECTION
#include "sysdep.h"
#include "libbfd.h"
static void insert PARAMS ((bfd *));
static void snip PARAMS ((bfd *));
static boolean close_one PARAMS ((void));
static boolean bfd_cache_delete PARAMS ((bfd *));
/*
INTERNAL_FUNCTION
BFD_CACHE_MAX_OPEN macro
@ -51,18 +56,10 @@ DESCRIPTION
*/
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. */
/* The number of BFD files we have open. */
static int open_files;
static bfd *cache_sentinel; /* Chain of BFDs with active fds we've
opened */
/*
INTERNAL_FUNCTION
bfd_last_cache
@ -79,233 +76,268 @@ DESCRIPTION
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))
*
*
INTERNAL_FUNCTION
bfd_cache_lookup
DESCRIPTION
Check to see if the required BFD is the same as the last one
looked up. If so, then it can use the stream 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)
/* Insert a BFD into the cache. */
static INLINE void
insert (abfd)
bfd *abfd;
{
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 ;
if (bfd_last_cache == NULL)
{
abfd->lru_next = abfd;
abfd->lru_prev = abfd;
}
kill->where = ftell((FILE *)(kill->iostream));
(void) bfd_cache_delete(kill);
else
{
abfd->lru_next = bfd_last_cache;
abfd->lru_prev = bfd_last_cache->lru_prev;
abfd->lru_prev->lru_next = abfd;
abfd->lru_next->lru_prev = abfd;
}
bfd_last_cache = abfd;
}
/* Cuts the BFD abfd out of the chain in the cache */
static void
DEFUN(snip,(abfd),
bfd *abfd)
/* Remove a BFD from the cache. */
static INLINE void
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;
abfd->lru_next->lru_prev = abfd->lru_prev;
if (abfd == bfd_last_cache)
{
bfd_last_cache = abfd->lru_next;
if (abfd == bfd_last_cache)
bfd_last_cache = NULL;
}
}
/* We need to open a new file, and the cache is full. Find the least
recently used cacheable BFD and close it. */
static boolean
DEFUN(bfd_cache_delete,(abfd),
bfd *abfd)
close_one ()
{
register bfd *kill;
if (bfd_last_cache == NULL)
kill = NULL;
else
{
for (kill = bfd_last_cache->lru_prev;
! kill->cacheable;
kill = kill->lru_prev)
{
if (kill == bfd_last_cache)
{
kill = NULL;
break;
}
}
}
if (kill == NULL)
{
/* There are no open cacheable BFD's. */
return true;
}
kill->where = ftell ((FILE *) kill->iostream);
return bfd_cache_delete (kill);
}
/* Close a BFD and remove it from the cache. */
static boolean
bfd_cache_delete (abfd)
bfd *abfd;
{
boolean ret;
if (fclose ((FILE *)(abfd->iostream)) == 0)
if (fclose ((FILE *) abfd->iostream) == 0)
ret = true;
else
{
ret = false;
bfd_error = system_call_error;
bfd_set_error (bfd_error_system_call);
}
snip (abfd);
abfd->iostream = NULL;
open_files--;
bfd_last_cache = 0;
--open_files;
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)
/*
INTERNAL_FUNCTION
bfd_cache_init
SYNOPSIS
boolean bfd_cache_init (bfd *abfd);
DESCRIPTION
Add a newly opened BFD to the cache.
*/
boolean
bfd_cache_init (abfd)
bfd *abfd;
{
BFD_ASSERT (abfd->iostream != NULL);
if (open_files >= BFD_CACHE_MAX_OPEN)
close_one ();
cache_sentinel = insert(abfd, cache_sentinel);
{
if (! close_one ())
return false;
}
insert (abfd);
++open_files;
return true;
}
/*
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 *);
boolean bfd_cache_close (bfd *abfd);
DESCRIPTION
Remove the BFD @var{abfd} from the cache. If the attached file is open,
then close it too.
RETURNS
<<false>> is returned if closing the file fails, <<true>> is
returned if all is well.
*/
boolean
DEFUN(bfd_cache_close,(abfd),
bfd *abfd)
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;
}
if (abfd->iostream == NULL)
return true;
return bfd_cache_delete (abfd);
}
/*
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* bfd_open_file(bfd *abfd);
DESCRIPTION
Call the OS to open a file for @var{abfd}. Return the <<FILE *>>
(possibly <<NULL>>) that results from this operation. Set up the
BFD so that future accesses know the file is open. If the <<FILE *>>
returned is <<NULL>>, then it won't have been put in the
cache, so it won't have to be removed from it.
*/
FILE *
DEFUN(bfd_open_file, (abfd),
bfd *abfd)
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;
if (open_files >= BFD_CACHE_MAX_OPEN)
{
if (! close_one ())
return NULL;
}
break;
}
if (abfd->iostream) {
bfd_cache_init (abfd);
}
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 == NULL)
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;
}
return (FILE *)(abfd->iostream);
if (abfd->iostream != NULL)
{
if (! bfd_cache_init (abfd))
return NULL;
}
return (FILE *) abfd->iostream;
}
/*
INTERNAL_FUNCTION
bfd_cache_lookup_worker
SYNOPSIS
FILE *bfd_cache_lookup_worker(bfd *abfd);
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
quick answer. Find a file descriptor for @var{abfd}. If
necessary, it open it. If there are already more than
<<BFD_CACHE_MAX_OPEN>> files open, it tries 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)
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 */
abfd = abfd->my_archive;
if (abfd->iostream != NULL)
{
/* Move the file to the start of the cache. */
if (abfd != bfd_last_cache)
{
snip (abfd);
cache_sentinel = insert(abfd, cache_sentinel);
insert (abfd);
}
}
/* 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
{
}
else
{
if (bfd_open_file (abfd) == NULL)
return NULL;
if (fseek ((FILE *) abfd->iostream, abfd->where, SEEK_SET) != 0)
return NULL;
}
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);
return (FILE *) abfd->iostream;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* Core file generic interface routines for BFD.
Copyright (C) 1990-1991 Free Software Foundation, Inc.
Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@ -23,7 +23,7 @@ SECTION
Core files
DESCRIPTION
Buff output this facinating topic
These are functions pertaining to core files.
*/
#include "bfd.h"
@ -36,20 +36,20 @@ FUNCTION
bfd_core_file_failing_command
SYNOPSIS
CONST char *bfd_core_file_failing_command(bfd *);
CONST char *bfd_core_file_failing_command(bfd *abfd);
DESCRIPTION
Returns a read-only string explaining what program was running
when it failed and produced the core file being read
Return a read-only string explaining which program was running
when it failed and produced the core file @var{abfd}.
*/
CONST char *
DEFUN(bfd_core_file_failing_command,(abfd),
bfd *abfd)
bfd_core_file_failing_command (abfd)
bfd *abfd;
{
if (abfd->format != bfd_core) {
bfd_error = invalid_operation;
bfd_set_error (bfd_error_invalid_operation);
return NULL;
}
return BFD_SEND (abfd, _core_file_failing_command, (abfd));
@ -60,11 +60,11 @@ FUNCTION
bfd_core_file_failing_signal
SYNOPSIS
int bfd_core_file_failing_signal(bfd *);
int bfd_core_file_failing_signal(bfd *abfd);
DESCRIPTION
Returns the signal number which caused the core dump which
generated the file the BFD is attached to.
generated the file the BFD @var{abfd} is attached to.
*/
int
@ -72,7 +72,7 @@ bfd_core_file_failing_signal (abfd)
bfd *abfd;
{
if (abfd->format != bfd_core) {
bfd_error = invalid_operation;
bfd_set_error (bfd_error_invalid_operation);
return 0;
}
return BFD_SEND (abfd, _core_file_failing_signal, (abfd));
@ -88,16 +88,16 @@ SYNOPSIS
(bfd *core_bfd, bfd *exec_bfd);
DESCRIPTION
Returns <<true>> if the core file attached to @var{core_bfd}
Return <<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>>.
@var{exec_bfd}, <<false>> otherwise.
*/
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;
bfd_set_error (bfd_error_wrong_format);
return false;
}

View File

@ -37,7 +37,8 @@ static bfd_arch_info_type arch_info_struct =
0,
};
void DEFUN_VOID(bfd_i386_arch)
void
bfd_i386_arch ()
{
bfd_arch_linkin(&arch_info_struct);
}

View File

@ -1,5 +1,5 @@
/* BFD library support routines for constructors
Copyright (C) 1990-1991 Free Software Foundation, Inc.
Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
Hacked by Steve Chamberlain of Cygnus Support. With some help from
Judy Chamberlain too.
@ -25,27 +25,27 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
SECTION
Constructors
Classes in C++ have `constructors' and `destructors'. These
Classes in C++ have @dfn{constructors} and @dfn{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
which is static 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
call a magic function as the first statement before <<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
With COFF, the compiler 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
(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
symbols, generate a C program from this, compile it, and link
with the partially linked input. This process is usually
called <<collect>>.
@ -54,10 +54,10 @@ SECTION
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
BFD allows applications (i.e., 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
implementation by providing a set of entry points for the
indiviual object back ends to call to maintain 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
@ -71,15 +71,15 @@ SECTION
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
The constructor module takes this information and 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
(<<SEC_CONSTRUCTOR>>), which the linker notices and does with
what it wants.
*/
@ -95,28 +95,30 @@ INTERNAL_FUNCTION
bfd_constructor_entry
SYNOPSIS
void bfd_constructor_entry(bfd *abfd,
boolean 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
@var{symbol_ptr_ptr} describes the
function to be called; @var{type} descibes the xtor type,
e.g., something like "CTOR" or "DTOR" would be fine. @var{abfd}
is the BFD which owns the function. 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.
Return <<true>> if successful, <<false>> if out of memory.
*/
void DEFUN(bfd_constructor_entry,(abfd, symbol_ptr_ptr, type),
bfd *abfd AND
asymbol **symbol_ptr_ptr AND
CONST char *type)
boolean
bfd_constructor_entry (abfd, symbol_ptr_ptr, type)
bfd *abfd;
asymbol **symbol_ptr_ptr;
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);
@ -131,6 +133,11 @@ void DEFUN(bfd_constructor_entry,(abfd, symbol_ptr_ptr, type),
{
arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd,
sizeof(arelent_chain));
if (!reloc)
{
bfd_set_error (bfd_error_no_memory);
return false;
}
/* reloc->relent.section = (asection *)NULL;*/
reloc->relent.addend = 0;
@ -144,5 +151,5 @@ void DEFUN(bfd_constructor_entry,(abfd, symbol_ptr_ptr, type),
rel_section->_cooked_size += sizeof(int *);
rel_section->reloc_count++;
}
return true;
}

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,7 @@ SECTION
#include "bfd.h"
#include "sysdep.h"
#include "bfdlink.h"
#include "libbfd.h"
#define ARCH_SIZE 0
#include "libelf.h"
@ -41,8 +42,8 @@ SECTION
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)
bfd_elf_hash (name)
CONST unsigned char *name;
{
unsigned long h = 0;
unsigned long g;
@ -65,33 +66,32 @@ DEFUN (bfd_elf_hash, (name),
buffer. */
static char *
DEFUN (elf_read, (abfd, offset, size),
bfd * abfd AND
long offset AND
int size)
elf_read (abfd, offset, size)
bfd * abfd;
long offset;
int size;
{
char *buf;
if ((buf = bfd_alloc (abfd, size)) == NULL)
{
bfd_error = no_memory;
bfd_set_error (bfd_error_no_memory);
return NULL;
}
if (bfd_seek (abfd, offset, SEEK_SET) == -1)
{
bfd_error = system_call_error;
return NULL;
}
return NULL;
if (bfd_read ((PTR) buf, size, 1, abfd) != size)
{
bfd_error = system_call_error;
if (bfd_get_error () != bfd_error_system_call)
bfd_set_error (bfd_error_file_truncated);
return NULL;
}
return buf;
}
boolean
DEFUN (elf_mkobject, (abfd), bfd * abfd)
elf_mkobject (abfd)
bfd * abfd;
{
/* this just does initialization */
/* coff_mkobject zalloc's space for tdata.coff_obj_data ... */
@ -99,7 +99,7 @@ DEFUN (elf_mkobject, (abfd), bfd * abfd)
bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
if (elf_tdata (abfd) == 0)
{
bfd_error = no_memory;
bfd_set_error (bfd_error_no_memory);
return false;
}
/* since everything is done at close time, do we need any
@ -109,9 +109,9 @@ DEFUN (elf_mkobject, (abfd), bfd * abfd)
}
char *
DEFUN (elf_get_str_section, (abfd, shindex),
bfd * abfd AND
unsigned int shindex)
elf_get_str_section (abfd, shindex)
bfd * abfd;
unsigned int shindex;
{
Elf_Internal_Shdr **i_shdrp;
char *shstrtab = NULL;
@ -135,10 +135,10 @@ DEFUN (elf_get_str_section, (abfd, shindex),
}
char *
DEFUN (elf_string_from_elf_section, (abfd, shindex, strindex),
bfd * abfd AND
unsigned int shindex AND
unsigned int strindex)
elf_string_from_elf_section (abfd, shindex, strindex)
bfd * abfd;
unsigned int shindex;
unsigned int strindex;
{
Elf_Internal_Shdr *hdr;
@ -154,6 +154,68 @@ DEFUN (elf_string_from_elf_section, (abfd, shindex, strindex),
return ((char *) hdr->rawdata) + strindex;
}
/* Make a BFD section from an ELF section. We store a pointer to the
BFD section in the rawdata field of the header. */
boolean
_bfd_elf_make_section_from_shdr (abfd, hdr, name)
bfd *abfd;
Elf_Internal_Shdr *hdr;
const char *name;
{
asection *newsect;
flagword flags;
if (hdr->rawdata != NULL)
{
BFD_ASSERT (strcmp (name, ((asection *) hdr->rawdata)->name) == 0);
return true;
}
newsect = bfd_make_section_anyway (abfd, name);
if (newsect == NULL)
return false;
newsect->filepos = hdr->sh_offset;
if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr)
|| ! bfd_set_section_size (abfd, newsect, hdr->sh_size)
|| ! bfd_set_section_alignment (abfd, newsect,
bfd_log2 (hdr->sh_addralign)))
return false;
flags = SEC_NO_FLAGS;
if (hdr->sh_type != SHT_NOBITS)
flags |= SEC_HAS_CONTENTS;
if ((hdr->sh_flags & SHF_ALLOC) != 0)
{
flags |= SEC_ALLOC;
if (hdr->sh_type != SHT_NOBITS)
flags |= SEC_LOAD;
}
if ((hdr->sh_flags & SHF_WRITE) == 0)
flags |= SEC_READONLY;
if ((hdr->sh_flags & SHF_EXECINSTR) != 0)
flags |= SEC_CODE;
else if ((flags & SEC_LOAD) != 0)
flags |= SEC_DATA;
/* The debugging sections appear to be recognized only by name, not
any sort of flag. */
if (strncmp (name, ".debug", sizeof ".debug" - 1) == 0
|| strncmp (name, ".line", sizeof ".line" - 1) == 0
|| strncmp (name, ".stab", sizeof ".stab" - 1) == 0)
flags |= SEC_DEBUGGING;
if (! bfd_set_section_flags (abfd, newsect, flags))
return false;
hdr->rawdata = (PTR) newsect;
elf_section_data (newsect)->this_hdr = *hdr;
return true;
}
/*
INTERNAL_FUNCTION
bfd_elf_find_section
@ -170,9 +232,9 @@ DESCRIPTION
*/
struct elf_internal_shdr *
DEFUN (bfd_elf_find_section, (abfd, name),
bfd * abfd AND
char *name)
bfd_elf_find_section (abfd, name)
bfd * abfd;
char *name;
{
Elf_Internal_Shdr **i_shdrp;
char *shstrtab;
@ -194,18 +256,6 @@ DEFUN (bfd_elf_find_section, (abfd, name),
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",
@ -222,23 +272,27 @@ const char *const bfd_elf_section_type_names[] = {
function. It just short circuits the reloc if producing
relocateable output against an external symbol. */
/*ARGSUSED*/
bfd_reloc_status_type
bfd_elf_generic_reloc (abfd,
reloc_entry,
symbol,
data,
input_section,
output_bfd)
output_bfd,
error_message)
bfd *abfd;
arelent *reloc_entry;
asymbol *symbol;
PTR data;
asection *input_section;
bfd *output_bfd;
char **error_message;
{
if (output_bfd != (bfd *) NULL
&& (symbol->flags & BSF_SECTION_SYM) == 0
&& reloc_entry->addend == 0)
&& (! reloc_entry->howto->partial_inplace
|| reloc_entry->addend == 0))
{
reloc_entry->address += input_section->output_offset;
return bfd_reloc_ok;
@ -246,3 +300,98 @@ bfd_elf_generic_reloc (abfd,
return bfd_reloc_continue;
}
/* Create an entry in an ELF linker hash table. */
struct bfd_hash_entry *
_bfd_elf_link_hash_newfunc (entry, table, string)
struct bfd_hash_entry *entry;
struct bfd_hash_table *table;
const char *string;
{
struct elf_link_hash_entry *ret = (struct elf_link_hash_entry *) entry;
/* Allocate the structure if it has not already been allocated by a
subclass. */
if (ret == (struct elf_link_hash_entry *) NULL)
ret = ((struct elf_link_hash_entry *)
bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry)));
if (ret == (struct elf_link_hash_entry *) NULL)
{
bfd_set_error (bfd_error_no_memory);
return (struct bfd_hash_entry *) ret;
}
/* Call the allocation method of the superclass. */
ret = ((struct elf_link_hash_entry *)
_bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
table, string));
if (ret != (struct elf_link_hash_entry *) NULL)
{
/* Set local fields. */
ret->indx = -1;
ret->size = 0;
ret->align = 0;
ret->dynindx = -1;
ret->dynstr_index = 0;
ret->weakdef = NULL;
ret->type = STT_NOTYPE;
ret->elf_link_hash_flags = 0;
}
return (struct bfd_hash_entry *) ret;
}
/* Initialize an ELF linker hash table. */
boolean
_bfd_elf_link_hash_table_init (table, abfd, newfunc)
struct elf_link_hash_table *table;
bfd *abfd;
struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
struct bfd_hash_table *,
const char *));
{
table->dynobj = NULL;
table->dynsymcount = 0;
table->dynstr = NULL;
table->bucketcount = 0;
return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
}
/* Create an ELF linker hash table. */
struct bfd_link_hash_table *
_bfd_elf_link_hash_table_create (abfd)
bfd *abfd;
{
struct elf_link_hash_table *ret;
ret = ((struct elf_link_hash_table *)
bfd_alloc (abfd, sizeof (struct elf_link_hash_table)));
if (ret == (struct elf_link_hash_table *) NULL)
{
bfd_set_error (bfd_error_no_memory);
return NULL;
}
if (! _bfd_elf_link_hash_table_init (ret, abfd, _bfd_elf_link_hash_newfunc))
{
bfd_release (abfd, ret);
return NULL;
}
return &ret->root;
}
/* This is a hook for the ELF emulation code in the generic linker to
tell the backend linker what file name to use for the DT_NEEDED
entry for a dynamic object. */
void
bfd_elf_set_dt_needed_name (abfd, name)
bfd *abfd;
const char *name;
{
elf_dt_needed_name (abfd) = name;
}

View File

@ -1,5 +1,5 @@
/* Generic BFD support for file formats.
Copyright (C) 1990-1991 Free Software Foundation, Inc.
Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@ -20,20 +20,20 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
SECTION
File Formats
File formats
A format is a BFD concept of high level file contents. The
A format is a BFD concept of high level file contents type. The
formats supported by BFD are:
o bfd_object
o <<bfd_object>>
The BFD may contain data, symbols, relocations and debug info.
o bfd_archive
o <<bfd_archive>>
The BFD contains other BFDs and an optional index.
o bfd_core
o <<bfd_core>>
The BFD contains the result of an executable core dump.
@ -44,9 +44,8 @@ SECTION
#include "sysdep.h"
#include "libbfd.h"
extern bfd_target *target_vector[];
extern bfd_target *default_vector[];
/* IMPORT from targets.c. */
extern const size_t _bfd_target_vector_entries;
/*
FUNCTION
@ -56,15 +55,14 @@ 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>>,
Verify if the file attached to the BFD @var{abfd} is compatible
with the format @var{format} (i.e., 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
If the BFD has been set to a specific target before the
call, only the named target and format combination is
checked. If the target has not been set, or has been set to
<<default>> then all the known target backends will be
<<default>>, then all the known target backends is
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.
@ -72,34 +70,62 @@ DESCRIPTION
The function returns <<true>> on success, otherwise <<false>>
with one of the following error codes:
o invalid_operation -
o <<bfd_error_invalid_operation>> -
if <<format>> is not one of <<bfd_object>>, <<bfd_archive>> or
<<bfd_core>>.
o system_call_error -
o <<bfd_error_system_call>> -
if an error occured during a read - even some file mismatches
can cause system_call_errors
can cause bfd_error_system_calls.
o file_not_recognised -
none of the backends recognised the file format
o <<file_not_recognised>> -
none of the backends recognised the file format.
o file_ambiguously_recognized -
o <<bfd_error_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_check_format (abfd, format)
bfd *abfd;
bfd_format format;
{
bfd_target **target, *save_targ, *right_targ;
return bfd_check_format_matches (abfd, format, NULL);
}
/*
FUNCTION
bfd_check_format_matches
SYNOPSIS
boolean bfd_check_format_matches(bfd *abfd, bfd_format format, char ***matching);
DESCRIPTION
Like <<bfd_check_format>>, except when it returns false with
<<bfd_errno>> set to <<bfd_error_file_ambiguously_recognized>>. In that
case, if @var{matching} is not NULL, it will be filled in with
a NULL-terminated list of the names of the formats that matched,
allocated with <<malloc>>.
Then the user may choose a format and try again.
When done with the list that @var{matching} points to, the caller
should free it.
*/
boolean
bfd_check_format_matches (abfd, format, matching)
bfd *abfd;
bfd_format format;
char ***matching;
{
const bfd_target * const *target, *save_targ, *right_targ;
char **matching_vector = NULL;
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;
bfd_set_error (bfd_error_invalid_operation);
return false;
}
@ -112,6 +138,19 @@ DEFUN(bfd_check_format,(abfd, format),
save_targ = abfd->xvec;
match_count = 0;
if (matching)
{
matching_vector =
(char **) malloc (sizeof (char *) *
(_bfd_target_vector_entries + 1));
if (!matching_vector)
{
bfd_set_error (bfd_error_no_memory);
return false;
}
matching_vector[0] = NULL;
*matching = matching_vector;
}
right_targ = 0;
@ -121,33 +160,46 @@ DEFUN(bfd_check_format,(abfd, 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! */
if (bfd_seek (abfd, (file_ptr)0, SEEK_SET) != 0) /* rewind! */
return false;
right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
if (right_targ) {
abfd->xvec = right_targ; /* Set the target as returned */
if (matching)
free (matching_vector);
return true; /* File position has moved, BTW */
}
}
for (target = target_vector; *target != NULL; target++) {
bfd_target *temp;
for (target = bfd_target_vector; *target != NULL; target++) {
const 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.
if (bfd_seek (abfd, (file_ptr)0, SEEK_SET) != 0)
return false;
/* If _bfd_check_format neglects to set bfd_error, assume bfd_error_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;
bfd_set_error (bfd_error_wrong_format);
temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
if (temp) { /* This format checks out as ok! */
right_targ = temp;
if (matching)
{
matching_vector[match_count] = temp->name;
matching_vector[match_count + 1] = NULL;
}
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])
if (temp == bfd_default_vector[0])
{
if (matching)
{
matching_vector[0] = temp->name;
matching_vector[1] = NULL;
}
match_count = 1;
break;
}
@ -160,51 +212,60 @@ DEFUN(bfd_check_format,(abfd, format),
*/
break;
#endif
} else if (bfd_error != wrong_format) {
} else if (bfd_get_error () != bfd_error_wrong_format) {
abfd->xvec = save_targ;
abfd->format = bfd_unknown;
if (matching && bfd_get_error () != bfd_error_file_ambiguously_recognized)
free (matching_vector);
return false;
}
}
if (match_count == 1) {
abfd->xvec = right_targ; /* Change BFD's target permanently */
if (matching)
free (matching_vector);
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);
if (match_count == 0)
{
bfd_set_error (bfd_error_file_not_recognized);
if (matching)
free (matching_vector);
}
else
bfd_set_error (bfd_error_file_ambiguously_recognized);
return false;
}
/*
FUNCTION
bfd_set_format
SYNOPSIS
boolean bfd_set_format(bfd *, bfd_format);
boolean bfd_set_format(bfd *abfd, bfd_format 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.
This function sets the file format of the BFD @var{abfd} to the
format @var{format}. If the target set in the BFD does not
support the format requested, the format is invalid, or the BFD
is not open for writing, then an error occurs.
*/
boolean
DEFUN(bfd_set_format,(abfd, format),
bfd *abfd AND
bfd_format format)
bfd_set_format (abfd, format)
bfd *abfd;
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;
bfd_set_error (bfd_error_invalid_operation);
return false;
}
@ -228,18 +289,17 @@ FUNCTION
bfd_format_string
SYNOPSIS
CONST char *bfd_format_string(bfd_format);
CONST char *bfd_format_string(bfd_format 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.
Return a pointer to a const string
<<invalid>>, <<object>>, <<archive>>, <<core>>, or <<unknown>>,
depending upon the value of @var{format}.
*/
CONST char *
DEFUN(bfd_format_string,(format),
bfd_format format)
bfd_format_string (format)
bfd_format format;
{
if (((int)format <(int) bfd_unknown)
|| ((int)format >=(int) bfd_type_end))

View File

@ -29,6 +29,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* ZMAGIC files start at address 0. This does not apply to QMAGIC. */
#define TEXT_START_ADDR 0
#define PAGE_SIZE 4096
#define SEGMENT_SIZE PAGE_SIZE
#define DEFAULT_ARCH bfd_arch_i386

View File

@ -1,5 +1,5 @@
/* bfd initialization stuff
Copyright (C) 1990-1991 Free Software Foundation, Inc.
Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@ -22,7 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "sysdep.h"
#include "libbfd.h"
extern void DEFUN_VOID (bfd_section_init);
extern void bfd_section_init ();
static boolean initialized = false;
@ -30,8 +30,7 @@ static boolean initialized = false;
SECTION
Initialization
This is the initialization section
These are the functions that handle initializing a BFD.
*/
/*
@ -42,11 +41,12 @@ SYNOPSIS
void bfd_init(void);
DESCRIPTION
This routine must be called before any other bfd function to
This routine must be called before any other BFD function to
initialize magical internal data structures.
*/
void DEFUN_VOID(bfd_init)
void
bfd_init ()
{
if (initialized == false) {
initialized = true;
@ -60,17 +60,18 @@ void DEFUN_VOID(bfd_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);
DESCRIPTION
This routine is called before any other BFD function using
initialized data. It ensures that the structures have
been initialized. Soon this function will go away, and the BFD
library will assume that <<bfd_init>> has been called.
*/
void DEFUN_VOID(bfd_check_init)
void
bfd_check_init ()
{
if (initialized == false) {
bfd_init();

View File

@ -18,10 +18,15 @@ 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. */
#ifndef LIBAOUT_H
#define LIBAOUT_H
/* 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. */
#include "bfdlink.h"
/* 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
@ -44,11 +49,50 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#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. */
/* Declare at file level, since used in parameter lists, which have
weird scope. */
struct external_exec;
struct internal_exec;
struct external_nlist;
struct reloc_ext_external;
struct reloc_std_external;
/* a.out backend linker hash table entries. */
struct aout_link_hash_entry
{
struct bfd_link_hash_entry root;
/* Whether this symbol has been written out. */
boolean written;
/* Symbol index in output file. */
int indx;
};
/* a.out backend linker hash table. */
struct aout_link_hash_table
{
struct bfd_link_hash_table root;
};
/* Look up an entry in an a.out link hash table. */
#define aout_link_hash_lookup(table, string, create, copy, follow) \
((struct aout_link_hash_entry *) \
bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow)))
/* Traverse an a.out link hash table. */
#define aout_link_hash_traverse(table, func, info) \
(bfd_link_hash_traverse \
(&(table)->root, \
(boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \
(info)))
/* Get the a.out link hash table from the info structure. This is
just a cast. */
#define aout_hash_table(p) ((struct aout_link_hash_table *) ((p)->hash))
/* Back-end information for various a.out targets. */
struct aout_backend_data
{
@ -61,6 +105,9 @@ struct aout_backend_data
If not, the text section starts on the next page. */
unsigned char text_includes_header;
/* The value to pass to N_SET_FLAGS. */
unsigned char exec_hdr_flags;
/* 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. */
@ -77,6 +124,39 @@ struct aout_backend_data
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;
/* Callback from the add symbols phase of the linker code to handle
a dynamic object. */
boolean (*add_dynamic_symbols) PARAMS ((bfd *, struct bfd_link_info *));
/* Callback from the add symbols phase of the linker code to handle
adding a single symbol to the global linker hash table. */
boolean (*add_one_symbol) PARAMS ((struct bfd_link_info *, bfd *,
const char *, flagword, asection *,
bfd_vma, const char *, boolean,
boolean,
struct bfd_link_hash_entry **));
/* Called to handle linking a dynamic object. */
boolean (*link_dynamic_object) PARAMS ((struct bfd_link_info *, bfd *));
/* Called for each global symbol being written out by the linker.
This should write out the dynamic symbol information. */
boolean (*write_dynamic_symbol) PARAMS ((bfd *, struct bfd_link_info *,
struct aout_link_hash_entry *));
/* This callback is called by the linker for each reloc against an
external symbol. RELOC is a pointer to the unswapped reloc. If
*SKIP is set to true, the reloc will be skipped. */
boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *info,
bfd *input_bfd,
asection *input_section,
struct aout_link_hash_entry *h,
PTR reloc, boolean *skip));
/* Called at the end of a link to finish up any dynamic linking
information. */
boolean (*finish_dynamic_link) PARAMS ((bfd *, struct bfd_link_info *));
};
#define aout_backend_info(abfd) \
((CONST struct aout_backend_data *)((abfd)->xvec->backend_data))
@ -123,10 +203,15 @@ enum machine_type {
M_68020 = 2,
M_SPARC = 3,
/* skip a bunch so we don't run into any of suns numbers */
/* make these up for the ns32k*/
M_NS32032 = (64), /* ns32032 running ? */
M_NS32532 = (64 + 5), /* ns32532 running mach */
M_386 = 100,
M_29K = 101, /* AMD 29000 */
M_386_DYNIX = 102, /* Sequent running dynix */
M_386_NETBSD = 134, /* NetBSD/386 binary */
M_532_NETBSD = 137, /* MetBSD/523 binary */
M_MIPS1 = 151, /* MIPS R2000/R3000 binary */
M_MIPS2 = 152, /* MIPS R4000/R6000 binary */
M_HP200 = 200, /* HP 200 (68010) BSD binary */
@ -134,7 +219,7 @@ enum machine_type {
M_HPUX = (0x20c % 256)/* HP 200/300 HPUX binary */
};
#define N_DYNAMIC(exec) ((exec).a_info & 0x8000000)
#define N_DYNAMIC(exec) ((exec).a_info & 0x80000000)
#ifndef N_MAGIC
# define N_MAGIC(exec) ((exec).a_info & 0xffff)
@ -155,6 +240,12 @@ enum machine_type {
| (((flags) & 0xff) << 24))
#endif
#ifndef N_SET_DYNAMIC
# define N_SET_DYNAMIC(exec, dynamic) \
((exec).a_info = (dynamic) ? ((exec).a_info | 0x80000000) : \
((exec).a_info & 0x7fffffff))
#endif
#ifndef N_SET_MAGIC
# define N_SET_MAGIC(exec, magic) \
((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff)))
@ -209,19 +300,40 @@ struct aoutdata {
/* Segment size - needed for alignment of demand paged files. */
unsigned long segment_size;
/* Zmagic disk block size - need to align the start of the text
section in ZMAGIC binaries. Normally the same as page_size. */
unsigned long zmagic_disk_block_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
{
default_format = 0,
/* Used on HP 9000/300 running HP/UX. See hp300hpux.c. */
gnu_encap_format,
/* Used on Linux, 386BSD, etc. See include/aout/aout64.h. */
q_magic_format
} subformat;
enum {
undecided_magic = 0,
z_magic,
o_magic,
n_magic } magic;
enum
{
undecided_magic = 0,
z_magic,
o_magic,
n_magic
} magic;
/* The external symbol information. */
struct external_nlist *external_syms;
bfd_size_type external_sym_count;
char *external_strings;
bfd_size_type external_string_size;
struct aout_link_hash_entry **sym_hashes;
/* A pointer for shared library information. */
PTR dynamic_info;
};
struct aout_data_struct {
@ -240,27 +352,49 @@ struct aout_data_struct {
#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)
#define obj_aout_external_syms(bfd) (adata(bfd).external_syms)
#define obj_aout_external_sym_count(bfd) (adata(bfd).external_sym_count)
#define obj_aout_external_strings(bfd) (adata(bfd).external_strings)
#define obj_aout_external_string_size(bfd) (adata(bfd).external_string_size)
#define obj_aout_sym_hashes(bfd) (adata(bfd).sym_hashes)
#define obj_aout_dynamic_info(bfd) (adata(bfd).dynamic_info)
/* 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))
/* Information we keep for each a.out section. This is currently only
used by the a.out backend linker. */
struct aout_section_data_struct
{
/* The unswapped relocation entries for this section. */
PTR relocs;
};
#define aout_section_data(s) \
((struct aout_section_data_struct *) (s)->used_by_bfd)
/* Prototype declarations for functions defined in aoutx.h */
boolean
NAME(aout,squirt_out_relocs) PARAMS ((bfd *abfd, asection *section));
bfd_target *
boolean
NAME(aout,make_sections) PARAMS ((bfd *));
const bfd_target *
NAME(aout,some_aout_object_p) PARAMS ((bfd *abfd,
struct internal_exec *execp,
bfd_target * (*callback)(bfd *)));
struct internal_exec *execp,
const 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));
unsigned long machine,
boolean *unknown));
boolean
NAME(aout,set_arch_mach) PARAMS ((bfd *abfd, enum bfd_architecture arch,
@ -276,30 +410,44 @@ NAME(aout,set_section_contents) PARAMS ((bfd *abfd, sec_ptr section,
asymbol *
NAME(aout,make_empty_symbol) PARAMS ((bfd *abfd));
boolean
NAME(aout,translate_symbol_table) PARAMS ((bfd *, aout_symbol_type *,
struct external_nlist *,
bfd_size_type, char *,
bfd_size_type,
boolean dynamic));
boolean
NAME(aout,slurp_symbol_table) PARAMS ((bfd *abfd));
void
boolean
NAME(aout,write_syms) PARAMS ((bfd *abfd));
void
NAME(aout,reclaim_symbol_table) PARAMS ((bfd *abfd));
unsigned int
long
NAME(aout,get_symtab_upper_bound) PARAMS ((bfd *abfd));
unsigned int
long
NAME(aout,get_symtab) PARAMS ((bfd *abfd, asymbol **location));
void
NAME(aout,swap_ext_reloc_in) PARAMS ((bfd *, struct reloc_ext_external *,
arelent *, asymbol **));
void
NAME(aout,swap_std_reloc_in) PARAMS ((bfd *, struct reloc_std_external *,
arelent *, asymbol **));
boolean
NAME(aout,slurp_reloc_table) PARAMS ((bfd *abfd, sec_ptr asect,
asymbol **symbols));
unsigned int
long
NAME(aout,canonicalize_reloc) PARAMS ((bfd *abfd, sec_ptr section,
arelent **relptr, asymbol **symbols));
unsigned int
long
NAME(aout,get_reloc_upper_bound) PARAMS ((bfd *abfd, sec_ptr asect));
void
@ -316,9 +464,6 @@ 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,
@ -339,6 +484,31 @@ void
NAME(aout,swap_exec_header_out) PARAMS ((bfd *abfd,
struct internal_exec *execp, struct external_exec *raw_bytes));
struct bfd_hash_entry *
NAME(aout,link_hash_newfunc)
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
boolean
NAME(aout,link_hash_table_init)
PARAMS ((struct aout_link_hash_table *, bfd *,
struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
struct bfd_hash_table *,
const char *)));
struct bfd_link_hash_table *
NAME(aout,link_hash_table_create) PARAMS ((bfd *));
boolean
NAME(aout,link_add_symbols) PARAMS ((bfd *, struct bfd_link_info *));
boolean
NAME(aout,final_link) PARAMS ((bfd *, struct bfd_link_info *,
void (*) (bfd *, file_ptr *, file_ptr *,
file_ptr *)));
boolean
NAME(aout,bfd_free_cached_info) PARAMS ((bfd *));
/* Prototypes for functions in stab-syms.c. */
CONST char *
@ -346,15 +516,17 @@ 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_32_get_section_contents _bfd_generic_get_section_contents
#define aout_64_get_section_contents bfd_generic_get_section_contents
#define aout_64_close_and_cleanup bfd_generic_close_and_cleanup
#define aout_64_get_section_contents _bfd_generic_get_section_contents
#ifndef NO_WRITE_HEADER_KLUDGE
#define NO_WRITE_HEADER_KLUDGE 0
#endif
#ifndef aout_32_bfd_is_local_label
#define aout_32_bfd_is_local_label bfd_generic_is_local_label
#endif
#ifndef WRITE_HEADERS
#define WRITE_HEADERS(abfd, execp) \
{ \
@ -372,22 +544,35 @@ aout_stab_name PARAMS ((int code));
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); \
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) return false; \
if (bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) \
!= EXEC_BYTES_SIZE) \
return false; \
/* Now write out reloc info, followed by syms and strings */ \
\
if (bfd_get_symcount (abfd) != 0) \
if (bfd_get_outsymbols (abfd) != (asymbol **) NULL \
&& bfd_get_symcount (abfd) != 0) \
{ \
bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET); \
if (bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET) \
!= 0) \
return false; \
\
NAME(aout,write_syms)(abfd); \
if (! NAME(aout,write_syms)(abfd)) return false; \
\
bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET); \
if (bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET) \
!= 0) \
return false; \
\
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_textsec (abfd))) \
return false; \
if (bfd_seek (abfd, (file_ptr)(N_DRELOFF(*execp)), SEEK_SET) \
!= 0) \
return false; \
\
if (!NAME(aout,squirt_out_relocs)(abfd, obj_datasec (abfd))) return false; \
if (!NAME(aout,squirt_out_relocs)(abfd, obj_datasec (abfd))) \
return false; \
} \
}
#endif
#endif /* ! defined (LIBAOUT_H) */

View File

@ -1,5 +1,5 @@
/* Assorted BFD support routines, only used internally.
Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
Copyright 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@ -24,161 +24,151 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
SECTION
libbfd
Internal functions
DESCRIPTION
This file contains various routines which are used within BFD.
These routines 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;
}
/* A routine which is used in target vectors for unsupported
operations. */
/*ARGSUSED*/
boolean
DEFUN(bfd_false ,(ignore),
bfd *ignore)
bfd_false (ignore)
bfd *ignore;
{
bfd_set_error (bfd_error_invalid_operation);
return false;
}
/* A routine which is used in target vectors for supported operations
which do not actually do anything. */
/*ARGSUSED*/
boolean
DEFUN(bfd_true,(ignore),
bfd *ignore)
bfd_true (ignore)
bfd *ignore;
{
return true;
}
/* A routine which is used in target vectors for unsupported
operations which return a pointer value. */
/*ARGSUSED*/
PTR
DEFUN(bfd_nullvoidptr,(ignore),
bfd *ignore)
bfd_nullvoidptr (ignore)
bfd *ignore;
{
return (PTR)NULL;
bfd_set_error (bfd_error_invalid_operation);
return NULL;
}
/*ARGSUSED*/
int
DEFUN(bfd_0,(ignore),
bfd *ignore)
bfd_0 (ignore)
bfd *ignore;
{
return 0;
}
/*ARGSUSED*/
unsigned int
DEFUN(bfd_0u,(ignore),
bfd *ignore)
bfd_0u (ignore)
bfd *ignore;
{
return 0;
}
/*ARGUSED*/
long
bfd_0l (ignore)
bfd *ignore;
{
return 0;
}
/* A routine which is used in target vectors for unsupported
operations which return -1 on error. */
/*ARGSUSED*/
long
_bfd_n1 (ignore_abfd)
bfd *ignore_abfd;
{
bfd_set_error (bfd_error_invalid_operation);
return -1;
}
/*ARGSUSED*/
void
DEFUN(bfd_void,(ignore),
bfd *ignore)
bfd_void (ignore)
bfd *ignore;
{
}
/*ARGSUSED*/
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_nocore_core_file_matches_executable_p (ignore_core_bfd, ignore_exec_bfd)
bfd *ignore_core_bfd;
bfd *ignore_exec_bfd;
{
bfd_error = invalid_operation;
bfd_set_error (bfd_error_invalid_operation);
return false;
}
/* of course you can't initialize a function to be the same as another, grr */
/* Routine to handle core_file_failing_command entry point for targets
without core file support. */
/*ARGSUSED*/
char *
DEFUN(_bfd_dummy_core_file_failing_command,(ignore_abfd),
bfd *ignore_abfd)
_bfd_nocore_core_file_failing_command (ignore_abfd)
bfd *ignore_abfd;
{
bfd_set_error (bfd_error_invalid_operation);
return (char *)NULL;
}
/* Routine to handle core_file_failing_signal entry point for targets
without core file support. */
/*ARGSUSED*/
int
DEFUN(_bfd_dummy_core_file_failing_signal,(ignore_abfd),
bfd *ignore_abfd)
_bfd_nocore_core_file_failing_signal (ignore_abfd)
bfd *ignore_abfd;
{
bfd_set_error (bfd_error_invalid_operation);
return 0;
}
bfd_target *
DEFUN(_bfd_dummy_target,(ignore_abfd),
bfd *ignore_abfd)
/*ARGSUSED*/
const bfd_target *
_bfd_dummy_target (ignore_abfd)
bfd *ignore_abfd;
{
bfd_set_error (bfd_error_wrong_format);
return 0;
}
/** zalloc -- allocate and clear storage */
#ifndef bfd_zmalloc
/* allocate and clear storage */
#ifndef zalloc
char *
DEFUN(zalloc,(size),
bfd_size_type size)
bfd_zmalloc (size)
bfd_size_type size;
{
char *ptr = (char *) malloc ((size_t)size);
char *ptr = (char *) malloc ((size_t) size);
if ((ptr != NULL) && (size != 0))
memset(ptr,0, (size_t) size);
if (ptr && size)
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);
}
#endif /* bfd_zmalloc */
/* Some IO code */
@ -191,20 +181,25 @@ DEFUN(bfd_xmalloc_by_size_t, (size),
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)
int
real_read (where, a,b, file)
PTR where;
int a;
int b;
FILE *file;
{
return fread(where, a,b,file);
}
/* Return value is amount read (FIXME: how are errors and end of file dealt
with? We never call bfd_set_error, which is probably a mistake). */
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)
bfd_read (ptr, size, nitems, abfd)
PTR ptr;
bfd_size_type size;
bfd_size_type nitems;
bfd *abfd;
{
int nread;
nread = real_read (ptr, 1, (int)(size*nitems), bfd_cache_lookup(abfd));
@ -212,21 +207,45 @@ DEFUN(bfd_read,(ptr, size, nitems, abfd),
if (nread > 0)
abfd->where += nread;
#endif
/* Set bfd_error if we did not read as much data as we expected.
If the read failed due to an error set the bfd_error_system_call,
else set bfd_error_file_truncated.
A BFD backend may wish to override bfd_error_file_truncated to
provide something more useful (eg. no_symbols or wrong_format). */
if (nread < (int)(size * nitems))
{
if (ferror (bfd_cache_lookup (abfd)))
bfd_set_error (bfd_error_system_call);
else
bfd_set_error (bfd_error_file_truncated);
}
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)
bfd_write (ptr, size, nitems, abfd)
CONST PTR ptr;
bfd_size_type size;
bfd_size_type nitems;
bfd *abfd;
{
int nwrote = fwrite (ptr, 1, (int)(size*nitems), bfd_cache_lookup(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
if (nwrote != size * nitems)
{
#ifdef ENOSPC
if (nwrote >= 0)
errno = ENOSPC;
#endif
bfd_set_error (bfd_error_system_call);
}
return nwrote;
}
@ -238,24 +257,25 @@ 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
Write a 4 byte integer @var{i} to the output BFD @var{abfd}, in big
endian order 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_write_bigendian_4byte_int (abfd, i)
bfd *abfd;
int i;
{
bfd_byte buffer[4];
bfd_putb32(i, buffer);
bfd_write((PTR)buffer, 4, 1, abfd);
if (bfd_write((PTR)buffer, 4, 1, abfd) != 4)
abort ();
}
long
DEFUN(bfd_tell,(abfd),
bfd *abfd)
bfd_tell (abfd)
bfd *abfd;
{
file_ptr ptr;
@ -268,25 +288,28 @@ DEFUN(bfd_tell,(abfd),
}
int
DEFUN(bfd_flush,(abfd),
bfd *abfd)
bfd_flush (abfd)
bfd *abfd;
{
return fflush (bfd_cache_lookup(abfd));
}
int
DEFUN(bfd_stat,(abfd, statbuf),
bfd *abfd AND
struct stat *statbuf)
bfd_stat (abfd, statbuf)
bfd *abfd;
struct stat *statbuf;
{
return fstat (fileno(bfd_cache_lookup(abfd)), statbuf);
}
/* Returns 0 for success, nonzero for failure (in which case bfd_get_error
can retrieve the error code). */
int
DEFUN(bfd_seek,(abfd, position, direction),
bfd * CONST abfd AND
CONST file_ptr position AND
CONST int direction)
bfd_seek (abfd, position, direction)
bfd * CONST abfd;
CONST file_ptr position;
CONST int direction;
{
int result;
FILE *f;
@ -302,7 +325,7 @@ DEFUN(bfd_seek,(abfd, position, direction),
#ifdef FILE_OFFSET_IS_CHAR_INDEX
if (abfd->format != bfd_archive && abfd->my_archive == 0)
{
#ifndef NDEBUG
#if 0
/* 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'
@ -343,8 +366,11 @@ DEFUN(bfd_seek,(abfd, position, direction),
result = fseek (f, file_position, direction);
if (result != 0)
/* Force redetermination of `where' field. */
bfd_tell (abfd);
{
/* Force redetermination of `where' field. */
bfd_tell (abfd);
bfd_set_error (bfd_error_system_call);
}
else
{
#ifdef FILE_OFFSET_IS_CHAR_INDEX
@ -366,11 +392,11 @@ DEFUN(bfd_seek,(abfd, position, direction),
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)
bfd_add_to_string_table (table, new_string, table_length, free_ptr)
char **table;
char *new_string;
unsigned int *table_length;
char **free_ptr;
{
size_t string_length = strlen (new_string) + 1; /* include null here */
char *base = *table;
@ -379,13 +405,13 @@ DEFUN(bfd_add_to_string_table,(table, new_string, table_length, free_ptr),
if (base == NULL) {
/* Avoid a useless regrow if we can (but of course we still
take it next time */
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);
base = bfd_zmalloc ((bfd_size_type) space_length);
if (base == NULL) {
bfd_error = no_memory;
bfd_set_error (bfd_error_no_memory);
return false;
}
}
@ -397,7 +423,7 @@ DEFUN(bfd_add_to_string_table,(table, new_string, table_length, free_ptr),
base = (char *) realloc (base, space_length);
if (base == NULL) {
bfd_error = no_memory;
bfd_set_error (bfd_error_no_memory);
return false;
}
@ -435,22 +461,22 @@ DESCRIPTION
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.
around in macros---for example, @file{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
In the put routines, @var{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.
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)
. (*((unsigned char *)(ptr)) = (unsigned char)(val))
.#define bfd_put_signed_8 \
. bfd_put_8
.#define bfd_get_8(abfd, ptr) \
@ -490,15 +516,14 @@ DESCRIPTION
/*
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
bretheren, 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.
order and their data in little endian order.
.
.{* Byte swapping macros for file header data. *}
.
@ -543,91 +568,91 @@ DESCRIPTION
/* 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 EIGHT_GAZILLION (((BFD_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)
bfd_getb16 (addr)
register const bfd_byte *addr;
{
return (addr[0] << 8) | addr[1];
return (addr[0] << 8) | addr[1];
}
bfd_vma
DEFUN(bfd_getl16,(addr),
register bfd_byte *addr)
bfd_getl16 (addr)
register const bfd_byte *addr;
{
return (addr[1] << 8) | addr[0];
return (addr[1] << 8) | addr[0];
}
bfd_signed_vma
DEFUN(bfd_getb_signed_16,(addr),
register bfd_byte *addr)
bfd_getb_signed_16 (addr)
register const bfd_byte *addr;
{
return COERCE16((addr[0] << 8) | addr[1]);
return COERCE16((addr[0] << 8) | addr[1]);
}
bfd_signed_vma
DEFUN(bfd_getl_signed_16,(addr),
register bfd_byte *addr)
bfd_getl_signed_16 (addr)
register const bfd_byte *addr;
{
return COERCE16((addr[1] << 8) | addr[0]);
return COERCE16((addr[1] << 8) | addr[0]);
}
void
DEFUN(bfd_putb16,(data, addr),
bfd_vma data AND
register bfd_byte *addr)
bfd_putb16 (data, addr)
bfd_vma data;
register bfd_byte *addr;
{
addr[0] = (bfd_byte)(data >> 8);
addr[1] = (bfd_byte )data;
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)
bfd_putl16 (data, addr)
bfd_vma data;
register bfd_byte *addr;
{
addr[0] = (bfd_byte )data;
addr[1] = (bfd_byte)(data >> 8);
addr[0] = (bfd_byte )data;
addr[1] = (bfd_byte)(data >> 8);
}
bfd_vma
bfd_getb32 (addr)
register bfd_byte *addr;
register const bfd_byte *addr;
{
return (((((bfd_vma)addr[0] << 8) | addr[1]) << 8)
| addr[2]) << 8 | addr[3];
return (((((bfd_vma)addr[0] << 8) | addr[1]) << 8)
| addr[2]) << 8 | addr[3];
}
bfd_vma
bfd_getl32 (addr)
register bfd_byte *addr;
register const bfd_byte *addr;
{
return (((((bfd_vma)addr[3] << 8) | addr[2]) << 8)
| addr[1]) << 8 | addr[0];
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;
register const bfd_byte *addr;
{
return COERCE32((((((bfd_vma)addr[0] << 8) | addr[1]) << 8)
| addr[2]) << 8 | addr[3]);
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;
register const bfd_byte *addr;
{
return COERCE32((((((bfd_vma)addr[3] << 8) | addr[2]) << 8)
| addr[1]) << 8 | addr[0]);
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)
bfd_getb64 (addr)
register const bfd_byte *addr;
{
#ifdef BFD64
bfd_vma low, high;
@ -647,14 +672,12 @@ DEFUN(bfd_getb64,(addr),
BFD_FAIL();
return 0;
#endif
}
bfd_vma
DEFUN(bfd_getl64,(addr),
register bfd_byte *addr)
bfd_getl64 (addr)
register const bfd_byte *addr;
{
#ifdef BFD64
bfd_vma low, high;
high= (((((((addr[7] << 8) |
@ -676,8 +699,8 @@ DEFUN(bfd_getl64,(addr),
}
bfd_signed_vma
DEFUN(bfd_getb_signed_64,(addr),
register bfd_byte *addr)
bfd_getb_signed_64 (addr)
register const bfd_byte *addr;
{
#ifdef BFD64
bfd_vma low, high;
@ -697,14 +720,12 @@ DEFUN(bfd_getb_signed_64,(addr),
BFD_FAIL();
return 0;
#endif
}
bfd_signed_vma
DEFUN(bfd_getl_signed_64,(addr),
register bfd_byte *addr)
bfd_getl_signed_64 (addr)
register const bfd_byte *addr;
{
#ifdef BFD64
bfd_vma low, high;
high= (((((((addr[7] << 8) |
@ -722,13 +743,12 @@ DEFUN(bfd_getl_signed_64,(addr),
BFD_FAIL();
return 0;
#endif
}
void
DEFUN(bfd_putb32,(data, addr),
bfd_vma data AND
register bfd_byte *addr)
bfd_putb32 (data, addr)
bfd_vma data;
register bfd_byte *addr;
{
addr[0] = (bfd_byte)(data >> 24);
addr[1] = (bfd_byte)(data >> 16);
@ -737,19 +757,20 @@ DEFUN(bfd_putb32,(data, addr),
}
void
DEFUN(bfd_putl32,(data, addr),
bfd_vma data AND
register bfd_byte *addr)
bfd_putl32 (data, addr)
bfd_vma data;
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)
bfd_putb64 (data, addr)
bfd_vma data;
register bfd_byte *addr;
{
#ifdef BFD64
addr[0] = (bfd_byte)(data >> (7*8));
@ -763,13 +784,12 @@ DEFUN(bfd_putb64,(data, addr),
#else
BFD_FAIL();
#endif
}
void
DEFUN(bfd_putl64,(data, addr),
bfd_vma data AND
register bfd_byte *addr)
bfd_putl64 (data, addr)
bfd_vma data;
register bfd_byte *addr;
{
#ifdef BFD64
addr[7] = (bfd_byte)(data >> (7*8));
@ -783,19 +803,17 @@ DEFUN(bfd_putl64,(data, addr),
#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)
_bfd_generic_get_section_contents (abfd, section, location, offset, count)
bfd *abfd;
sec_ptr section;
PTR location;
file_ptr offset;
bfd_size_type count;
{
if (count == 0)
return true;
@ -811,32 +829,33 @@ DEFUN(bfd_generic_get_section_contents, (abfd, section, location, offset, count)
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)
_bfd_generic_set_section_contents (abfd, section, location, offset, count)
bfd *abfd;
sec_ptr section;
PTR location;
file_ptr offset;
bfd_size_type count;
{
if (count == 0)
return true;
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);
if (count == 0)
return true;
if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) == -1
|| bfd_write (location, (bfd_size_type) 1, count, abfd) != count)
return false;
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);
DESCRIPTION
Return the log base 2 of the value supplied, rounded up. E.g., an
@var{x} of 1025 returns 11.
*/
unsigned
@ -848,3 +867,14 @@ bfd_log2(x)
result++;
return result;
}
boolean
bfd_generic_is_local_label (abfd, sym)
bfd *abfd;
asymbol *sym;
{
char locals_prefix = (bfd_get_symbol_leading_char (abfd) == '_') ? 'L' : '.';
return (sym->name[0] == locals_prefix);
}

View File

@ -1,8 +1,12 @@
/* 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.
Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
Written by Cygnus Support.
** NOTE: libbfd.h is a GENERATED file. Don't change it; instead,
** change libbfd-in.h or the other BFD source files processed to
** generate this file.
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
@ -19,7 +23,6 @@ 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. */
/* 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) \
@ -44,7 +47,8 @@ struct artdata {
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.
/* when more compilers are standard C, this can be a time_t */
long armap_timestamp; /* Timestamp value written into armap.
This is used for BSD archives to check
that the timestamp is recent enough
for the BSD linker to not complain,
@ -52,6 +56,7 @@ struct artdata {
archive. */
file_ptr armap_datepos; /* Position within archive to seek to
rewrite the date field. */
PTR tdata; /* Backend specific information. */
};
#define bfd_ardata(bfd) ((bfd)->tdata.aout_ar_data)
@ -65,14 +70,14 @@ struct areltdata {
#define arelt_size(bfd) (((struct areltdata *)((bfd)->arelt_data))->parsed_size)
char *zalloc PARAMS ((bfd_size_type size));
char *bfd_zmalloc 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));
PTR bfd_realloc PARAMS ((bfd *abfd, PTR orig, size_t size));
void bfd_alloc_grow PARAMS ((bfd *abfd, PTR thing, size_t size));
PTR bfd_alloc_finish PARAMS ((bfd *abfd));
PTR bfd_alloc_by_size_t PARAMS ((bfd *abfd, size_t wanted));
@ -92,17 +97,19 @@ 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));
bfd * _bfd_look_for_bfd_in_cache PARAMS ((bfd *arch_bfd, file_ptr index));
boolean _bfd_add_bfd_to_archive_cache PARAMS ((bfd *, file_ptr, bfd *));
boolean _bfd_generic_mkarchive PARAMS ((bfd *abfd));
struct areltdata * snarf_ar_hdr PARAMS ((bfd *abfd));
bfd_target * bfd_generic_archive_p PARAMS ((bfd *abfd));
struct areltdata *_bfd_snarf_ar_hdr PARAMS ((bfd *abfd));
const bfd_target *bfd_generic_archive_p PARAMS ((bfd *abfd));
boolean bfd_slurp_armap PARAMS ((bfd *abfd));
boolean bfd_slurp_bsd_armap_f2 PARAMS ((bfd *abfd));
#define bfd_slurp_bsd_armap bfd_slurp_armap
#define bfd_slurp_coff_armap bfd_slurp_armap
boolean _bfd_slurp_extended_name_table PARAMS ((bfd *abfd));
boolean _bfd_write_archive_contents PARAMS ((bfd *abfd));
bfd * new_bfd PARAMS (());
bfd *_bfd_get_elt_at_filepos PARAMS ((bfd *archive, file_ptr filepos));
bfd * _bfd_new_bfd PARAMS ((void));
#define DEFAULT_STRING_SPACE_SIZE 0x2000
boolean bfd_add_to_string_table PARAMS ((char **table, char *new_string,
@ -114,15 +121,12 @@ boolean bfd_true PARAMS ((bfd *ignore));
PTR bfd_nullvoidptr PARAMS ((bfd *ignore));
int bfd_0 PARAMS ((bfd *ignore));
unsigned int bfd_0u PARAMS ((bfd *ignore));
long bfd_0l PARAMS ((bfd *ignore));
long _bfd_n1 PARAMS ((bfd *ignore));
void bfd_void PARAMS ((bfd *ignore));
bfd * 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));
bfd *_bfd_new_bfd_contained_in PARAMS ((bfd *));
const bfd_target *_bfd_dummy_target PARAMS ((bfd *abfd));
void bfd_dont_truncate_arname PARAMS ((bfd *abfd, CONST char *filename,
char *hdr));
@ -142,14 +146,230 @@ bfd * bfd_generic_openr_next_archived_file PARAMS ((bfd *archive,
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));
/* Generic routines to use for BFD_JUMP_TABLE_GENERIC. Use
BFD_JUMP_TABLE_GENERIC (_bfd_generic). */
boolean bfd_generic_set_section_contents PARAMS ((bfd *abfd, sec_ptr section,
PTR location, file_ptr offset,
bfd_size_type count));
#define _bfd_generic_close_and_cleanup bfd_true
#define _bfd_generic_bfd_free_cached_info bfd_true
#define _bfd_generic_new_section_hook \
((boolean (*) PARAMS ((bfd *, asection *))) bfd_true)
extern boolean _bfd_generic_get_section_contents
PARAMS ((bfd *, asection *, PTR location, file_ptr offset,
bfd_size_type count));
/* Generic routines to use for BFD_JUMP_TABLE_COPY. Use
BFD_JUMP_TABLE_COPY (_bfd_generic). */
#define _bfd_generic_bfd_copy_private_bfd_data \
((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true)
#define _bfd_generic_bfd_copy_private_section_data \
((boolean (*) PARAMS ((bfd *, asection *, bfd *, asection *))) bfd_true)
/* Routines to use for BFD_JUMP_TABLE_CORE when there is no core file
support. Use BFD_JUMP_TABLE_CORE (_bfd_nocore). */
extern char *_bfd_nocore_core_file_failing_command PARAMS ((bfd *));
extern int _bfd_nocore_core_file_failing_signal PARAMS ((bfd *));
extern boolean _bfd_nocore_core_file_matches_executable_p
PARAMS ((bfd *, bfd *));
/* Routines to use for BFD_JUMP_TABLE_ARCHIVE when there is no archive
file support. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive). */
#define _bfd_noarchive_slurp_armap bfd_false
#define _bfd_noarchive_slurp_extended_name_table bfd_false
#define _bfd_noarchive_truncate_arname \
((void (*) PARAMS ((bfd *, const char *, char *))) bfd_void)
#define _bfd_noarchive_write_armap \
((boolean (*) \
PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \
bfd_false)
#define _bfd_noarchive_openr_next_archived_file \
((bfd *(*) PARAMS ((bfd *, bfd *))) bfd_nullvoidptr)
#define _bfd_noarchive_generic_stat_arch_elt bfd_generic_stat_arch_elt
/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get BSD style
archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd). */
#define _bfd_archive_bsd_slurp_armap bfd_slurp_bsd_armap
#define _bfd_archive_bsd_slurp_extended_name_table \
_bfd_slurp_extended_name_table
#define _bfd_archive_bsd_truncate_arname bfd_bsd_truncate_arname
#define _bfd_archive_bsd_write_armap bsd_write_armap
#define _bfd_archive_bsd_openr_next_archived_file \
bfd_generic_openr_next_archived_file
#define _bfd_archive_bsd_generic_stat_arch_elt \
bfd_generic_stat_arch_elt
/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get COFF style
archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff). */
#define _bfd_archive_coff_slurp_armap bfd_slurp_coff_armap
#define _bfd_archive_coff_slurp_extended_name_table \
_bfd_slurp_extended_name_table
#define _bfd_archive_coff_truncate_arname bfd_dont_truncate_arname
#define _bfd_archive_coff_write_armap coff_write_armap
#define _bfd_archive_coff_openr_next_archived_file \
bfd_generic_openr_next_archived_file
#define _bfd_archive_coff_generic_stat_arch_elt \
bfd_generic_stat_arch_elt
/* Routines to use for BFD_JUMP_TABLE_SYMBOLS where there is no symbol
support. Use BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols). */
#define _bfd_nosymbols_get_symtab_upper_bound _bfd_n1
#define _bfd_nosymbols_get_symtab \
((long (*) PARAMS ((bfd *, asymbol **))) _bfd_n1)
#define _bfd_nosymbols_make_empty_symbol \
((asymbol *(*) PARAMS ((bfd *))) bfd_nullvoidptr)
#define _bfd_nosymbols_print_symbol \
((void (*) PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type))) bfd_void)
#define _bfd_nosymbols_get_symbol_info \
((void (*) PARAMS ((bfd *, asymbol *, symbol_info *))) bfd_void)
#define _bfd_nosymbols_bfd_is_local_label \
((boolean (*) PARAMS ((bfd *, asymbol *))) bfd_false)
#define _bfd_nosymbols_get_lineno \
((alent *(*) PARAMS ((bfd *, asymbol *))) bfd_nullvoidptr)
#define _bfd_nosymbols_find_nearest_line \
((boolean (*) \
PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **, \
const char **, unsigned int *))) \
bfd_false)
#define _bfd_nosymbols_bfd_make_debug_symbol \
((asymbol *(*) PARAMS ((bfd *, PTR, unsigned long))) bfd_nullvoidptr)
/* Routines to use for BFD_JUMP_TABLE_RELOCS when there is no reloc
support. Use BFD_JUMP_TABLE_RELOCS (_bfd_norelocs). */
#define _bfd_norelocs_get_reloc_upper_bound \
((long (*) PARAMS ((bfd *, asection *))) _bfd_n1)
#define _bfd_norelocs_canonicalize_reloc \
((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) _bfd_n1)
#define _bfd_norelocs_bfd_reloc_type_lookup \
((const reloc_howto_type *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) \
bfd_nullvoidptr)
/* Routines to use for BFD_JUMP_TABLE_WRITE for targets which may not
be written. Use BFD_JUMP_TABLE_WRITE (_bfd_nowrite). */
#define _bfd_nowrite_set_arch_mach \
((boolean (*) PARAMS ((bfd *, enum bfd_architecture, unsigned long))) \
bfd_false)
#define _bfd_nowrite_set_section_contents \
((boolean (*) PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type))) \
bfd_false)
/* Generic routines to use for BFD_JUMP_TABLE_WRITE. Use
BFD_JUMP_TABLE_WRITE (_bfd_generic). */
#define _bfd_generic_set_arch_mach bfd_default_set_arch_mach
extern boolean _bfd_generic_set_section_contents
PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
/* Routines to use for BFD_JUMP_TABLE_LINK for targets which do not
support linking. Use BFD_JUMP_TABLE_LINK (_bfd_nolink). */
#define _bfd_nolink_sizeof_headers ((int (*) PARAMS ((bfd *, boolean))) bfd_0)
#define _bfd_nolink_bfd_get_relocated_section_contents \
((bfd_byte *(*) \
PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, \
bfd_byte *, boolean, asymbol **))) \
bfd_nullvoidptr)
#define _bfd_nolink_bfd_relax_section \
((boolean (*) \
PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *))) \
bfd_false)
#define _bfd_nolink_bfd_link_hash_table_create \
((struct bfd_link_hash_table *(*) PARAMS ((bfd *))) bfd_nullvoidptr)
#define _bfd_nolink_bfd_link_add_symbols \
((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
#define _bfd_nolink_bfd_final_link \
((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false)
/* Routines to use for BFD_JUMP_TABLE_DYNAMIC for targets which do not
have dynamic symbols or relocs. Use BFD_JUMP_TABLE_DYNAMIC
(_bfd_nodynamic). */
#define _bfd_nodynamic_get_dynamic_symtab_upper_bound _bfd_n1
#define _bfd_nodynamic_canonicalize_dynamic_symtab \
((long (*) PARAMS ((bfd *, asymbol **))) _bfd_n1)
#define _bfd_nodynamic_get_dynamic_reloc_upper_bound _bfd_n1
#define _bfd_nodynamic_canonicalize_dynamic_reloc \
((long (*) PARAMS ((bfd *, arelent **, asymbol **))) _bfd_n1)
/* Generic routine to determine of the given symbol is a local
label. */
extern boolean bfd_generic_is_local_label PARAMS ((bfd *, asymbol *));
/* A routine to create entries for a bfd_link_hash_table. */
extern struct bfd_hash_entry *_bfd_link_hash_newfunc
PARAMS ((struct bfd_hash_entry *entry,
struct bfd_hash_table *table,
const char *string));
/* Initialize a bfd_link_hash_table. */
extern boolean _bfd_link_hash_table_init
PARAMS ((struct bfd_link_hash_table *, bfd *,
struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
struct bfd_hash_table *,
const char *)));
/* Generic link hash table creation routine. */
extern struct bfd_link_hash_table *_bfd_generic_link_hash_table_create
PARAMS ((bfd *));
/* Generic add symbol routine. */
extern boolean _bfd_generic_link_add_symbols
PARAMS ((bfd *, struct bfd_link_info *));
/* Generic add symbol routine. This version is used by targets for
which the linker must collect constructors and destructors by name,
as the collect2 program does. */
extern boolean _bfd_generic_link_add_symbols_collect
PARAMS ((bfd *, struct bfd_link_info *));
/* Generic archive add symbol routine. */
extern boolean _bfd_generic_link_add_archive_symbols
PARAMS ((bfd *, struct bfd_link_info *,
boolean (*checkfn) (bfd *, struct bfd_link_info *, boolean *)));
/* Forward declaration to avoid prototype errors. */
typedef struct bfd_link_hash_entry _bfd_link_hash_entry;
/* Generic routine to add a single symbol. */
extern boolean _bfd_generic_link_add_one_symbol
PARAMS ((struct bfd_link_info *, bfd *, const char *name, flagword,
asection *, bfd_vma, const char *, boolean copy,
boolean constructor, struct bfd_link_hash_entry **));
/* Generic link routine. */
extern boolean _bfd_generic_final_link
PARAMS ((bfd *, struct bfd_link_info *));
/* Generic reloc_link_order processing routine. */
extern boolean _bfd_generic_reloc_link_order
PARAMS ((bfd *, struct bfd_link_info *, asection *,
struct bfd_link_order *));
/* Default link order processing routine. */
extern boolean _bfd_default_link_order
PARAMS ((bfd *, struct bfd_link_info *, asection *,
struct bfd_link_order *));
/* Count the number of reloc entries in a link order list. */
extern unsigned int _bfd_count_link_order_relocs
PARAMS ((struct bfd_link_order *));
/* Final link relocation routine. */
extern bfd_reloc_status_type _bfd_final_link_relocate
PARAMS ((const reloc_howto_type *, bfd *, asection *, bfd_byte *,
bfd_vma address, bfd_vma value, bfd_vma addend));
/* Relocate a particular location by a howto and a value. */
extern bfd_reloc_status_type _bfd_relocate_contents
PARAMS ((const reloc_howto_type *, bfd *, bfd_vma, bfd_byte *));
/* Macros to tell if bfds are read or write enabled.
Note that bfds open for read may be scribbled into if the fd passed
@ -183,20 +403,16 @@ extern bfd *bfd_last_cache;
#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
/* List of supported target vectors, and the default vector (if
bfd_default_vector[0] is NULL, there is no default). */
extern const bfd_target * const bfd_target_vector[];
extern const bfd_target * const bfd_default_vector[];
/* 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));
@ -211,42 +427,41 @@ extern bfd *bfd_last_cache;
(FILE*)(bfd_last_cache->iostream): \
bfd_cache_lookup_worker(x))
boolean
bfd_cache_close PARAMS ((bfd *));
bfd_cache_init PARAMS ((bfd *abfd));
boolean
bfd_cache_close PARAMS ((bfd *abfd));
FILE*
bfd_open_file PARAMS ((bfd *));
bfd_open_file PARAMS ((bfd *abfd));
FILE *
bfd_cache_lookup_worker PARAMS ((bfd *));
bfd_cache_lookup_worker PARAMS ((bfd *abfd));
void
boolean
bfd_constructor_entry PARAMS ((bfd *abfd,
asymbol **symbol_ptr_ptr,
CONST char*type));
CONST struct reloc_howto_struct *
const struct reloc_howto_struct *
bfd_default_reloc_type_lookup
PARAMS ((bfd *abfd AND
bfd_reloc_code_real_type code));
PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
boolean
bfd_generic_relax_section
PARAMS ((bfd *abfd,
asection *section,
asymbol **symbols));
struct bfd_link_info *,
boolean *));
bfd_byte *
bfd_generic_get_relocated_section_contents PARAMS ((bfd *abfd,
struct bfd_seclet *seclet,
struct bfd_link_info *link_info,
struct bfd_link_order *link_order,
bfd_byte *data,
boolean relocateable));
boolean
bfd_generic_seclet_link
PARAMS ((bfd *abfd,
PTR data,
boolean relocateable));
boolean relocateable,
asymbol **symbols));
extern bfd_arch_info_type bfd_default_arch_struct;
boolean
@ -254,11 +469,11 @@ bfd_default_set_arch_mach PARAMS ((bfd *abfd,
enum bfd_architecture arch,
unsigned long mach));
void
void
bfd_arch_init PARAMS ((void));
void
bfd_arch_linkin PARAMS ((bfd_arch_info_type *));
bfd_arch_linkin PARAMS ((bfd_arch_info_type *ptr));
CONST bfd_arch_info_type *
bfd_default_compatible
@ -266,7 +481,7 @@ bfd_default_compatible
CONST bfd_arch_info_type *b));
boolean
bfd_default_scan PARAMS ((CONST struct bfd_arch_info *, CONST char *));
bfd_default_scan PARAMS ((CONST struct bfd_arch_info *info, CONST char *string));
struct elf_internal_shdr *
bfd_elf_find_section PARAMS ((bfd *abfd, char *name));

View File

@ -1,5 +1,5 @@
/* BFD COFF object file private structure.
Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@ -75,20 +75,20 @@ typedef struct coff_tdata
#define coffsymbol(asymbol) ((coff_symbol_type *)(&((asymbol)->the_bfd)))
/* Functions in coffgen.c. */
extern bfd_target *coff_object_p PARAMS ((bfd *));
extern const 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 long coff_get_symtab_upper_bound PARAMS ((bfd *));
extern long coff_get_symtab PARAMS ((bfd *, asymbol **));
extern int coff_count_linenumbers PARAMS ((bfd *));
extern struct coff_symbol_struct *coff_symbol_from PARAMS ((bfd *, asymbol *));
extern void coff_renumber_symbols PARAMS ((bfd *));
extern boolean 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 boolean coff_write_symbols PARAMS ((bfd *));
extern boolean coff_write_linenumbers PARAMS ((bfd *));
extern alent *coff_get_lineno PARAMS ((bfd *, asymbol *));
extern asymbol *coff_section_symbol PARAMS ((bfd *, char *));
extern struct coff_ptr_struct *coff_get_normalized_symtab PARAMS ((bfd *));
extern unsigned int coff_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
extern long coff_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
extern asymbol *coff_make_empty_symbol PARAMS ((bfd *));
extern void coff_print_symbol PARAMS ((bfd *, PTR filep, asymbol *,
bfd_print_symbol_type how));
@ -104,30 +104,42 @@ extern boolean coff_find_nearest_line PARAMS ((bfd *,
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 boolean bfd_coff_reloc16_relax_section
PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *));
extern bfd_byte *bfd_coff_reloc16_get_relocated_section_contents
PARAMS ((bfd *, struct bfd_seclet *, bfd_byte *, boolean relocateable));
PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *,
bfd_byte *, boolean relocateable, asymbol **));
extern bfd_vma bfd_coff_reloc16_get_value PARAMS ((arelent *,
struct bfd_seclet *));
struct bfd_link_info *,
asection *));
extern void bfd_perform_slip PARAMS ((bfd *abfd, unsigned int slip,
asection *input_section,
bfd_vma val));
/* And more taken from the source .. */
typedef struct coff_ptr_struct
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 value of this symbol be renumbered. Used for
XCOFF C_BSTAT symbols. Set by coff_slurp_symbol_table. */
unsigned int fix_value : 1;
/* Should the tag field of this symbol be renumbered.
Created by coff_pointerize_aux. */
char fix_tag;
unsigned int fix_tag : 1;
/* Should the endidx field of this symbol be renumbered.
Created by coff_pointerize_aux. */
char fix_end;
unsigned int fix_end : 1;
/* Should the x_csect.x_scnlen field be renumbered.
Created by coff_slurp_symbol_table. */
unsigned int fix_scnlen : 1;
/* The container for the symbol structure as read and translated
from the file. */
@ -155,13 +167,15 @@ struct lineno_cache_entry *lineno;
/* Have the line numbers been relocated yet ? */
boolean done_lineno;
} coff_symbol_type;
typedef struct
typedef struct
{
void (*_bfd_coff_swap_aux_in) PARAMS ((
bfd *abfd ,
bfd *abfd,
PTR ext,
int type,
int class ,
int class,
int indaux,
int numaux,
PTR in));
void (*_bfd_coff_swap_sym_in) PARAMS ((
@ -179,6 +193,8 @@ typedef struct
PTR in,
int type,
int class,
int indaux,
int numaux,
PTR ext));
unsigned int (*_bfd_coff_swap_sym_out) PARAMS ((
@ -257,23 +273,25 @@ typedef struct
struct internal_syment *sym));
void (*_bfd_coff_reloc16_extra_cases) PARAMS ((
bfd *abfd,
struct bfd_seclet *seclet,
struct bfd_link_info *link_info,
struct bfd_link_order *link_order,
arelent *reloc,
bfd_byte *data,
unsigned int *src_ptr,
unsigned int *dst_ptr));
int (*_bfd_coff_reloc16_estimate) PARAMS ((
bfd *abfd,
asection *input_section,
asymbol **symbols,
arelent *r,
unsigned int shrink));
unsigned int shrink,
struct bfd_link_info *link_info));
} 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_aux_in(a,e,t,c,ind,num,i) \
((coff_backend_info (a)->_bfd_coff_swap_aux_in) (a,e,t,c,ind,num,i))
#define bfd_coff_swap_sym_in(a,e,i) \
((coff_backend_info (a)->_bfd_coff_swap_sym_in) (a,e,i))
@ -287,8 +305,8 @@ typedef struct
#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_aux_out(a,i,t,c,ind,num,o) \
((coff_backend_info (a)->_bfd_coff_swap_aux_out) (a,i,t,c,ind,num,o))
#define bfd_coff_swap_sym_out(abfd, i,o) \
((coff_backend_info (abfd)->_bfd_coff_swap_sym_out) (abfd, i, o))
@ -341,12 +359,11 @@ typedef struct
#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)\
#define bfd_coff_reloc16_extra_cases(abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)\
((coff_backend_info (abfd)->_bfd_coff_reloc16_extra_cases)\
(abfd, seclet, reloc, data, src_ptr, dst_ptr))
(abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr))
#define bfd_coff_reloc16_estimate(abfd, section, symbols, reloc, shrink)\
#define bfd_coff_reloc16_estimate(abfd, section, reloc, shrink, link_info)\
((coff_backend_info (abfd)->_bfd_coff_reloc16_estimate)\
(section, symbols, reloc, shrink))
(abfd, section, reloc, shrink, link_info))

View File

@ -18,6 +18,12 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "bfdlink.h"
#ifndef ECOFF_H
#include "coff/ecoff.h"
#endif
/* 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
@ -32,57 +38,36 @@ struct ecoff_backend_data
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;
/* True if the .rdata section is part of the text segment, as on the
Alpha. False if .rdata is part of the data segment, as on the
MIPS. */
boolean rdata_in_text;
/* 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. */
/* How to swap debugging information. */
struct ecoff_debug_swap debug_swap;
/* 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 *));
void (*adjust_reloc_in) PARAMS ((bfd *, const struct internal_reloc *,
arelent *));
void (*adjust_reloc_out) PARAMS ((bfd *, const arelent *,
struct internal_reloc *));
/* Relocate section contents while linking. */
boolean (*relocate_section) PARAMS ((bfd *output_bfd, struct bfd_link_info *,
bfd *input_bfd, asection *input_section,
bfd_byte *contents,
PTR external_relocs));
};
/* This is the target specific information kept for ECOFF files. */
@ -95,7 +80,7 @@ typedef struct ecoff_tdata
ecoff_compute_section_file_positions. */
file_ptr reloc_filepos;
/* The symbol table file position, set by ecoff_mkobject_hook. */
/* The symbol table file position, set by _bfd_ecoff_mkobject_hook. */
file_ptr sym_filepos;
/* The start and end of the text segment. Only valid for an
@ -119,38 +104,26 @@ typedef struct ecoff_tdata
unsigned long fprmask;
unsigned long cprmask[4];
/* The size of the unswapped ECOFF symbolic information. */
bfd_size_type raw_size;
/* The ECOFF symbolic debugging information. */
struct ecoff_debug_info debug_info;
/* 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;
/* A mapping from external symbol numbers to entries in the linker
hash table, used when linking. */
struct ecoff_link_hash_entry **sym_hashes;
/* A mapping from reloc symbol indices to sections, used when
linking. */
asection **symndx_to_section;
/* True if this BFD was written by the backend linker. */
boolean linker;
} ecoff_data_type;
/* Each canonical asymbol really looks like this. */
@ -182,84 +155,143 @@ typedef struct ecoff_symbol_struct
#define ecoff_get_sym_index(symbol) ((unsigned long) (symbol)->udata)
#define ecoff_set_sym_index(symbol, idx) ((symbol)->udata = (PTR) (idx))
/* When generating MIPS embedded PIC code, the linker relaxes the code
to turn PC relative branches into longer code sequences when the PC
relative branch is out of range. This involves reading the relocs
in bfd_relax_section as well as in bfd_final_link, and requires the
code to keep track of which relocs have been expanded. A pointer
to this structure is put in the used_by_bfd pointer of a section to
keep track of this information. The user_by_bfd pointer will be
NULL if the information was not needed. */
struct ecoff_section_tdata
{
/* The unswapped relocs for this section. These are stored in
memory so the input file does not have to be read twice. */
PTR external_relocs;
/* The contents of the section. These bytes may or may not be saved
in memory, but if it is this is a pointer to them. */
bfd_byte *contents;
/* Offset adjustments for PC relative branches. A number other than
1 is an addend for a PC relative branch, or a switch table entry
which is the difference of two .text locations; this addend
arises because the branch or difference crosses one or more
branches which were expanded into a larger code sequence. A 1
means that this branch was itself expanded into a larger code
sequence. 1 is not a possible offset, since all offsets must be
multiples of the instruction size, which is 4; also, the only
relocs with non-zero offsets will be PC relative branches or
switch table entries within the same object file. If this field
is NULL, no branches were expanded and no offsets are required.
Otherwise there are as many entries as there are relocs in the
section, and the entry for any reloc that is not PC relative is
zero. */
long *offsets;
};
/* An accessor macro for the ecoff_section_tdata structure. */
#define ecoff_section_data(abfd, sec) \
((struct ecoff_section_tdata *) (sec)->used_by_bfd)
/* ECOFF linker hash table entries. */
struct ecoff_link_hash_entry
{
struct bfd_link_hash_entry root;
/* Symbol index in output file. */
long indx;
/* BFD that ext field value came from. */
bfd *abfd;
/* ECOFF external symbol information. */
EXTR esym;
/* Nonzero if this symbol has been written out. */
char written;
/* Nonzero if this symbol was referred to as small undefined. */
char small;
};
/* ECOFF linker hash table. */
struct ecoff_link_hash_table
{
struct bfd_link_hash_table root;
};
/* Make an ECOFF object. */
extern boolean ecoff_mkobject PARAMS ((bfd *));
extern boolean _bfd_ecoff_mkobject PARAMS ((bfd *));
/* Read in the ECOFF symbolic debugging information. */
extern boolean ecoff_slurp_symbolic_info PARAMS ((bfd *));
extern boolean _bfd_ecoff_slurp_symbolic_info
PARAMS ((bfd *, asection *, struct ecoff_debug_info *));
/* 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)
extern boolean _bfd_ecoff_write_object_contents PARAMS ((bfd *abfd));
extern const bfd_target *_bfd_ecoff_archive_p PARAMS ((bfd *abfd));
#define _bfd_ecoff_close_and_cleanup _bfd_generic_close_and_cleanup
#define _bfd_ecoff_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
extern boolean _bfd_ecoff_new_section_hook
PARAMS ((bfd *, asection *));
extern boolean _bfd_ecoff_get_section_contents
PARAMS ((bfd *, asection *, PTR location, file_ptr, bfd_size_type));
extern boolean _bfd_ecoff_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *));
#define _bfd_ecoff_bfd_copy_private_section_data \
_bfd_generic_bfd_copy_private_section_data
extern boolean _bfd_ecoff_slurp_armap PARAMS ((bfd *abfd));
#define _bfd_ecoff_slurp_extended_name_table _bfd_slurp_extended_name_table
#define _bfd_ecoff_truncate_arname bfd_dont_truncate_arname
extern boolean _bfd_ecoff_write_armap
PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
#define _bfd_ecoff_openr_next_archived_file \
bfd_generic_openr_next_archived_file
#define _bfd_ecoff_generic_stat_arch_elt bfd_generic_stat_arch_elt
extern long _bfd_ecoff_get_symtab_upper_bound PARAMS ((bfd *abfd));
extern long _bfd_ecoff_get_symtab PARAMS ((bfd *abfd, asymbol **alocation));
extern asymbol *_bfd_ecoff_make_empty_symbol PARAMS ((bfd *abfd));
extern void _bfd_ecoff_print_symbol
PARAMS ((bfd *, PTR filep, asymbol *, bfd_print_symbol_type));
extern void _bfd_ecoff_get_symbol_info
PARAMS ((bfd *, asymbol *, symbol_info *));
#define _bfd_ecoff_bfd_is_local_label bfd_generic_is_local_label
#define _bfd_ecoff_get_lineno _bfd_nosymbols_get_lineno
extern boolean _bfd_ecoff_find_nearest_line
PARAMS ((bfd *, asection *, asymbol **, bfd_vma offset,
const char **filename_ptr, const char **fnname_ptr,
unsigned int *retline_ptr));
#define _bfd_ecoff_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
#define _bfd_ecoff_get_reloc_upper_bound coff_get_reloc_upper_bound
extern long _bfd_ecoff_canonicalize_reloc
PARAMS ((bfd *, asection *, arelent **, asymbol **symbols));
/* ecoff_bfd_reloc_type_lookup defined by backend. */
extern boolean _bfd_ecoff_set_arch_mach
PARAMS ((bfd *, enum bfd_architecture, unsigned long machine));
extern boolean _bfd_ecoff_set_section_contents
PARAMS ((bfd *, asection *, PTR location, file_ptr, bfd_size_type));
extern int _bfd_ecoff_sizeof_headers PARAMS ((bfd *abfd, boolean reloc));
/* ecoff_bfd_get_relocated_section_contents defined by backend. */
/* ecoff_bfd_relax_section defined by backend. */
extern struct bfd_link_hash_table *_bfd_ecoff_bfd_link_hash_table_create
PARAMS ((bfd *));
extern boolean _bfd_ecoff_bfd_link_add_symbols
PARAMS ((bfd *, struct bfd_link_info *));
extern boolean _bfd_ecoff_bfd_final_link
PARAMS ((bfd *, struct bfd_link_info *));
/* 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 \
extern PTR _bfd_ecoff_mkobject_hook PARAMS ((bfd *, PTR filehdr, PTR aouthdr));
extern asection *_bfd_ecoff_make_section_hook PARAMS ((bfd *abfd, char *name));
#define _bfd_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));
extern boolean _bfd_ecoff_set_arch_mach_hook PARAMS ((bfd *abfd, PTR filehdr));
extern flagword _bfd_ecoff_styp_to_sec_flags PARAMS ((bfd *abfd, PTR hdr));
extern boolean _bfd_ecoff_slurp_symbol_table PARAMS ((bfd *abfd));

View File

@ -24,6 +24,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "elf/common.h"
#include "elf/internal.h"
#include "elf/external.h"
#include "bfdlink.h"
/* If size isn't specified as 64 or 32, NAME macro should fail. */
#ifndef NAME
@ -42,36 +43,331 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define ElfNAME(X) NAME(Elf,X)
#define elfNAME(X) NAME(elf,X)
/* Information held for an ELF symbol. The first field is the
corresponding asymbol. Every symbol is an ELF file is actually a
pointer to this structure, although it is often handled as a
pointer to an asymbol. */
typedef struct
{
/* The BFD symbol. */
asymbol symbol;
/* ELF symbol information. */
Elf_Internal_Sym internal_elf_sym;
/* Backend specific information. */
union
{
unsigned int hppa_arg_reloc;
PTR mips_extr;
PTR any;
}
tc_data;
} elf_symbol_type;
/* ELF linker hash table entries. */
struct elf_link_hash_entry
{
struct bfd_link_hash_entry root;
/* Symbol index in output file. This is initialized to -1. It is
set to -2 if the symbol is used by a reloc. */
long indx;
/* Symbol size. */
bfd_size_type size;
/* Symbol alignment (common symbols only). */
bfd_size_type align;
/* Symbol index as a dynamic symbol. Initialized to -1, and remains
-1 if this is not a dynamic symbol. */
long dynindx;
/* String table index in .dynstr if this is a dynamic symbol. */
unsigned long dynstr_index;
/* If this is a weak defined symbol from a dynamic object, this
field points to a defined symbol with the same value, if there is
one. Otherwise it is NULL. */
struct elf_link_hash_entry *weakdef;
/* Symbol type (STT_NOTYPE, STT_OBJECT, etc.). */
char type;
/* Some flags; legal values follow. */
unsigned char elf_link_hash_flags;
/* Symbol is referenced by a non-shared object. */
#define ELF_LINK_HASH_REF_REGULAR 01
/* Symbol is defined by a non-shared object. */
#define ELF_LINK_HASH_DEF_REGULAR 02
/* Symbol is referenced by a shared object. */
#define ELF_LINK_HASH_REF_DYNAMIC 04
/* Symbol is defined by a shared object. */
#define ELF_LINK_HASH_DEF_DYNAMIC 010
/* Symbol is referenced by two or more shared objects. */
#define ELF_LINK_HASH_REF_DYNAMIC_MULTIPLE 020
/* Symbol is defined by two or more shared objects. */
#define ELF_LINK_HASH_DEF_DYNAMIC_MULTIPLE 040
/* Dynamic symbol has been adjustd. */
#define ELF_LINK_HASH_DYNAMIC_ADJUSTED 0100
/* Symbol is defined as weak. */
#define ELF_LINK_HASH_DEFINED_WEAK 0200
};
/* ELF linker hash table. */
struct elf_link_hash_table
{
struct bfd_link_hash_table root;
/* The first dynamic object found during a link. We create several
special input sections when linking against dynamic objects, and
we simply attach them to the first one found. */
bfd *dynobj;
/* The number of symbols found in the link which must be put into
the .dynsym section. */
size_t dynsymcount;
/* The string table of dynamic symbols, which becomes the .dynstr
section. */
struct strtab *dynstr;
/* The number of buckets in the hash table in the .hash section.
This is based on the number of dynamic symbols. */
size_t bucketcount;
};
/* Look up an entry in an ELF linker hash table. */
#define elf_link_hash_lookup(table, string, create, copy, follow) \
((struct elf_link_hash_entry *) \
bfd_link_hash_lookup (&(table)->root, (string), (create), \
(copy), (follow)))
/* Traverse an ELF linker hash table. */
#define elf_link_hash_traverse(table, func, info) \
(bfd_link_hash_traverse \
(&(table)->root, \
(boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \
(info)))
/* Get the ELF linker hash table from a link_info structure. */
#define elf_hash_table(p) ((struct elf_link_hash_table *) ((p)->hash))
/* Constant information held for an ELF backend. */
struct elf_backend_data
{
/* Whether the backend uses REL or RELA relocations. FIXME: some
ELF backends use both. When we need to support one, this whole
approach will need to be changed. */
int use_rela_p;
/* Whether this backend is 64 bits or not. FIXME: Who cares? */
int elf_64_p;
/* The architecture for this backend. */
enum bfd_architecture arch;
/* The ELF machine code (EM_xxxx) for this backend. */
int elf_machine_code;
/* The maximum page size for this backend. */
bfd_vma maxpagesize;
/* This is true if the linker should act like collect and gather
global constructors and destructors by name. This is true for
MIPS ELF because the Irix 5 tools can not handle the .init
section. */
boolean collect;
/* A function to translate an ELF RELA relocation to a BFD arelent
structure. */
void (*elf_info_to_howto) PARAMS ((bfd *, arelent *,
Elf_Internal_Rela *));
/* A function to translate an ELF REL relocation to a BFD arelent
structure. */
void (*elf_info_to_howto_rel) PARAMS ((bfd *, arelent *,
Elf_Internal_Rel *));
bfd_vma maxpagesize;
void (*write_relocs) PARAMS ((bfd *, asection *, PTR));
/* A function to determine whether a symbol is global when
partitioning the symbol table into local and global symbols.
This should be NULL for most targets, in which case the correct
thing will be done. MIPS ELF, at least on the Irix 5, has
special requirements. */
boolean (*elf_backend_sym_is_global) PARAMS ((bfd *, asymbol *));
/* The remaining functions are hooks which are called only if they
are not NULL. */
/* A function to permit a backend specific check on whether a
particular BFD format is relevant for an object file, and to
permit the backend to set any global information it wishes. When
this is called elf_elfheader is set, but anything else should be
used with caution. If this returns false, the check_format
routine will return a bfd_error_wrong_format error. */
boolean (*elf_backend_object_p) PARAMS ((bfd *));
/* A function to do additional symbol processing when reading the
ELF symbol table. This is where any processor-specific special
section indices are handled. */
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 *));
/* A function to do additional symbol processing after reading the
entire ELF symbol table. */
boolean (*elf_backend_symbol_table_processing) PARAMS ((bfd *,
elf_symbol_type *,
int));
/* A function to do additional processing on the ELF section header
just before writing it out. This is used to set the flags and
type fields for some sections, or to actually write out data for
unusual sections. */
boolean (*elf_backend_section_processing) PARAMS ((bfd *,
Elf32_Internal_Shdr *));
/* A function to handle unusual section types when creating BFD
sections from ELF sections. */
boolean (*elf_backend_section_from_shdr) PARAMS ((bfd *,
Elf32_Internal_Shdr *,
char *));
/* A function to set up the ELF section header for a BFD section in
preparation for writing it out. This is where the flags and type
fields are set for unusual sections. */
boolean (*elf_backend_fake_sections) PARAMS ((bfd *, Elf32_Internal_Shdr *,
asection *));
/* A function to get the ELF section index for a BFD section. If
this returns true, the section was found. If it is a normal ELF
section, *RETVAL should be left unchanged. If it is not a normal
ELF section *RETVAL should be set to the SHN_xxxx index. */
boolean (*elf_backend_section_from_bfd_section)
PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *, int *retval));
/* If this field is not NULL, it is called by the add_symbols phase
of a link just before adding a symbol to the global linker hash
table. It may modify any of the fields as it wishes. If *NAME
is set to NULL, the symbol will be skipped rather than being
added to the hash table. This function is responsible for
handling all processor dependent symbol bindings and section
indices, and must set at least *FLAGS and *SEC for each processor
dependent case; failure to do so will cause a link error. */
boolean (*elf_add_symbol_hook)
PARAMS ((bfd *abfd, struct bfd_link_info *info,
const Elf_Internal_Sym *, const char **name,
flagword *flags, asection **sec, bfd_vma *value));
/* If this field is not NULL, it is called by the elf_link_output_sym
phase of a link for each symbol which will appear in the object file. */
boolean (*elf_backend_link_output_symbol_hook)
PARAMS ((bfd *, struct bfd_link_info *info, const char *,
Elf_Internal_Sym *, asection *));
/* The CREATE_DYNAMIC_SECTIONS function is called by the ELF backend
linker the first time it encounters a dynamic object in the link.
This function must create any sections required for dynamic
linking. The ABFD argument is a dynamic object. The .interp,
.dynamic, .dynsym, .dynstr, and .hash functions have already been
created, and this function may modify the section flags if
desired. This function will normally create the .got and .plt
sections, but different backends have different requirements. */
boolean (*elf_backend_create_dynamic_sections)
PARAMS ((bfd *abfd, struct bfd_link_info *info));
/* The ADJUST_DYNAMIC_SYMBOL function is called by the ELF backend
linker for every symbol which is defined by a dynamic object and
referenced by a regular object. This is called after all the
input files have been seen, but before the SIZE_DYNAMIC_SECTIONS
function has been called. The hash table entry should be
bfd_link_hash_defined, and it should be defined in a section from
a dynamic object. Dynamic object sections are not included in
the final link, and this function is responsible for changing the
value to something which the rest of the link can deal with.
This will normally involve adding an entry to the .plt or .got or
some such section, and setting the symbol to point to that. */
boolean (*elf_backend_adjust_dynamic_symbol)
PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
/* The SIZE_DYNAMIC_SECTIONS function is called by the ELF backend
linker after all the linker input files have been seen but before
the sections sizes have been set. This is called after
ADJUST_DYNAMIC_SYMBOL has been called on all appropriate symbols.
It is only called when linking against a dynamic object. It must
set the sizes of the dynamic sections, and may fill in their
contents as well. The generic ELF linker can handle the .dynsym,
.dynstr and .hash sections. This function must handle the
.interp section and any sections created by the
CREATE_DYNAMIC_SECTIONS entry point. */
boolean (*elf_backend_size_dynamic_sections)
PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
/* The RELOCATE_SECTION function is called by the ELF backend linker
to handle the relocations for a section.
The relocs are always passed as Rela structures; if the section
actually uses Rel structures, the r_addend field will always be
zero.
This function is responsible for adjust the section contents as
necessary, and (if using Rela relocs and generating a
relocateable output file) adjusting the reloc addend as
necessary.
This function does not have to worry about setting the reloc
address or the reloc symbol index.
LOCAL_SYMS is a pointer to the swapped in local symbols.
LOCAL_SECTIONS is an array giving the section in the input file
corresponding to the st_shndx field of each local symbol.
The global hash table entry for the global symbols can be found
via elf_sym_hashes (input_bfd).
When generating relocateable output, this function must handle
STB_LOCAL/STT_SECTION symbols specially. The output symbol is
going to be the section symbol corresponding to the output
section, which means that the addend must be adjusted
accordingly. */
boolean (*elf_backend_relocate_section)
PARAMS ((bfd *output_bfd, struct bfd_link_info *info,
bfd *input_bfd, asection *input_section, bfd_byte *contents,
Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
asection **local_sections, char *output_names));
/* The FINISH_DYNAMIC_SYMBOL function is called by the ELF backend
linker just before it writes a symbol out to the .dynsym section.
The processor backend may make any required adjustment to the
symbol. It may also take the opportunity to set contents of the
dynamic sections. Note that FINISH_DYNAMIC_SYMBOL is called on
all .dynsym symbols, while ADJUST_DYNAMIC_SYMBOL is only called
on those symbols which are defined by a dynamic object. */
boolean (*elf_backend_finish_dynamic_symbol)
PARAMS ((bfd *output_bfd, struct bfd_link_info *info,
struct elf_link_hash_entry *h, Elf_Internal_Sym *sym));
/* The FINISH_DYNAMIC_SECTIONS function is called by the ELF backend
linker just before it writes all the dynamic sections out to the
output file. The FINISH_DYNAMIC_SYMBOL will have been called on
all dynamic symbols. */
boolean (*elf_backend_finish_dynamic_sections)
PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
/* A function to do any beginning processing needed for the ELF file
before building the ELF headers and computing file positions. */
void (*elf_backend_begin_write_processing)
PARAMS ((bfd *, struct bfd_link_info *));
/* A function to do any final processing needed for the ELF file
before writing it out. */
void (*elf_backend_final_write_processing)
PARAMS ((bfd *, struct bfd_link_info *));
/* The swapping table to use when dealing with ECOFF information.
Used for the MIPS ELF .mdebug section. */
const struct ecoff_debug_swap *elf_backend_ecoff_debug_swap;
};
struct elf_sym_extra
@ -81,21 +377,29 @@ struct elf_sym_extra
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;
/* Information stored for each BFD section in an ELF file. This
structure is allocated by elf_new_section_hook. */
struct bfd_elf_section_data {
/* The ELF header for this section. */
Elf_Internal_Shdr this_hdr;
/* The ELF header for the reloc section associated with this
section, if any. */
Elf_Internal_Shdr rel_hdr;
int this_idx, rel_idx;
/* The ELF section number of this section. Only used for an output
file. */
int this_idx;
/* The ELF section number of the reloc section associated with this
section, if any. Only used for an output file. */
int rel_idx;
/* Used by the backend linker to store the symbol hash table entries
associated with relocs against global symbols. */
struct elf_link_hash_entry **rel_hashes;
/* A pointer to the unswapped external relocs; this may be NULL. */
PTR relocs;
};
#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)
@ -118,20 +422,38 @@ struct elf_obj_tdata
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;
Elf_Internal_Shdr dynsymtab_hdr;
Elf_Internal_Shdr dynstrtab_hdr;
int symtab_section, shstrtab_section, strtab_section, dynsymtab_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) */
/* A mapping from external symbols to entries in the linker hash
table, used when linking. This is indexed by the symbol index
minus the sh_info field of the symbol table header. */
struct elf_link_hash_entry **sym_hashes;
/* The linker ELF emulation code needs to let the backend ELF linker
know what filename should be used for a dynamic object if the
dynamic object is found using a search. This field is used to
hold that information. */
const char *dt_needed_name;
/* Irix 5 often screws up the symbol table, sorting local symbols
after global symbols. This flag is set if the symbol table in
this BFD appears to be screwed up. If it is, we ignore the
sh_info field in the symbol table header, and always read all the
symbols. */
boolean bad_symtab;
};
#define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data)
@ -139,6 +461,7 @@ struct elf_obj_tdata
#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_dynsymtab(bfd) (elf_tdata(bfd) -> dynsymtab_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)
@ -146,11 +469,12 @@ struct elf_obj_tdata
#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)
#define elf_sym_hashes(bfd) (elf_tdata(bfd) -> sym_hashes)
#define elf_dt_needed_name(bfd) (elf_tdata(bfd) -> dt_needed_name)
#define elf_bad_symtab(bfd) (elf_tdata(bfd) -> bad_symtab)
extern char * elf_string_from_elf_section PARAMS ((bfd *, unsigned, unsigned));
extern char * elf_get_str_section PARAMS ((bfd *, unsigned));
@ -165,15 +489,27 @@ extern bfd_reloc_status_type bfd_elf_generic_reloc PARAMS ((bfd *,
asymbol *,
PTR,
asection *,
bfd *));
bfd *,
char **));
extern boolean bfd_elf_mkobject PARAMS ((bfd *));
extern Elf_Internal_Shdr *bfd_elf_find_section PARAMS ((bfd *, char *));
extern boolean _bfd_elf_make_section_from_shdr
PARAMS ((bfd *abfd, Elf_Internal_Shdr *hdr, const char *name));
extern struct bfd_hash_entry *_bfd_elf_link_hash_newfunc
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
extern struct bfd_link_hash_table *_bfd_elf_link_hash_table_create
PARAMS ((bfd *));
extern boolean _bfd_elf_link_hash_table_init
PARAMS ((struct elf_link_hash_table *, bfd *,
struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
struct bfd_hash_table *,
const 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 const bfd_target *bfd_elf32_object_p PARAMS ((bfd *));
extern const 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 *,
@ -182,12 +518,13 @@ 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 long bfd_elf32_get_symtab_upper_bound PARAMS ((bfd *));
extern long bfd_elf32_get_symtab PARAMS ((bfd *, asymbol **));
extern long bfd_elf32_get_dynamic_symtab_upper_bound PARAMS ((bfd *));
extern long bfd_elf32_canonicalize_dynamic_symtab PARAMS ((bfd *, asymbol **));
extern long bfd_elf32_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
extern long 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));
@ -204,13 +541,36 @@ extern boolean bfd_elf32_find_nearest_line PARAMS ((bfd *, asection *,
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 *));
extern boolean bfd_elf32_bfd_link_add_symbols
PARAMS ((bfd *, struct bfd_link_info *));
extern boolean bfd_elf32_bfd_final_link
PARAMS ((bfd *, struct bfd_link_info *));
extern void bfd_elf32_swap_symbol_in
PARAMS ((bfd *, Elf32_External_Sym *, Elf_Internal_Sym *));
extern void bfd_elf32_swap_symbol_out
PARAMS ((bfd *, Elf_Internal_Sym *, Elf32_External_Sym *));
extern void bfd_elf32_swap_reloc_in
PARAMS ((bfd *, Elf32_External_Rel *, Elf_Internal_Rel *));
extern void bfd_elf32_swap_reloc_out
PARAMS ((bfd *, Elf_Internal_Rel *, Elf32_External_Rel *));
extern void bfd_elf32_swap_reloca_in
PARAMS ((bfd *, Elf32_External_Rela *, Elf_Internal_Rela *));
extern void bfd_elf32_swap_reloca_out
PARAMS ((bfd *, Elf_Internal_Rela *, Elf32_External_Rela *));
extern void bfd_elf32_swap_dyn_in
PARAMS ((bfd *, const Elf32_External_Dyn *, Elf_Internal_Dyn *));
extern void bfd_elf32_swap_dyn_out
PARAMS ((bfd *, const Elf_Internal_Dyn *, Elf32_External_Dyn *));
extern boolean bfd_elf32_add_dynamic_entry
PARAMS ((struct bfd_link_info *, bfd_vma, bfd_vma));
/* 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 const bfd_target *bfd_elf64_object_p PARAMS ((bfd *));
extern const 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 *,
@ -219,12 +579,13 @@ 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 long bfd_elf64_get_symtab_upper_bound PARAMS ((bfd *));
extern long bfd_elf64_get_symtab PARAMS ((bfd *, asymbol **));
extern long bfd_elf64_get_dynamic_symtab_upper_bound PARAMS ((bfd *));
extern long bfd_elf64_canonicalize_dynamic_symtab PARAMS ((bfd *, asymbol **));
extern long bfd_elf64_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr));
extern long 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));
@ -241,6 +602,29 @@ extern boolean bfd_elf64_find_nearest_line PARAMS ((bfd *, asection *,
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 *));
extern boolean bfd_elf64_bfd_link_add_symbols
PARAMS ((bfd *, struct bfd_link_info *));
extern boolean bfd_elf64_bfd_final_link
PARAMS ((bfd *, struct bfd_link_info *));
extern void bfd_elf64_swap_symbol_in
PARAMS ((bfd *, Elf64_External_Sym *, Elf_Internal_Sym *));
extern void bfd_elf64_swap_symbol_out
PARAMS ((bfd *, Elf_Internal_Sym *, Elf64_External_Sym *));
extern void bfd_elf64_swap_reloc_in
PARAMS ((bfd *, Elf64_External_Rel *, Elf_Internal_Rel *));
extern void bfd_elf64_swap_reloc_out
PARAMS ((bfd *, Elf_Internal_Rel *, Elf64_External_Rel *));
extern void bfd_elf64_swap_reloca_in
PARAMS ((bfd *, Elf64_External_Rela *, Elf_Internal_Rela *));
extern void bfd_elf64_swap_reloca_out
PARAMS ((bfd *, Elf_Internal_Rela *, Elf64_External_Rela *));
extern void bfd_elf64_swap_dyn_in
PARAMS ((bfd *, const Elf64_External_Dyn *, Elf_Internal_Dyn *));
extern void bfd_elf64_swap_dyn_out
PARAMS ((bfd *, const Elf_Internal_Dyn *, Elf64_External_Dyn *));
extern boolean bfd_elf64_add_dynamic_entry
PARAMS ((struct bfd_link_info *, bfd_vma, bfd_vma));
/* If the target doesn't have reloc handling written yet: */
extern void bfd_elf64_no_info_to_howto PARAMS ((bfd *, arelent *,

View File

@ -1,5 +1,5 @@
/* opncls.c -- open and close a BFD.
Copyright (C) 1990-1991 Free Software Foundation, Inc.
Copyright (C) 1990 91, 92, 93, 94 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@ -22,29 +22,34 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#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_alloc malloc
#define obstack_chunk_free free
/* Return a new BFD. All BFD's are allocated through this routine. */
bfd *
new_bfd PARAMS ((void))
_bfd_new_bfd ()
{
bfd *nbfd;
nbfd = (bfd *)zalloc (sizeof (bfd));
nbfd = (bfd *)bfd_zmalloc (sizeof (bfd));
if (!nbfd)
return 0;
{
bfd_set_error (bfd_error_no_memory);
return 0;
}
bfd_check_init();
obstack_begin((PTR)&nbfd->memory, 128);
if (!obstack_begin(&nbfd->memory, 128))
{
bfd_set_error (bfd_error_no_memory);
return 0;
}
nbfd->arch_info = &bfd_default_arch_struct;
@ -69,12 +74,12 @@ new_bfd PARAMS ((void))
/* Allocate a new BFD as a member of archive OBFD. */
bfd *
new_bfd_contained_in (obfd)
_bfd_new_bfd_contained_in (obfd)
bfd *obfd;
{
bfd *nbfd;
nbfd = new_bfd();
nbfd = _bfd_new_bfd();
nbfd->xvec = obfd->xvec;
nbfd->my_archive = obfd;
nbfd->direction = read_direction;
@ -84,7 +89,7 @@ new_bfd_contained_in (obfd)
/*
SECTION
Opening and Closing BFDs
Opening and closing BFDs
*/
@ -93,33 +98,36 @@ FUNCTION
bfd_openr
SYNOPSIS
bfd *bfd_openr(CONST char *filename, CONST char*target);
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.
Open the file @var{filename} (using <<fopen>>) with the target
@var{target}. Return 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.
Calls <<bfd_find_target>>, so @var{target} is interpreted as by
that function.
If <<NULL>> is returned then an error has occured. Possible errors
are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or <<system_call>> error.
*/
bfd *
DEFUN(bfd_openr, (filename, target),
CONST char *filename AND
CONST char *target)
bfd_openr (filename, target)
CONST char *filename;
CONST char *target;
{
bfd *nbfd;
bfd_target *target_vec;
const bfd_target *target_vec;
nbfd = new_bfd();
nbfd = _bfd_new_bfd();
if (nbfd == NULL) {
bfd_error = no_memory;
bfd_set_error (bfd_error_no_memory);
return NULL;
}
target_vec = bfd_find_target (target, nbfd);
if (target_vec == NULL) {
bfd_error = invalid_target;
bfd_set_error (bfd_error_invalid_target);
return NULL;
}
@ -127,7 +135,7 @@ DEFUN(bfd_openr, (filename, target),
nbfd->direction = read_direction;
if (bfd_open_file (nbfd) == NULL) {
bfd_error = system_call_error; /* File didn't exist, or some such */
bfd_set_error (bfd_error_system_call); /* File didn't exist, or some such */
bfd_release(nbfd,0);
return NULL;
}
@ -151,36 +159,35 @@ 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.
<<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.
When the file is later <<bfd_close>>d, 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
file descriptor (but subject to closure at any time), call
bfd_set_cacheable(bfd, 1) on 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
<<bfd_close>>, and will not be affected by BFD operations on other
files.
Possible errors are no_memory, invalid_target and system_call
error.
Possible errors are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
*/
bfd *
DEFUN(bfd_fdopenr,(filename, target, fd),
CONST char *filename AND
CONST char *target AND
int fd)
bfd_fdopenr (filename, target, fd)
CONST char *filename;
CONST char *target;
int fd;
{
bfd *nbfd;
bfd_target *target_vec;
const bfd_target *target_vec;
int fdflags;
bfd_error = system_call_error;
bfd_set_error (bfd_error_system_call);
#ifdef NO_FCNTL
fdflags = O_RDWR; /* Assume full access */
@ -189,16 +196,16 @@ DEFUN(bfd_fdopenr,(filename, target, fd),
#endif
if (fdflags == -1) return NULL;
nbfd = new_bfd();
nbfd = _bfd_new_bfd();
if (nbfd == NULL) {
bfd_error = no_memory;
bfd_set_error (bfd_error_no_memory);
return NULL;
}
target_vec = bfd_find_target (target, nbfd);
if (target_vec == NULL) {
bfd_error = invalid_target;
bfd_set_error (bfd_error_invalid_target);
return NULL;
}
#if defined(VMS) || defined(__GO32__)
@ -232,7 +239,8 @@ DEFUN(bfd_fdopenr,(filename, target, fd),
default: abort ();
}
bfd_cache_init (nbfd);
if (! bfd_cache_init (nbfd))
return NULL;
return nbfd;
}
@ -250,29 +258,29 @@ 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.
Create a BFD, associated with file @var{filename}, using the
file format @var{target}, and return a pointer to it.
Possible errors are system_call_error, no_memory,
invalid_target.
Possible errors are <<bfd_error_system_call>>, <<bfd_error_no_memory>>,
<<bfd_error_invalid_target>>.
*/
bfd *
DEFUN(bfd_openw,(filename, target),
CONST char *filename AND
CONST char *target)
bfd_openw (filename, target)
CONST char *filename;
CONST char *target;
{
bfd *nbfd;
bfd_target *target_vec;
const bfd_target *target_vec;
bfd_error = system_call_error;
bfd_set_error (bfd_error_system_call);
/* nbfd has to point to head of malloc'ed block so that bfd_close may
reclaim it correctly. */
nbfd = new_bfd();
nbfd = _bfd_new_bfd();
if (nbfd == NULL) {
bfd_error = no_memory;
bfd_set_error (bfd_error_no_memory);
return NULL;
}
@ -283,7 +291,7 @@ DEFUN(bfd_openw,(filename, target),
nbfd->direction = write_direction;
if (bfd_open_file (nbfd) == NULL) {
bfd_error = system_call_error; /* File not writeable, etc */
bfd_set_error (bfd_error_system_call); /* File not writeable, etc */
(void) obstack_free (&nbfd->memory, (PTR)0);
return NULL;
}
@ -296,11 +304,11 @@ FUNCTION
bfd_close
SYNOPSIS
boolean bfd_close(bfd *);
boolean bfd_close(bfd *abfd);
DESCRIPTION
This function closes a BFD. If the BFD was open for writing,
Close 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.
@ -308,7 +316,7 @@ DESCRIPTION
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).
if it was passed in to BFD by <<bfd_fdopenr>>).
RETURNS
<<true>> is returned if all is ok, otherwise <<false>>.
@ -316,8 +324,8 @@ RETURNS
boolean
DEFUN(bfd_close,(abfd),
bfd *abfd)
bfd_close (abfd)
bfd *abfd;
{
boolean ret;
@ -361,7 +369,7 @@ SYNOPSIS
boolean bfd_close_all_done(bfd *);
DESCRIPTION
This function closes a BFD. It differs from <<bfd_close>>
Close a BFD. 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.
@ -377,8 +385,8 @@ RETURNS
*/
boolean
DEFUN(bfd_close_all_done,(abfd),
bfd *abfd)
bfd_close_all_done (abfd)
bfd *abfd;
{
boolean ret;
@ -417,14 +425,13 @@ SYNOPSIS
bfd_size_type bfd_alloc_size(bfd *abfd);
DESCRIPTION
Return the number of bytes in the obstacks connected to the
supplied BFD.
Return the number of bytes in the obstacks connected to @var{abfd}.
*/
bfd_size_type
DEFUN(bfd_alloc_size,(abfd),
bfd *abfd)
bfd_alloc_size (abfd)
bfd *abfd;
{
struct _obstack_chunk *chunk = abfd->memory.chunk;
size_t size = 0;
@ -445,7 +452,7 @@ SYNOPSIS
bfd *bfd_create(CONST char *filename, bfd *templ);
DESCRIPTION
This routine creates a new BFD in the manner of
Create 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>>.
@ -453,13 +460,13 @@ DESCRIPTION
*/
bfd *
DEFUN(bfd_create,(filename, templ),
CONST char *filename AND
bfd *templ)
bfd_create (filename, templ)
CONST char *filename;
bfd *templ;
{
bfd *nbfd = new_bfd();
bfd *nbfd = _bfd_new_bfd();
if (nbfd == (bfd *)NULL) {
bfd_error = no_memory;
bfd_set_error (bfd_error_no_memory);
return (bfd *)NULL;
}
nbfd->filename = filename;
@ -479,56 +486,63 @@ 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.
Allocate a block of @var{wanted} bytes of memory in the obstack
attatched to <<abfd>> and return a pointer to it.
*/
PTR
DEFUN(bfd_alloc_by_size_t,(abfd, size),
bfd *abfd AND
size_t size)
bfd_alloc_by_size_t (abfd, size)
bfd *abfd;
size_t size;
{
PTR res = obstack_alloc(&(abfd->memory), size);
return res;
return obstack_alloc(&(abfd->memory), size);
}
DEFUN(void bfd_alloc_grow,(abfd, ptr, size),
bfd *abfd AND
PTR ptr AND
size_t size)
void
bfd_alloc_grow (abfd, ptr, size)
bfd *abfd;
PTR ptr;
size_t size;
{
(void) obstack_grow(&(abfd->memory), ptr, size);
}
DEFUN(PTR bfd_alloc_finish,(abfd),
bfd *abfd)
PTR
bfd_alloc_finish (abfd)
bfd *abfd;
{
return obstack_finish(&(abfd->memory));
}
DEFUN(PTR bfd_alloc, (abfd, size),
bfd *abfd AND
size_t size)
PTR
bfd_alloc (abfd, size)
bfd *abfd;
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
bfd_zalloc (abfd, size)
bfd *abfd;
size_t size;
{
PTR res;
res = bfd_alloc(abfd, size);
memset(res, 0, (size_t)size);
if (res)
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
bfd_realloc (abfd, old, size)
bfd *abfd;
PTR old;
size_t size;
{
PTR res = bfd_alloc(abfd, size);
memcpy(res, old, (size_t)size);
if (res)
memcpy(res, old, (size_t)size);
return res;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* Table of stab names for the BFD library.
Copyright (C) 1990-1991 Free Software Foundation, Inc.
Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "bfd.h"
#define ARCH_SIZE 32 /* Value doesn't matter. */
#define ARCH_SIZE 32 /* Value doesn't matter. */
#include "libaout.h"
#include "aout/aout64.h"
@ -28,30 +28,35 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#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[]
= {
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")
};
__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)
aout_stab_name (code)
int code;
{
register int i = sizeof(aout_stab_names) / sizeof(aout_stab_names[0]);
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;

View File

@ -22,20 +22,20 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
SECTION
Symbols
BFD trys to maintain as much symbol information as it can when
BFD tries 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
format. To maintain more than the information 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
understand. If a coff symbol table were read, but were 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
@ -43,8 +43,8 @@ SECTION
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.
like the linker to output a symbol as it was read, since the ``behind
the scenes'' information will be still available.
@menu
@* Reading Symbols::
@* Writing Symbols::
@ -55,57 +55,63 @@ SECTION
INODE
Reading Symbols, Writing Symbols, Symbols, Symbols
SUBSECTION
Reading Symbols
Reading symbols
There are two stages to reading a symbol table from a BFD;
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:
excerpt from an application which reads the symbol table:
| unsigned int storage_needed;
| long storage_needed;
| asymbol **symbol_table;
| unsigned int number_of_symbols;
| unsigned int i;
|
| storage_needed = get_symtab_upper_bound (abfd);
|
| long number_of_symbols;
| long i;
|
| storage_needed = bfd_get_symtab_upper_bound (abfd);
|
| if (storage_needed < 0)
| FAIL
|
| if (storage_needed == 0) {
| return ;
| }
| symbol_table = (asymbol **) bfd_xmalloc (storage_needed);
| symbol_table = (asymbol **) xmalloc (storage_needed);
| ...
| number_of_symbols =
| bfd_canonicalize_symtab (abfd, symbol_table);
|
| number_of_symbols =
| bfd_canonicalize_symtab (abfd, symbol_table);
|
| if (number_of_symbols < 0)
| FAIL
|
| 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.
connected to the BFD; it is freed when the BFD is closed.
INODE
Writing Symbols, typedef asymbol, Reading Symbols, Symbols
SUBSECTION
Writing Symbols
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
operations. The BFD output 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>>. Here is an
example showing the creation of a symbol table with only one element:
| #include "bfd.h"
| main()
| 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);
@ -113,23 +119,23 @@ SUBSECTION
| 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
|
| ./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
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.
be described.
*/
@ -153,7 +159,7 @@ SUBSECTION
CODE_FRAGMENT
.
.typedef struct symbol_cache_entry
.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
@ -167,7 +173,7 @@ CODE_FRAGMENT
.
. 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
. {* The text of the symbol. The name is left alone, and not copied; the
. application may not alter it. *}
. CONST char *name;
.
@ -188,7 +194,7 @@ CODE_FRAGMENT
. 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 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 *}
.
@ -249,9 +255,12 @@ CODE_FRAGMENT
. for ELF STT_FILE symbols. *}
.#define BSF_FILE 0x4000
.
. {* Symbol is from dynamic linking information. *}
.#define BSF_DYNAMIC 0x8000
.
. flagword flags;
.
. {* A pointer to the section to which this symbol is
. {* 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;
@ -268,39 +277,53 @@ CODE_FRAGMENT
#include "libbfd.h"
#include "aout/stab_gnu.h"
/*
DOCDD
INODE
symbol handling functions, , typedef asymbol, Symbols
SUBSECTION
Symbol Handling Functions
Symbol handling functions
*/
/*
FUNCTION
get_symtab_upper_bound
bfd_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,
Return the number of bytes required to store a vector of pointers
to <<asymbols>> for all the symbols in the BFD @var{abfd},
including a terminal NULL pointer. If there are no symbols in
the BFD, then 0 is returned.
the BFD, then return 0. If an error occurs, return -1.
.#define get_symtab_upper_bound(abfd) \
. BFD_SEND (abfd, _get_symtab_upper_bound, (abfd))
.#define bfd_get_symtab_upper_bound(abfd) \
. BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd))
*/
/*
FUNCTION
bfd_is_local_label
SYNOPSIS
boolean bfd_is_local_label(bfd *abfd, asymbol *sym);
DESCRIPTION
Return true if the given symbol @var{sym} in the BFD @var{abfd} is
a compiler generated local label, else return false.
.#define bfd_is_local_label(abfd, sym) \
. BFD_SEND (abfd, _bfd_is_local_label,(abfd, sym))
*/
/*
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
Read the symbols from the BFD @var{abfd}, and fills in
the vector @var{location} with pointers to the symbols and
a trailing NULL.
Return the actual number of symbol pointers, not
including the NULL.
@ -315,12 +338,13 @@ DESCRIPTION
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 (bfd *abfd, asymbol **location, unsigned int count);
DESCRIPTION
Arrange that when the output BFD @var{abfd} is closed,
the table @var{location} of @var{count} pointers to symbols
will be written.
*/
boolean
@ -329,10 +353,11 @@ bfd_set_symtab (abfd, location, symcount)
asymbol **location;
unsigned int symcount;
{
if ((abfd->format != bfd_object) || (bfd_read_p (abfd))) {
bfd_error = invalid_operation;
return false;
}
if ((abfd->format != bfd_object) || (bfd_read_p (abfd)))
{
bfd_set_error (bfd_error_invalid_operation);
return false;
}
bfd_get_outsymbols (abfd) = location;
bfd_get_symcount (abfd) = symcount;
@ -343,35 +368,40 @@ bfd_set_symtab (abfd, location, symcount)
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);
DESCRIPTION
Print the value and flags of the @var{symbol} supplied to the
stream @var{file}.
*/
void
DEFUN(bfd_print_symbol_vandf,(file, symbol),
PTR file AND
asymbol *symbol)
bfd_print_symbol_vandf (arg, symbol)
PTR arg;
asymbol *symbol;
{
FILE *file = (FILE *) arg;
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' :' ');
if (symbol->section != (asection *) NULL)
{
fprintf_vma (file, symbol->value + symbol->section->vma);
}
else
{
fprintf_vma (file, symbol->value);
}
/* This presumes that a symbol can not be both BSF_DEBUGGING and
BSF_DYNAMIC. */
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'
: (type & BSF_DYNAMIC) ? 'D' : ' ');
}
@ -380,10 +410,10 @@ FUNCTION
bfd_make_empty_symbol
DESCRIPTION
This function creates a new <<asymbol>> structure for the BFD,
and returns a pointer to it.
Create a new <<asymbol>> structure for the BFD @var{abfd}
and return a pointer to it.
This routine is necessary, since each back end has private
This routine is necessary because 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.
@ -397,7 +427,7 @@ FUNCTION
bfd_make_debug_symbol
DESCRIPTION
This function creates a new <<asymbol>> structure for the BFD,
Create a new <<asymbol>> structure for the BFD @var{abfd},
to be used as a debugging symbol. Further details of its use have
yet to be worked out.
@ -411,10 +441,11 @@ struct section_to_type
char type;
};
/* Map COFF section names to POSIX/BSD single-character symbol types.
/* Map 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[] = {
static CONST struct section_to_type stt[] =
{
{"*DEBUG*", 'N'},
{".bss", 'b'},
{".data", 'd'},
@ -426,7 +457,7 @@ static CONST struct section_to_type stt[] = {
};
/* Return the single-character symbol type corresponding to
COFF section S, or '?' for an unknown COFF section. */
section S, or '?' for an unknown COFF section. */
static char
coff_section_type (s)
@ -453,27 +484,27 @@ FUNCTION
DESCRIPTION
Return a character corresponding to the symbol
class of symbol, or '?' for an unknown class.
class of @var{symbol}, or '?' for an unknown class.
SYNOPSIS
int bfd_decode_symclass(asymbol *symbol);
*/
int
DEFUN(bfd_decode_symclass,(symbol),
asymbol *symbol)
bfd_decode_symclass (symbol)
asymbol *symbol;
{
char c;
if (bfd_is_com_section (symbol->section))
return 'C';
if (symbol->section == &bfd_und_section)
if (bfd_is_und_section (symbol->section))
return 'U';
if (symbol->section == &bfd_ind_section)
if (bfd_is_ind_section (symbol->section))
return 'I';
if (!(symbol->flags & (BSF_GLOBAL|BSF_LOCAL)))
if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL)))
return '?';
if (symbol->section == &bfd_abs_section)
if (bfd_is_abs_section (symbol->section))
c = 'a';
else if (symbol->section)
c = coff_section_type (symbol->section->name);
@ -484,8 +515,8 @@ asymbol *symbol)
return c;
/* We don't have to handle these cases just yet, but we will soon:
N_SETV: 'v';
N_SETA: 'l';
N_SETV: 'v';
N_SETA: 'l';
N_SETT: 'x';
N_SETD: 'z';
N_SETB: 's';
@ -507,21 +538,20 @@ SYNOPSIS
*/
void
DEFUN(bfd_symbol_info,(symbol, ret),
asymbol *symbol AND
symbol_info *ret)
bfd_symbol_info (symbol, ret)
asymbol *symbol;
symbol_info *ret;
{
ret->type = bfd_decode_symclass (symbol);
if (ret->type != 'U')
ret->value = symbol->value+symbol->section->vma;
ret->value = symbol->value + symbol->section->vma;
else
ret->value = 0;
ret->name = symbol->name;
}
void
bfd_symbol_is_absolute()
bfd_symbol_is_absolute ()
{
abort();
abort ();
}

View File

@ -30,13 +30,12 @@
#ifdef __bsdi__
/* 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 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

View File

@ -1,5 +1,5 @@
/* Generic target-file-type support for the BFD library.
Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
Copyright 1990, 91, 92, 93, 1994 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@ -38,25 +38,25 @@ DESCRIPTION
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
o Create a BFD by calling the internal routine
<<_bfd_new_bfd>>, then call <<bfd_find_target>> 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
look up the environment variable <<GNUTARGET>> and use
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
o If the target string is still <<NULL>>, or the target string is
<<default>>, then use the first item in the target vector
as the target type, and set <<target_defaulted>> in the BFD 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
o Otherwise, inspect the elements in the target vector
one by one, until a match on target name is found. When found,
that is used.
use it.
o Otherwise the error <<invalid_target>> is returned to
o Otherwise return the error <<bfd_error_invalid_target>> to
<<bfd_openr>>.
o <<bfd_openr>> attempts to open the file using
@ -66,8 +66,8 @@ DESCRIPTION
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.
type is tried to see if it recognizes the specified format.
<<bfd_check_format>> returns <<true>> when the caller guesses right.
@menu
@* bfd_target::
@end menu
@ -84,16 +84,16 @@ SUBSECTION
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.
target. It includes things like its byte order, name, and which
routines to call to do various operations.
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
The macros below 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"
routines by hand inside the BFD implementation. The @var{arglist}
argument must be parenthesized; it contains all the arguments
to the called function.
@ -102,13 +102,29 @@ DESCRIPTION
.#define BFD_SEND(bfd, message, arglist) \
. ((*((bfd)->xvec->message)) arglist)
.
.#ifdef DEBUG_BFD_SEND
.#undef BFD_SEND
.#define BFD_SEND(bfd, message, arglist) \
. (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \
. ((*((bfd)->xvec->message)) arglist) : \
. (bfd_assert (__FILE__,__LINE__), NULL))
.#endif
For operations which index on the BFD format
For operations which index on the BFD format:
.#define BFD_SEND_FMT(bfd, message, arglist) \
. (((bfd)->xvec->message[(int)((bfd)->format)]) arglist)
.
.#ifdef DEBUG_BFD_SEND
.#undef BFD_SEND_FMT
.#define BFD_SEND_FMT(bfd, message, arglist) \
. (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \
. (((bfd)->xvec->message[(int)((bfd)->format)]) arglist) : \
. (bfd_assert (__FILE__,__LINE__), NULL))
.#endif
This is the struct which defines the type of BFD this is. The
This is the structure 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.
@ -118,28 +134,34 @@ DESCRIPTION
the entry points which call them. Too bad we can't have one
macro to define them both!
.enum bfd_flavour {
. bfd_target_unknown_flavour,
. bfd_target_aout_flavour,
. bfd_target_coff_flavour,
. bfd_target_ecoff_flavour,
. bfd_target_elf_flavour,
. bfd_target_ieee_flavour,
. bfd_target_nlm_flavour,
. bfd_target_oasys_flavour,
. bfd_target_tekhex_flavour,
. bfd_target_srec_flavour,
. bfd_target_som_flavour,
. bfd_target_os9k_flavour};
.
.{* Forward declaration. *}
.typedef struct bfd_link_info _bfd_link_info;
.
.typedef struct bfd_target
.{
Identifies the kind of target, eg SunOS4, Ultrix, etc.
Identifies the kind of target, e.g., 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;
. enum bfd_flavour flavour;
The order of bytes within the data area of a file.
@ -149,22 +171,22 @@ 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 -
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
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 _.
(if any), perhaps `_'.
. char symbol_leading_char;
The pad character for filenames within an archive header.
The pad character for file names within an archive header.
. char ar_pad_char;
@ -176,60 +198,95 @@ 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.
Entries for byte swapping for data. These are different from the other
entry points, since they don't take a BFD asthe first argument.
Certain other handlers could do the same.
. bfd_vma (*bfd_getx64) PARAMS ((bfd_byte *));
. bfd_signed_vma (*bfd_getx_signed_64) PARAMS ((bfd_byte *));
. bfd_vma (*bfd_getx64) PARAMS ((const bfd_byte *));
. bfd_signed_vma (*bfd_getx_signed_64) PARAMS ((const bfd_byte *));
. void (*bfd_putx64) PARAMS ((bfd_vma, bfd_byte *));
. bfd_vma (*bfd_getx32) PARAMS ((bfd_byte *));
. bfd_signed_vma (*bfd_getx_signed_32) PARAMS ((bfd_byte *));
. bfd_vma (*bfd_getx32) PARAMS ((const bfd_byte *));
. bfd_signed_vma (*bfd_getx_signed_32) PARAMS ((const bfd_byte *));
. void (*bfd_putx32) PARAMS ((bfd_vma, bfd_byte *));
. bfd_vma (*bfd_getx16) PARAMS ((bfd_byte *));
. bfd_signed_vma (*bfd_getx_signed_16) PARAMS ((bfd_byte *));
. bfd_vma (*bfd_getx16) PARAMS ((const bfd_byte *));
. bfd_signed_vma (*bfd_getx_signed_16) PARAMS ((const bfd_byte *));
. void (*bfd_putx16) PARAMS ((bfd_vma, bfd_byte *));
Byte swapping for the headers
. bfd_vma (*bfd_h_getx64) PARAMS ((bfd_byte *));
. bfd_signed_vma (*bfd_h_getx_signed_64) PARAMS ((bfd_byte *));
. bfd_vma (*bfd_h_getx64) PARAMS ((const bfd_byte *));
. bfd_signed_vma (*bfd_h_getx_signed_64) PARAMS ((const bfd_byte *));
. void (*bfd_h_putx64) PARAMS ((bfd_vma, bfd_byte *));
. bfd_vma (*bfd_h_getx32) PARAMS ((bfd_byte *));
. bfd_signed_vma (*bfd_h_getx_signed_32) PARAMS ((bfd_byte *));
. bfd_vma (*bfd_h_getx32) PARAMS ((const bfd_byte *));
. bfd_signed_vma (*bfd_h_getx_signed_32) PARAMS ((const bfd_byte *));
. void (*bfd_h_putx32) PARAMS ((bfd_vma, bfd_byte *));
. bfd_vma (*bfd_h_getx16) PARAMS ((bfd_byte *));
. bfd_signed_vma (*bfd_h_getx_signed_16) PARAMS ((bfd_byte *));
. bfd_vma (*bfd_h_getx16) PARAMS ((const bfd_byte *));
. bfd_signed_vma (*bfd_h_getx_signed_16) PARAMS ((const bfd_byte *));
. void (*bfd_h_putx16) PARAMS ((bfd_vma, bfd_byte *));
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.
Check the format of a file being read. Return a <<bfd_target *>> or zero.
. struct bfd_target * (*_bfd_check_format[bfd_type_end]) PARAMS ((bfd *));
. const 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.
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
The general target vector.
.
. {* Generic entry points. *}
.#define BFD_JUMP_TABLE_GENERIC(NAME)\
.CAT(NAME,_close_and_cleanup),\
.CAT(NAME,_bfd_free_cached_info),\
.CAT(NAME,_new_section_hook),\
.CAT(NAME,_get_section_contents)
. {* Called when the BFD is being closed to do any necessary cleanup. *}
. boolean (*_close_and_cleanup) PARAMS ((bfd *));
. {* Ask the BFD to free all cached information. *}
. boolean (*_bfd_free_cached_info) PARAMS ((bfd *));
. {* Called when a new section is created. *}
. boolean (*_new_section_hook) PARAMS ((bfd *, sec_ptr));
. {* Read the contents of a section. *}
. boolean (*_bfd_get_section_contents) PARAMS ((bfd *, sec_ptr, PTR,
. file_ptr, bfd_size_type));
.
. {* Entry points to copy private data. *}
.#define BFD_JUMP_TABLE_COPY(NAME)\
.CAT(NAME,_bfd_copy_private_bfd_data),\
.CAT(NAME,_bfd_copy_private_section_data)
. {* Called to copy BFD general private data from one object file
. to another. *}
. boolean (*_bfd_copy_private_bfd_data) PARAMS ((bfd *, bfd *));
. {* Called to copy BFD private section data from one object file
. to another. *}
. boolean (*_bfd_copy_private_section_data) PARAMS ((bfd *, sec_ptr,
. bfd *, sec_ptr));
.
. {* Core file entry points. *}
.#define BFD_JUMP_TABLE_CORE(NAME)\
.CAT(NAME,_core_file_failing_command),\
.CAT(NAME,_core_file_failing_signal),\
.CAT(NAME,_core_file_matches_executable_p)
. char * (*_core_file_failing_command) PARAMS ((bfd *));
. int (*_core_file_failing_signal) PARAMS ((bfd *));
. boolean (*_core_file_matches_executable_p) PARAMS ((bfd *, bfd *));
Archive entry points
.
. {* Archive entry points. *}
.#define BFD_JUMP_TABLE_ARCHIVE(NAME)\
.CAT(NAME,_slurp_armap),\
.CAT(NAME,_slurp_extended_name_table),\
.CAT(NAME,_truncate_arname),\
.CAT(NAME,_write_armap),\
.CAT(NAME,_openr_next_archived_file),\
.CAT(NAME,_generic_stat_arch_elt)
. boolean (*_bfd_slurp_armap) PARAMS ((bfd *));
. boolean (*_bfd_slurp_extended_name_table) PARAMS ((bfd *));
. void (*_bfd_truncate_arname) PARAMS ((bfd *, CONST char *, char *));
@ -238,24 +295,23 @@ Archive entry points
. 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 **));
. bfd * (*openr_next_archived_file) PARAMS ((bfd *arch, bfd *prev));
. int (*_bfd_stat_arch_elt) PARAMS ((bfd *, struct stat *));
.
. {* Entry points used for symbols. *}
.#define BFD_JUMP_TABLE_SYMBOLS(NAME)\
.CAT(NAME,_get_symtab_upper_bound),\
.CAT(NAME,_get_symtab),\
.CAT(NAME,_make_empty_symbol),\
.CAT(NAME,_print_symbol),\
.CAT(NAME,_get_symbol_info),\
.CAT(NAME,_bfd_is_local_label),\
.CAT(NAME,_get_lineno),\
.CAT(NAME,_find_nearest_line),\
.CAT(NAME,_bfd_make_debug_symbol)
. long (*_bfd_get_symtab_upper_bound) PARAMS ((bfd *));
. long (*_bfd_canonicalize_symtab) PARAMS ((bfd *,
. struct symbol_cache_entry **));
. struct symbol_cache_entry *
. (*_bfd_make_empty_symbol) PARAMS ((bfd *));
. void (*_bfd_print_symbol) PARAMS ((bfd *, PTR,
@ -266,42 +322,13 @@ Symbols and relocations
. struct symbol_cache_entry *,
. symbol_info *));
.#define bfd_get_symbol_info(b,p,e) BFD_SEND(b, _bfd_get_symbol_info, (b,p,e))
. boolean (*_bfd_is_local_label) PARAMS ((bfd *, asymbol *));
.
. alent * (*_get_lineno) PARAMS ((bfd *, struct symbol_cache_entry *));
.
. boolean (*_bfd_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. *}
@ -309,6 +336,74 @@ Symbols and relocations
. bfd *abfd,
. void *ptr,
. unsigned long size));
.
. {* Routines for relocs. *}
.#define BFD_JUMP_TABLE_RELOCS(NAME)\
.CAT(NAME,_get_reloc_upper_bound),\
.CAT(NAME,_canonicalize_reloc),\
.CAT(NAME,_bfd_reloc_type_lookup)
. long (*_get_reloc_upper_bound) PARAMS ((bfd *, sec_ptr));
. long (*_bfd_canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **,
. struct symbol_cache_entry **));
. {* See documentation on reloc types. *}
. CONST struct reloc_howto_struct *
. (*reloc_type_lookup) PARAMS ((bfd *abfd,
. bfd_reloc_code_real_type code));
.
. {* Routines used when writing an object file. *}
.#define BFD_JUMP_TABLE_WRITE(NAME)\
.CAT(NAME,_set_arch_mach),\
.CAT(NAME,_set_section_contents)
. boolean (*_bfd_set_arch_mach) PARAMS ((bfd *, enum bfd_architecture,
. unsigned long));
. boolean (*_bfd_set_section_contents) PARAMS ((bfd *, sec_ptr, PTR,
. file_ptr, bfd_size_type));
.
. {* Routines used by the linker. *}
.#define BFD_JUMP_TABLE_LINK(NAME)\
.CAT(NAME,_sizeof_headers),\
.CAT(NAME,_bfd_get_relocated_section_contents),\
.CAT(NAME,_bfd_relax_section),\
.CAT(NAME,_bfd_link_hash_table_create),\
.CAT(NAME,_bfd_link_add_symbols),\
.CAT(NAME,_bfd_final_link)
. int (*_bfd_sizeof_headers) PARAMS ((bfd *, boolean));
. bfd_byte * (*_bfd_get_relocated_section_contents) PARAMS ((bfd *,
. struct bfd_link_info *, struct bfd_link_order *,
. bfd_byte *data, boolean relocateable,
. struct symbol_cache_entry **));
.
. boolean (*_bfd_relax_section) PARAMS ((bfd *, struct sec *,
. struct bfd_link_info *, boolean *again));
.
. {* Create a hash table for the linker. Different backends store
. different information in this table. *}
. struct bfd_link_hash_table *(*_bfd_link_hash_table_create) PARAMS ((bfd *));
.
. {* Add symbols from this object file into the hash table. *}
. boolean (*_bfd_link_add_symbols) PARAMS ((bfd *, struct bfd_link_info *));
.
. {* Do a link based on the link_order structures attached to each
. section of the BFD. *}
. boolean (*_bfd_final_link) PARAMS ((bfd *, struct bfd_link_info *));
.
. {* Routines to handle dynamic symbols and relocs. *}
.#define BFD_JUMP_TABLE_DYNAMIC(NAME)\
.CAT(NAME,_get_dynamic_symtab_upper_bound),\
.CAT(NAME,_canonicalize_dynamic_symtab),\
.CAT(NAME,_get_dynamic_reloc_upper_bound),\
.CAT(NAME,_canonicalize_dynamic_reloc)
. {* Get the amount of memory required to hold the dynamic symbols. *}
. long (*_bfd_get_dynamic_symtab_upper_bound) PARAMS ((bfd *));
. {* Read in the dynamic symbols. *}
. long (*_bfd_canonicalize_dynamic_symtab)
. PARAMS ((bfd *, struct symbol_cache_entry **));
. {* Get the amount of memory required to hold the dynamic relocs. *}
. long (*_bfd_get_dynamic_reloc_upper_bound) PARAMS ((bfd *));
. {* Read in the dynamic relocs. *}
. long (*_bfd_canonicalize_dynamic_reloc)
. PARAMS ((bfd *, arelent **, struct symbol_cache_entry **));
.
Data for use by back-end routines, which isn't generic enough to belong
in this structure.
@ -322,77 +417,93 @@ in this structure.
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 netbsd386_vec;
extern bfd_target freebsd386_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 const bfd_target a29kcoff_big_vec;
extern const bfd_target a_out_adobe_vec;
extern const bfd_target aout_mips_big_vec;
extern const bfd_target aout_mips_little_vec;
extern const bfd_target aout0_big_vec;
extern const bfd_target apollocoff_vec;
extern const bfd_target b_out_vec_big_host;
extern const bfd_target b_out_vec_little_host;
extern const bfd_target bfd_elf32_big_generic_vec;
extern const bfd_target bfd_elf32_bigmips_vec;
extern const bfd_target bfd_elf32_hppa_vec;
extern const bfd_target bfd_elf32_i386_vec;
extern const bfd_target bfd_elf32_i860_vec;
extern const bfd_target bfd_elf32_little_generic_vec;
extern const bfd_target bfd_elf32_littlemips_vec;
extern const bfd_target bfd_elf32_m68k_vec;
extern const bfd_target bfd_elf32_m88k_vec;
extern const bfd_target bfd_elf32_powerpc_vec;
extern const bfd_target bfd_elf32_sparc_vec;
extern const bfd_target bfd_elf64_big_generic_vec;
extern const bfd_target bfd_elf64_little_generic_vec;
extern const bfd_target bfd_elf64_sparc_vec;
extern const bfd_target demo_64_vec;
extern const bfd_target ecoff_big_vec;
extern const bfd_target ecoff_little_vec;
extern const bfd_target ecoffalpha_little_vec;
extern const bfd_target h8300coff_vec;
extern const bfd_target h8500coff_vec;
extern const bfd_target host_aout_vec;
extern const bfd_target hp300bsd_vec;
extern const bfd_target hp300hpux_vec;
extern const bfd_target som_vec;
extern const bfd_target i386aout_vec;
extern const bfd_target i386bsd_vec;
extern const bfd_target i386dynix_vec;
extern const bfd_target i386os9k_vec;
extern const bfd_target netbsd386_vec;
extern const bfd_target freebsd386_vec;
extern const bfd_target i386coff_vec;
extern const bfd_target go32coff_vec;
extern const bfd_target i386linux_vec;
extern const bfd_target i386lynx_aout_vec;
extern const bfd_target i386lynx_coff_vec;
extern const bfd_target i386mach3_vec;
extern const bfd_target icoff_big_vec;
extern const bfd_target icoff_little_vec;
extern const bfd_target ieee_vec;
extern const bfd_target m68kcoff_vec;
extern const bfd_target m68kcoffun_vec;
extern const bfd_target m68klynx_aout_vec;
extern const bfd_target m68klynx_coff_vec;
extern const bfd_target m88kbcs_vec;
extern const bfd_target m88kmach3_vec;
extern const bfd_target netbsd532_vec;
extern const bfd_target newsos3_vec;
extern const bfd_target nlm32_i386_vec;
extern const bfd_target nlm32_sparc_vec;
extern const bfd_target nlm32_alpha_vec;
extern const bfd_target nlm32_powerpc_vec;
extern const bfd_target oasys_vec;
extern const bfd_target pc532mach_vec;
extern const bfd_target rs6000coff_vec;
extern const bfd_target shcoff_vec;
extern const bfd_target sparclynx_aout_vec;
extern const bfd_target sparclynx_coff_vec;
extern const bfd_target sparccoff_vec;
extern const bfd_target sunos_big_vec;
extern const bfd_target tekhex_vec;
extern const bfd_target we32kcoff_vec;
extern const bfd_target z8kcoff_vec;
/* srec is always included. */
extern bfd_target srec_vec;
extern bfd_target symbolsrec_vec;
extern const bfd_target srec_vec;
extern const 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;
extern const bfd_target aix386_core_vec;
extern const bfd_target cisco_core_vec;
extern const bfd_target hpux_core_vec;
extern const bfd_target hppabsd_core_vec;
extern const bfd_target irix_core_vec;
extern const bfd_target osf_core_vec;
extern const bfd_target sco_core_vec;
extern const bfd_target trad_core_vec;
extern const bfd_target ptrace_core_vec;
bfd_target *target_vector[] = {
const bfd_target * const bfd_target_vector[] = {
#ifdef SELECT_VECS
@ -417,26 +528,32 @@ bfd_target *target_vector[] = {
&aout_mips_little_vec,
&b_out_vec_big_host,
&b_out_vec_little_host,
#if 0 /* No one seems to use this. */
/* This, and other vectors, may not be used in any *.mt configuration.
But that does not mean they are unnecessary. If configured with
--enable-targets=all, objdump or gdb should be able to examine
the file even if we don't recognize the machine type. */
&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,
&bfd_elf32_powerpc_vec,
#ifdef BFD64 /* No one seems to use this. */
&bfd_elf64_big_generic_vec,
&bfd_elf64_little_generic_vec,
#endif
#if 0
&bfd_elf64_sparc_vec,
#endif
/* We don't include cisco_core_vec. Although it has a magic number,
the magic number isn't at the beginning of the file, and thus
might spuriously match other kinds of files. */
#ifdef BFD64
&demo_64_vec, /* Only compiled if host has long-long support */
#endif
@ -448,25 +565,33 @@ bfd_target *target_vector[] = {
&h8300coff_vec,
&h8500coff_vec,
#if 0
/* Since a.out files lack decent magic numbers, no way to recognize
which kind of a.out file it is. */
&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,
#if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD) || defined (HOST_HPPAOSF)
&som_vec,
#endif
&i386aout_vec,
&i386bsd_vec,
&netbsd386_vec,
&freebsd386_vec,
&i386coff_vec,
&go32coff_vec,
#if 0
/* Since a.out files lack decent magic numbers, no way to recognize
which kind of a.out file it is. */
&i386linux_vec,
#endif
&i386lynx_aout_vec,
&i386lynx_coff_vec,
#if 0
/* No distinguishing features for Mach 3 executables. */
&i386mach3_vec,
#endif
&i386os9k_vec,
&icoff_big_vec,
&icoff_little_vec,
&ieee_vec,
@ -475,17 +600,14 @@ bfd_target *target_vector[] = {
&m68klynx_aout_vec,
&m68klynx_coff_vec,
&m88kbcs_vec,
&m88kmach3_vec,
&newsos3_vec,
#if 0 /* No one seems to use this. */
&nlm32_big_generic_vec,
#endif
&netbsd386_vec,
&netbsd532_vec,
&nlm32_i386_vec,
#if 0 /* No one seems to use this. */
&nlm32_little_generic_vec,
#endif
&nlm32_sparc_vec,
#ifdef BFD64
&nlm64_big_generic_vec,
&nlm64_little_generic_vec,
&nlm32_alpha_vec,
#endif
#if 0
/* We have no oasys tools anymore, so we can't test any of this
@ -495,9 +617,13 @@ bfd_target *target_vector[] = {
can be annoying target mis-matches. */
&oasys_vec,
#endif
&pc532machaout_vec,
&rs6000coff_vec,
&shcoff_vec,
&sparclynx_aout_vec,
&sparclynx_coff_vec,
&sunos_big_vec,
&aout0_big_vec,
#if 0
&tekhex_vec,
#endif
@ -518,57 +644,66 @@ bfd_target *target_vector[] = {
#ifdef HPUX_CORE
&hpux_core_vec,
#endif
#ifdef HPPABSD_CORE
&hppabsd_core_vec,
#endif
#ifdef IRIX_CORE
&irix_core_vec,
#endif
#ifdef OSF_CORE
&osf_core_vec,
#endif
#ifdef SCO_CORE
&sco_core_vec,
#endif
#ifdef TRAD_CORE
&trad_core_vec,
#endif
#ifdef PTRACE_CORE
&ptrace_core_vec,
#endif
NULL /* end of list marker */
};
/* default_vector[0] contains either the address of the default vector,
/* bfd_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[] = {
const bfd_target * const bfd_default_vector[] = {
#ifdef DEFAULT_VECTOR
&DEFAULT_VECTOR,
#endif
NULL
};
/* When there is an ambiguous match, bfd_check_format_matches puts the
names of the matching targets in an array. This variable is the maximum
number of entries that the array could possibly need. */
const size_t _bfd_target_vector_entries = sizeof(bfd_target_vector)/sizeof(*bfd_target_vector);
/*
FUNCTION
bfd_find_target
SYNOPSIS
const bfd_target *bfd_find_target(CONST char *target_name, bfd *abfd);
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.
Return a pointer to the transfer vector for the object target
named @var{target_name}. If @var{target_name} is <<NULL>>, choose the
one in the environment variable <<GNUTARGET>>; if that is null or not
defined, then choose the first entry in the target list.
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)
const bfd_target *
bfd_find_target (target_name, abfd)
CONST char *target_name;
bfd *abfd;
{
bfd_target **target;
const bfd_target * const *target;
extern char *getenv ();
CONST char *targname = (target_name ? target_name :
(CONST char *) getenv ("GNUTARGET"));
@ -576,17 +711,17 @@ DEFUN(bfd_find_target,(target_name, abfd),
/* This is safe; the vector cannot be null */
if (targname == NULL || !strcmp (targname, "default")) {
abfd->target_defaulted = true;
return abfd->xvec = target_vector[0];
return abfd->xvec = bfd_target_vector[0];
}
abfd->target_defaulted = false;
for (target = &target_vector[0]; *target != NULL; target++) {
for (target = &bfd_target_vector[0]; *target != NULL; target++) {
if (!strcmp (targname, (*target)->name))
return abfd->xvec = *target;
}
bfd_error = invalid_target;
bfd_set_error (bfd_error_invalid_target);
return NULL;
}
@ -595,18 +730,18 @@ DEFUN(bfd_find_target,(target_name, abfd),
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 **bfd_target_list(void);
DESCRIPTION
Return a freshly malloced NULL-terminated
vector of the names of all the valid BFD targets. Do not
modify the names.
*/
CONST char **
DEFUN_VOID(bfd_target_list)
const char **
bfd_target_list ()
{
int vec_length= 0;
#ifdef NATIVE_HPPAHPUX_COMPILER
@ -614,21 +749,21 @@ DEFUN_VOID(bfd_target_list)
to loop endlessly when compiling this file. This avoids it. */
volatile
#endif
bfd_target **target;
const bfd_target * const *target;
CONST char **name_list, **name_ptr;
for (target = &target_vector[0]; *target != NULL; target++)
for (target = &bfd_target_vector[0]; *target != NULL; target++)
vec_length++;
name_ptr =
name_list = (CONST char **) zalloc ((vec_length + 1) * sizeof (char **));
name_ptr = name_list = (CONST char **)
bfd_zmalloc ((vec_length + 1) * sizeof (char **));
if (name_list == NULL) {
bfd_error = no_memory;
bfd_set_error (bfd_error_no_memory);
return NULL;
}
for (target = &target_vector[0]; *target != NULL; target++)
for (target = &bfd_target_vector[0]; *target != NULL; target++)
*(name_ptr++) = (*target)->name;
return name_list;

View File

@ -1,5 +1,5 @@
/* BFD back end for traditional Unix core files (U-area and raw sections)
Copyright 1988, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
Copyright 1988, 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
Written by John Gilmore of Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@ -63,7 +63,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* forward declarations */
bfd_target * trad_unix_core_file_p PARAMS ((bfd *abfd));
const 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
@ -72,7 +72,7 @@ boolean trad_unix_core_file_matches_executable_p
/* Handle 4.2-style (and perhaps also sysV-style) core dump file. */
/* ARGSUSED */
bfd_target *
const bfd_target *
trad_unix_core_file_p (abfd)
bfd *abfd;
@ -82,7 +82,7 @@ trad_unix_core_file_p (abfd)
#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)
if (bfd_seek (abfd, TRAD_CORE_USER_OFFSET, SEEK_SET) != 0)
return 0;
#endif
@ -90,19 +90,19 @@ trad_unix_core_file_p (abfd)
if (val != sizeof u)
{
/* Too small to be a core file */
bfd_error = wrong_format;
bfd_set_error (bfd_error_wrong_format);
return 0;
}
/* Sanity check perhaps??? */
if (u.u_dsize > 0x1000000) /* Remember, it's in pages... */
{
bfd_error = wrong_format;
bfd_set_error (bfd_error_wrong_format);
return 0;
}
if (u.u_ssize > 0x1000000)
{
bfd_error = wrong_format;
bfd_set_error (bfd_error_wrong_format);
return 0;
}
@ -114,14 +114,19 @@ trad_unix_core_file_p (abfd)
return 0;
if (fstat (fileno (stream), &statbuf) < 0)
{
bfd_error = system_call_error;
bfd_set_error (bfd_error_system_call);
return 0;
}
if (NBPG * (UPAGES + u.u_dsize + u.u_ssize) > statbuf.st_size)
if (NBPG * (UPAGES + u.u_dsize
#ifdef TRAD_CORE_DSIZE_INCLUDES_TSIZE
- u.u_tsize
#endif
+ u.u_ssize) > statbuf.st_size)
{
bfd_error = file_truncated;
bfd_set_error (bfd_error_file_truncated);
return 0;
}
#ifndef TRAD_CORE_ALLOW_ANY_EXTRA_SIZE
if (NBPG * (UPAGES + u.u_dsize + u.u_ssize)
#ifdef TRAD_CORE_EXTRA_SIZE_ALLOWED
/* Some systems write the file too big. */
@ -131,9 +136,10 @@ trad_unix_core_file_p (abfd)
{
/* 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;
bfd_set_error (bfd_error_wrong_format);
return 0;
}
#endif
}
/* OK, we believe you. You're a core file (sure, sure). */
@ -141,9 +147,9 @@ trad_unix_core_file_p (abfd)
/* 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));
bfd_zmalloc (sizeof (struct trad_core_struct));
if (rawptr == NULL) {
bfd_error = no_memory;
bfd_set_error (bfd_error_no_memory);
return 0;
}
@ -154,20 +160,20 @@ trad_unix_core_file_p (abfd)
/* Create the sections. This is raunchy, but bfd_close wants to free
them separately. */
core_stacksec(abfd) = (asection *) zalloc (sizeof (asection));
core_stacksec(abfd) = (asection *) bfd_zmalloc (sizeof (asection));
if (core_stacksec (abfd) == NULL) {
loser:
bfd_error = no_memory;
bfd_set_error (bfd_error_no_memory);
free ((void *)rawptr);
return 0;
}
core_datasec (abfd) = (asection *) zalloc (sizeof (asection));
core_datasec (abfd) = (asection *) bfd_zmalloc (sizeof (asection));
if (core_datasec (abfd) == NULL) {
loser1:
free ((void *)core_stacksec (abfd));
goto loser;
}
core_regsec (abfd) = (asection *) zalloc (sizeof (asection));
core_regsec (abfd) = (asection *) bfd_zmalloc (sizeof (asection));
if (core_regsec (abfd) == NULL) {
free ((void *)core_datasec (abfd));
goto loser1;
@ -179,9 +185,13 @@ trad_unix_core_file_p (abfd)
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_regsec (abfd)->flags = SEC_HAS_CONTENTS;
core_datasec (abfd)->_raw_size = NBPG * u.u_dsize;
core_datasec (abfd)->_raw_size = NBPG * u.u_dsize
#ifdef TRAD_CORE_DSIZE_INCLUDES_TSIZE
- NBPG * u.u_tsize
#endif
;
core_stacksec (abfd)->_raw_size = NBPG * u.u_ssize;
core_regsec (abfd)->_raw_size = NBPG * UPAGES; /* Larger than sizeof struct u */
@ -192,14 +202,7 @@ trad_unix_core_file_p (abfd)
#else
core_datasec (abfd)->vma = HOST_TEXT_START_ADDR + (NBPG * u.u_tsize);
#endif
/* a hack, but it works for FreeBSD !! */
#include <vm/vm_param.h>
/* this should really be in <vm/vm_param.h>, but somebody forgot it */
#ifndef vm_page_size
#define vm_page_size 4096
#endif
#define HOST_STACK_START_ADDR trunc_page(u.u_kproc.kp_eproc.e_vm.vm_maxsaddr \
+ MAXSSIZ - ctob(u.u_ssize))
#ifdef HOST_STACK_START_ADDR
core_stacksec (abfd)->vma = HOST_STACK_START_ADDR;
#else
@ -223,11 +226,11 @@ trad_unix_core_file_p (abfd)
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;
core_stacksec (abfd)->filepos = (NBPG * UPAGES) + NBPG * u.u_dsize
#ifdef TRAD_CORE_DSIZE_INCLUDES_TSIZE
- NBPG * u.u_tsize
#endif
;
core_regsec (abfd)->filepos = 0; /* Register segment is the upage */
/* Align to word at least */
@ -276,74 +279,18 @@ trad_unix_core_file_matches_executable_p (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_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort )
#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
#define NO_SIGNED_GET ((bfd_signed_vma (*) PARAMS ((bfd_byte *))) swap_abort )
#define NO_SIGNED_GET \
((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort )
bfd_target trad_core_vec =
const bfd_target trad_core_vec =
{
"trad-core",
bfd_target_unknown_flavour,
@ -351,7 +298,7 @@ bfd_target trad_core_vec =
true, /* target headers byte order */
(HAS_RELOC | EXEC_P | /* object flags */
HAS_LINENO | HAS_DEBUG |
HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
0, /* symbol prefix */
' ', /* ar_pad_char */
@ -379,6 +326,15 @@ bfd_target trad_core_vec =
bfd_false, bfd_false
},
JUMP_TABLE(trad_unix),
BFD_JUMP_TABLE_GENERIC (_bfd_generic),
BFD_JUMP_TABLE_COPY (_bfd_generic),
BFD_JUMP_TABLE_CORE (trad_unix),
BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
BFD_JUMP_TABLE_WRITE (_bfd_generic),
BFD_JUMP_TABLE_LINK (_bfd_nolink),
BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
(PTR) 0 /* backend_data */
};

View File

@ -1,19 +1,23 @@
PROG = gdb
BINDIR= /usr/bin
CLEANFILES+= y.tab.h c-exp.tab.c ch-exp.tab.c m2-exp.tab.c
SRCS = main.c blockframe.c breakpoint.c findvar.c stack.c thread.c \
source.c values.c eval.c valops.c valarith.c valprint.c printcmd.c \
symtab.c symfile.c symmisc.c infcmd.c infrun.c command.c utils.c \
expprint.c environ.c gdbtypes.c copying.c i386-tdep.c i386-pinsn.c \
freebsd-solib.c ser-unix.c exec.c fork-child.c infptrace.c inftarg.c \
corelow.c coredep.c freebsd-nat.c remote.c dcache.c remote-utils.c \
mem-break.c target.c putenv.c parse.c language.c buildsym.c \
objfiles.c minsyms.c maint.c demangle.c dbxread.c coffread.c \
elfread.c dwarfread.c mipsread.c stabsread.c core.c c-lang.c \
ch-lang.c m2-lang.c complaints.c typeprint.c c-typeprint.c \
ch-typeprint.c m2-typeprint.c c-valprint.c cp-valprint.c ch-valprint.c \
m2-valprint.c nlmread.c serial.c inflow.c regex.c init.c \
c-exp.tab.c ch-exp.tab.c m2-exp.tab.c version.c i386-dis.c dis-buf.c
SRCS = annotate.c blockframe.c breakpoint.c buildsym.c c-lang.c \
c-typeprint.c c-valprint.c ch-lang.c ch-typeprint.c \
ch-valprint.c coffread.c command.c complaints.c copying.c core.c \
coredep.c corelow.c cp-valprint.c \
dcache.c dbxread.c demangle.c disassemble.c dis-buf.c dwarfread.c \
elfread.c environ.c eval.c exec.c expprint.c \
findvar.c fork-child.c freebsd-nat.c gdbtypes.c i386-dis.c \
i386-pinsn.c i386-tdep.c infcmd.c inflow.c infptrace.c \
infrun.c inftarg.c init.c kcorelow.c language.c \
m2-lang.c m2-typeprint.c m2-valprint.c main.c maint.c \
mem-break.c minsyms.c objfiles.c parse.c \
printcmd.c regex.c remote.c remote-utils.c solib.c source.c \
stabsread.c stack.c symfile.c symmisc.c \
symtab.c target.c thread.c top.c \
typeprint.c utils.c valarith.c valops.c \
valprint.c values.c version.c serial.c ser-unix.c mdebugread.c\
c-exp.tab.c ch-exp.tab.c m2-exp.tab.c
c-exp.tab.c: $(.CURDIR)/c-exp.y
yacc -d -p c_ $(.CURDIR)/c-exp.y
@ -40,7 +44,6 @@ m2-exp.tab.c: $(.CURDIR)/m2-exp.y
mv m2-exp.new ./m2-exp.tab.c
CFLAGS+= -I$(.CURDIR)/. -I${DESTDIR}/usr/include/readline -I$(.CURDIR)/../bfd
DPADD+= ${LIBREADLINE} ${LIBTERMCAP}
LDADD+= -lreadline -ltermcap

View File

@ -27,6 +27,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
VOLATILE `volatile' `'
SIGNED `signed' `'
PTRCONST `void *const' `char *'
ANSI_PROTOTYPES 1 not defined
CONST is also defined, but is obsolete. Just use const.
@ -111,6 +112,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define PROTO(type, name, arglist) type name arglist
#define PARAMS(paramlist) paramlist
#define ANSI_PROTOTYPES 1
#else /* Not ANSI C. */

View File

@ -36,9 +36,10 @@ struct external_exec
#define OMAGIC 0407 /* ...object file or impure executable. */
#define NMAGIC 0410 /* Code indicating pure executable. */
#define ZMAGIC 0413 /* Code indicating demand-paged executable. */
#define BMAGIC 0415 /* Used by a b.out object. */
/* This indicates a demand-paged executable with the header in the text.
As far as I know it is only used by 386BSD and/or BSDI. */
It is used by 386BSD (and variants) and Linux, at least. */
#define QMAGIC 0314
# ifndef N_BADMAG
# define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
@ -57,7 +58,7 @@ struct external_exec
#endif
/* The difference between PAGE_SIZE and N_SEGSIZE is that PAGE_SIZE is
the the finest granularity at which you can page something, thus it
the finest granularity at which you can page something, thus it
controls the padding (if any) before the text segment of a ZMAGIC
file. N_SEGSIZE is the resolution at which things can be marked as
read-only versus read/write, so it controls the padding between the
@ -121,6 +122,11 @@ struct external_exec
#define N_SHARED_LIB(x) ((x).a_entry < TEXT_START_ADDR)
#endif
/* Returning 0 not TEXT_START_ADDR for OMAGIC and NMAGIC is based on
the assumption that we are dealing with a .o file, not an
executable. This is necessary for OMAGIC (but means we don't work
right on the output from ld -N); more questionable for NMAGIC. */
#ifndef N_TXTADDR
#define N_TXTADDR(x) \
(/* The address of a QMAGIC file is always one page in, */ \
@ -134,6 +140,19 @@ struct external_exec
)
#endif
/* If N_HEADER_IN_TEXT is not true for ZMAGIC, there is some padding
to make the text segment start at a certain boundary. For most
systems, this boundary is PAGE_SIZE. But for Linux, in the
time-honored tradition of crazy ZMAGIC hacks, it is 1024 which is
not what PAGE_SIZE needs to be for QMAGIC. */
#ifndef ZMAGIC_DISK_BLOCK_SIZE
#define ZMAGIC_DISK_BLOCK_SIZE PAGE_SIZE
#endif
#define N_DISK_BLOCK_SIZE(x) \
(N_MAGIC(x) == ZMAGIC ? ZMAGIC_DISK_BLOCK_SIZE : PAGE_SIZE)
/* Offset in an a.out of the start of the text section. */
#ifndef N_TXTOFF
#define N_TXTOFF(x) \
@ -142,7 +161,7 @@ struct external_exec
N_SHARED_LIB(x) ? 0 : \
N_HEADER_IN_TEXT(x) ? \
EXEC_BYTES_SIZE : /* no padding */\
PAGE_SIZE /* a page of padding */\
ZMAGIC_DISK_BLOCK_SIZE /* a page of padding */\
)
#endif
/* Size of the text section. It's always as stated, except that we
@ -174,15 +193,21 @@ struct external_exec
/* Offsets of the various portions of the file after the text segment. */
/* For {N,Q,Z}MAGIC, there is padding to make the data segment start
on a page boundary. Most of the time the a_text field (and thus
N_TXTSIZE) already contains this padding. But if it doesn't (I
think maybe this happens on BSDI and/or 386BSD), then add it. */
/* For {Q,Z}MAGIC, there is padding to make the data segment start on
a page boundary. Most of the time the a_text field (and thus
N_TXTSIZE) already contains this padding. It is possible that for
BSDI and/or 386BSD it sometimes doesn't contain the padding, and
perhaps we should be adding it here. But this seems kind of
questionable and probably should be BSDI/386BSD-specific if we do
do it.
For NMAGIC (at least for hp300 BSD, probably others), there is
padding in memory only, not on disk, so we must *not* ever pad here
for NMAGIC. */
#ifndef N_DATOFF
#define N_DATOFF(x) \
(N_MAGIC(x) == OMAGIC ? N_TXTOFF(x) + N_TXTSIZE(x) : \
PAGE_SIZE + ((N_TXTOFF(x) + N_TXTSIZE(x) - 1) & ~(PAGE_SIZE - 1)))
(N_TXTOFF(x) + N_TXTSIZE(x))
#endif
#ifndef N_TRELOFF
@ -263,6 +288,17 @@ struct internal_nlist {
#define N_WARNING 0x1e
/* Weak symbols. These are a GNU extension to the a.out format. The
semantics are those of ELF weak symbols. Weak symbols are always
externally visible. The N_WEAK? values are squeezed into the
available slots. The value of a N_WEAKU symbol is 0. The values
of the other types are the definitions. */
#define N_WEAKU 0x0d /* Weak undefined symbol. */
#define N_WEAKA 0x0e /* Weak absolute symbol. */
#define N_WEAKT 0x0f /* Weak text symbol. */
#define N_WEAKD 0x10 /* Weak data symbol. */
#define N_WEAKB 0x11 /* Weak bss symbol. */
/* Relocations
There are two types of relocation flavours for a.out systems,
@ -286,25 +322,25 @@ struct reloc_std_external {
bfd_byte r_type[1]; /* relocation type */
};
#define RELOC_STD_BITS_PCREL_BIG 0x80
#define RELOC_STD_BITS_PCREL_LITTLE 0x01
#define RELOC_STD_BITS_PCREL_BIG ((unsigned int) 0x80)
#define RELOC_STD_BITS_PCREL_LITTLE ((unsigned int) 0x01)
#define RELOC_STD_BITS_LENGTH_BIG 0x60
#define RELOC_STD_BITS_LENGTH_SH_BIG 5 /* To shift to units place */
#define RELOC_STD_BITS_LENGTH_LITTLE 0x06
#define RELOC_STD_BITS_LENGTH_BIG ((unsigned int) 0x60)
#define RELOC_STD_BITS_LENGTH_SH_BIG 5
#define RELOC_STD_BITS_LENGTH_LITTLE ((unsigned int) 0x06)
#define RELOC_STD_BITS_LENGTH_SH_LITTLE 1
#define RELOC_STD_BITS_EXTERN_BIG 0x10
#define RELOC_STD_BITS_EXTERN_LITTLE 0x08
#define RELOC_STD_BITS_EXTERN_BIG ((unsigned int) 0x10)
#define RELOC_STD_BITS_EXTERN_LITTLE ((unsigned int) 0x08)
#define RELOC_STD_BITS_BASEREL_BIG 0x08
#define RELOC_STD_BITS_BASEREL_LITTLE 0x08
#define RELOC_STD_BITS_BASEREL_BIG ((unsigned int) 0x08)
#define RELOC_STD_BITS_BASEREL_LITTLE ((unsigned int) 0x10)
#define RELOC_STD_BITS_JMPTABLE_BIG 0x04
#define RELOC_STD_BITS_JMPTABLE_LITTLE 0x04
#define RELOC_STD_BITS_JMPTABLE_BIG ((unsigned int) 0x04)
#define RELOC_STD_BITS_JMPTABLE_LITTLE ((unsigned int) 0x20)
#define RELOC_STD_BITS_RELATIVE_BIG 0x02
#define RELOC_STD_BITS_RELATIVE_LITTLE 0x02
#define RELOC_STD_BITS_RELATIVE_BIG ((unsigned int) 0x02)
#define RELOC_STD_BITS_RELATIVE_LITTLE ((unsigned int) 0x40)
#define RELOC_STD_SIZE (BYTES_IN_WORD + 3 + 1) /* Bytes per relocation entry */
@ -346,12 +382,12 @@ struct reloc_ext_external {
bfd_byte r_addend[BYTES_IN_WORD]; /* datum addend */
};
#define RELOC_EXT_BITS_EXTERN_BIG 0x80
#define RELOC_EXT_BITS_EXTERN_LITTLE 0x01
#define RELOC_EXT_BITS_EXTERN_BIG ((unsigned int) 0x80)
#define RELOC_EXT_BITS_EXTERN_LITTLE ((unsigned int) 0x01)
#define RELOC_EXT_BITS_TYPE_BIG 0x1F
#define RELOC_EXT_BITS_TYPE_BIG ((unsigned int) 0x1F)
#define RELOC_EXT_BITS_TYPE_SH_BIG 0
#define RELOC_EXT_BITS_TYPE_LITTLE 0xF8
#define RELOC_EXT_BITS_TYPE_LITTLE ((unsigned int) 0xF8)
#define RELOC_EXT_BITS_TYPE_SH_LITTLE 3
/* Bytes per relocation entry */
@ -402,7 +438,13 @@ enum reloc_type
RELOC_CONST,
RELOC_CONSTH,
/* All the new ones I can think of, for sparc v9 */
RELOC_64, /* data[0:63] = addend + sv */
RELOC_DISP64, /* data[0:63] = addend - pc + sv */
RELOC_WDISP21, /* data[0:20] = (addend + sv - pc)>>2 */
RELOC_DISP21, /* data[0:20] = addend - pc + sv */
RELOC_DISP14, /* data[0:13] = addend - pc + sv */
/* Q .
What are the other ones,
Since this is a clean slate, can we throw away the ones we dont

View File

@ -6,10 +6,14 @@
#ifndef __GNU_AR_H__
#define __GNU_AR_H__
#define ARMAG "!<arch>\n" /* For COFF and a.out archives */
#define ARMAGB "!<bout>\n" /* For b.out archives */
/* Note that the usual '\n' in magic strings may translate to different
characters, as allowed by ANSI. '\012' has a fixed value, and remains
compatible with existing BSDish archives. */
#define ARMAG "!<arch>\012" /* For COFF and a.out archives */
#define ARMAGB "!<bout>\012" /* For b.out archives */
#define SARMAG 8
#define ARFMAG "`\n"
#define ARFMAG "`\012"
/* The ar_date field of the armap (__.SYMDEF) member of an archive
must be greater than the modified date of the entire file, or

View File

@ -219,11 +219,11 @@ __define_stab (N_LENG, 0xfe, "LENG")
| 00 UNDEF | 02 ABS | 04 TEXT | 06 DATA |
| 01 |EXT | 03 |EXT | 05 |EXT | 07 |EXT |
| 08 BSS | 0A INDR | 0C FN_SEQ | 0E |
| 09 |EXT | 0B | 0D | 0F |
| 08 BSS | 0A INDR | 0C FN_SEQ | 0E WEAKA |
| 09 |EXT | 0B | 0D WEAKU | 0F WEAKT |
| 10 | 12 COMM | 14 SETA | 16 SETT |
| 11 | 13 | 15 | 17 |
| 10 WEAKD | 12 COMM | 14 SETA | 16 SETT |
| 11 WEAKB | 13 | 15 | 17 |
| 18 SETD | 1A SETB | 1C SETV | 1E WARNING|
| 19 | 1B | 1D | 1F FN |

View File

@ -28,6 +28,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "value.h" /* for read_register */
#include "target.h" /* for target_has_stack */
#include "inferior.h" /* for read_pc */
#include "annotate.h"
/* Is ADDR inside the startup file? Note that if your machine
has a way to detect the bottom of the stack, there is no need
@ -192,6 +193,7 @@ flush_cached_frames ()
obstack_init (&frame_cache_obstack);
current_frame = (struct frame_info *) 0; /* Invalidate cache */
annotate_frames_invalid ();
}
/* Flush the frame cache, and start a new one if necessary. */
@ -389,13 +391,18 @@ get_prev_frame_info (next_frame)
Only change here is that create_new_frame would no longer init extra
frame info; SETUP_ARBITRARY_FRAME would have to do that.
INIT_PREV_FRAME(fromleaf, prev)
Replace INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC.
Replace INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC. This should
also return a flag saying whether to keep the new frame, or
whether to discard it, because on some machines (e.g. mips) it
is really awkward to have FRAME_CHAIN_VALID called *before*
INIT_EXTRA_FRAME_INFO (there is no good way to get information
deduced in FRAME_CHAIN_VALID into the extra fields of the new frame).
std_frame_pc(fromleaf, prev)
This is the default setting for INIT_PREV_FRAME. It just does what
the default INIT_FRAME_PC does. Some machines will call it from
INIT_PREV_FRAME (either at the beginning, the end, or in the middle).
Some machines won't use it.
kingdon@cygnus.com, 13Apr93. */
kingdon@cygnus.com, 13Apr93, 31Jan94. */
#ifdef INIT_FRAME_PC_FIRST
INIT_FRAME_PC_FIRST (fromleaf, prev);
@ -406,10 +413,25 @@ get_prev_frame_info (next_frame)
#endif
/* This entry is in the frame queue now, which is good since
FRAME_SAVED_PC may use that queue to figure out it's value
FRAME_SAVED_PC may use that queue to figure out its value
(see tm-sparc.h). We want the pc saved in the inferior frame. */
INIT_FRAME_PC(fromleaf, prev);
/* If ->frame and ->pc are unchanged, we are in the process of getting
ourselves into an infinite backtrace. Some architectures check this
in FRAME_CHAIN or thereabouts, but it seems like there is no reason
this can't be an architecture-independent check. */
if (next_frame != NULL)
{
if (prev->frame == next_frame->frame
&& prev->pc == next_frame->pc)
{
next_frame->prev = NULL;
obstack_free (&frame_cache_obstack, prev);
return NULL;
}
}
find_pc_partial_function (prev->pc, &name,
(CORE_ADDR *)NULL,(CORE_ADDR *)NULL);
if (IN_SIGTRAMP (prev->pc, name))
@ -726,7 +748,7 @@ find_pc_partial_function (pc, name, address, endaddr)
/* See if we're in a transfer table for Sun shared libs. */
if (msymbol -> type == mst_text)
if (msymbol -> type == mst_text || msymbol -> type == mst_file_text)
cache_pc_function_low = SYMBOL_VALUE_ADDRESS (msymbol);
else
/* It is a transfer table for Sun shared libraries. */
@ -785,6 +807,29 @@ block_innermost_frame (block)
}
}
/* Return the full FRAME which corresponds to the given FRAME_ADDR
or NULL if no FRAME on the chain corresponds to FRAME_ADDR. */
FRAME
find_frame_addr_in_frame_chain (frame_addr)
FRAME_ADDR frame_addr;
{
FRAME frame = NULL;
if (frame_addr == (CORE_ADDR)0)
return NULL;
while (1)
{
frame = get_prev_frame (frame);
if (frame == NULL)
return NULL;
if (FRAME_FP (frame) == frame_addr)
return frame;
}
}
#ifdef SIGCONTEXT_PC_OFFSET
/* Get saved user PC for sigtramp from sigcontext for BSD style sigtramp. */

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* Data structures associated with breakpoints in GDB.
Copyright (C) 1992 Free Software Foundation, Inc.
Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
This file is part of GDB.
@ -39,9 +39,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
enum bptype {
bp_breakpoint, /* Normal breakpoint */
bp_hardware_breakpoint, /* Hardware assisted breakpoint */
bp_until, /* used by until command */
bp_finish, /* used by finish command */
bp_watchpoint, /* Watchpoint */
bp_hardware_watchpoint, /* Hardware assisted watchpoint */
bp_read_watchpoint, /* read watchpoint, (hardware assisted) */
bp_access_watchpoint, /* access watchpoint, (hardware assisted) */
bp_longjmp, /* secret breakpoint to find longjmp() */
bp_longjmp_resume, /* secret breakpoint to escape longjmp() */
@ -49,6 +53,23 @@ enum bptype {
stepping over signal handlers, and for skipping prologues. */
bp_step_resume,
/* Used by wait_for_inferior for stepping over signal handlers. */
bp_through_sigtramp,
/* Used to detect when a watchpoint expression has gone out of
scope. These breakpoints are usually not visible to the user.
This breakpoint has some interesting properties:
1) There's always a 1:1 mapping between watchpoints
on local variables and watchpoint_scope breakpoints.
2) It automatically deletes itself and the watchpoint it's
associated with when hit.
3) It can never be disabled. */
bp_watchpoint_scope,
/* The breakpoint at the end of a call dummy. */
/* FIXME: What if the function we are calling longjmp()s out of the
call, or the user gets out with the "return" command? We currently
@ -144,9 +165,31 @@ struct breakpoint
valid anywhere (e.g. consists just of global symbols). */
struct block *exp_valid_block;
/* Value of the watchpoint the last time we checked it. */
value val;
value_ptr val;
/* Holds the value chain for a hardware watchpoint expression. */
value_ptr val_chain;
/* Holds the address of the related watchpoint_scope breakpoint
when using watchpoints on local variables (might the concept
of a related breakpoint be useful elsewhere, if not just call
it the watchpoint_scope breakpoint or something like that. FIXME). */
struct breakpoint *related_breakpoint;
/* Holds the frame address which identifies the frame this watchpoint
should be evaluated in, or NULL if the watchpoint should be evaluated
on the outermost frame. */
FRAME_ADDR watchpoint_frame;
/* Thread number for thread-specific breakpoint, or -1 if don't care */
int thread;
/* Count of the number of times this breakpoint was taken, dumped
with the info, but not used for anything else. Useful for
seeing how many times you hit a break prior to the program
aborting, so you can back up to just before the abort. */
int hit_count;
};
/* The following stuff is an abstract data type "bpstat" ("breakpoint status").
@ -207,6 +250,13 @@ enum bpstat_what_main_action {
/* Clear longjmp_resume breakpoint, then handle as BPSTAT_WHAT_SINGLE. */
BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE,
/* Clear step resume breakpoint, and keep checking. */
BPSTAT_WHAT_STEP_RESUME,
/* Clear through_sigtramp breakpoint, muck with trap_expected, and keep
checking. */
BPSTAT_WHAT_THROUGH_SIGTRAMP,
/* This is just used to keep track of how many enums there are. */
BPSTAT_WHAT_LAST
};
@ -214,11 +264,6 @@ enum bpstat_what_main_action {
struct bpstat_what {
enum bpstat_what_main_action main_action;
/* Did we hit the step resume breakpoint? This is separate from the
main_action to allow for it to be combined with any of the main
actions. */
int step_resume;
/* Did we hit a call dummy breakpoint? This only goes with a main_action
of BPSTAT_WHAT_STOP_SILENT or BPSTAT_WHAT_STOP_NOISY (the concept of
continuing from a call dummy without popping the frame is not a
@ -274,7 +319,7 @@ struct bpstat
/* Commands left to be done. */
struct command_line *commands;
/* Old value associated with a watchpoint. */
value old_val;
value_ptr old_val;
/* Nonzero if this breakpoint tells us to print the frame. */
char print;
@ -294,11 +339,11 @@ struct bpstat
struct frame_info;
#endif
extern int
breakpoint_here_p PARAMS ((CORE_ADDR));
extern int breakpoint_here_p PARAMS ((CORE_ADDR));
extern int
breakpoint_thread_match PARAMS ((CORE_ADDR, int));
extern int frame_in_dummy PARAMS ((struct frame_info *));
extern int breakpoint_thread_match PARAMS ((CORE_ADDR, int));
extern void
until_break_command PARAMS ((char *, int));
@ -354,6 +399,8 @@ disable_longjmp_breakpoint PARAMS ((void));
extern void
set_longjmp_resume_breakpoint PARAMS ((CORE_ADDR, FRAME));
extern void clear_breakpoint_hit_counts PARAMS ((void));
/* The following are for displays, which aren't really breakpoints, but
here is as good a place as any for them. */

View File

@ -39,6 +39,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "buildsym.h" /* Our own declarations */
#undef EXTERN
/* For cleanup_undefined_types and finish_global_stabs (somewhat
questionable--see comment where we call them). */
#include "stabsread.h"
static int
compare_line_numbers PARAMS ((const void *, const void *));
@ -347,6 +351,15 @@ make_blockvector (objfile)
if (BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i-1))
> BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i)))
{
/* FIXME-32x64: loses if CORE_ADDR doesn't fit in a
long. Possible solutions include a version of
complain which takes a callback, a
sprintf_address_numeric to match
print_address_numeric, or a way to set up a GDB_FILE
* which causes sprintf rather than fprintf to be
called. */
complain (&blockvector_complaint,
(unsigned long) BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i)));
}
@ -392,8 +405,9 @@ start_subfile (name, dirname)
current_subfile = subfile;
/* Save its name and compilation directory name */
subfile->name = (name == NULL)? NULL : strdup (name);
subfile->dirname = (dirname == NULL) ? NULL : strdup (dirname);
subfile->name = (name == NULL) ? NULL : savestring (name, strlen (name));
subfile->dirname =
(dirname == NULL) ? NULL : savestring (dirname, strlen (dirname));
/* Initialize line-number recording for this subfile. */
subfile->line_vector = NULL;
@ -466,7 +480,7 @@ patch_subfile_names (subfile, name)
&& subfile->name[strlen(subfile->name)-1] == '/')
{
subfile->dirname = subfile->name;
subfile->name = strdup (name);
subfile->name = savestring (name, strlen (name));
/* Default the source language to whatever can be deduced from
the filename. If nothing can be deduced (such as for a C/C++

View File

@ -1,5 +1,5 @@
/* C language support routines for GDB, the GNU debugger.
Copyright 1992, 1993 Free Software Foundation, Inc.
Copyright 1992, 1993, 1994 Free Software Foundation, Inc.
This file is part of GDB.
@ -32,7 +32,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
static void
emit_char (c, stream, quoter)
register int c;
FILE *stream;
GDB_FILE *stream;
int quoter;
{
@ -81,7 +81,7 @@ emit_char (c, stream, quoter)
static void
c_printchar (c, stream)
int c;
FILE *stream;
GDB_FILE *stream;
{
fputs_filtered ("'", stream);
emit_char (c, stream, '\'');
@ -95,7 +95,7 @@ c_printchar (c, stream)
static void
c_printstr (stream, string, length, force_ellipses)
FILE *stream;
GDB_FILE *stream;
char *string;
unsigned int length;
int force_ellipses;
@ -116,7 +116,7 @@ c_printstr (stream, string, length, force_ellipses)
if (length == 0)
{
fputs_filtered ("\"\"", stdout);
fputs_filtered ("\"\"", stream);
return;
}
@ -243,7 +243,7 @@ c_create_fundamental_type (objfile, typeid)
case FT_SIGNED_CHAR:
type = init_type (TYPE_CODE_INT,
TARGET_CHAR_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED, "signed char", objfile);
0, "signed char", objfile);
break;
case FT_UNSIGNED_CHAR:
type = init_type (TYPE_CODE_INT,
@ -258,7 +258,7 @@ c_create_fundamental_type (objfile, typeid)
case FT_SIGNED_SHORT:
type = init_type (TYPE_CODE_INT,
TARGET_SHORT_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED, "short", objfile); /* FIXME-fnf */
0, "short", objfile); /* FIXME-fnf */
break;
case FT_UNSIGNED_SHORT:
type = init_type (TYPE_CODE_INT,
@ -273,7 +273,7 @@ c_create_fundamental_type (objfile, typeid)
case FT_SIGNED_INTEGER:
type = init_type (TYPE_CODE_INT,
TARGET_INT_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED, "int", objfile); /* FIXME -fnf */
0, "int", objfile); /* FIXME -fnf */
break;
case FT_UNSIGNED_INTEGER:
type = init_type (TYPE_CODE_INT,
@ -288,7 +288,7 @@ c_create_fundamental_type (objfile, typeid)
case FT_SIGNED_LONG:
type = init_type (TYPE_CODE_INT,
TARGET_LONG_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED, "long", objfile); /* FIXME -fnf */
0, "long", objfile); /* FIXME -fnf */
break;
case FT_UNSIGNED_LONG:
type = init_type (TYPE_CODE_INT,
@ -303,7 +303,7 @@ c_create_fundamental_type (objfile, typeid)
case FT_SIGNED_LONG_LONG:
type = init_type (TYPE_CODE_INT,
TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED, "signed long long", objfile);
0, "signed long long", objfile);
break;
case FT_UNSIGNED_LONG_LONG:
type = init_type (TYPE_CODE_INT,
@ -404,8 +404,7 @@ const struct language_defn c_language_defn = {
c_create_fundamental_type, /* Create fundamental type in this language */
c_print_type, /* Print a type using appropriate syntax */
c_val_print, /* Print a value using appropriate syntax */
&BUILTIN_TYPE_LONGEST, /* longest signed integral type */
&BUILTIN_TYPE_UNSIGNED_LONGEST,/* longest unsigned integral type */
c_value_print, /* Print a top-level value */
&builtin_type_double, /* longest floating point type */ /*FIXME*/
{"", "", "", ""}, /* Binary format info */
{"0%lo", "0", "o", ""}, /* Octal format info */
@ -428,8 +427,7 @@ const struct language_defn cplus_language_defn = {
c_create_fundamental_type, /* Create fundamental type in this language */
c_print_type, /* Print a type using appropriate syntax */
c_val_print, /* Print a value using appropriate syntax */
&BUILTIN_TYPE_LONGEST, /* longest signed integral type */
&BUILTIN_TYPE_UNSIGNED_LONGEST,/* longest unsigned integral type */
c_value_print, /* Print a top-level value */
&builtin_type_double, /* longest floating point type */ /*FIXME*/
{"", "", "", ""}, /* Binary format info */
{"0%lo", "0", "o", ""}, /* Octal format info */
@ -439,9 +437,33 @@ const struct language_defn cplus_language_defn = {
LANG_MAGIC
};
const struct language_defn asm_language_defn = {
"asm", /* Language name */
language_asm,
c_builtin_types,
range_check_off,
type_check_off,
c_parse,
c_error,
c_printchar, /* Print a character constant */
c_printstr, /* Function to print string constant */
c_create_fundamental_type, /* Create fundamental type in this language */
c_print_type, /* Print a type using appropriate syntax */
c_val_print, /* Print a value using appropriate syntax */
c_value_print, /* Print a top-level value */
&builtin_type_double, /* longest floating point type */ /*FIXME*/
{"", "", "", ""}, /* Binary format info */
{"0%lo", "0", "o", ""}, /* Octal format info */
{"%ld", "", "d", ""}, /* Decimal format info */
{"0x%lx", "0x", "x", ""}, /* Hex format info */
c_op_print_tab, /* expression operators for printing */
LANG_MAGIC
};
void
_initialize_c_language ()
{
add_language (&c_language_defn);
add_language (&cplus_language_defn);
add_language (&asm_language_defn);
}

View File

@ -17,6 +17,10 @@ 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. */
#ifdef __STDC__ /* Forward decls for prototypes */
struct value;
#endif
extern int
c_parse PARAMS ((void)); /* Defined in c-exp.y */
@ -24,8 +28,11 @@ extern void
c_error PARAMS ((char *)); /* Defined in c-exp.y */
extern void /* Defined in c-typeprint.c */
c_print_type PARAMS ((struct type *, char *, FILE *, int, int));
c_print_type PARAMS ((struct type *, char *, GDB_FILE *, int, int));
extern int
c_val_print PARAMS ((struct type *, char *, CORE_ADDR, FILE *, int, int,
c_val_print PARAMS ((struct type *, char *, CORE_ADDR, GDB_FILE *, int, int,
int, enum val_prettyprint));
extern int
c_value_print PARAMS ((struct value *, GDB_FILE *, int, enum val_prettyprint));

View File

@ -36,22 +36,20 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <string.h>
#include <errno.h>
extern int demangle; /* whether to print C++ syms raw or source-form */
static void
c_type_print_args PARAMS ((struct type *, GDB_FILE *));
static void
c_type_print_args PARAMS ((struct type *, FILE *));
c_type_print_varspec_suffix PARAMS ((struct type *, GDB_FILE *, int, int, int));
static void
c_type_print_varspec_suffix PARAMS ((struct type *, FILE *, int, int, int));
static void
cp_type_print_derivation_info PARAMS ((FILE *, struct type *));
cp_type_print_derivation_info PARAMS ((GDB_FILE *, struct type *));
void
c_type_print_varspec_prefix PARAMS ((struct type *, FILE *, int, int));
c_type_print_varspec_prefix PARAMS ((struct type *, GDB_FILE *, int, int));
void
c_type_print_base PARAMS ((struct type *, FILE *, int, int));
c_type_print_base PARAMS ((struct type *, GDB_FILE *, int, int));
/* Print a description of a type in the format of a
@ -62,7 +60,7 @@ void
c_typedef_print (type, new, stream)
struct type *type;
struct symbol *new;
FILE *stream;
GDB_FILE *stream;
{
switch (current_language->la_language)
{
@ -104,7 +102,7 @@ void
c_print_type (type, varstring, stream, show, level)
struct type *type;
char *varstring;
FILE *stream;
GDB_FILE *stream;
int show;
int level;
{
@ -145,7 +143,7 @@ cp_type_print_method_args (args, prefix, varstring, staticp, stream)
char *prefix;
char *varstring;
int staticp;
FILE *stream;
GDB_FILE *stream;
{
int i;
@ -199,7 +197,7 @@ cp_type_print_method_args (args, prefix, varstring, staticp, stream)
static void
cp_type_print_derivation_info (stream, type)
FILE *stream;
GDB_FILE *stream;
struct type *type;
{
char *name;
@ -231,7 +229,7 @@ cp_type_print_derivation_info (stream, type)
void
c_type_print_varspec_prefix (type, stream, show, passed_a_ptr)
struct type *type;
FILE *stream;
GDB_FILE *stream;
int show;
int passed_a_ptr;
{
@ -266,7 +264,7 @@ c_type_print_varspec_prefix (type, stream, show, passed_a_ptr)
case TYPE_CODE_METHOD:
if (passed_a_ptr)
fprintf (stream, "(");
fprintf_unfiltered (stream, "(");
c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
if (passed_a_ptr)
{
@ -316,7 +314,7 @@ c_type_print_varspec_prefix (type, stream, show, passed_a_ptr)
static void
c_type_print_args (type, stream)
struct type *type;
FILE *stream;
GDB_FILE *stream;
{
int i;
struct type **args;
@ -358,7 +356,7 @@ c_type_print_args (type, stream)
static void
c_type_print_varspec_suffix (type, stream, show, passed_a_ptr, demangled_args)
struct type *type;
FILE *stream;
GDB_FILE *stream;
int show;
int passed_a_ptr;
int demangled_args;
@ -409,12 +407,12 @@ c_type_print_varspec_suffix (type, stream, show, passed_a_ptr, demangled_args)
break;
case TYPE_CODE_FUNC:
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
passed_a_ptr, 0);
if (passed_a_ptr)
fprintf_filtered (stream, ")");
if (!demangled_args)
fprintf_filtered (stream, "()");
c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
passed_a_ptr, 0);
break;
case TYPE_CODE_UNDEF:
@ -443,12 +441,12 @@ c_type_print_varspec_suffix (type, stream, show, passed_a_ptr, demangled_args)
SHOW positive means print details about the type (e.g. enum values),
and print structure elements passing SHOW - 1 for show.
SHOW zero means just print the type name or struct tag if there is one.
SHOW negative means just print the type name or struct tag if there is one.
If there is no name, print something sensible but concise like
"struct {...}".
SHOW negative means the same things as SHOW zero. The difference is that
zero is used for printing structure elements and -1 is used for the
"whatis" command. But I don't see any need to distinguish.
SHOW zero means just print the type name or struct tag if there is one.
If there is no name, print something sensible but not as concise like
"struct {int x; int y;}".
LEVEL is the number of spaces to indent by.
We increase it for some recursive calls. */
@ -456,7 +454,7 @@ c_type_print_varspec_suffix (type, stream, show, passed_a_ptr, demangled_args)
void
c_type_print_base (type, stream, show, level)
struct type *type;
FILE *stream;
GDB_FILE *stream;
int show;
int level;
{
@ -488,6 +486,8 @@ c_type_print_base (type, stream, show, level)
return;
}
check_stub_type (type);
switch (TYPE_CODE (type))
{
case TYPE_CODE_ARRAY:
@ -521,16 +521,14 @@ c_type_print_base (type, stream, show, level)
fputs_filtered (" ", stream);
}
wrap_here (" ");
if (show <= 0)
if (show < 0)
{
/* If we just printed a tag name, no need to print anything else. */
if (TYPE_TAG_NAME (type) == NULL)
fprintf_filtered (stream, "{...}");
}
else if (show > 0)
else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
{
check_stub_type (type);
cp_type_print_derivation_info (stream, type);
fprintf_filtered (stream, "{\n");
@ -665,7 +663,7 @@ c_type_print_base (type, stream, show, level)
if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
{
/* Keep GDB from crashing here. */
fprintf (stream, "<undefined type> %s;\n",
fprintf_unfiltered (stream, "<undefined type> %s;\n",
TYPE_FN_FIELD_PHYSNAME (f, j));
break;
}
@ -730,13 +728,13 @@ c_type_print_base (type, stream, show, level)
}
wrap_here (" ");
if (show <= 0)
if (show < 0)
{
/* If we just printed a tag name, no need to print anything else. */
if (TYPE_TAG_NAME (type) == NULL)
fprintf_filtered (stream, "{...}");
}
else if (show > 0)
else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
{
fprintf_filtered (stream, "{");
len = TYPE_NFIELDS (type);

View File

@ -1,5 +1,6 @@
/* Support for printing C values for GDB, the GNU debugger.
Copyright 1986, 1988, 1989, 1991 Free Software Foundation, Inc.
Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994
Free Software Foundation, Inc.
This file is part of GDB.
@ -29,16 +30,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* BEGIN-FIXME */
extern int vtblprint; /* Controls printing of vtbl's */
extern int demangle; /* whether to print C++ syms raw or src-form */
extern void
cp_print_class_member PARAMS ((char *, struct type *, FILE *, char *));
cp_print_class_member PARAMS ((char *, struct type *, GDB_FILE *, char *));
extern void
cp_print_class_method PARAMS ((char *, struct type *, FILE *));
cp_print_class_method PARAMS ((char *, struct type *, GDB_FILE *));
extern void
cp_print_value_fields PARAMS ((struct type *, char *, FILE *, int, int,
cp_print_value_fields PARAMS ((struct type *, char *, GDB_FILE *, int, int,
enum val_prettyprint, struct type **));
extern int
@ -53,11 +53,11 @@ cp_is_vtbl_member PARAMS ((struct type *));
/* BEGIN-FIXME: Hooks into c-typeprint.c */
extern void
c_type_print_varspec_prefix PARAMS ((struct type *, FILE *, int, int));
c_type_print_varspec_prefix PARAMS ((struct type *, GDB_FILE *, int, int));
extern void
cp_type_print_method_args PARAMS ((struct type **, char *, char *, int,
FILE *));
GDB_FILE *));
/* END-FIXME */
@ -83,7 +83,7 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
struct type *type;
char *valaddr;
CORE_ADDR address;
FILE *stream;
GDB_FILE *stream;
int format;
int deref_ref;
int recurse;
@ -109,9 +109,26 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
print_spaces_filtered (2 + 2 * recurse, stream);
}
/* For an array of chars, print with string syntax. */
if (eltlen == 1 && TYPE_CODE (elttype) == TYPE_CODE_INT
if (eltlen == 1 &&
((TYPE_CODE (elttype) == TYPE_CODE_INT)
|| ((current_language->la_language == language_m2)
&& (TYPE_CODE (elttype) == TYPE_CODE_CHAR)))
&& (format == 0 || format == 's'))
{
/* If requested, look for the first null char and only print
elements up to it. */
if (stop_print_at_null)
{
int temp_len;
/* Look for a NULL char. */
for (temp_len = 0;
valaddr[temp_len]
&& temp_len < len && temp_len < print_max;
temp_len++);
len = temp_len;
}
LA_PRINT_STRING (stream, valaddr, len, 0);
i = len;
}
@ -145,6 +162,15 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
print_scalar_formatted (valaddr, type, format, 0, stream);
break;
}
if (vtblprint && cp_is_vtbl_ptr_type(type))
{
/* Print the unmangled name if desired. */
/* Print vtable entry - we only get here if we ARE using
-fvtable_thunks. (Otherwise, look under TYPE_CODE_STRUCT.) */
print_address_demangle(extract_address (valaddr, TYPE_LENGTH (type)),
stream, demangle);
break;
}
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD)
{
cp_print_class_method (valaddr, type, stream);
@ -171,7 +197,7 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
if (addressprint && format != 's')
{
fprintf_filtered (stream, "0x%lx", (unsigned long)addr);
print_address_numeric (addr, 1, stream);
}
/* For a pointer to char or unsigned char, also print the string
@ -197,17 +223,17 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
fputs_filtered (SYMBOL_SOURCE_NAME (msymbol), stream);
fputs_filtered (">", stream);
}
if (vtblprint)
if (vt_address && vtblprint)
{
value vt_val;
value_ptr vt_val;
struct symbol *wsym = (struct symbol *)NULL;
struct type *wtype;
struct symtab *s;
struct block *block = (struct block *)NULL;
int is_this_fld;
wsym = lookup_symbol (SYMBOL_NAME(msymbol), block,
if (msymbol != NULL)
wsym = lookup_symbol (SYMBOL_NAME(msymbol), block,
VAR_NAMESPACE, &is_this_fld, &s);
if (wsym)
@ -230,9 +256,10 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
}
}
/* Return number of characters printed, plus one for the
terminating null if we have "reached the end". */
return (i + (print_max && i != print_max));
/* Return number of characters printed, including the terminating
'\0' if we reached the end. val_print_string takes care including
the terminating '\0' if necessary. */
return i;
}
break;
@ -250,8 +277,10 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
}
if (addressprint)
{
fprintf_filtered (stream, "@0x%lx",
unpack_long (builtin_type_int, valaddr));
fprintf_filtered (stream, "@");
print_address_numeric
(extract_address (valaddr,
TARGET_PTR_BIT / HOST_CHAR_BIT), 1, stream);
if (deref_ref)
fputs_filtered (": ", stream);
}
@ -260,7 +289,7 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
{
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_UNDEF)
{
value deref_val =
value_ptr deref_val =
value_at
(TYPE_TARGET_TYPE (type),
unpack_pointer (lookup_pointer_type (builtin_type_void),
@ -286,6 +315,8 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
if (vtblprint && cp_is_vtbl_ptr_type(type))
{
/* Print the unmangled name if desired. */
/* Print vtable entry - we only get here if NOT using
-fvtable_thunks. (Otherwise, look under TYPE_CODE_PTR.) */
print_address_demangle(*((int *) (valaddr + /* FIXME bytesex */
TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8)),
stream, demangle);
@ -340,6 +371,16 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
/* Do something at least vaguely reasonable, for example if the
language is set wrong. */
case TYPE_CODE_RANGE:
/* FIXME: create_range_type does not set the unsigned bit in a
range type (I think it probably should copy it from the target
type), so we won't print values which are too large to
fit in a signed integer correctly. */
/* FIXME: Doesn't handle ranges of enums correctly. (Can't just
print with the target type, though, because the size of our type
and the target type might differ). */
/* FALLTHROUGH */
case TYPE_CODE_INT:
format = format ? format : output_format;
if (format)
@ -396,11 +437,6 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
fprintf_filtered (stream, "<error type>");
break;
case TYPE_CODE_RANGE:
/* FIXME, we should not ever have to print one of these yet. */
fprintf_filtered (stream, "<range type>");
break;
case TYPE_CODE_UNDEF:
/* This happens (without TYPE_FLAG_STUB set) on systems which don't use
dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar"
@ -411,6 +447,67 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
default:
error ("Invalid C/C++ type code %d in symbol table.", TYPE_CODE (type));
}
fflush (stream);
gdb_flush (stream);
return (0);
}
int
c_value_print (val, stream, format, pretty)
value_ptr val;
GDB_FILE *stream;
int format;
enum val_prettyprint pretty;
{
/* A "repeated" value really contains several values in a row.
They are made by the @ operator.
Print such values as if they were arrays. */
if (VALUE_REPEATED (val))
{
register unsigned int n = VALUE_REPETITIONS (val);
register unsigned int typelen = TYPE_LENGTH (VALUE_TYPE (val));
fprintf_filtered (stream, "{");
/* Print arrays of characters using string syntax. */
if (typelen == 1 && TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT
&& format == 0)
LA_PRINT_STRING (stream, VALUE_CONTENTS (val), n, 0);
else
{
value_print_array_elements (val, stream, format, pretty);
}
fprintf_filtered (stream, "}");
return (n * typelen);
}
else
{
struct type *type = VALUE_TYPE (val);
/* If it is a pointer, indicate what it points to.
Print type also if it is a reference.
C++: if it is a member pointer, we will take care
of that when we print it. */
if (TYPE_CODE (type) == TYPE_CODE_PTR ||
TYPE_CODE (type) == TYPE_CODE_REF)
{
/* Hack: remove (char *) for char strings. Their
type is indicated by the quoted string anyway. */
if (TYPE_CODE (type) == TYPE_CODE_PTR &&
TYPE_LENGTH (TYPE_TARGET_TYPE (type)) == sizeof(char) &&
TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_INT &&
!TYPE_UNSIGNED (TYPE_TARGET_TYPE (type)))
{
/* Print nothing */
}
else
{
fprintf_filtered (stream, "(");
type_print (type, "", stream, -1);
fprintf_filtered (stream, ") ");
}
}
return (val_print (type, VALUE_CONTENTS (val),
VALUE_ADDRESS (val), stream, format, 1, 0, pretty));
}
}

View File

@ -52,7 +52,7 @@ chill_demangle (mangled)
static void
chill_printchar (c, stream)
register int c;
FILE *stream;
GDB_FILE *stream;
{
c &= 0xFF; /* Avoid sign bit follies */
@ -79,7 +79,7 @@ chill_printchar (c, stream)
static void
chill_printstr (stream, string, length, force_ellipses)
FILE *stream;
GDB_FILE *stream;
char *string;
unsigned int length;
int force_ellipses;
@ -95,7 +95,7 @@ chill_printstr (stream, string, length, force_ellipses)
if (length == 0)
{
chill_printchar ('\0', stream);
fputs_filtered ("\"\"", stream);
return;
}
@ -128,7 +128,7 @@ chill_printstr (stream, string, length, force_ellipses)
{
if (in_control_form || in_literal_form)
{
fputs_filtered ("'//", stream);
fputs_filtered ("\"//", stream);
in_control_form = in_literal_form = 0;
}
chill_printchar (c, stream);
@ -145,10 +145,10 @@ chill_printstr (stream, string, length, force_ellipses)
{
if (in_control_form)
{
fputs_filtered ("'//", stream);
fputs_filtered ("\"//", stream);
in_control_form = 0;
}
fputs_filtered ("'", stream);
fputs_filtered ("\"", stream);
in_literal_form = 1;
}
fprintf_filtered (stream, "%c", c);
@ -159,10 +159,10 @@ chill_printstr (stream, string, length, force_ellipses)
{
if (in_literal_form)
{
fputs_filtered ("'//", stream);
fputs_filtered ("\"//", stream);
in_literal_form = 0;
}
fputs_filtered ("c'", stream);
fputs_filtered ("c\"", stream);
in_control_form = 1;
}
fprintf_filtered (stream, "%.2x", c);
@ -174,7 +174,7 @@ chill_printstr (stream, string, length, force_ellipses)
/* Terminate the quotes if necessary. */
if (in_literal_form || in_control_form)
{
fputs_filtered ("'", stream);
fputs_filtered ("\"", stream);
}
if (force_ellipses || (i < length))
{
@ -182,6 +182,21 @@ chill_printstr (stream, string, length, force_ellipses)
}
}
/* Return 1 if TYPE is a varying string or array. */
int
chill_is_varying_struct (type)
struct type *type;
{
if (TYPE_CODE (type) != TYPE_CODE_STRUCT)
return 0;
if (TYPE_NFIELDS (type) != 2)
return 0;
if (strcmp (TYPE_FIELD_NAME (type, 0), "__var_length") != 0)
return 0;
return 1;
}
static struct type *
chill_create_fundamental_type (objfile, typeid)
struct objfile *objfile;
@ -212,13 +227,13 @@ chill_create_fundamental_type (objfile, typeid)
type = init_type (TYPE_CODE_CHAR, 1, TYPE_FLAG_UNSIGNED, "CHAR", objfile);
break;
case FT_SIGNED_CHAR:
type = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_SIGNED, "BYTE", objfile);
type = init_type (TYPE_CODE_INT, 1, 0, "BYTE", objfile);
break;
case FT_UNSIGNED_CHAR:
type = init_type (TYPE_CODE_INT, 1, TYPE_FLAG_UNSIGNED, "UBYTE", objfile);
break;
case FT_SHORT: /* Chill ints are 2 bytes */
type = init_type (TYPE_CODE_INT, 2, TYPE_FLAG_SIGNED, "INT", objfile);
type = init_type (TYPE_CODE_INT, 2, 0, "INT", objfile);
break;
case FT_UNSIGNED_SHORT: /* Chill ints are 2 bytes */
type = init_type (TYPE_CODE_INT, 2, TYPE_FLAG_UNSIGNED, "UINT", objfile);
@ -227,7 +242,7 @@ chill_create_fundamental_type (objfile, typeid)
case FT_SIGNED_INTEGER: /* FIXME? */
case FT_LONG: /* Chill longs are 4 bytes */
case FT_SIGNED_LONG: /* Chill longs are 4 bytes */
type = init_type (TYPE_CODE_INT, 4, TYPE_FLAG_SIGNED, "LONG", objfile);
type = init_type (TYPE_CODE_INT, 4, 0, "LONG", objfile);
break;
case FT_UNSIGNED_INTEGER: /* FIXME? */
case FT_UNSIGNED_LONG: /* Chill longs are 4 bytes */
@ -300,8 +315,7 @@ const struct language_defn chill_language_defn = {
chill_create_fundamental_type,/* Create fundamental type in this language */
chill_print_type, /* Print a type using appropriate syntax */
chill_val_print, /* Print a value using appropriate syntax */
&BUILTIN_TYPE_LONGEST, /* longest signed integral type */
&BUILTIN_TYPE_UNSIGNED_LONGEST,/* longest unsigned integral type */
chill_value_print, /* Print a top-levl value */
&builtin_type_chill_real, /* longest floating point type */
{"", "B'", "", ""}, /* Binary format info */
{"O'%lo", "O'", "o", ""}, /* Octal format info */

View File

@ -17,6 +17,10 @@ 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. */
#ifdef __STDC__ /* Forward decls for prototypes */
struct value;
#endif
extern int
chill_parse PARAMS ((void)); /* Defined in ch-exp.y */
@ -24,8 +28,17 @@ extern void
chill_error PARAMS ((char *)); /* Defined in ch-exp.y */
extern void /* Defined in ch-typeprint.c */
chill_print_type PARAMS ((struct type *, char *, FILE *, int, int));
chill_print_type PARAMS ((struct type *, char *, GDB_FILE *, int, int));
extern int
chill_val_print PARAMS ((struct type *, char *, CORE_ADDR, FILE *, int, int,
chill_val_print PARAMS ((struct type *, char *, CORE_ADDR, GDB_FILE *, int, int,
int, enum val_prettyprint));
extern int
chill_value_print PARAMS ((struct value *, GDB_FILE *,
int, enum val_prettyprint));
extern int
chill_is_varying_struct PARAMS ((struct type *type));

View File

@ -31,18 +31,19 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "language.h"
#include "demangle.h"
#include "ch-lang.h"
#include "typeprint.h"
#include <string.h>
#include <errno.h>
static void
chill_type_print_base PARAMS ((struct type *, FILE *, int, int));
chill_type_print_base PARAMS ((struct type *, GDB_FILE *, int, int));
void
chill_print_type (type, varstring, stream, show, level)
struct type *type;
char *varstring;
FILE *stream;
GDB_FILE *stream;
int show;
int level;
{
@ -69,11 +70,10 @@ chill_print_type (type, varstring, stream, show, level)
static void
chill_type_print_base (type, stream, show, level)
struct type *type;
FILE *stream;
GDB_FILE *stream;
int show;
int level;
{
char *name;
register int len;
register int i;
struct type *index_type;
@ -99,6 +99,8 @@ chill_type_print_base (type, stream, show, level)
return;
}
check_stub_type (type);
switch (TYPE_CODE (type))
{
case TYPE_CODE_PTR:
@ -111,6 +113,14 @@ chill_type_print_base (type, stream, show, level)
chill_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
break;
case TYPE_CODE_BOOL:
/* FIXME: we should probably just print the TYPE_NAME, in case
anyone ever fixes the compiler to give us the real names
in the presence of the chill equivalent of typedef (assuming
there is one). */
fprintf_filtered (stream, "BOOL");
break;
case TYPE_CODE_ARRAY:
range_type = TYPE_FIELD_TYPE (type, 0);
index_type = TYPE_TARGET_TYPE (range_type);
@ -124,11 +134,22 @@ chill_type_print_base (type, stream, show, level)
chill_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level);
break;
case TYPE_CODE_BITSTRING:
fprintf_filtered (stream, "BOOLS (%d)",
TYPE_FIELD_BITPOS (TYPE_FIELD_TYPE(type,0), 1) + 1);
break;
case TYPE_CODE_SET:
fputs_filtered ("POWERSET ", stream);
chill_print_type (TYPE_FIELD_TYPE (type, 0), "", stream,
show - 1, level);
break;
case TYPE_CODE_STRING:
range_type = TYPE_FIELD_TYPE (type, 0);
index_type = TYPE_TARGET_TYPE (range_type);
high_bound = TYPE_FIELD_BITPOS (range_type, 1);
fputs_filtered ("CHAR (", stream);
fputs_filtered ("CHARS (", stream);
print_type_scalar (index_type, high_bound + 1, stream);
fputs_filtered (")", stream);
break;
@ -147,20 +168,16 @@ chill_type_print_base (type, stream, show, level)
break;
case TYPE_CODE_STRUCT:
fprintf_filtered (stream, "STRUCT ");
if ((name = type_name_no_tag (type)) != NULL)
if (chill_is_varying_struct (type))
{
fputs_filtered (name, stream);
fputs_filtered (" ", stream);
wrap_here (" ");
}
if (show < 0)
{
fprintf_filtered (stream, "(...)");
chill_type_print_base (TYPE_FIELD_TYPE (type, 1),
stream, show, level);
fputs_filtered (" VARYING", stream);
}
else
{
check_stub_type (type);
fprintf_filtered (stream, "STRUCT ");
fprintf_filtered (stream, "(\n");
if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0))
{
@ -178,11 +195,42 @@ chill_type_print_base (type, stream, show, level)
len = TYPE_NFIELDS (type);
for (i = TYPE_N_BASECLASSES (type); i < len; i++)
{
struct type *field_type = TYPE_FIELD_TYPE (type, i);
QUIT;
print_spaces_filtered (level + 4, stream);
chill_print_type (TYPE_FIELD_TYPE (type, i),
TYPE_FIELD_NAME (type, i),
stream, show - 1, level + 4);
if (TYPE_CODE (field_type) == TYPE_CODE_UNION)
{ int j; /* variant number */
fputs_filtered ("CASE OF\n", stream);
for (j = 0; j < TYPE_NFIELDS (field_type); j++)
{ int k; /* variant field index */
struct type *variant_type
= TYPE_FIELD_TYPE (field_type, j);
int var_len = TYPE_NFIELDS (variant_type);
print_spaces_filtered (level + 4, stream);
if (strcmp (TYPE_FIELD_NAME (field_type, j),
"else") == 0)
fputs_filtered ("ELSE\n", stream);
else
fputs_filtered (":\n", stream);
if (TYPE_CODE (variant_type) != TYPE_CODE_STRUCT)
error ("variant record confusion");
for (k = 0; k < var_len; k++)
{
print_spaces_filtered (level + 8, stream);
chill_print_type (TYPE_FIELD_TYPE (variant_type, k),
TYPE_FIELD_NAME (variant_type, k),
stream, show - 1, level + 8);
if (k < (var_len - 1))
fputs_filtered (",", stream);
fputs_filtered ("\n", stream);
}
}
fputs_filtered ("ESAC\n", stream);
}
else
chill_print_type (field_type,
TYPE_FIELD_NAME (type, i),
stream, show - 1, level + 4);
if (i < (len - 1))
{
fputs_filtered (",", stream);
@ -194,11 +242,53 @@ chill_type_print_base (type, stream, show, level)
}
break;
case TYPE_CODE_RANGE:
if (TYPE_DUMMY_RANGE (type))
chill_type_print_base (TYPE_TARGET_TYPE (type),
stream, show, level);
else if (TYPE_TARGET_TYPE (type))
{
chill_type_print_base (TYPE_TARGET_TYPE (type),
stream, show, level);
fputs_filtered (" (", stream);
print_type_scalar (TYPE_TARGET_TYPE (type),
TYPE_FIELD_BITPOS (type, 0), stream);
fputs_filtered (":", stream);
print_type_scalar (TYPE_TARGET_TYPE (type),
TYPE_FIELD_BITPOS (type, 1), stream);
fputs_filtered (")", stream);
}
else
fprintf_filtered (stream, "RANGE? (%s : %d)",
TYPE_FIELD_BITPOS (type, 0),
TYPE_FIELD_BITPOS (type, 1));
break;
case TYPE_CODE_ENUM:
{
register int lastval = 0;
fprintf_filtered (stream, "SET (");
len = TYPE_NFIELDS (type);
for (i = 0; i < len; i++)
{
QUIT;
if (i) fprintf_filtered (stream, ", ");
wrap_here (" ");
fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
if (lastval != TYPE_FIELD_BITPOS (type, i))
{
fprintf_filtered (stream, " = %d", TYPE_FIELD_BITPOS (type, i));
lastval = TYPE_FIELD_BITPOS (type, i);
}
lastval++;
}
fprintf_filtered (stream, ")");
}
break;
case TYPE_CODE_VOID:
case TYPE_CODE_UNDEF:
case TYPE_CODE_ERROR:
case TYPE_CODE_RANGE:
case TYPE_CODE_ENUM:
case TYPE_CODE_UNION:
case TYPE_CODE_METHOD:
error ("missing language support in chill_type_print_base");

View File

@ -1,5 +1,6 @@
/* Support for printing Chill values for GDB, the GNU debugger.
Copyright 1986, 1988, 1989, 1991 Free Software Foundation, Inc.
Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994
Free Software Foundation, Inc.
This file is part of GDB.
@ -26,12 +27,106 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "value.h"
#include "language.h"
#include "demangle.h"
#include "c-lang.h" /* For c_val_print */
#include "typeprint.h"
#include "ch-lang.h"
static void
chill_print_value_fields PARAMS ((struct type *, char *, FILE *, int, int,
chill_print_value_fields PARAMS ((struct type *, char *, GDB_FILE *, int, int,
enum val_prettyprint, struct type **));
/* Print the elements of an array.
Similar to val_print_array_elements, but prints
element indexes (in Chill syntax). */
static void
chill_val_print_array_elements (type, valaddr, address, stream,
format, deref_ref, recurse, pretty)
struct type *type;
char *valaddr;
CORE_ADDR address;
GDB_FILE *stream;
int format;
int deref_ref;
int recurse;
enum val_prettyprint pretty;
{
unsigned int i = 0;
unsigned int things_printed = 0;
unsigned len;
struct type *elttype;
struct type *range_type = TYPE_FIELD_TYPE (type, 0);
struct type *index_type = TYPE_TARGET_TYPE (range_type);
unsigned eltlen;
/* Position of the array element we are examining to see
whether it is repeated. */
unsigned int rep1;
/* Number of repetitions we have detected so far. */
unsigned int reps;
LONGEST low_bound = TYPE_FIELD_BITPOS (range_type, 0);
LONGEST high_bound = TYPE_FIELD_BITPOS (range_type, 1);
elttype = TYPE_TARGET_TYPE (type);
eltlen = TYPE_LENGTH (elttype);
len = TYPE_LENGTH (type) / eltlen;
annotate_array_section_begin (i, elttype);
for (; i < len && things_printed < print_max; i++)
{
if (i != 0)
{
if (prettyprint_arrays)
{
fprintf_filtered (stream, ",\n");
print_spaces_filtered (2 + 2 * recurse, stream);
}
else
{
fprintf_filtered (stream, ", ");
}
}
wrap_here (n_spaces (2 + 2 * recurse));
rep1 = i + 1;
reps = 1;
while ((rep1 < len) &&
!memcmp (valaddr + i * eltlen, valaddr + rep1 * eltlen, eltlen))
{
++reps;
++rep1;
}
fputs_filtered ("(", stream);
print_type_scalar (index_type, low_bound + i, stream);
if (reps > 1)
{
fputs_filtered (":", stream);
print_type_scalar (index_type, low_bound + i + reps - 1, stream);
fputs_filtered ("): ", stream);
val_print (elttype, valaddr + i * eltlen, 0, stream, format,
deref_ref, recurse + 1, pretty);
i = rep1 - 1;
things_printed += 1;
}
else
{
fputs_filtered ("): ", stream);
val_print (elttype, valaddr + i * eltlen, 0, stream, format,
deref_ref, recurse + 1, pretty);
annotate_elt ();
things_printed++;
}
}
annotate_array_section_end ();
if (i < len)
{
fprintf_filtered (stream, "...");
}
}
/* Print data of type TYPE located at VALADDR (within GDB), which came from
the inferior at address ADDRESS, onto stdio stream STREAM according to
FORMAT (a letter or 0 for natural format). The data at VALADDR is in
@ -51,7 +146,7 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
struct type *type;
char *valaddr;
CORE_ADDR address;
FILE *stream;
GDB_FILE *stream;
int format;
int deref_ref;
int recurse;
@ -72,8 +167,8 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
print_spaces_filtered (2 + 2 * recurse, stream);
}
fprintf_filtered (stream, "[");
val_print_array_elements (type, valaddr, address, stream, format,
deref_ref, recurse, pretty, 0);
chill_val_print_array_elements (type, valaddr, address, stream,
format, deref_ref, recurse, pretty);
fprintf_filtered (stream, "]");
}
else
@ -126,6 +221,7 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
}
else
{
/* FIXME: Why is this using builtin_type_chill_bool not type? */
val = unpack_long (builtin_type_chill_bool, valaddr);
fprintf_filtered (stream, val ? "TRUE" : "FALSE");
}
@ -146,6 +242,13 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
}
addr = unpack_pointer (type, valaddr);
elttype = TYPE_TARGET_TYPE (type);
/* We assume a NULL pointer is all zeros ... */
if (addr == 0)
{
fputs_filtered ("NULL", stream);
return 0;
}
if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
{
@ -156,7 +259,7 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
}
if (addressprint && format != 's')
{
fprintf_filtered (stream, "H'%lx", (unsigned long) addr);
print_address_numeric (addr, 1, stream);
}
/* For a pointer to char or unsigned char, also print the string
@ -182,12 +285,6 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
print_scalar_formatted (valaddr, type, format, 0, stream);
break;
}
if (addressprint && format != 's')
{
/* This used to say `addr', which is unset at this point.
Is `address' what is meant? */
fprintf_filtered (stream, "H'%lx ", (unsigned long) address);
}
i = TYPE_LENGTH (type);
LA_PRINT_STRING (stream, valaddr, i, 0);
/* Return number of characters printed, plus one for the terminating
@ -195,7 +292,81 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
return (i + (print_max && i != print_max));
break;
case TYPE_CODE_BITSTRING:
case TYPE_CODE_SET:
elttype = TYPE_FIELD_TYPE (type, 0);
check_stub_type (elttype);
if (TYPE_FLAGS (elttype) & TYPE_FLAG_STUB)
{
fprintf_filtered (stream, "<incomplete type>");
gdb_flush (stream);
break;
}
{
struct type *range = elttype;
int low_bound = TYPE_LOW_BOUND (range);
int high_bound = TYPE_HIGH_BOUND (range);
int i;
int is_bitstring = TYPE_CODE (type) == TYPE_CODE_BITSTRING;
int need_comma = 0;
if (is_bitstring)
fputs_filtered ("B'", stream);
else
fputs_filtered ("[", stream);
for (i = low_bound; i <= high_bound; i++)
{
int element = value_bit_index (type, valaddr, i);
if (is_bitstring)
fprintf_filtered (stream, "%d", element);
else if (element)
{
if (need_comma)
fputs_filtered (", ", stream);
print_type_scalar (TYPE_TARGET_TYPE (range), i, stream);
need_comma = 1;
/* Look for a continuous range of true elements. */
if (i+1 <= high_bound && value_bit_index (type, valaddr, ++i))
{
int j = i; /* j is the upper bound so far of the range */
fputs_filtered (":", stream);
while (i+1 <= high_bound
&& value_bit_index (type, valaddr, ++i))
j = i;
print_type_scalar (TYPE_TARGET_TYPE (range), j, stream);
}
}
}
if (is_bitstring)
fputs_filtered ("'", stream);
else
fputs_filtered ("]", stream);
}
break;
case TYPE_CODE_STRUCT:
if (chill_is_varying_struct (type))
{
struct type *inner = TYPE_FIELD_TYPE (type, 1);
long length = unpack_long (TYPE_FIELD_TYPE (type, 0), valaddr);
char *data_addr = valaddr + TYPE_FIELD_BITPOS (type, 1) / 8;
switch (TYPE_CODE (inner))
{
case TYPE_CODE_STRING:
if (length > TYPE_LENGTH (type))
{
fprintf_filtered (stream,
"<dynamic length %d > static length %d>",
length, TYPE_LENGTH (type));
}
LA_PRINT_STRING (stream, data_addr, length, 0);
return length;
default:
break;
}
}
chill_print_value_fields (type, valaddr, stream, format, recurse, pretty,
0);
break;
@ -203,8 +374,12 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
case TYPE_CODE_REF:
if (addressprint)
{
fprintf_filtered (stream, "LOC(H'%lx)",
unpack_long (builtin_type_int, valaddr));
fprintf_filtered (stream, "LOC(");
print_address_numeric
(extract_address (valaddr, TARGET_PTR_BIT / HOST_CHAR_BIT),
1,
stream);
fprintf_filtered (stream, ")");
if (deref_ref)
fputs_filtered (": ", stream);
}
@ -213,7 +388,7 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
{
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_UNDEF)
{
value deref_val =
value_ptr deref_val =
value_at
(TYPE_TARGET_TYPE (type),
unpack_pointer (lookup_pointer_type (builtin_type_void),
@ -233,19 +408,24 @@ chill_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
deref_ref, recurse, pretty);
break;
case TYPE_CODE_RANGE:
if (TYPE_TARGET_TYPE (type))
chill_val_print (TYPE_TARGET_TYPE (type), valaddr, address, stream,
format, deref_ref, recurse, pretty);
break;
case TYPE_CODE_MEMBER:
case TYPE_CODE_UNION:
case TYPE_CODE_FUNC:
case TYPE_CODE_VOID:
case TYPE_CODE_ERROR:
case TYPE_CODE_RANGE:
default:
/* Let's derfer printing to the C printer, rather than
/* Let's defer printing to the C printer, rather than
print an error message. FIXME! */
c_val_print (type, valaddr, address, stream, format,
deref_ref, recurse, pretty);
}
fflush (stream);
gdb_flush (stream);
return (0);
}
@ -263,7 +443,7 @@ chill_print_value_fields (type, valaddr, stream, format, recurse, pretty,
dont_print)
struct type *type;
char *valaddr;
FILE *stream;
GDB_FILE *stream;
int format;
int recurse;
enum val_prettyprint pretty;
@ -304,7 +484,7 @@ chill_print_value_fields (type, valaddr, stream, format, recurse, pretty,
fputs_filtered (": ", stream);
if (TYPE_FIELD_PACKED (type, i))
{
value v;
value_ptr v;
/* Bitfields require special handling, especially due to byte
order problems. */
@ -329,4 +509,73 @@ chill_print_value_fields (type, valaddr, stream, format, recurse, pretty,
}
fprintf_filtered (stream, "]");
}
int
chill_value_print (val, stream, format, pretty)
value_ptr val;
GDB_FILE *stream;
int format;
enum val_prettyprint pretty;
{
/* A "repeated" value really contains several values in a row.
They are made by the @ operator.
Print such values as if they were arrays. */
if (VALUE_REPEATED (val))
{
register unsigned int n = VALUE_REPETITIONS (val);
register unsigned int typelen = TYPE_LENGTH (VALUE_TYPE (val));
fprintf_filtered (stream, "[");
/* Print arrays of characters using string syntax. */
if (typelen == 1 && TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT
&& format == 0)
LA_PRINT_STRING (stream, VALUE_CONTENTS (val), n, 0);
else
{
value_print_array_elements (val, stream, format, pretty);
}
fprintf_filtered (stream, "]");
return (n * typelen);
}
else
{
struct type *type = VALUE_TYPE (val);
/* If it is a pointer, indicate what it points to.
Print type also if it is a reference.
C++: if it is a member pointer, we will take care
of that when we print it. */
if (TYPE_CODE (type) == TYPE_CODE_PTR ||
TYPE_CODE (type) == TYPE_CODE_REF)
{
char *valaddr = VALUE_CONTENTS (val);
CORE_ADDR addr = unpack_pointer (type, valaddr);
if (TYPE_CODE (type) != TYPE_CODE_PTR || addr != 0)
{
int i;
char *name = TYPE_NAME (type);
if (name)
fputs_filtered (name, stream);
else if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID)
fputs_filtered ("PTR", stream);
else
{
fprintf_filtered (stream, "(");
type_print (type, "", stream, -1);
fprintf_filtered (stream, ")");
}
fprintf_filtered (stream, "(");
i = val_print (type, valaddr, VALUE_ADDRESS (val),
stream, format, 1, 0, pretty);
fprintf_filtered (stream, ")");
return i;
}
}
return (val_print (type, VALUE_CONTENTS (val),
VALUE_ADDRESS (val), stream, format, 1, 0, pretty));
}
}

View File

@ -36,56 +36,39 @@
#define _RDATA ".rdata"
#define _SDATA ".sdata"
#define _SBSS ".sbss"
#define _LITA ".lita"
#define _LIT4 ".lit4"
#define _LIT8 ".lit8"
#define _LIB ".lib"
#define _INIT ".init"
#define _FINI ".fini"
#define _PDATA ".pdata"
#define _XDATA ".xdata"
/* ECOFF uses some additional section flags. */
#define STYP_RDATA 0x100
#define STYP_SDATA 0x200
#define STYP_SBSS 0x400
#define STYP_ECOFF_FINI 0x1000000
#define STYP_LIT8 0x8000000
#define STYP_LIT4 0x10000000
#define STYP_RDATA 0x100
#define STYP_SDATA 0x200
#define STYP_SBSS 0x400
#define STYP_ECOFF_FINI 0x1000000
#define STYP_EXTENDESC 0x2000000 /* 0x02FFF000 bits => scn type, rest clr */
#define STYP_LITA 0x4000000
#define STYP_LIT8 0x8000000
#define STYP_LIT4 0x10000000
#define STYP_ECOFF_LIB 0x40000000
#define STYP_ECOFF_INIT 0x80000000
#define STYP_OTHER_LOAD (STYP_ECOFF_INIT | STYP_ECOFF_FINI)
/* extended section types */
#define STYP_COMMENT 0x2100000
#define STYP_XDATA 0x2400000
#define STYP_PDATA 0x2800000
/* The linker needs a section to hold small common variables while
linking. There is no convenient way to create it when the linker
needs it, so we always create one for each BFD. We then avoid
writing it out. */
#define SCOMMON ".scommon"
/* The ECOFF a.out header carries information about register masks and
the gp value. The assembler needs to be able to write out this
information, and objcopy needs to be able to copy it from one file
to another. To handle this in BFD, we use a dummy section to hold
the information. We call this section .reginfo, since MIPS ELF has
a .reginfo section which serves a similar purpose. When BFD
recognizes an ECOFF object, it copies the information into a
private data structure. When the .reginfo section is read, the
information is retrieved from the private data structure. When the
.reginfo section is written, the information in the private data
structure is updated. The contents of the .reginfo section, as
seen by programs outside BFD, is a ecoff_reginfo structure. The
contents of the structure are as seen on the host, so no swapping
issues arise.
The assembler used to update the private BFD data structures
directly. With this approach, it instead just creates a .reginfo
section and updates that. The real advantage of this approach is
that objcopy works automatically. */
#define REGINFO ".reginfo"
struct ecoff_reginfo
{
bfd_vma gp_value; /* GP register value. */
unsigned long gprmask; /* General registers used. */
unsigned long cprmask[4]; /* Coprocessor registers used. */
unsigned long fprmask; /* Floating pointer registers used. */
};
/* If the extern bit in a reloc is 1, then r_symndx is an index into
the external symbol table. If the extern bit is 0, then r_symndx
indicates a section, and is one of the following values. */
@ -105,6 +88,8 @@ struct ecoff_reginfo
#define RELOC_SECTION_LITA 13
#define RELOC_SECTION_ABS 14
#define NUM_RELOC_SECTIONS 15
/********************** STABS **********************/
/* gcc uses mips-tfile to output type information in special stabs
@ -146,42 +131,42 @@ struct tir_ext {
unsigned char t_tq23[1];
};
#define TIR_BITS1_FBITFIELD_BIG 0x80
#define TIR_BITS1_FBITFIELD_LITTLE 0x01
#define TIR_BITS1_FBITFIELD_BIG ((unsigned int) 0x80)
#define TIR_BITS1_FBITFIELD_LITTLE ((unsigned int) 0x01)
#define TIR_BITS1_CONTINUED_BIG 0x40
#define TIR_BITS1_CONTINUED_LITTLE 0x02
#define TIR_BITS1_CONTINUED_BIG ((unsigned int) 0x40)
#define TIR_BITS1_CONTINUED_LITTLE ((unsigned int) 0x02)
#define TIR_BITS1_BT_BIG 0x3F
#define TIR_BITS1_BT_BIG ((unsigned int) 0x3F)
#define TIR_BITS1_BT_SH_BIG 0
#define TIR_BITS1_BT_LITTLE 0xFC
#define TIR_BITS1_BT_LITTLE ((unsigned int) 0xFC)
#define TIR_BITS1_BT_SH_LITTLE 2
#define TIR_BITS_TQ4_BIG 0xF0
#define TIR_BITS_TQ4_BIG ((unsigned int) 0xF0)
#define TIR_BITS_TQ4_SH_BIG 4
#define TIR_BITS_TQ5_BIG 0x0F
#define TIR_BITS_TQ5_BIG ((unsigned int) 0x0F)
#define TIR_BITS_TQ5_SH_BIG 0
#define TIR_BITS_TQ4_LITTLE 0x0F
#define TIR_BITS_TQ4_LITTLE ((unsigned int) 0x0F)
#define TIR_BITS_TQ4_SH_LITTLE 0
#define TIR_BITS_TQ5_LITTLE 0xF0
#define TIR_BITS_TQ5_LITTLE ((unsigned int) 0xF0)
#define TIR_BITS_TQ5_SH_LITTLE 4
#define TIR_BITS_TQ0_BIG 0xF0
#define TIR_BITS_TQ0_BIG ((unsigned int) 0xF0)
#define TIR_BITS_TQ0_SH_BIG 4
#define TIR_BITS_TQ1_BIG 0x0F
#define TIR_BITS_TQ1_BIG ((unsigned int) 0x0F)
#define TIR_BITS_TQ1_SH_BIG 0
#define TIR_BITS_TQ0_LITTLE 0x0F
#define TIR_BITS_TQ0_LITTLE ((unsigned int) 0x0F)
#define TIR_BITS_TQ0_SH_LITTLE 0
#define TIR_BITS_TQ1_LITTLE 0xF0
#define TIR_BITS_TQ1_LITTLE ((unsigned int) 0xF0)
#define TIR_BITS_TQ1_SH_LITTLE 4
#define TIR_BITS_TQ2_BIG 0xF0
#define TIR_BITS_TQ2_BIG ((unsigned int) 0xF0)
#define TIR_BITS_TQ2_SH_BIG 4
#define TIR_BITS_TQ3_BIG 0x0F
#define TIR_BITS_TQ3_BIG ((unsigned int) 0x0F)
#define TIR_BITS_TQ3_SH_BIG 0
#define TIR_BITS_TQ2_LITTLE 0x0F
#define TIR_BITS_TQ2_LITTLE ((unsigned int) 0x0F)
#define TIR_BITS_TQ2_SH_LITTLE 0
#define TIR_BITS_TQ3_LITTLE 0xF0
#define TIR_BITS_TQ3_LITTLE ((unsigned int) 0xF0)
#define TIR_BITS_TQ3_SH_LITTLE 4
/* Relative symbol external record */
@ -191,19 +176,19 @@ struct rndx_ext {
};
#define RNDX_BITS0_RFD_SH_LEFT_BIG 4
#define RNDX_BITS1_RFD_BIG 0xF0
#define RNDX_BITS1_RFD_BIG ((unsigned int) 0xF0)
#define RNDX_BITS1_RFD_SH_BIG 4
#define RNDX_BITS0_RFD_SH_LEFT_LITTLE 0
#define RNDX_BITS1_RFD_LITTLE 0x0F
#define RNDX_BITS1_RFD_LITTLE ((unsigned int) 0x0F)
#define RNDX_BITS1_RFD_SH_LEFT_LITTLE 8
#define RNDX_BITS1_INDEX_BIG 0x0F
#define RNDX_BITS1_INDEX_BIG ((unsigned int) 0x0F)
#define RNDX_BITS1_INDEX_SH_LEFT_BIG 16
#define RNDX_BITS2_INDEX_SH_LEFT_BIG 8
#define RNDX_BITS3_INDEX_SH_LEFT_BIG 0
#define RNDX_BITS1_INDEX_LITTLE 0xF0
#define RNDX_BITS1_INDEX_LITTLE ((unsigned int) 0xF0)
#define RNDX_BITS1_INDEX_SH_LITTLE 4
#define RNDX_BITS2_INDEX_SH_LEFT_LITTLE 4
#define RNDX_BITS3_INDEX_SH_LEFT_LITTLE 12
@ -249,14 +234,136 @@ union aux_ext {
#define AUX_PUT_COUNT(bigend, val, ax) \
AUX_PUT_ANY ((bigend), (val), (ax), a_count)
/* Prototypes for the swapping functions. These require that sym.h be
included before this file. */
/********************** SYMBOLS **********************/
extern void ecoff_swap_tir_in PARAMS ((int bigend, struct tir_ext *, TIR *));
extern void ecoff_swap_tir_out PARAMS ((int bigend, TIR *, struct tir_ext *));
extern void ecoff_swap_rndx_in PARAMS ((int bigend, struct rndx_ext *,
RNDXR *));
extern void ecoff_swap_rndx_out PARAMS ((int bigend, RNDXR *,
struct rndx_ext *));
/* For efficiency, gdb deals directly with the unswapped symbolic
information (that way it only takes the time to swap information
that it really needs to read). gdb originally retrieved the
information directly from the BFD backend information, but that
strategy, besides being sort of ugly, does not work for MIPS ELF,
which also uses ECOFF debugging information. This structure holds
pointers to the (mostly) unswapped symbolic information. */
struct ecoff_debug_info
{
/* The swapped ECOFF symbolic header. */
HDRR symbolic_header;
/* Pointers to the unswapped symbolic information. Note that the
pointers to external structures point to different sorts of
information on different ECOFF targets. The ecoff_debug_swap
structure provides the sizes of the structures and the functions
needed to swap the information in and out. These pointers are
all pointers to arrays, not single structures. They will be NULL
if there are no instances of the relevant structure. These
fields are also used by the assembler to output ECOFF debugging
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 */
/* These fields are used when linking. They may disappear at some
point. */
char *ssext_end;
PTR external_ext_end;
/* When linking, this field holds a mapping from the input FDR
numbers to the output numbers, and is used when writing out the
external symbols. It is NULL if no mapping is required. */
RFDT *ifdmap;
/* The swapped FDR information. Currently this is never NULL, but
code using this structure should probably double-check in case
this changes in the future. This is a pointer to an array, not a
single structure. */
FDR *fdr;
/* When relaxing MIPS embedded PIC code, we may need to adjust
symbol values when they are output. This is a linked list of
structures indicating how values should be adjusted. There is no
requirement that the entries be in any order, or that they not
overlap. This field is normally NULL, in which case no
adjustments need to be made. */
struct ecoff_value_adjust *adjust;
};
/* This structure describes how to adjust symbol values when
outputting MIPS embedded PIC code. These adjustments only apply to
the internal symbols, as the external symbol values will come from
the hash table and have already been adjusted. */
struct ecoff_value_adjust
{
/* Next entry on adjustment list. */
struct ecoff_value_adjust *next;
/* Starting VMA of adjustment. This is the VMA in the ECOFF file,
not the offset from the start of the section. Thus it should
indicate a particular section. */
bfd_vma start;
/* Ending VMA of adjustment. */
bfd_vma end;
/* Adjustment. This should be added to the value of the symbol, or
FDR. This is zero for the last entry in the array. */
long adjust;
};
/********************** SWAPPING **********************/
/* The generic ECOFF code needs to be able to swap debugging
information in and out in the specific format used by a particular
ECOFF implementation. This structure provides the information
needed to do this. */
struct ecoff_debug_swap
{
/* Symbol table magic number. */
int sym_magic;
/* Alignment of debugging information. E.g., 4. */
bfd_size_type debug_align;
/* 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 *));
void (*swap_tir_in) PARAMS ((int, const struct tir_ext *, TIR *));
void (*swap_rndx_in) PARAMS ((int, const struct rndx_ext *, RNDXR *));
/* 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));
void (*swap_tir_out) PARAMS ((int, const TIR *, struct tir_ext *));
void (*swap_rndx_out) PARAMS ((int, const RNDXR *, struct rndx_ext *));
/* Function to read symbol data and set up pointers in
ecoff_debug_info structure. The section argument is used for
ELF, not straight ECOFF. */
boolean (*read_debug_info) PARAMS ((bfd *, asection *,
struct ecoff_debug_info *));
};
#endif /* ! defined (ECOFF_H) */

View File

@ -78,9 +78,9 @@ struct internal_aouthdr
unsigned long fprmask; /* Floating pointer registers used. */
/* Apollo stuff */
long o_inlib;
long o_sri;
long vid[2];
long o_inlib; /* inlib data */
long o_sri; /* Static Resource Information */
long vid[2]; /* Version id */
};
/********************** STORAGE CLASSES **********************/
@ -365,7 +365,11 @@ union internal_auxent
******************************************/
struct
{
long x_scnlen; /* csect length */
union
{ /* csect length or enclosing csect */
long l;
struct coff_ptr_struct *p;
} x_scnlen;
long x_parmhash; /* parm type hash index */
unsigned short x_snhash; /* sect num with parm hash */
unsigned char x_smtyp; /* symbol align and type */
@ -440,7 +444,7 @@ struct internal_reloc
unsigned short r_type; /* Relocation type */
unsigned char r_size; /* Used by RS/6000 and ECOFF */
unsigned char r_extern; /* Used by ECOFF */
unsigned long r_offset; /* Used by RS/6000 and ECOFF */
unsigned long r_offset; /* Used by Alpha ECOFF, SPARC, others */
};
#define R_RELBYTE 017
@ -499,7 +503,7 @@ struct internal_reloc
#define R_CALLR 0x05 /* callr 12 bit disp */
#define R_SEG 0x10 /* set if in segmented mode */
#define R_IMM4H 0x24 /* high nibble */
#define R_DISP7 0x25 /* djnz displacement */
/* H8500 modes */
@ -533,6 +537,6 @@ struct internal_reloc
#define R_SH_IMM4BY4 21
#define R_SH_PCRELIMM8BY2 22
#define R_SH_PCRELIMM8BY4 23
#define R_SH_IMM16 24 /* 16 bit immediate */

View File

@ -184,7 +184,7 @@ typedef struct pdr {
* for use by the static exception system.
*/
typedef struct runtime_pdr {
unsigned long adr; /* memory address of start of procedure */
bfd_vma adr; /* memory address of start of procedure */
long regmask; /* save register mask */
long regoffset; /* save register offset */
long fregmask; /* save floating point register mask */
@ -224,7 +224,7 @@ typedef long LINER, *pLINER;
typedef struct {
long iss; /* index into String Space of name */
long value; /* value of symbol */
bfd_vma value; /* value of symbol */
unsigned st : 6; /* symbol type */
unsigned sc : 5; /* storage class - text, data, etc */
unsigned reserved : 1; /* reserved */
@ -248,7 +248,7 @@ typedef struct {
* Same as the SYMR except it contains file context to determine where
* the index is.
*/
typedef struct {
typedef struct ecoff_extr {
unsigned jmptbl:1; /* symbol is a jump table entry for shlibs */
unsigned cobol_main:1; /* symbol is a cobol main procedure */
unsigned weakext:1; /* symbol is weak external */

View File

@ -112,7 +112,8 @@
#define stStruct 26 /* Beginning of block defining a struct type */
#define stUnion 27 /* Beginning of block defining a union type */
#define stEnum 28 /* Beginning of block defining an enum type */
/* Psuedo-symbols - internal to debugger */
#define stIndirect 34 /* Indirect type specification */
/* Pseudo-symbols - internal to debugger */
#define stStr 60 /* string */
#define stNumber 61 /* pure number (ie. 4 NOR 2+2) */
#define stExpr 62 /* 2+2 vs. 4 */

View File

@ -1,6 +1,6 @@
/* Read coff symbol tables and convert to internal format, for GDB.
Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993
Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994
Free Software Foundation, Inc.
This file is part of GDB.
@ -23,12 +23,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "symtab.h"
#include "gdbtypes.h"
#include "breakpoint.h"
#include "bfd.h"
#include "symfile.h"
#include "objfiles.h"
#include "buildsym.h"
#include "gdb-stabs.h"
#include "complaints.h"
#include <obstack.h>
#include <string.h>
@ -39,6 +35,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "coff/internal.h" /* Internal format of COFF symbols in BFD */
#include "libcoff.h" /* FIXME secret internal data from BFD */
#include "symfile.h"
#include "objfiles.h"
#include "buildsym.h"
#include "gdb-stabs.h"
#include "stabsread.h"
#include "complaints.h"
struct coff_symfile_info {
file_ptr min_lineno_offset; /* Where in file lowest line#s are */
file_ptr max_lineno_offset; /* 1+last byte of line#s in file */
@ -75,13 +78,10 @@ struct coff_symfile_info {
static CORE_ADDR cur_src_start_addr;
static CORE_ADDR cur_src_end_addr;
/* Core address of the end of the first object file. */
static CORE_ADDR first_object_file_end;
/* The addresses of the symbol table stream and number of symbols
of the object file we are reading (as copied into core). */
static FILE *nlist_stream_global;
static GDB_FILE *nlist_stream_global;
static int nlist_nsyms_global;
/* Vector of line number information. */
@ -143,8 +143,6 @@ static struct symbol *opaque_type_chain[HASHSIZE];
struct type *in_function_type;
#endif
struct pending_block *pending_blocks;
/* Complaints about various problems in the file being read */
struct complaint ef_complaint =
@ -223,9 +221,6 @@ free_linetab PARAMS ((void));
static int
init_lineno PARAMS ((int, long, int));
static char *
getfilename PARAMS ((union internal_auxent *));
static char *
getsymname PARAMS ((struct internal_syment *));
@ -257,8 +252,8 @@ coff_symfile_read PARAMS ((struct objfile *, struct section_offsets *, int));
static void
coff_symfile_finish PARAMS ((struct objfile *));
static void
record_minimal_symbol PARAMS ((char *, CORE_ADDR, enum minimal_symbol_type));
static void record_minimal_symbol
PARAMS ((char *, CORE_ADDR, enum minimal_symbol_type, struct objfile *));
static void
coff_end_symtab PARAMS ((struct objfile *));
@ -483,15 +478,17 @@ coff_end_symtab (objfile)
}
static void
record_minimal_symbol (name, address, type)
record_minimal_symbol (name, address, type, objfile)
char *name;
CORE_ADDR address;
enum minimal_symbol_type type;
struct objfile *objfile;
{
/* We don't want TDESC entry points in the minimal symbol table */
if (name[0] == '@') return;
prim_record_minimal_symbol (savestring (name, strlen (name)), address, type);
prim_record_minimal_symbol (savestring (name, strlen (name)), address, type,
objfile);
}
/* coff_symfile_init ()
@ -513,7 +510,7 @@ static void
coff_symfile_init (objfile)
struct objfile *objfile;
{
asection *section, *strsection;
asection *section;
bfd *abfd = objfile->obfd;
/* Allocate struct to keep track of stab reading. */
@ -609,7 +606,7 @@ coff_symfile_read (objfile, section_offsets, mainline)
symfile_bfd = abfd; /* Kludge for swap routines */
/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
desc = fileno ((FILE *)(abfd->iostream)); /* File descriptor */
desc = fileno ((GDB_FILE *)(abfd->iostream)); /* File descriptor */
num_symbols = bfd_get_symcount (abfd); /* How many syms */
symtab_offset = cdata->sym_filepos; /* Symbol table file offset */
stringtab_offset = symtab_offset + /* String table file offset */
@ -662,7 +659,13 @@ coff_symfile_read (objfile, section_offsets, mainline)
/* Sort symbols alphabetically within each block. */
sort_all_symtab_syms ();
{
struct symtab *s;
for (s = objfile -> symtabs; s != NULL; s = s -> next)
{
sort_symtab_syms (s);
}
}
/* Install any minimal symbols that have been collected as the current
minimal symbols for this objfile. */
@ -675,7 +678,7 @@ coff_symfile_read (objfile, section_offsets, mainline)
{
/* FIXME: dubious. Why can't we use something normal like
bfd_get_section_contents? */
fseek ((FILE *) abfd->iostream, abfd->where, 0);
fseek ((GDB_FILE *) abfd->iostream, abfd->where, 0);
stabsize = bfd_section_size (abfd, info->stabsect);
stabstrsize = bfd_section_size (abfd, info->stabstrsect);
@ -723,7 +726,7 @@ read_coff_symtab (symtab_offset, nsyms, objfile)
int nsyms;
struct objfile *objfile;
{
FILE *stream;
GDB_FILE *stream;
register struct context_stack *new;
struct coff_symbol coff_symbol;
register struct coff_symbol *cs = &coff_symbol;
@ -736,7 +739,6 @@ read_coff_symtab (symtab_offset, nsyms, objfile)
/* A .file is open. */
int in_source_file = 0;
int num_object_files = 0;
int next_file_symnum = -1;
/* Name of the current file. */
@ -807,7 +809,7 @@ read_coff_symtab (symtab_offset, nsyms, objfile)
coff_end_symtab (objfile);
coff_start_symtab ();
complete_symtab ("_globals_", 0, first_object_file_end);
complete_symtab ("_globals_", 0, 0);
/* done with all files, everything from here on out is globals */
}
@ -820,7 +822,7 @@ read_coff_symtab (symtab_offset, nsyms, objfile)
if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
{
/* Record all functions -- external and static -- in minsyms. */
record_minimal_symbol (cs->c_name, cs->c_value, mst_text);
record_minimal_symbol (cs->c_name, cs->c_value, mst_text, objfile);
fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
fcn_start_addr = cs->c_value;
@ -849,7 +851,7 @@ read_coff_symtab (symtab_offset, nsyms, objfile)
*/
next_file_symnum = cs->c_value;
if (cs->c_naux > 0)
filestring = getfilename (&main_aux);
filestring = coff_getfilename (&main_aux);
else
filestring = "";
@ -870,11 +872,6 @@ read_coff_symtab (symtab_offset, nsyms, objfile)
if (STREQ (cs->c_name, ".text")) {
/* FIXME: don't wire in ".text" as section name
or symbol name! */
if (++num_object_files == 1) {
/* last address of startup file */
first_object_file_end = cs->c_value +
main_aux.x_scn.x_scnlen;
}
/* Check for in_source_file deals with case of
a file with debugging symbols
followed by a later file with no symbols. */
@ -901,29 +898,32 @@ read_coff_symtab (symtab_offset, nsyms, objfile)
break;
/* fall in for static symbols that don't start with '.' */
case C_EXT:
/* Record external symbols in minsyms if we don't have debug
info for them. FIXME, this is probably the wrong thing
to do. Why don't we record them even if we do have
debug symbol info? What really belongs in the minsyms
anyway? Fred!?? */
if (!SDB_TYPE (cs->c_type)) {
/* FIXME: This is BOGUS Will Robinson!
Coff should provide the SEC_CODE flag for executable sections,
then if we could look up sections by section number we
could see if the flags indicate SEC_CODE. If so, then
record this symbol as a function in the minimal symbol table.
But why are absolute syms recorded as functions, anyway? */
if (cs->c_secnum <= text_bfd_scnum+1) {/* text or abs */
record_minimal_symbol (cs->c_name, cs->c_value,
mst_text);
break;
} else {
record_minimal_symbol (cs->c_name, cs->c_value,
mst_data);
break;
}
}
process_coff_symbol (cs, &main_aux, objfile);
/* Record it in the minimal symbols regardless of SDB_TYPE.
This parallels what we do for other debug formats, and
probably is needed to make print_address_symbolic work right
without the "set fast-symbolic-addr off" kludge. */
/* FIXME: This bogusly assumes the sections are in a certain
order, text (SEC_CODE) sections are before data sections,
etc. */
if (cs->c_secnum <= text_bfd_scnum+1)
{
/* text or absolute. (FIXME, should use mst_abs if
absolute). */
record_minimal_symbol
(cs->c_name, cs->c_value,
cs->c_sclass == C_STAT ? mst_file_text : mst_text,
objfile);
}
else
{
record_minimal_symbol
(cs->c_name, cs->c_value,
cs->c_sclass == C_STAT ? mst_file_data : mst_data,
objfile);
}
if (SDB_TYPE (cs->c_type))
process_coff_symbol (cs, &main_aux, objfile);
break;
case C_FCN:
@ -1119,7 +1119,7 @@ read_one_sym (cs, sym, aux)
{
fread (temp_aux, local_auxesz, 1, nlist_stream_global);
bfd_coff_swap_aux_in (symfile_bfd, temp_aux, sym->n_type, sym->n_sclass,
(char *)aux);
0, cs->c_naux, (char *)aux);
/* If more than one aux entry, read past it (only the first aux
is important). */
for (i = 1; i < cs->c_naux; i++)
@ -1151,6 +1151,11 @@ init_stringtab (chan, offset)
free_stringtab ();
/* If the file is stripped, the offset might be zero, indicating no
string table. Just return with `stringtab' set to null. */
if (offset == 0)
return 0;
if (lseek (chan, offset, 0) < 0)
return -1;
@ -1206,8 +1211,8 @@ getsymname (symbol_entry)
only the last component of the name. Result is in static storage and
is only good for temporary use. */
static char *
getfilename (aux_entry)
char *
coff_getfilename (aux_entry)
union internal_auxent *aux_entry;
{
static char buffer[BUFSIZ];
@ -1413,7 +1418,6 @@ process_coff_symbol (cs, aux, objfile)
= (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
sizeof (struct symbol));
char *name;
struct type *temptype;
memset (sym, 0, sizeof (struct symbol));
name = cs->c_name;
@ -1503,17 +1507,21 @@ process_coff_symbol (cs, aux, objfile)
#endif
add_symbol_to_list (sym, &local_symbols);
#if !defined (BELIEVE_PCC_PROMOTION) && (TARGET_BYTE_ORDER == BIG_ENDIAN)
/* If PCC says a parameter is a short or a char,
aligned on an int boundary, realign it to the "little end"
of the int. */
temptype = lookup_fundamental_type (current_objfile, FT_INTEGER);
if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)
&& TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT
&& 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (temptype))
{
/* If PCC says a parameter is a short or a char,
aligned on an int boundary, realign it to the "little end"
of the int. */
struct type *temptype;
temptype = lookup_fundamental_type (current_objfile, FT_INTEGER);
if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)
&& TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT
&& 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (temptype))
{
SYMBOL_VALUE (sym) += TYPE_LENGTH (temptype)
- TYPE_LENGTH (SYMBOL_TYPE (sym));
SYMBOL_VALUE (sym) +=
TYPE_LENGTH (temptype)
- TYPE_LENGTH (SYMBOL_TYPE (sym));
}
}
#endif
break;
@ -1524,17 +1532,22 @@ process_coff_symbol (cs, aux, objfile)
#if !defined (BELIEVE_PCC_PROMOTION)
/* FIXME: This should retain the current type, since it's just
a register value. gnu@adobe, 26Feb93 */
/* If PCC says a parameter is a short or a char,
it is really an int. */
temptype = lookup_fundamental_type (current_objfile, FT_INTEGER);
if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)
&& TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT)
{
SYMBOL_TYPE (sym) = TYPE_UNSIGNED (SYMBOL_TYPE (sym))
? lookup_fundamental_type (current_objfile,
FT_UNSIGNED_INTEGER)
: temptype;
}
{
/* If PCC says a parameter is a short or a char,
it is really an int. */
struct type *temptype;
temptype =
lookup_fundamental_type (current_objfile, FT_INTEGER);
if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)
&& TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT)
{
SYMBOL_TYPE (sym) =
(TYPE_UNSIGNED (SYMBOL_TYPE (sym))
? lookup_fundamental_type (current_objfile,
FT_UNSIGNED_INTEGER)
: temptype);
}
}
#endif
break;
@ -1544,7 +1557,34 @@ process_coff_symbol (cs, aux, objfile)
/* If type has no name, give it one */
if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
TYPE_NAME (SYMBOL_TYPE (sym)) = concat (SYMBOL_NAME (sym), NULL);
{
if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR
|| TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_FUNC)
{
/* If we are giving a name to a type such as "pointer to
foo" or "function returning foo", we better not set
the TYPE_NAME. If the program contains "typedef char
*caddr_t;", we don't want all variables of type char
* to print as caddr_t. This is not just a
consequence of GDB's type management; CC and GCC (at
least through version 2.4) both output variables of
either type char * or caddr_t with the type
refering to the C_TPDEF symbol for caddr_t. If a future
compiler cleans this up it GDB is not ready for it
yet, but if it becomes ready we somehow need to
disable this check (without breaking the PCC/GCC2.4
case).
Sigh.
Fortunately, this check seems not to be necessary
for anything except pointers or functions. */
;
}
else
TYPE_NAME (SYMBOL_TYPE (sym)) =
concat (SYMBOL_NAME (sym), NULL);
}
/* Keep track of any type which points to empty structured type,
so it can be filled from a definition from another file. A
@ -2018,16 +2058,6 @@ coff_read_enum_type (index, length, lastsym)
break;
}
#if 0
/* This screws up perfectly good C programs with enums. FIXME. */
/* Is this Modula-2's BOOLEAN type? Flag it as such if so. */
if(TYPE_NFIELDS(type) == 2 &&
((STREQ(TYPE_FIELD_NAME(type,0),"TRUE") &&
STREQ(TYPE_FIELD_NAME(type,1),"FALSE")) ||
(STREQ(TYPE_FIELD_NAME(type,1),"TRUE") &&
STREQ(TYPE_FIELD_NAME(type,0),"FALSE"))))
TYPE_CODE(type) = TYPE_CODE_BOOL;
#endif
return type;
}
@ -2038,11 +2068,12 @@ coff_symfile_offsets (objfile, addr)
{
struct section_offsets *section_offsets;
int i;
objfile->num_sections = SECT_OFF_MAX;
section_offsets = (struct section_offsets *)
obstack_alloc (&objfile -> psymbol_obstack,
sizeof (struct section_offsets) +
sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
sizeof (struct section_offsets)
+ sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
for (i = 0; i < SECT_OFF_MAX; i++)
ANOFFSET (section_offsets, i) = addr;
@ -2054,8 +2085,7 @@ coff_symfile_offsets (objfile, addr)
static struct sym_fns coff_sym_fns =
{
"coff", /* sym_name: name or name prefix of BFD target type */
4, /* sym_namelen: number of significant sym_name chars */
bfd_target_coff_flavour,
coff_new_init, /* sym_new_init: init anything gbl to entire symtab */
coff_symfile_init, /* sym_init: read initial info, setup for sym_read() */
coff_symfile_read, /* sym_read: read a symbol file into symtab */

View File

@ -31,7 +31,7 @@ static void
show_user PARAMS ((char *, int));
static void
show_user_1 PARAMS ((struct cmd_list_element *, FILE *));
show_user_1 PARAMS ((struct cmd_list_element *, GDB_FILE *));
static void
make_command PARAMS ((char *, int));
@ -43,7 +43,7 @@ static int
parse_binary_operation PARAMS ((char *));
static void
print_doc_line PARAMS ((FILE *, char *));
print_doc_line PARAMS ((GDB_FILE *, char *));
/* Add element named NAME.
CLASS is the top level category into which commands are broken down
@ -190,7 +190,7 @@ add_abbrev_prefix_cmd (name, class, fun, doc, prefixlist, prefixname,
return c;
}
/* ARGSUSED */
/* This is an empty "cfunc". */
void
not_just_help_class_command (args, from_tty)
char *args;
@ -198,6 +198,17 @@ not_just_help_class_command (args, from_tty)
{
}
/* This is an empty "sfunc". */
static void empty_sfunc PARAMS ((char *, int, struct cmd_list_element *));
static void
empty_sfunc (args, from_tty, c)
char *args;
int from_tty;
struct cmd_list_element *c;
{
}
/* Add element named NAME to command list LIST (the list for set
or some sublist thereof).
CLASS is as in add_cmd.
@ -214,17 +225,15 @@ add_set_cmd (name, class, var_type, var, doc, list)
char *doc;
struct cmd_list_element **list;
{
/* For set/show, we have to call do_setshow_command
differently than an ordinary function (take commandlist as
well as arg), so the function field isn't helpful. However,
function == NULL means that it's a help class, so set the function
to not_just_help_class_command. */
struct cmd_list_element *c
= add_cmd (name, class, not_just_help_class_command, doc, list);
= add_cmd (name, class, NO_FUNCTION, doc, list);
c->type = set_cmd;
c->var_type = var_type;
c->var = var;
/* This needs to be something besides NO_FUNCTION so that this isn't
treated as a help class. */
c->function.sfunc = empty_sfunc;
return c;
}
@ -247,7 +256,7 @@ add_show_from_set (setcmd, list)
&& setcmd->doc[2] == 't' && setcmd->doc[3] == ' ')
showcmd->doc = concat ("Show ", setcmd->doc + 4, NULL);
else
fprintf (stderr, "GDB internal error: Bad docstring for set command\n");
fprintf_unfiltered (gdb_stderr, "GDB internal error: Bad docstring for set command\n");
showcmd->next = *list;
*list = showcmd;
@ -303,7 +312,7 @@ delete_cmd (name, list)
void
help_cmd (command, stream)
char *command;
FILE *stream;
GDB_FILE *stream;
{
struct cmd_list_element *c;
extern struct cmd_list_element *cmdlist;
@ -368,7 +377,7 @@ help_list (list, cmdtype, class, stream)
struct cmd_list_element *list;
char *cmdtype;
enum command_class class;
FILE *stream;
GDB_FILE *stream;
{
int len;
char *cmdtype1, *cmdtype2;
@ -409,7 +418,7 @@ Command name abbreviations are allowed if unambiguous.\n",
/* Print only the first line of STR on STREAM. */
static void
print_doc_line (stream, str)
FILE *stream;
GDB_FILE *stream;
char *str;
{
static char *line_buffer = 0;
@ -460,7 +469,7 @@ help_cmd_list (list, class, prefix, recurse, stream)
enum command_class class;
char *prefix;
int recurse;
FILE *stream;
GDB_FILE *stream;
{
register struct cmd_list_element *c;
@ -675,12 +684,15 @@ lookup_cmd (line, list, cmdtype, allow_unknown, ignore_help_classes)
struct cmd_list_element *last_list = 0;
struct cmd_list_element *c =
lookup_cmd_1 (line, list, &last_list, ignore_help_classes);
#if 0
/* This is wrong for complete_command. */
char *ptr = (*line) + strlen (*line) - 1;
/* Clear off trailing whitespace. */
while (ptr >= *line && (*ptr == ' ' || *ptr == '\t'))
ptr--;
*(ptr + 1) = '\0';
#endif
if (!c)
{
@ -1041,6 +1053,11 @@ do_setshow_command (arg, from_tty, c)
{
/* \ at end of argument is used after spaces
so they won't be lost. */
/* This is obsolete now that we no longer strip
trailing whitespace and actually, the backslash
didn't get here in my test, readline or
something did something funky with a backslash
right before a newline. */
if (*p == 0)
break;
ch = parse_escape (&p);
@ -1052,8 +1069,10 @@ do_setshow_command (arg, from_tty, c)
else
*q++ = ch;
}
#if 0
if (*(p - 1) != '\\')
*q++ = ' ';
#endif
*q++ = '\0';
new = (char *) xrealloc (new, q - new);
if (*(char **)c->var != NULL)
@ -1111,52 +1130,52 @@ do_setshow_command (arg, from_tty, c)
else if (c->type == show_cmd)
{
/* Print doc minus "show" at start. */
print_doc_line (stdout, c->doc + 5);
print_doc_line (gdb_stdout, c->doc + 5);
fputs_filtered (" is ", stdout);
fputs_filtered (" is ", gdb_stdout);
wrap_here (" ");
switch (c->var_type)
{
case var_string:
{
unsigned char *p;
fputs_filtered ("\"", stdout);
fputs_filtered ("\"", gdb_stdout);
for (p = *(unsigned char **) c->var; *p != '\0'; p++)
gdb_printchar (*p, stdout, '"');
fputs_filtered ("\"", stdout);
gdb_printchar (*p, gdb_stdout, '"');
fputs_filtered ("\"", gdb_stdout);
}
break;
case var_string_noescape:
case var_filename:
fputs_filtered ("\"", stdout);
fputs_filtered (*(char **) c->var, stdout);
fputs_filtered ("\"", stdout);
fputs_filtered ("\"", gdb_stdout);
fputs_filtered (*(char **) c->var, gdb_stdout);
fputs_filtered ("\"", gdb_stdout);
break;
case var_boolean:
fputs_filtered (*(int *) c->var ? "on" : "off", stdout);
fputs_filtered (*(int *) c->var ? "on" : "off", gdb_stdout);
break;
case var_uinteger:
if (*(unsigned int *) c->var == UINT_MAX) {
fputs_filtered ("unlimited", stdout);
fputs_filtered ("unlimited", gdb_stdout);
break;
}
/* else fall through */
case var_zinteger:
fprintf_filtered (stdout, "%u", *(unsigned int *) c->var);
fprintf_filtered (gdb_stdout, "%u", *(unsigned int *) c->var);
break;
case var_integer:
if (*(int *) c->var == INT_MAX)
{
fputs_filtered ("unlimited", stdout);
fputs_filtered ("unlimited", gdb_stdout);
}
else
fprintf_filtered (stdout, "%d", *(int *) c->var);
fprintf_filtered (gdb_stdout, "%d", *(int *) c->var);
break;
default:
error ("gdb internal error: bad var_type in do_setshow_command");
}
fputs_filtered (".\n", stdout);
fputs_filtered (".\n", gdb_stdout);
}
else
error ("gdb internal error: bad cmd_type in do_setshow_command");
@ -1178,9 +1197,9 @@ cmd_show_list (list, from_tty, prefix)
cmd_show_list (*list->prefixlist, from_tty, list->prefixname + 5);
if (list->type == show_cmd)
{
fputs_filtered (prefix, stdout);
fputs_filtered (list->name, stdout);
fputs_filtered (": ", stdout);
fputs_filtered (prefix, gdb_stdout);
fputs_filtered (list->name, gdb_stdout);
fputs_filtered (": ", gdb_stdout);
do_setshow_command ((char *)NULL, from_tty, list);
}
}
@ -1216,8 +1235,10 @@ shell_escape (arg, from_tty)
else
execl (user_shell, p, "-c", arg, 0);
fprintf (stderr, "Exec of shell failed\n");
exit (0);
fprintf_unfiltered (gdb_stderr, "Cannot execute %s: %s\n", user_shell,
safe_strerror (errno));
gdb_flush (gdb_stderr);
_exit (0177);
}
if (pid != -1)
@ -1250,7 +1271,7 @@ make_command (arg, from_tty)
static void
show_user_1 (c, stream)
struct cmd_list_element *c;
FILE *stream;
GDB_FILE *stream;
{
register struct command_line *cmdlines;
@ -1283,14 +1304,14 @@ show_user (args, from_tty)
c = lookup_cmd (&args, cmdlist, "", 0, 1);
if (c->class != class_user)
error ("Not a user command.");
show_user_1 (c, stdout);
show_user_1 (c, gdb_stdout);
}
else
{
for (c = cmdlist; c; c = c->next)
{
if (c->class == class_user)
show_user_1 (c, stdout);
show_user_1 (c, gdb_stdout);
}
}
}

View File

@ -69,13 +69,18 @@ struct cmd_list_element
enum command_class class;
/* Function definition of this command.
Zero for command class names and for help topics that
NO_FUNCTION for command class names and for help topics that
are not really commands. */
union {
union
{
/* If type is not_set_cmd, call it like this: */
void (*cfunc) PARAMS ((char *args, int from_tty));
/* If type is cmd_set or show_cmd, first set the variables, and
then call this. */
void (*sfunc) PARAMS ((char *args, int from_tty,
struct cmd_list_element *c));
} function;
} function;
# define NO_FUNCTION ((void (*) PARAMS((char *args, int from_tty))) 0)
/* Documentation of this command (or help topic).
@ -194,15 +199,15 @@ extern void
delete_cmd PARAMS ((char *, struct cmd_list_element **));
extern void
help_cmd PARAMS ((char *, FILE *));
help_cmd PARAMS ((char *, GDB_FILE *));
extern void
help_list PARAMS ((struct cmd_list_element *, char *, enum command_class,
FILE *));
GDB_FILE *));
extern void
help_cmd_list PARAMS ((struct cmd_list_element *, enum command_class, char *,
int, FILE *));
int, GDB_FILE *));
extern struct cmd_list_element *
add_set_cmd PARAMS ((char *, enum command_class, var_types, char *, char *,

View File

@ -112,7 +112,7 @@ complain (va_alist)
/* If GDB dumps core, we'd like to see the complaints first. Presumably
GDB will not be sending so many complaints that this becomes a
performance hog. */
fflush (stdout);
gdb_flush (gdb_stdout);
va_end (args);
}

View File

@ -1,5 +1,6 @@
/* Core dump and executable file functions above target vector, for GDB.
Copyright 1986, 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994
Free Software Foundation, Inc.
This file is part of GDB.
@ -18,6 +19,7 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "defs.h"
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
@ -30,6 +32,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "target.h"
#include "gdbcore.h"
#include "dis-asm.h"
#include "language.h"
extern char registers[];
@ -135,19 +138,24 @@ memory_error (status, memaddr)
int status;
CORE_ADDR memaddr;
{
if (status == EIO)
{
/* Actually, address between memaddr and memaddr + len
was out of bounds. */
error ("Cannot access memory at address %s.",
local_hex_string((unsigned long) memaddr));
error_begin ();
printf_filtered ("Cannot access memory at address ");
print_address_numeric (memaddr, 1, gdb_stdout);
printf_filtered (".\n");
return_to_top_level (RETURN_ERROR);
}
else
{
error ("Error accessing memory address %s: %s.",
local_hex_string ((unsigned long) memaddr),
safe_strerror (status));
error_begin ();
printf_filtered ("Error accessing memory address ");
print_address_numeric (memaddr, 1, gdb_stdout);
printf_filtered (": %s.\n",
safe_strerror (status));
return_to_top_level (RETURN_ERROR);
}
}
@ -233,6 +241,46 @@ read_memory_unsigned_integer (memaddr, len)
return extract_unsigned_integer (buf, len);
}
#if 0
/* Enable after 4.12. It is not tested. */
/* Search code. Targets can just make this their search function, or
if the protocol has a less general search function, they can call this
in the cases it can't handle. */
void
generic_search (len, data, mask, startaddr, increment, lorange, hirange
addr_found, data_found)
int len;
char *data;
char *mask;
CORE_ADDR startaddr;
int increment;
CORE_ADDR lorange;
CORE_ADDR hirange;
CORE_ADDR *addr_found;
char *data_found;
{
int i;
CORE_ADDR curaddr = startaddr;
while (curaddr >= lorange && curaddr < hirange)
{
read_memory (curaddr, data_found, len);
for (i = 0; i < len; ++i)
if ((data_found[i] & mask[i]) != data[i])
goto try_again;
/* It matches. */
*addr_found = curaddr;
return;
try_again:
curaddr += increment;
}
*addr_found = (CORE_ADDR)0;
return;
}
#endif /* 0 */
/* The current default bfd target. Points to storage allocated for
gnutarget_string. */
char *gnutarget;

View File

@ -24,6 +24,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <sys/types.h>
#include <sys/param.h>
#include "gdbcore.h"
#include "value.h" /* For supply_register. */
#include "inferior.h"
/* These are needed on various systems to expand REGISTER_U_ADDR. */
#ifndef USG
@ -40,6 +42,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#endif /* NO_PTRACE_H */
#endif
#ifndef CORE_REGISTER_ADDR
#define CORE_REGISTER_ADDR(regno, regptr) register_addr(regno, regptr)
#endif /* CORE_REGISTER_ADDR */
#ifdef NEED_SYS_CORE_H
#include <sys/core.h>
#endif
@ -68,19 +74,20 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
register unsigned int addr;
int bad_reg = -1;
register reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */
int numregs = ARCH_NUM_REGS;
/* If u.u_ar0 was an absolute address in the core file, relativize it now,
so we can use it as an offset into core_reg_sect. When we're done,
"register 0" will be at core_reg_sect+reg_ptr, and we can use
register_addr to offset to the other registers. If this is a modern
CORE_REGISTER_ADDR to offset to the other registers. If this is a modern
core file without a upage, reg_ptr will be zero and this is all a big
NOP. */
if (reg_ptr > core_reg_size)
reg_ptr -= KERNEL_U_ADDR;
for (regno = 0; regno < NUM_REGS; regno++)
for (regno = 0; regno < numregs; regno++)
{
addr = register_addr (regno, reg_ptr);
addr = CORE_REGISTER_ADDR (regno, reg_ptr);
if (addr >= core_reg_size) {
if (bad_reg < 0)
bad_reg = regno;
@ -107,7 +114,7 @@ register_addr (regno, blockend)
{
int addr;
if (regno < 0 || regno >= NUM_REGS)
if (regno < 0 || regno >= ARCH_NUM_REGS)
error ("Invalid register number %d.", regno);
REGISTER_U_ADDR (addr, blockend, regno);

View File

@ -1,5 +1,6 @@
/* Core dump and executable file functions below target vector, for GDB.
Copyright 1986, 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994
Free Software Foundation, Inc.
This file is part of GDB.
@ -18,6 +19,7 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "defs.h"
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
@ -28,6 +30,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "bfd.h"
#include "target.h"
#include "gdbcore.h"
#include "thread.h"
static void
core_files_info PARAMS ((struct target_ops *));
@ -69,13 +72,14 @@ core_close (quitting)
}
#ifdef SOLIB_ADD
/* Stub function for catch_errors around shared library hacking. */
/* Stub function for catch_errors around shared library hacking. FROM_TTYP
is really an int * which points to from_tty. */
static int
solib_add_stub (from_tty)
char *from_tty;
solib_add_stub (from_ttyp)
char *from_ttyp;
{
SOLIB_ADD (NULL, (int)from_tty, &core_ops);
SOLIB_ADD (NULL, *(int *)from_ttyp, &core_ops);
return 0;
}
#endif /* SOLIB_ADD */
@ -151,7 +155,7 @@ core_open (filename, from_tty)
{
/* Do it after the err msg */
make_cleanup (bfd_close, temp_bfd);
error ("\"%s\" is not a core dump: %s", filename, bfd_errmsg(bfd_error));
error ("\"%s\" is not a core dump: %s", filename, bfd_errmsg(bfd_get_error ()));
}
/* Looks semi-reasonable. Toss the old core file and work on the new. */
@ -167,7 +171,7 @@ core_open (filename, from_tty)
if (build_section_table (core_bfd, &core_ops.to_sections,
&core_ops.to_sections_end))
error ("Can't find sections in `%s': %s", bfd_get_filename(core_bfd),
bfd_errmsg (bfd_error));
bfd_errmsg (bfd_get_error ()));
ontop = !push_target (&core_ops);
discard_cleanups (old_chain);
@ -193,7 +197,7 @@ core_open (filename, from_tty)
/* Add symbols and section mappings for any shared libraries */
#ifdef SOLIB_ADD
catch_errors (solib_add_stub, (char *)from_tty, (char *)0,
catch_errors (solib_add_stub, &from_tty, (char *)0,
RETURN_MASK_ALL);
#endif
@ -260,8 +264,8 @@ get_core_registers (regno)
else
{
cant:
fprintf_filtered (stderr, "Couldn't fetch registers from core file: %s\n",
bfd_errmsg (bfd_error));
fprintf_filtered (gdb_stderr, "Couldn't fetch registers from core file: %s\n",
bfd_errmsg (bfd_get_error ()));
}
/* Now do it again for the float registers, if they exist. */
@ -277,8 +281,8 @@ get_core_registers (regno)
}
else
{
fprintf_filtered (stderr, "Couldn't fetch register set 2 from core file: %s\n",
bfd_errmsg (bfd_error));
fprintf_filtered (gdb_stderr, "Couldn't fetch register set 2 from core file: %s\n",
bfd_errmsg (bfd_get_error ()));
}
}
registers_fetched();
@ -299,6 +303,7 @@ ignore (addr, contents)
CORE_ADDR addr;
char *contents;
{
return 0;
}
struct target_ops core_ops = {

View File

@ -26,6 +26,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "command.h"
#include "gdbcmd.h"
#include "demangle.h"
#include "annotate.h"
int vtblprint; /* Controls printing of vtbl's */
int objectprint; /* Controls looking up an object's derived type
@ -33,39 +34,30 @@ int objectprint; /* Controls looking up an object's derived type
struct obstack dont_print_obstack;
static void
cplus_print_value PARAMS ((struct type *, char *, FILE *, int, int,
cplus_print_value PARAMS ((struct type *, char *, GDB_FILE *, int, int,
enum val_prettyprint, struct type **));
/* BEGIN-FIXME: Hooks into typeprint.c, find a better home for prototypes. */
extern void
c_type_print_base PARAMS ((struct type *, FILE *, int, int));
c_type_print_base PARAMS ((struct type *, GDB_FILE *, int, int));
extern void
c_type_print_varspec_prefix PARAMS ((struct type *, FILE *, int, int));
c_type_print_varspec_prefix PARAMS ((struct type *, GDB_FILE *, int, int));
extern void
cp_type_print_method_args PARAMS ((struct type **, char *, char *, int,
FILE *));
GDB_FILE *));
extern struct obstack dont_print_obstack;
/* END-FIXME */
/* BEGIN-FIXME: Hooks into c-valprint.c */
extern int
c_val_print PARAMS ((struct type *, char *, CORE_ADDR, FILE *, int, int, int,
enum val_prettyprint));
/* END-FIXME */
void
cp_print_class_method (valaddr, type, stream)
char *valaddr;
struct type *type;
FILE *stream;
GDB_FILE *stream;
{
struct type *domain;
struct fn_field *f = NULL;
@ -136,7 +128,7 @@ cp_print_class_method (valaddr, type, stream)
{
fprintf_filtered (stream, "&");
c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0);
fprintf (stream, kind);
fprintf_unfiltered (stream, kind);
if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
&& TYPE_FN_FIELD_PHYSNAME (f, j)[1] == CPLUS_MARKER)
{
@ -159,6 +151,13 @@ cp_print_class_method (valaddr, type, stream)
}
}
/* This was what it was for gcc 2.4.5 and earlier. */
static const char vtbl_ptr_name_old[] =
{ CPLUS_MARKER,'v','t','b','l','_','p','t','r','_','t','y','p','e', 0 };
/* It was changed to this after 2.4.5. */
const char vtbl_ptr_name[] =
{ '_','_','v','t','b','l','_','p','t','r','_','t','y','p','e', 0 };
/* Return truth value for assertion that TYPE is of the type
"pointer to virtual function". */
@ -167,12 +166,6 @@ cp_is_vtbl_ptr_type(type)
struct type *type;
{
char *typename = type_name_no_tag (type);
/* This was what it was for gcc 2.4.5 and earlier. */
static const char vtbl_ptr_name_old[] =
{ CPLUS_MARKER,'v','t','b','l','_','p','t','r','_','t','y','p','e', 0 };
/* It was changed to this after 2.4.5. */
static const char vtbl_ptr_name[] =
{ '_','_','v','t','b','l','_','p','t','r','_','t','y','p','e', 0 };
return (typename != NULL
&& (STREQ (typename, vtbl_ptr_name)
@ -187,14 +180,20 @@ cp_is_vtbl_member(type)
struct type *type;
{
if (TYPE_CODE (type) == TYPE_CODE_PTR)
type = TYPE_TARGET_TYPE (type);
else
return 0;
if (TYPE_CODE (type) == TYPE_CODE_ARRAY
&& TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT)
/* Virtual functions tables are full of pointers to virtual functions. */
return cp_is_vtbl_ptr_type (TYPE_TARGET_TYPE (type));
{
type = TYPE_TARGET_TYPE (type);
if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
{
type = TYPE_TARGET_TYPE (type);
if (TYPE_CODE (type) == TYPE_CODE_STRUCT /* if not using thunks */
|| TYPE_CODE (type) == TYPE_CODE_PTR) /* if using thunks */
{
/* Virtual functions tables are full of pointers
to virtual functions. */
return cp_is_vtbl_ptr_type (type);
}
}
}
return 0;
}
@ -212,7 +211,7 @@ cp_print_value_fields (type, valaddr, stream, format, recurse, pretty,
dont_print)
struct type *type;
char *valaddr;
FILE *stream;
GDB_FILE *stream;
int format;
int recurse;
enum val_prettyprint pretty;
@ -285,30 +284,51 @@ cp_print_value_fields (type, valaddr, stream, format, recurse, pretty,
}
else
{
annotate_field_begin (TYPE_FIELD_TYPE (type, i));
fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
language_cplus,
DMGL_PARAMS | DMGL_ANSI);
annotate_field_name_end ();
fputs_filtered (" = ", stream);
annotate_field_value ();
}
if (TYPE_FIELD_PACKED (type, i))
{
value v;
value_ptr v;
/* Bitfields require special handling, especially due to byte
order problems. */
v = value_from_longest (TYPE_FIELD_TYPE (type, i),
if (TYPE_FIELD_IGNORE (type, i))
{
fputs_filtered ("<optimized out or zero length>", stream);
}
else
{
v = value_from_longest (TYPE_FIELD_TYPE (type, i),
unpack_field_as_long (type, valaddr, i));
c_val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0,
stream, format, 0, recurse + 1, pretty);
val_print (TYPE_FIELD_TYPE(type, i), VALUE_CONTENTS (v), 0,
stream, format, 0, recurse + 1, pretty);
}
}
else
{
c_val_print (TYPE_FIELD_TYPE (type, i),
valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
0, stream, format, 0, recurse + 1, pretty);
if (TYPE_FIELD_IGNORE (type, i))
{
fputs_filtered ("<optimized out or zero length>", stream);
}
else
{
val_print (TYPE_FIELD_TYPE (type, i),
valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
0, stream, format, 0, recurse + 1, pretty);
}
}
annotate_field_end ();
}
if (pretty)
{
fprintf_filtered (stream, "\n");
@ -325,7 +345,7 @@ static void
cplus_print_value (type, valaddr, stream, format, recurse, pretty, dont_print)
struct type *type;
char *valaddr;
FILE *stream;
GDB_FILE *stream;
int format;
int recurse;
enum val_prettyprint pretty;
@ -348,9 +368,14 @@ cplus_print_value (type, valaddr, stream, format, recurse, pretty, dont_print)
for (i = 0; i < n_baseclasses; i++)
{
/* FIXME-32x64--assumes that a target pointer can fit in a char *.
Fix it by nuking baseclass_addr. */
char *baddr;
int err;
char *basename = TYPE_NAME (TYPE_BASECLASS (type, i));
char *basename;
check_stub_type (TYPE_BASECLASS (type, i));
basename = TYPE_NAME (TYPE_BASECLASS (type, i));
if (BASETYPE_VIA_VIRTUAL (type, i))
{
@ -384,8 +409,11 @@ cplus_print_value (type, valaddr, stream, format, recurse, pretty, dont_print)
fputs_filtered (basename ? basename : "", stream);
fputs_filtered ("> = ", stream);
if (err != 0)
fprintf_filtered (stream,
"<invalid address 0x%lx>", (unsigned long) baddr);
{
fprintf_filtered (stream, "<invalid address ");
print_address_numeric ((CORE_ADDR) baddr, 1, stream);
fprintf_filtered (stream, ">");
}
else
cp_print_value_fields (TYPE_BASECLASS (type, i), baddr, stream, format,
recurse, pretty,
@ -411,7 +439,7 @@ void
cp_print_class_member (valaddr, domain, stream, prefix)
char *valaddr;
struct type *domain;
FILE *stream;
GDB_FILE *stream;
char *prefix;
{

View File

@ -1,5 +1,5 @@
/* Read dbx symbol tables and convert to internal format, for GDB.
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993
Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994
Free Software Foundation, Inc.
This file is part of GDB.
@ -52,7 +52,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "command.h"
#include "target.h"
#include "gdbcore.h" /* for bfd stuff */
#include "libbfd.h" /* FIXME Secret internal BFD stuff (bfd_read) */
#include "libaout.h" /* FIXME Secret internal BFD stuff for a.out */
#include "symfile.h"
#include "objfiles.h"
@ -108,25 +107,6 @@ struct symloc {
#define IGNORE_SYMBOL(type) (type == (int)N_NSYMS)
#endif
/* Macro for name of symbol to indicate a file compiled with gcc. */
#ifndef GCC_COMPILED_FLAG_SYMBOL
#define GCC_COMPILED_FLAG_SYMBOL "gcc_compiled."
#endif
/* Macro for name of symbol to indicate a file compiled with gcc2. */
#ifndef GCC2_COMPILED_FLAG_SYMBOL
#define GCC2_COMPILED_FLAG_SYMBOL "gcc2_compiled."
#endif
/* Define this as 1 if a pcc declaration of a char or short argument
gives the correct address. Otherwise assume pcc gives the
address of the corresponding int, which is not the same on a
big-endian machine. */
#ifndef BELIEVE_PCC_PROMOTION
#define BELIEVE_PCC_PROMOTION 0
#endif
/* Remember what we deduced to be the source language of this psymtab. */
static enum language psymtab_language = language_unknown;
@ -158,6 +138,20 @@ static unsigned string_table_offset;
static unsigned int file_string_table_offset;
static unsigned int next_file_string_table_offset;
/* .o and NLM files contain unrelocated addresses which are based at 0. When
non-zero, this flag disables some of the special cases for Solaris elf+stab
text addresses at location 0. */
static int symfile_relocatable = 0;
/* If this is nonzero, N_LBRAC, N_RBRAC, and N_SLINE entries are relative
to the function start address. */
static int block_address_function_relative = 0;
/* This is the lowest text address we have yet encountered. */
static CORE_ADDR lowest_text_address;
/* Complaints about the symbols we have encountered. */
struct complaint lbrac_complaint =
@ -170,7 +164,7 @@ struct complaint unknown_symtype_complaint =
{"unknown symbol type %s", 0, 0};
struct complaint unknown_symchar_complaint =
{"unknown symbol type character `%c'", 0, 0};
{"unknown symbol descriptor `%c'", 0, 0};
struct complaint lbrac_rbrac_complaint =
{"block start larger than block end", 0, 0};
@ -221,6 +215,10 @@ dbx_psymtab_to_symtab PARAMS ((struct partial_symtab *));
static void
dbx_psymtab_to_symtab_1 PARAMS ((struct partial_symtab *));
static void
read_dbx_dynamic_symtab PARAMS ((struct section_offsets *,
struct objfile *objfile));
static void
read_dbx_symtab PARAMS ((struct section_offsets *, struct objfile *,
CORE_ADDR, int));
@ -419,47 +417,46 @@ record_minimal_symbol (name, address, type, objfile)
struct objfile *objfile;
{
enum minimal_symbol_type ms_type;
int section;
switch (type)
{
case N_TEXT | N_EXT: ms_type = mst_text; break;
case N_DATA | N_EXT: ms_type = mst_data; break;
case N_BSS | N_EXT: ms_type = mst_bss; break;
case N_ABS | N_EXT: ms_type = mst_abs; break;
case N_TEXT | N_EXT:
ms_type = mst_text;
section = SECT_OFF_TEXT;
break;
case N_DATA | N_EXT:
ms_type = mst_data;
section = SECT_OFF_DATA;
break;
case N_BSS | N_EXT:
ms_type = mst_bss;
section = SECT_OFF_BSS;
break;
case N_ABS | N_EXT:
ms_type = mst_abs;
section = -1;
break;
#ifdef N_SETV
case N_SETV | N_EXT: ms_type = mst_data; break;
case N_SETV | N_EXT:
ms_type = mst_data;
section = SECT_OFF_DATA;
break;
case N_SETV:
/* I don't think this type actually exists; since a N_SETV is the result
of going over many .o files, it doesn't make sense to have one
file local. */
ms_type = mst_file_data;
section = SECT_OFF_DATA;
break;
#endif
case N_TEXT:
/* Don't put gcc_compiled, __gnu_compiled_cplus, and friends into
the minimal symbols, because if there is also another symbol
at the same address (e.g. the first function of the file),
lookup_minimal_symbol_by_pc would have no way of getting the
right one. */
if (name[0] == 'g'
&& (strcmp (name, GCC_COMPILED_FLAG_SYMBOL) == 0
|| strcmp (name, GCC2_COMPILED_FLAG_SYMBOL) == 0))
return;
{
char *tempstring = name;
if (tempstring[0] == bfd_get_symbol_leading_char (objfile->obfd))
++tempstring;
if (STREQN (tempstring, "__gnu_compiled", 14))
return;
}
case N_NBTEXT:
case N_FN:
case N_FN_SEQ:
ms_type = mst_file_text;
section = SECT_OFF_TEXT;
break;
case N_DATA:
ms_type = mst_file_data;
@ -478,19 +475,29 @@ record_minimal_symbol (name, address, type, objfile)
if (VTBL_PREFIX_P ((tempstring)))
ms_type = mst_data;
}
section = SECT_OFF_DATA;
break;
case N_BSS:
ms_type = mst_file_bss;
section = SECT_OFF_BSS;
break;
default:
ms_type = mst_unknown;
section = -1;
break;
default: ms_type = mst_unknown; break;
}
prim_record_minimal_symbol
if ((ms_type == mst_file_text || ms_type == mst_text)
&& address < lowest_text_address)
lowest_text_address = address;
prim_record_minimal_symbol_and_info
(obsavestring (name, strlen (name), &objfile -> symbol_obstack),
address,
ms_type);
ms_type,
NULL,
section,
objfile);
}
/* Scan and build partial symbols for a symbol file.
@ -513,6 +520,28 @@ dbx_symfile_read (objfile, section_offsets, mainline)
int val;
struct cleanup *back_to;
val = strlen (objfile->name);
/* .o and .nlm files are relocatables with text, data and bss segs based at
0. This flag disables special (Solaris stabs-in-elf only) fixups for
symbols with a value of 0. XXX - This is a Krock. Solaris stabs-in-elf
should be fixed to determine pst->textlow without using this text seg of
0 fixup crap. */
if (strcmp (&objfile->name[val-2], ".o") == 0
|| strcmp (&objfile->name[val-4], ".nlm") == 0)
symfile_relocatable = 1;
/* This is true for Solaris (and all other systems which put stabs
in sections, hopefully, since it would be silly to do things
differently from Solaris), and false for SunOS4 and other a.out
file formats. */
block_address_function_relative =
((0 == strncmp (bfd_get_target (objfile->obfd), "elf", 3))
|| (0 == strncmp (bfd_get_target (objfile->obfd), "som", 3))
|| (0 == strncmp (bfd_get_target (objfile->obfd), "coff", 4))
|| (0 == strncmp (bfd_get_target (objfile->obfd), "nlm", 3)));
sym_bfd = objfile->obfd;
val = bfd_seek (objfile->obfd, DBX_SYMTAB_OFFSET (objfile), SEEK_SET);
if (val < 0)
@ -538,17 +567,15 @@ dbx_symfile_read (objfile, section_offsets, mainline)
bfd_section_vma (sym_bfd, DBX_TEXT_SECT (objfile)),
bfd_section_size (sym_bfd, DBX_TEXT_SECT (objfile)));
/* Add the dynamic symbols. */
read_dbx_dynamic_symtab (section_offsets, objfile);
/* Install any minimal symbols that have been collected as the current
minimal symbols for this objfile. */
install_minimal_symbols (objfile);
if (!have_partial_symbols ()) {
wrap_here ("");
printf_filtered ("(no debugging symbols found)...");
wrap_here ("");
}
do_cleanups (back_to);
}
@ -854,6 +881,150 @@ free_bincl_list (objfile)
bincls_allocated = 0;
}
/* Scan a SunOs dynamic symbol table for symbols of interest and
add them to the minimal symbol table. */
static void
read_dbx_dynamic_symtab (section_offsets, objfile)
struct section_offsets *section_offsets;
struct objfile *objfile;
{
bfd *abfd = objfile->obfd;
struct cleanup *back_to;
int counter;
long dynsym_size;
long dynsym_count;
asymbol **dynsyms;
asymbol **symptr;
arelent **relptr;
long dynrel_size;
long dynrel_count;
arelent **dynrels;
CORE_ADDR sym_value;
/* Check that the symbol file has dynamic symbols that we know about.
bfd_arch_unknown can happen if we are reading a sun3 symbol file
on a sun4 host (and vice versa) and bfd is not configured
--with-target=all. This would trigger an assertion in bfd/sunos.c,
so we ignore the dynamic symbols in this case. */
if (bfd_get_flavour (abfd) != bfd_target_aout_flavour
|| (bfd_get_file_flags (abfd) & DYNAMIC) == 0
|| bfd_get_arch (abfd) == bfd_arch_unknown)
return;
dynsym_size = bfd_get_dynamic_symtab_upper_bound (abfd);
if (dynsym_size < 0)
return;
dynsyms = (asymbol **) xmalloc (dynsym_size);
back_to = make_cleanup (free, dynsyms);
dynsym_count = bfd_canonicalize_dynamic_symtab (abfd, dynsyms);
if (dynsym_count < 0)
{
do_cleanups (back_to);
return;
}
/* Enter dynamic symbols into the minimal symbol table
if this is a stripped executable. */
if (bfd_get_symcount (abfd) <= 0)
{
symptr = dynsyms;
for (counter = 0; counter < dynsym_count; counter++, symptr++)
{
asymbol *sym = *symptr;
asection *sec;
int type;
sec = bfd_get_section (sym);
/* BFD symbols are section relative. */
sym_value = sym->value + sec->vma;
if (bfd_get_section_flags (abfd, sec) & SEC_CODE)
{
sym_value += ANOFFSET (section_offsets, SECT_OFF_TEXT);
type = N_TEXT;
}
else if (bfd_get_section_flags (abfd, sec) & SEC_DATA)
{
sym_value += ANOFFSET (section_offsets, SECT_OFF_DATA);
type = N_DATA;
}
else if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
{
sym_value += ANOFFSET (section_offsets, SECT_OFF_BSS);
type = N_BSS;
}
else
continue;
if (sym->flags & BSF_GLOBAL)
type |= N_EXT;
record_minimal_symbol ((char *) bfd_asymbol_name (sym), sym_value,
type, objfile);
}
}
/* Symbols from shared libraries have a dynamic relocation entry
that points to the associated slot in the procedure linkage table.
We make a mininal symbol table entry with type mst_solib_trampoline
at the address in the procedure linkage table. */
dynrel_size = bfd_get_dynamic_reloc_upper_bound (abfd);
if (dynrel_size < 0)
{
do_cleanups (back_to);
return;
}
dynrels = (arelent **) xmalloc (dynrel_size);
make_cleanup (free, dynrels);
dynrel_count = bfd_canonicalize_dynamic_reloc (abfd, dynrels, dynsyms);
if (dynrel_count < 0)
{
do_cleanups (back_to);
return;
}
for (counter = 0, relptr = dynrels;
counter < dynrel_count;
counter++, relptr++)
{
arelent *rel = *relptr;
CORE_ADDR address =
rel->address + ANOFFSET (section_offsets, SECT_OFF_DATA);
switch (bfd_get_arch (abfd))
{
case bfd_arch_sparc:
if (rel->howto->type != RELOC_JMP_SLOT)
continue;
break;
case bfd_arch_m68k:
/* `16' is the type BFD produces for a jump table relocation. */
if (rel->howto->type != 16)
continue;
/* Adjust address in the jump table to point to
the start of the bsr instruction. */
address -= 2;
break;
default:
continue;
}
prim_record_minimal_symbol (bfd_asymbol_name (*rel->sym_ptr_ptr),
address,
mst_solib_trampoline,
objfile);
}
do_cleanups (back_to);
}
/* Given pointers to an a.out symbol table in core containing dbx
style data, setup partial_symtab's describing each source file for
which debugging information is available.
@ -876,9 +1047,6 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size)
struct cleanup *back_to;
bfd *abfd;
/* End of the text segment of the executable file. */
CORE_ADDR end_of_text_addr;
/* Current partial symtab */
struct partial_symtab *pst;
@ -917,12 +1085,7 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size)
last_source_file = NULL;
#ifdef END_OF_TEXT_DEFAULT
end_of_text_addr = END_OF_TEXT_DEFAULT;
#else
end_of_text_addr = text_addr + section_offsets->offsets[SECT_OFF_TEXT]
+ text_size; /* Relocate */
#endif
lowest_text_address = (CORE_ADDR)-1;
symfile_bfd = objfile->obfd; /* For next_text_symbol */
abfd = objfile->obfd;
@ -965,7 +1128,7 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size)
if (((unsigned)bufp->n_strx + file_string_table_offset) >= \
DBX_STRINGTAB_SIZE (objfile)) { \
complain (&string_table_offset_complaint, symnum); \
namestring = "foo"; \
namestring = "<bad string table offset>"; \
} else \
namestring = bufp->n_strx + file_string_table_offset + \
DBX_STRINGTAB (objfile)
@ -995,7 +1158,11 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size)
if (pst)
{
end_psymtab (pst, psymtab_include_list, includes_used,
symnum * symbol_size, end_of_text_addr,
symnum * symbol_size,
(lowest_text_address == (CORE_ADDR)-1
? (text_addr + section_offsets->offsets[SECT_OFF_TEXT])
: lowest_text_address)
+ text_size,
dependency_list, dependencies_used);
}
@ -1061,16 +1228,15 @@ end_psymtab (pst, include_list, num_includes, capping_symbol_offset,
CORE_ADDR capping_text;
struct partial_symtab **dependency_list;
int number_dependencies;
/* struct partial_symbol *capping_global, *capping_static;*/
{
int i;
struct partial_symtab *p1;
struct objfile *objfile = pst -> objfile;
if (capping_symbol_offset != -1)
LDSYMLEN(pst) = capping_symbol_offset - LDSYMOFF(pst);
pst->texthigh = capping_text;
#ifdef N_SO_ADDRESS_MAYBE_MISSING
/* Under Solaris, the N_SO symbols always have a value of 0,
instead of the usual address of the .o file. Therefore,
we have to do some tricks to fill in texthigh and textlow.
@ -1137,6 +1303,9 @@ end_psymtab (pst, include_list, num_includes, capping_symbol_offset,
/* this test will be true if the last .o file is only data */
if (pst->textlow == 0)
/* This loses if the text section really starts at address zero
(generally true when we are debugging a .o file, for example).
That is why this whole thing is inside N_SO_ADDRESS_MAYBE_MISSING. */
pst->textlow = pst->texthigh;
/* If we know our own starting text address, then walk through all other
@ -1145,6 +1314,8 @@ end_psymtab (pst, include_list, num_includes, capping_symbol_offset,
own ending address to our starting address, nor to set addresses on
`dependency' files that have both textlow and texthigh zero. */
if (pst->textlow) {
struct partial_symtab *p1;
ALL_OBJFILE_PSYMTABS (objfile, p1) {
if (p1->texthigh == 0 && p1->textlow != 0 && p1 != pst) {
p1->texthigh = pst->textlow;
@ -1156,7 +1327,7 @@ end_psymtab (pst, include_list, num_includes, capping_symbol_offset,
}
/* End of kludge for patching Solaris textlow and texthigh. */
#endif /* N_SO_ADDRESS_MAYBE_MISSING. */
pst->n_global_syms =
objfile->global_psymbols.next - (objfile->global_psymbols.list + pst->globals_offset);
@ -1215,30 +1386,36 @@ end_psymtab (pst, include_list, num_includes, capping_symbol_offset,
free_named_symtabs (pst->filename);
if (num_includes == 0
&& number_dependencies == 0
&& pst->n_global_syms == 0
&& pst->n_static_syms == 0) {
/* Throw away this psymtab, it's empty. We can't deallocate it, since
it is on the obstack, but we can forget to chain it on the list. */
struct partial_symtab *prev_pst;
&& number_dependencies == 0
&& pst->n_global_syms == 0
&& pst->n_static_syms == 0)
{
/* Throw away this psymtab, it's empty. We can't deallocate it, since
it is on the obstack, but we can forget to chain it on the list. */
/* Empty psymtabs happen as a result of header files which don't have
any symbols in them. There can be a lot of them. But this check
is wrong, in that a psymtab with N_SLINE entries but nothing else
is not empty, but we don't realize that. Fixing that without slowing
things down might be tricky. */
struct partial_symtab *prev_pst;
/* First, snip it out of the psymtab chain */
/* First, snip it out of the psymtab chain */
if (pst->objfile->psymtabs == pst)
pst->objfile->psymtabs = pst->next;
else
for (prev_pst = pst->objfile->psymtabs; prev_pst; prev_pst = pst->next)
if (prev_pst->next == pst)
prev_pst->next = pst->next;
if (pst->objfile->psymtabs == pst)
pst->objfile->psymtabs = pst->next;
else
for (prev_pst = pst->objfile->psymtabs; prev_pst; prev_pst = pst->next)
if (prev_pst->next == pst)
prev_pst->next = pst->next;
/* Next, put it on a free list for recycling */
/* Next, put it on a free list for recycling */
pst->next = pst->objfile->free_psymtabs;
pst->objfile->free_psymtabs = pst;
pst->next = pst->objfile->free_psymtabs;
pst->objfile->free_psymtabs = pst;
/* Indicate that psymtab was thrown away. */
pst = (struct partial_symtab *)NULL;
}
/* Indicate that psymtab was thrown away. */
pst = (struct partial_symtab *)NULL;
}
return pst;
}
@ -1254,7 +1431,7 @@ dbx_psymtab_to_symtab_1 (pst)
if (pst->readin)
{
fprintf (stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
pst->filename);
return;
}
@ -1266,13 +1443,13 @@ dbx_psymtab_to_symtab_1 (pst)
/* Inform about additional files that need to be read in. */
if (info_verbose)
{
fputs_filtered (" ", stdout);
fputs_filtered (" ", gdb_stdout);
wrap_here ("");
fputs_filtered ("and ", stdout);
fputs_filtered ("and ", gdb_stdout);
wrap_here ("");
printf_filtered ("%s...", pst->dependencies[i]->filename);
wrap_here (""); /* Flush output */
fflush (stdout);
gdb_flush (gdb_stdout);
}
dbx_psymtab_to_symtab_1 (pst->dependencies[i]);
}
@ -1311,7 +1488,7 @@ dbx_psymtab_to_symtab (pst)
if (pst->readin)
{
fprintf (stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
pst->filename);
return;
}
@ -1323,7 +1500,7 @@ dbx_psymtab_to_symtab (pst)
if (info_verbose)
{
printf_filtered ("Reading in symbols for %s...", pst->filename);
fflush (stdout);
gdb_flush (gdb_stdout);
}
sym_bfd = pst->objfile->obfd;
@ -1395,10 +1572,16 @@ read_ofile_symtab (pst)
processing_gcc_compilation = 0;
if (bufp->n_type == N_TEXT)
{
const char *tempstring = namestring;
if (STREQ (namestring, GCC_COMPILED_FLAG_SYMBOL))
processing_gcc_compilation = 1;
else if (STREQ (namestring, GCC2_COMPILED_FLAG_SYMBOL))
processing_gcc_compilation = 2;
if (tempstring[0] == bfd_get_symbol_leading_char (symfile_bfd))
++tempstring;
if (STREQN (tempstring, "__gnu_compiled", 14))
processing_gcc_compilation = 2;
}
/* Try to select a C++ demangling based on the compilation unit
@ -1538,10 +1721,6 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
used to relocate these symbol types rather than SECTION_OFFSETS. */
static CORE_ADDR function_start_offset;
/* If this is nonzero, N_LBRAC, N_RBRAC, and N_SLINE entries are relative
to the function start address. */
int block_address_function_relative;
/* If this is nonzero, we've seen a non-gcc N_OPT symbol for this source
file. Used to detect the SunPRO solaris compiler. */
static int n_opt_found;
@ -1550,12 +1729,6 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
N_STSYM or N_GSYM for SunOS4 acc; N_FUN for other compilers. */
static int function_stab_type = 0;
/* This is true for Solaris (and all other stabs-in-elf systems, hopefully,
since it would be silly to do things differently from Solaris), and
false for SunOS4 and other a.out file formats. */
block_address_function_relative =
0 == strncmp (bfd_get_target (objfile->obfd), "elf", 3);
if (!block_address_function_relative)
/* N_LBRAC, N_RBRAC and N_SLINE entries are not relative to the
function start address, so just use the text offset. */
@ -1643,33 +1816,38 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
if (!VARIABLES_INSIDE_BLOCK(desc, processing_gcc_compilation))
local_symbols = new->locals;
/* If this is not the outermost LBRAC...RBRAC pair in the
function, its local symbols preceded it, and are the ones
just recovered from the context stack. Defined the block for them.
If this is the outermost LBRAC...RBRAC pair, there is no
need to do anything; leave the symbols that preceded it
to be attached to the function's own block. However, if
it is so, we need to indicate that we just moved outside
of the function. */
if (local_symbols
&& (context_stack_depth
> !VARIABLES_INSIDE_BLOCK(desc, processing_gcc_compilation)))
if (context_stack_depth
> !VARIABLES_INSIDE_BLOCK(desc, processing_gcc_compilation))
{
/* FIXME Muzzle a compiler bug that makes end < start. */
if (new->start_addr > valu)
/* This is not the outermost LBRAC...RBRAC pair in the function,
its local symbols preceded it, and are the ones just recovered
from the context stack. Define the block for them (but don't
bother if the block contains no symbols. Should we complain
on blocks without symbols? I can't think of any useful purpose
for them). */
if (local_symbols != NULL)
{
complain (&lbrac_rbrac_complaint);
new->start_addr = valu;
/* Muzzle a compiler bug that makes end < start. (which
compilers? Is this ever harmful?). */
if (new->start_addr > valu)
{
complain (&lbrac_rbrac_complaint);
new->start_addr = valu;
}
/* Make a block for the local symbols within. */
finish_block (0, &local_symbols, new->old_blocks,
new->start_addr, valu, objfile);
}
/* Make a block for the local symbols within. */
finish_block (0, &local_symbols, new->old_blocks,
new->start_addr, valu, objfile);
}
else
{
/* This is the outermost LBRAC...RBRAC pair. There is no
need to do anything; leave the symbols that preceded it
to be attached to the function's own block. We need to
indicate that we just moved outside of the function. */
within_function = 0;
}
if (VARIABLES_INSIDE_BLOCK(desc, processing_gcc_compilation))
/* Now pop locals of block just finished. */
local_symbols = new->locals;
@ -1718,11 +1896,16 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
end_symtab (valu, 0, 0, objfile, SECT_OFF_TEXT);
end_stabs ();
}
/* Null name means this just marks the end of text for this .o file.
Don't start a new symtab in this case. */
if (*name == '\000')
break;
start_stabs ();
start_symtab (name, NULL, valu);
break;
case N_SOL:
/* This type of symbol indicates the start of data for
a sub-source-file, one whose contents were copied or
@ -1784,13 +1967,30 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
call level, which we really don't want to do). */
{
char *p;
p = strchr (name, ':');
if (p != 0 && p[1] == 'S')
/* .o files and NLMs have non-zero text seg offsets, but don't need
their static syms offset in this fashion. XXX - This is really a
crock that should be fixed in the solib handling code so that I
don't have to work around it here. */
if (!symfile_relocatable)
{
/* The linker relocated it. There used to be a kludge here
to add the text offset, but that will break if we ever
start using the text offset (currently it is always zero). */
goto define_a_symbol;
p = strchr (name, ':');
if (p != 0 && p[1] == 'S')
{
/* The linker relocated it. We don't want to add an
elfstab_offset_sections-type offset, but we *do* want
to add whatever solib.c passed to symbol_file_add as
addr (this is known to affect SunOS4, and I suspect ELF
too). Since elfstab_offset_sections currently does not
muck with the text offset (there is no Ttext.text
symbol), we can get addr from the text offset. If
elfstab_offset_sections ever starts dealing with the
text offset, and we still need to do this, we need to
invent a SECT_OFF_ADDR_KLUDGE or something. */
valu += ANOFFSET (section_offsets, SECT_OFF_TEXT);
goto define_a_symbol;
}
}
/* Since it's not the kludge case, re-dispatch to the right handler. */
switch (type) {
@ -1836,8 +2036,7 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
case N_NBBSS:
case N_NBSTS:
case N_NBLCS:
complain (&unknown_symtype_complaint,
local_hex_string((unsigned long) type));
complain (&unknown_symtype_complaint, local_hex_string (type));
/* FALLTHROUGH */
/* The following symbol types don't need the address field relocated,
@ -2138,31 +2337,88 @@ elfstab_build_psymtabs (objfile, section_offsets, mainline,
dbx_symfile_read (objfile, section_offsets, 0);
}
/* Scan and build partial symbols for a PA symbol file.
This PA file has already been processed to get its minimal symbols.
/* Scan and build partial symbols for a file with special sections for stabs
and stabstrings. The file has already been processed to get its minimal
symbols, and any other symbols that might be necessary to resolve GSYMs.
This routine is the equivalent of dbx_symfile_init and dbx_symfile_read
rolled into one.
OBJFILE is the object file we are reading symbols from.
ADDR is the address relative to which the symbols are (e.g.
the base address of the text segment).
MAINLINE is true if we are reading the main symbol
table (as opposed to a shared lib or dynamically loaded file).
ADDR is the address relative to which the symbols are (e.g. the base address
of the text segment).
MAINLINE is true if we are reading the main symbol table (as opposed to a
shared lib or dynamically loaded file).
STAB_NAME is the name of the section that contains the stabs.
STABSTR_NAME is the name of the section that contains the stab strings.
*/
This routine is mostly copied from dbx_symfile_init and dbx_symfile_read. */
void
pastab_build_psymtabs (objfile, section_offsets, mainline)
stabsect_build_psymtabs (objfile, section_offsets, mainline, stab_name,
stabstr_name, text_name)
struct objfile *objfile;
struct section_offsets *section_offsets;
int mainline;
char *stab_name;
char *stabstr_name;
char *text_name;
{
int val;
bfd *sym_bfd = objfile->obfd;
char *name = bfd_get_filename (sym_bfd);
asection *stabsect;
asection *stabstrsect;
stabsect = bfd_get_section_by_name (sym_bfd, stab_name);
stabstrsect = bfd_get_section_by_name (sym_bfd, stabstr_name);
if (!stabsect)
return;
if (!stabstrsect)
error ("stabsect_build_psymtabs: Found stabs (%s), but not string section (%s)",
stab_name, stabstr_name);
objfile->sym_stab_info = (PTR) xmalloc (sizeof (struct dbx_symfile_info));
memset (DBX_SYMFILE_INFO (objfile), 0, sizeof (struct dbx_symfile_info));
DBX_TEXT_SECT (objfile) = bfd_get_section_by_name (sym_bfd, text_name);
if (!DBX_TEXT_SECT (objfile))
error ("Can't find %s section in symbol file", text_name);
DBX_SYMBOL_SIZE (objfile) = sizeof (struct external_nlist);
DBX_SYMCOUNT (objfile) = bfd_section_size (sym_bfd, stabsect)
/ DBX_SYMBOL_SIZE (objfile);
DBX_STRINGTAB_SIZE (objfile) = bfd_section_size (sym_bfd, stabstrsect);
DBX_SYMTAB_OFFSET (objfile) = stabsect->filepos; /* XXX - FIXME: POKING INSIDE BFD DATA STRUCTURES */
if (DBX_STRINGTAB_SIZE (objfile) > bfd_get_size (sym_bfd))
error ("ridiculous string table size: %d bytes", DBX_STRINGTAB_SIZE (objfile));
DBX_STRINGTAB (objfile) = (char *)
obstack_alloc (&objfile->psymbol_obstack, DBX_STRINGTAB_SIZE (objfile) + 1);
/* Now read in the string table in one big gulp. */
val = bfd_get_section_contents (sym_bfd, /* bfd */
stabstrsect, /* bfd section */
DBX_STRINGTAB (objfile), /* input buffer */
0, /* offset into section */
DBX_STRINGTAB_SIZE (objfile)); /* amount to read */
if (!val)
perror_with_name (name);
stabsread_new_init ();
buildsym_new_init ();
free_header_files ();
init_header_files ();
install_minimal_symbols (objfile);
/* In a PA file, we've already installed the minimal symbols that came
from the PA (non-stab) symbol table, so always act like an
incremental load here. */
/* Now, do an incremental load */
dbx_symfile_read (objfile, section_offsets, mainline);
processing_acc_compilation = 1;
dbx_symfile_read (objfile, section_offsets, 0);
}
/* Parse the user's idea of an offset for dynamic linking, into our idea
@ -2175,11 +2431,12 @@ dbx_symfile_offsets (objfile, addr)
{
struct section_offsets *section_offsets;
int i;
objfile->num_sections = SECT_OFF_MAX;
section_offsets = (struct section_offsets *)
obstack_alloc (&objfile -> psymbol_obstack,
sizeof (struct section_offsets) +
sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
sizeof (struct section_offsets)
+ sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
for (i = 0; i < SECT_OFF_MAX; i++)
ANOFFSET (section_offsets, i) = addr;
@ -2187,36 +2444,9 @@ dbx_symfile_offsets (objfile, addr)
return section_offsets;
}
/* Register our willingness to decode symbols for SunOS and a.out and
NetBSD and b.out files handled by BFD... */
static struct sym_fns sunos_sym_fns =
{
"sunOs", /* sym_name: name or name prefix of BFD target type */
6, /* sym_namelen: number of significant sym_name chars */
dbx_new_init, /* sym_new_init: init anything gbl to entire symtab */
dbx_symfile_init, /* sym_init: read initial info, setup for sym_read() */
dbx_symfile_read, /* sym_read: read a symbol file into symtab */
dbx_symfile_finish, /* sym_finish: finished with file, cleanup */
dbx_symfile_offsets, /* sym_offsets: parse user's offsets to internal form */
NULL /* next: pointer to next struct sym_fns */
};
static struct sym_fns aout_sym_fns =
{
"a.out", /* sym_name: name or name prefix of BFD target type */
5, /* sym_namelen: number of significant sym_name chars */
dbx_new_init, /* sym_new_init: init anything gbl to entire symtab */
dbx_symfile_init, /* sym_init: read initial info, setup for sym_read() */
dbx_symfile_read, /* sym_read: read a symbol file into symtab */
dbx_symfile_finish, /* sym_finish: finished with file, cleanup */
dbx_symfile_offsets, /* sym_offsets: parse user's offsets to internal form */
NULL /* next: pointer to next struct sym_fns */
};
static struct sym_fns bout_sym_fns =
{
"b.out", /* sym_name: name or name prefix of BFD target type */
5, /* sym_namelen: number of significant sym_name chars */
bfd_target_aout_flavour,
dbx_new_init, /* sym_new_init: init anything gbl to entire symtab */
dbx_symfile_init, /* sym_init: read initial info, setup for sym_read() */
dbx_symfile_read, /* sym_read: read a symbol file into symtab */
@ -2228,7 +2458,5 @@ static struct sym_fns bout_sym_fns =
void
_initialize_dbxread ()
{
add_symtab_fns(&sunos_sym_fns);
add_symtab_fns(&aout_sym_fns);
add_symtab_fns(&bout_sym_fns);
}

View File

@ -27,12 +27,16 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "ansidecl.h"
/* An address in the program being debugged. Host byte order. */
#ifndef CORE_ADDR_TYPE
typedef unsigned int CORE_ADDR;
#else
typedef CORE_ADDR_TYPE CORE_ADDR;
#endif
/* For BFD64 and bfd_vma. */
#include "bfd.h"
/* An address in the program being debugged. Host byte order. Rather
than duplicate all the logic in BFD which figures out what type
this is (long, long long, etc.) and whether it needs to be 64
bits (the host/target interactions are subtle), we just use
bfd_vma. */
typedef bfd_vma CORE_ADDR;
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
@ -88,7 +92,8 @@ enum language
language_c, /* C */
language_cplus, /* C++ */
language_chill, /* Chill */
language_m2 /* Modula-2 */
language_m2, /* Modula-2 */
language_asm /* Assembly language */
};
/* the cleanup list records things that have to be undone
@ -211,7 +216,11 @@ myread PARAMS ((int, char *, int));
extern int
query ();
/* Annotation stuff. */
extern int annotation_level; /* in stack.c */
extern void
begin_line PARAMS ((void));
@ -221,15 +230,39 @@ wrap_here PARAMS ((char *));
extern void
reinitialize_more_filter PARAMS ((void));
typedef FILE GDB_FILE;
#define gdb_stdout stdout
#define gdb_stderr stderr
extern int
print_insn PARAMS ((CORE_ADDR, FILE *));
print_insn PARAMS ((CORE_ADDR, GDB_FILE *));
extern void
fputs_filtered PARAMS ((const char *, FILE *));
gdb_flush PARAMS ((GDB_FILE *));
extern GDB_FILE *
gdb_fopen PARAMS ((char * name, char * mode));
extern void
fputs_filtered PARAMS ((const char *, GDB_FILE *));
extern void
fputs_unfiltered PARAMS ((const char *, GDB_FILE *));
extern void
fputc_unfiltered PARAMS ((int, GDB_FILE *));
extern void
putc_unfiltered PARAMS ((int));
#define putchar_unfiltered(C) putc_unfiltered(C)
extern void
puts_filtered PARAMS ((char *));
extern void
puts_unfiltered PARAMS ((char *));
extern void
vprintf_filtered ();
@ -249,19 +282,34 @@ extern void
printfi_filtered ();
extern void
print_spaces PARAMS ((int, FILE *));
vprintf_unfiltered ();
extern void
print_spaces_filtered PARAMS ((int, FILE *));
vfprintf_unfiltered ();
extern void
fprintf_unfiltered ();
extern void
printf_unfiltered ();
extern void
print_spaces PARAMS ((int, GDB_FILE *));
extern void
print_spaces_filtered PARAMS ((int, GDB_FILE *));
extern char *
n_spaces PARAMS ((int));
extern void
gdb_printchar PARAMS ((int, FILE *, int));
gdb_printchar PARAMS ((int, GDB_FILE *, int));
/* Print a host address. */
extern void gdb_print_address PARAMS ((void *, GDB_FILE *));
extern void
fprintf_symbol_filtered PARAMS ((FILE *, char *, enum language, int));
fprintf_symbol_filtered PARAMS ((GDB_FILE *, char *, enum language, int));
extern void
perror_with_name PARAMS ((char *));
@ -290,14 +338,11 @@ extern char *
gdb_readline PARAMS ((char *));
extern char *
command_line_input PARAMS ((char *, int));
command_line_input PARAMS ((char *, int, char *));
extern void
print_prompt PARAMS ((void));
extern int
batch_mode PARAMS ((void));
extern int
input_from_terminal_p PARAMS ((void));
@ -307,10 +352,13 @@ extern void
set_next_address PARAMS ((CORE_ADDR));
extern void
print_address_symbolic PARAMS ((CORE_ADDR, FILE *, int, char *));
print_address_symbolic PARAMS ((CORE_ADDR, GDB_FILE *, int, char *));
extern void
print_address PARAMS ((CORE_ADDR, FILE *));
print_address_numeric PARAMS ((CORE_ADDR, int, GDB_FILE *));
extern void
print_address PARAMS ((CORE_ADDR, GDB_FILE *));
/* From source.c */
@ -384,6 +432,10 @@ enum val_prettyprint
#include "nm.h"
#ifdef KERNEL_DEBUG
extern int kernel_debugging;
#endif
/* If the xm.h file did not define the mode string used to open the
files, assume that binary files are opened the same way as text
files */
@ -466,80 +518,32 @@ enum val_prettyprint
#define LONG_MAX ((long)(ULONG_MAX >> 1)) /* 0x7FFFFFFF for 32-bits */
#endif
/* Number of bits in a char or unsigned char for the target machine.
Just like CHAR_BIT in <limits.h> but describes the target machine. */
#if !defined (TARGET_CHAR_BIT)
#define TARGET_CHAR_BIT 8
#endif
#ifdef BFD64
/* Number of bits in a short or unsigned short for the target machine. */
#if !defined (TARGET_SHORT_BIT)
#define TARGET_SHORT_BIT (2 * TARGET_CHAR_BIT)
#endif
/* This is to make sure that LONGEST is at least as big as CORE_ADDR. */
/* Number of bits in an int or unsigned int for the target machine. */
#if !defined (TARGET_INT_BIT)
#define TARGET_INT_BIT (4 * TARGET_CHAR_BIT)
#endif
#define LONGEST BFD_HOST_64_BIT
/* Number of bits in a long or unsigned long for the target machine. */
#if !defined (TARGET_LONG_BIT)
#define TARGET_LONG_BIT (4 * TARGET_CHAR_BIT)
#endif
#else /* No BFD64 */
/* Number of bits in a long long or unsigned long long for the target machine. */
#if !defined (TARGET_LONG_LONG_BIT)
#define TARGET_LONG_LONG_BIT (2 * TARGET_LONG_BIT)
#endif
/* If all compilers for this host support "long long" and we want to
use it for LONGEST (the performance hit is about 10% on a testsuite
run based on one DECstation test), then the xm.h file can define
CC_HAS_LONG_LONG.
/* Number of bits in a float for the target machine. */
#if !defined (TARGET_FLOAT_BIT)
#define TARGET_FLOAT_BIT (4 * TARGET_CHAR_BIT)
#endif
/* Number of bits in a double for the target machine. */
#if !defined (TARGET_DOUBLE_BIT)
#define TARGET_DOUBLE_BIT (8 * TARGET_CHAR_BIT)
#endif
/* Number of bits in a long double for the target machine. */
#if !defined (TARGET_LONG_DOUBLE_BIT)
#define TARGET_LONG_DOUBLE_BIT (2 * TARGET_DOUBLE_BIT)
#endif
/* Number of bits in a "complex" for the target machine. */
#if !defined (TARGET_COMPLEX_BIT)
#define TARGET_COMPLEX_BIT (2 * TARGET_FLOAT_BIT)
#endif
/* Number of bits in a "double complex" for the target machine. */
#if !defined (TARGET_DOUBLE_COMPLEX_BIT)
#define TARGET_DOUBLE_COMPLEX_BIT (2 * TARGET_DOUBLE_BIT)
#endif
/* Number of bits in a pointer for the target machine */
#if !defined (TARGET_PTR_BIT)
#define TARGET_PTR_BIT TARGET_INT_BIT
#endif
/* Default to support for "long long" if the host compiler being used is gcc.
Config files must define CC_HAS_LONG_LONG to use other host compilers
that are capable of supporting "long long", and to cause gdb to use that
support. Not defining CC_HAS_LONG_LONG will suppress use of "long long"
regardless of what compiler is used.
FIXME: For now, automatic selection of "long long" as the default when
gcc is used is disabled, pending further testing. Concerns include the
impact on gdb performance and the universality of bugfree long long
support on platforms that do have gcc. Compiling with FORCE_LONG_LONG
will select "long long" use for testing purposes. -fnf */
Using GCC 1.39 on BSDI with long long causes about 700 new
testsuite failures. Using long long for LONGEST on the DECstation
causes 3 new FAILs in the testsuite and many heuristic fencepost
warnings. These are not investigated, but a first guess would be
that the BSDI problems are GCC bugs in long long support and the
latter are GDB bugs. */
#ifndef CC_HAS_LONG_LONG
# if defined (__GNUC__) && defined (FORCE_LONG_LONG) /* See FIXME above */
# if defined (__GNUC__) && defined (FORCE_LONG_LONG)
# define CC_HAS_LONG_LONG 1
# endif
#endif
/* LONGEST should not be a typedef, because "unsigned LONGEST" needs to work.
CC_HAS_LONG_LONG is defined if the host compiler supports "long long"
variables and we wish to make use of that support. */
@ -552,30 +556,13 @@ enum val_prettyprint
# endif
#endif
#endif /* No BFD64 */
/* Convert a LONGEST to an int. This is used in contexts (e.g. number of
arguments to a function, number in a value history, register number, etc.)
where the value must not be larger than can fit in an int. */
#ifndef longest_to_int
# ifdef CC_HAS_LONG_LONG
# define longest_to_int(x) (((x) > INT_MAX || (x) < INT_MIN) \
? (error ("Value out of range."),0) : (int) (x))
# else
/* Assume sizeof (int) == sizeof (long). */
# define longest_to_int(x) ((int) (x))
# endif
#endif
/* If we picked up a copy of CHAR_BIT from a configuration file
(which may get it by including <limits.h>) then use it to set
the number of bits in a host char. If not, use the same size
as the target. */
#if defined (CHAR_BIT)
#define HOST_CHAR_BIT CHAR_BIT
#else
#define HOST_CHAR_BIT TARGET_CHAR_BIT
#endif
extern int longest_to_int PARAMS ((LONGEST));
/* Assorted functions we can declare, now that const and volatile are
defined. */
@ -627,9 +614,19 @@ parse_escape PARAMS ((char **));
extern const char * const reg_names[];
/* Message to be printed before the error message, when an error occurs. */
extern char *error_pre_print;
/* Message to be printed before the warning message, when a warning occurs. */
extern char *warning_pre_print;
extern NORETURN void /* Does not return to the caller. */
error ();
extern void error_begin PARAMS ((void));
extern NORETURN void /* Does not return to the caller. */
fatal ();
@ -723,7 +720,7 @@ psignal PARAMS ((unsigned, const char *));
#endif
extern int
fclose PARAMS ((FILE *stream)); /* 4.9.5.1 */
fclose PARAMS ((GDB_FILE *stream)); /* 4.9.5.1 */
extern void
perror PARAMS ((const char *)); /* 4.9.10.4 */
@ -750,7 +747,7 @@ free PARAMS ((void *)); /* 4.10.3.2 */
extern void
qsort PARAMS ((void *base, size_t nmemb, /* 4.10.5.2 */
size_t size,
int (*comp)(const void *, const void *)));
int (*compar)(const void *, const void *)));
#ifndef MEM_FNS_DECLARED /* Some non-ANSI use void *, not char *. */
extern PTR
@ -784,17 +781,21 @@ strerror PARAMS ((int)); /* 4.11.6.2 */
#ifndef alloca
# ifdef __GNUC__
# define alloca __builtin_alloca
# else
# else /* Not GNU C */
# ifdef sparc
# include <alloca.h> /* NOTE: Doesn't declare alloca() */
# endif
# ifdef __STDC__
extern void *alloca (size_t);
# else /* __STDC__ */
/* We need to be careful not to declare this in a way which conflicts with
bison. Bison never declares it as char *, but under various circumstances
(like __hpux) we need to use void *. */
# if defined (__STDC__) || defined (__hpux)
extern void *alloca ();
# else /* Don't use void *. */
extern char *alloca ();
# endif
# endif
#endif
# endif /* Don't use void *. */
# endif /* Not GNU C */
#endif /* alloca not defined */
/* TARGET_BYTE_ORDER and HOST_BYTE_ORDER must be defined to one of these. */
@ -813,6 +814,73 @@ strerror PARAMS ((int)); /* 4.11.6.2 */
#include "tm.h"
/* Number of bits in a char or unsigned char for the target machine.
Just like CHAR_BIT in <limits.h> but describes the target machine. */
#if !defined (TARGET_CHAR_BIT)
#define TARGET_CHAR_BIT 8
#endif
/* Number of bits in a short or unsigned short for the target machine. */
#if !defined (TARGET_SHORT_BIT)
#define TARGET_SHORT_BIT (2 * TARGET_CHAR_BIT)
#endif
/* Number of bits in an int or unsigned int for the target machine. */
#if !defined (TARGET_INT_BIT)
#define TARGET_INT_BIT (4 * TARGET_CHAR_BIT)
#endif
/* Number of bits in a long or unsigned long for the target machine. */
#if !defined (TARGET_LONG_BIT)
#define TARGET_LONG_BIT (4 * TARGET_CHAR_BIT)
#endif
/* Number of bits in a long long or unsigned long long for the target machine. */
#if !defined (TARGET_LONG_LONG_BIT)
#define TARGET_LONG_LONG_BIT (2 * TARGET_LONG_BIT)
#endif
/* Number of bits in a float for the target machine. */
#if !defined (TARGET_FLOAT_BIT)
#define TARGET_FLOAT_BIT (4 * TARGET_CHAR_BIT)
#endif
/* Number of bits in a double for the target machine. */
#if !defined (TARGET_DOUBLE_BIT)
#define TARGET_DOUBLE_BIT (8 * TARGET_CHAR_BIT)
#endif
/* Number of bits in a long double for the target machine. */
#if !defined (TARGET_LONG_DOUBLE_BIT)
#define TARGET_LONG_DOUBLE_BIT (2 * TARGET_DOUBLE_BIT)
#endif
/* Number of bits in a "complex" for the target machine. */
#if !defined (TARGET_COMPLEX_BIT)
#define TARGET_COMPLEX_BIT (2 * TARGET_FLOAT_BIT)
#endif
/* Number of bits in a "double complex" for the target machine. */
#if !defined (TARGET_DOUBLE_COMPLEX_BIT)
#define TARGET_DOUBLE_COMPLEX_BIT (2 * TARGET_DOUBLE_BIT)
#endif
/* Number of bits in a pointer for the target machine */
#if !defined (TARGET_PTR_BIT)
#define TARGET_PTR_BIT TARGET_INT_BIT
#endif
/* If we picked up a copy of CHAR_BIT from a configuration file
(which may get it by including <limits.h>) then use it to set
the number of bits in a host char. If not, use the same size
as the target. */
#if defined (CHAR_BIT)
#define HOST_CHAR_BIT CHAR_BIT
#else
#define HOST_CHAR_BIT TARGET_CHAR_BIT
#endif
/* The bit byte-order has to do just with numbering of bits in
debugging symbols and such. Conceptually, it's quite separate
from byte/word byte order. */
@ -827,27 +895,6 @@ strerror PARAMS ((int)); /* 4.11.6.2 */
#endif /* Little endian. */
#endif /* BITS_BIG_ENDIAN not defined. */
/* Swap LEN bytes at BUFFER between target and host byte-order. This is
the wrong way to do byte-swapping because it assumes that you have a way
to have a host variable of exactly the right size.
extract_* are the right way. */
#if TARGET_BYTE_ORDER == HOST_BYTE_ORDER
#define SWAP_TARGET_AND_HOST(buffer,len)
#else /* Target and host byte order differ. */
#define SWAP_TARGET_AND_HOST(buffer,len) \
{ \
char tmp; \
char *p = (char *)(buffer); \
char *q = ((char *)(buffer)) + len - 1; \
for (; p < q; p++, q--) \
{ \
tmp = *q; \
*q = *p; \
*p = tmp; \
} \
}
#endif /* Target and host byte order differ. */
/* In findvar.c. */
LONGEST extract_signed_integer PARAMS ((void *, int));
unsigned LONGEST extract_unsigned_integer PARAMS ((void *, int));
@ -856,6 +903,9 @@ CORE_ADDR extract_address PARAMS ((void *, int));
void store_signed_integer PARAMS ((void *, int, LONGEST));
void store_unsigned_integer PARAMS ((void *, int, unsigned LONGEST));
void store_address PARAMS ((void *, int, CORE_ADDR));
double extract_floating PARAMS ((void *, int));
void store_floating PARAMS ((void *, int, double));
/* On some machines there are bits in addresses which are not really
part of the address, but are used by the kernel, the hardware, etc.
@ -875,13 +925,8 @@ void store_address PARAMS ((void *, int, CORE_ADDR));
extern CORE_ADDR
push_bytes PARAMS ((CORE_ADDR, char *, int));
/* In some modules, we don't have a definition of REGISTER_TYPE yet, so we
must avoid prototyping this function for now. FIXME. Should be:
extern CORE_ADDR
push_word PARAMS ((CORE_ADDR, REGISTER_TYPE));
*/
extern CORE_ADDR
push_word ();
push_word PARAMS ((CORE_ADDR, unsigned LONGEST));
/* Some parts of gdb might be considered optional, in the sense that they
are not essential for being able to build a working, usable debugger

View File

@ -70,17 +70,6 @@ static const struct demangler
{NULL, unknown_demangling, NULL}
};
/* show current demangling style. */
static void
show_demangling_command (ignore, from_tty)
char *ignore;
int from_tty;
{
/* done automatically by show command. */
}
/* set current demangling style. called by the "set demangling" command
after it has updated the current_demangling_style_string to match
what the user has entered.
@ -98,9 +87,10 @@ show_demangling_command (ignore, from_tty)
a malloc'd string, even if it is a null-string. */
static void
set_demangling_command (ignore, from_tty)
char *ignore;
int from_tty;
set_demangling_command (ignore, from_tty, c)
char *ignore;
int from_tty;
struct cmd_list_element *c;
{
const struct demangler *dem;
@ -127,19 +117,20 @@ set_demangling_command (ignore, from_tty)
{
if (*current_demangling_style_string != '\0')
{
printf ("Unknown demangling style `%s'.\n",
printf_unfiltered ("Unknown demangling style `%s'.\n",
current_demangling_style_string);
}
printf ("The currently understood settings are:\n\n");
printf_unfiltered ("The currently understood settings are:\n\n");
for (dem = demanglers; dem -> demangling_style_name != NULL; dem++)
{
printf ("%-10s %s\n", dem -> demangling_style_name,
printf_unfiltered ("%-10s %s\n", dem -> demangling_style_name,
dem -> demangling_style_doc);
if (dem -> demangling_style == current_demangling_style)
{
free (current_demangling_style_string);
current_demangling_style_string =
strdup (dem -> demangling_style_name);
savestring (dem -> demangling_style_name,
strlen (dem -> demangling_style_name));
}
}
if (current_demangling_style == unknown_demangling)
@ -149,7 +140,8 @@ set_demangling_command (ignore, from_tty)
one as the default. */
current_demangling_style = demanglers[0].demangling_style;
current_demangling_style_string =
strdup (demanglers[0].demangling_style_name);
savestring (demanglers[0].demangling_style_name,
strlen (demanglers[0].demangling_style_name));
warning ("`%s' style demangling chosen as the default.\n",
current_demangling_style_string);
}
@ -166,7 +158,7 @@ set_demangling_style (style)
{
free (current_demangling_style_string);
}
current_demangling_style_string = strdup (style);
current_demangling_style_string = savestring (style, strlen (style));
set_demangling_command ((char *) NULL, 0);
}
@ -181,8 +173,7 @@ _initialize_demangler ()
Use `set demangle-style' without arguments for a list of demangling styles.",
&setlist);
show = add_show_from_set (set, &showlist);
set -> function.cfunc = set_demangling_command;
show -> function.cfunc = show_demangling_command;
set -> function.sfunc = set_demangling_command;
/* Set the default demangling style chosen at compilation time. */
set_demangling_style (DEFAULT_DEMANGLING_STYLE);

View File

@ -69,6 +69,9 @@ extern enum demangling_styles
extern char *
cplus_demangle PARAMS ((CONST char *mangled, int options));
extern int
cplus_demangle_opname PARAMS ((char *opname, char *result, int options));
/* Note: This sets global state. FIXME if you care about multi-threading. */
extern void

View File

@ -19,7 +19,7 @@ enum dis_insn_type {
dis_jsr, /* Jump to subroutine */
dis_condjsr, /* Conditional jump to subroutine */
dis_dref, /* Data reference instruction */
dis_dref2, /* Two data references in instruction */
dis_dref2 /* Two data references in instruction */
};
/* This struct is passed into the instruction decoding routine,
@ -111,10 +111,13 @@ extern int print_insn_i960 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_sh PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_hppa PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_m88k PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_ns32k PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_big_powerpc PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_little_powerpc PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_rs6000 PARAMS ((bfd_vma, disassemble_info*));
/* Fetch the disassembler for a given BFD, if that support is available. */
extern disassembler_ftype disassembler PARAMS ((bfd *));
/* This block of definitions is for particular callers who read instructions

View File

@ -1,5 +1,5 @@
/* Disassemble from a buffer, for GNU.
Copyright (C) 1993 Free Software Foundation, Inc.
Copyright (C) 1993, 1994 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -16,6 +16,7 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "dis-asm.h"
#include "sysdep.h"
#include <errno.h>
/* Get LENGTH bytes from info's buffer, at target address memaddr.

View File

@ -1,5 +1,5 @@
/* DWARF debugging format support for GDB.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
Written by Fred Fish at Cygnus Support. Portions based on dbxread.c,
mipsread.c, coffread.c, and dwarfread.c from a Data General SVR4 gdb port.
@ -44,9 +44,6 @@ other things to work on, if you get bored. :-)
#include "gdbtypes.h"
#include "symfile.h"
#include "objfiles.h"
#include <time.h> /* For time_t in libbfd.h. */
#include <sys/types.h> /* For time_t, if not in time.h. */
#include "libbfd.h" /* FIXME Secret Internal BFD stuff (bfd_read) */
#include "elf/dwarf.h"
#include "buildsym.h"
#include "demangle.h"
@ -56,7 +53,6 @@ other things to work on, if you get bored. :-)
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#ifndef NO_SYS_FILE
#include <sys/file.h>
@ -1989,10 +1985,21 @@ process_dies (thisdie, enddie, objfile)
{
nextdie = thisdie + di.die_length;
}
#ifdef SMASH_TEXT_ADDRESS
/* I think that these are always text, not data, addresses. */
SMASH_TEXT_ADDRESS (di.at_low_pc);
SMASH_TEXT_ADDRESS (di.at_high_pc);
#endif
switch (di.die_tag)
{
case TAG_compile_unit:
read_file_scope (&di, thisdie, nextdie, objfile);
/* Skip Tag_compile_unit if we are already inside a compilation
unit, we are unable to handle nested compilation units
properly (FIXME). */
if (current_subfile == NULL)
read_file_scope (&di, thisdie, nextdie, objfile);
else
nextdie = thisdie + di.die_length;
break;
case TAG_global_subroutine:
case TAG_subroutine:
@ -2364,14 +2371,14 @@ psymtab_to_symtab_1 (pst)
/* Inform about additional files that need to be read in. */
if (info_verbose)
{
fputs_filtered (" ", stdout);
fputs_filtered (" ", gdb_stdout);
wrap_here ("");
fputs_filtered ("and ", stdout);
fputs_filtered ("and ", gdb_stdout);
wrap_here ("");
printf_filtered ("%s...",
pst -> dependencies[i] -> filename);
wrap_here ("");
fflush (stdout); /* Flush output */
gdb_flush (gdb_stdout); /* Flush output */
}
psymtab_to_symtab_1 (pst -> dependencies[i]);
}
@ -2385,7 +2392,7 @@ psymtab_to_symtab_1 (pst)
{
printf_filtered ("%d DIE's, sorting...", diecount);
wrap_here ("");
fflush (stdout);
gdb_flush (gdb_stdout);
}
sort_symtab_syms (pst -> symtab);
do_cleanups (old_chain);
@ -2435,7 +2442,7 @@ dwarf_psymtab_to_symtab (pst)
{
printf_filtered ("Reading in symbols for %s...",
pst -> filename);
fflush (stdout);
gdb_flush (gdb_stdout);
}
psymtab_to_symtab_1 (pst);
@ -2453,7 +2460,7 @@ dwarf_psymtab_to_symtab (pst)
if (info_verbose)
{
printf_filtered ("done.\n");
fflush (stdout);
gdb_flush (gdb_stdout);
}
}
}
@ -2613,6 +2620,9 @@ add_partial_symbol (dip, objfile)
case TAG_structure_type:
case TAG_union_type:
case TAG_enumeration_type:
/* Do not add opaque aggregate definitions to the psymtab. */
if (!dip -> has_at_byte_size)
break;
ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
STRUCT_NAMESPACE, LOC_TYPEDEF,
objfile -> static_psymbols,

View File

@ -1,5 +1,5 @@
/* ELF support for BFD.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
Written by Fred Fish @ Cygnus Support, from information published
in "UNIX System V Release 4, Programmers Guide: ANSI C and
@ -69,16 +69,27 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Values for e_machine, which identifies the architecture */
#define EM_NONE 0 /* No machine */
#define EM_M32 1 /* AT&T WE 32100 */
#define EM_SPARC 2 /* SUN SPARC */
#define EM_386 3 /* Intel 80386 */
#define EM_68K 4 /* Motorola m68k family */
#define EM_88K 5 /* Motorola m88k family */
#define EM_860 7 /* Intel 80860 */
#define EM_MIPS 8 /* MIPS R3000 */
#define EM_HPPA 9 /* HP PA-RISC */
#define EM_NONE 0 /* No machine */
#define EM_M32 1 /* AT&T WE 32100 */
#define EM_SPARC 2 /* SUN SPARC */
#define EM_386 3 /* Intel 80386 */
#define EM_68K 4 /* Motorola m68k family */
#define EM_88K 5 /* Motorola m88k family */
#define EM_860 7 /* Intel 80860 */
#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */
#define EM_SPARC64 11 /* SPARC v9 (not official) 64-bit */
#define EM_PARISC 15 /* HPPA */
/* If it is necessary to assign new unofficial EM_* values, please pick large
random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision
with official or non-GNU unofficial values. */
/* Cygnus PowerPC ELF backend. Written in the absence of an ABI. */
#define EM_CYGNUS_POWERPC 0x9025
/* Values for e_version */
@ -169,7 +180,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
other places. */
#define SHN_UNDEF 0 /* Undefined section reference */
#define SHN_LORESERV 0xFF00 /* Begin range of reserved indices */
#define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */
#define SHN_LOPROC 0xFF00 /* Begin range of appl-specific */
#define SHN_HIPROC 0xFF1F /* End range of appl-specific */
#define SHN_ABS 0xFFF1 /* Associated symbol is absolute */
@ -178,13 +189,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* relocation info handling macros */
#define ELF32_R_SYM(i) ((i)>>8)
#define ELF32_R_TYPE(i) ((unsigned char)(i))
#define ELF32_R_INFO(s,t) (((s)<<8)+(unsigned char)(t))
#define ELF32_R_SYM(i) ((i) >> 8)
#define ELF32_R_TYPE(i) ((i) & 0xff)
#define ELF32_R_INFO(s,t) (((s) << 8) + ((t) & 0xff))
#define ELF64_R_SYM(i) ((i)>>32)
#define ELF64_R_TYPE(i) ((Elf64_Word)(i))
#define ELF64_R_INFO(s,t) (((Elf64_Xword)(s)<<32)+(Elf64_Xword)(t))
#define ELF64_R_SYM(i) ((i) >> 32)
#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
#define ELF64_R_INFO(s,t) (((bfd_vma) (s) << 32) + (bfd_vma) (t))
/* Dynamic section tags */

View File

@ -1,5 +1,5 @@
/* ELF support for BFD.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
Written by Fred Fish @ Cygnus Support, from information published
in "UNIX System V Release 4, Programmers Guide: ANSI C and
@ -28,24 +28,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
the elf-common.h file which contains the portions that are common to
both the internal and external representations. */
/* Types used by various structures, functions, etc. */
typedef unsigned long Elf32_Addr; /* Unsigned program address */
typedef unsigned long Elf32_Off; /* Unsigned file offset */
typedef long Elf32_Sword; /* Signed large integer */
typedef unsigned long Elf32_Word; /* Unsigned large integer */
typedef unsigned short Elf32_Half; /* Unsigned medium integer */
typedef unsigned char Elf32_Char; /* Unsigned tiny integer */
#ifdef HOST_64_BIT
typedef unsigned HOST_64_BIT Elf64_Addr;
typedef unsigned HOST_64_BIT Elf64_Off;
typedef HOST_64_BIT Elf64_Sxword;
typedef unsigned HOST_64_BIT Elf64_Xword;
#endif
typedef long Elf64_Sword;
typedef unsigned long Elf64_Word;
typedef unsigned short Elf64_Half;
/* NOTE that these structures are not kept in the same order as they appear
in the object file. In some cases they've been reordered for more optimal
@ -111,8 +93,8 @@ typedef struct elf_internal_shdr {
unsigned int sh_addralign; /* Section alignment */
/* The internal rep also has some cached info associated with it. */
void *rawdata; /* null if unused... */
void *contents; /* null if unused... */
PTR rawdata; /* null if unused... */
PTR contents; /* null if unused... */
bfd_vma size; /* size of contents (0 if unused) */
} Elf_Internal_Shdr;
@ -176,20 +158,17 @@ typedef struct elf_internal_rela {
/* dynamic section structure */
typedef struct {
Elf32_Sword d_tag; /* entry tag value */
typedef struct elf_internal_dyn {
/* This needs to support 64-bit values in elf64. */
bfd_vma d_tag; /* entry tag value */
union {
Elf32_Word d_val;
Elf32_Addr d_ptr;
/* This needs to support 64-bit values in elf64. */
bfd_vma d_val;
bfd_vma d_ptr;
} d_un;
} Elf32_Internal_Dyn;
} Elf_Internal_Dyn;
#ifdef HOST_64_BIT
typedef struct {
Elf64_Xword d_tag; /* entry tag value */
union {
Elf64_Xword d_val;
Elf64_Addr d_ptr;
} d_un;
} Elf64_Internal_Dyn;
#endif
#define elf32_internal_dyn elf_internal_dyn
#define elf64_internal_dyn elf_internal_dyn
#define Elf32_Internal_Dyn Elf_Internal_Dyn
#define Elf64_Internal_Dyn Elf_Internal_Dyn

View File

@ -1,5 +1,5 @@
/* Read ELF (Executable and Linking Format) object files for GDB.
Copyright 1991, 1992 Free Software Foundation, Inc.
Copyright 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
Written by Fred Fish at Cygnus Support.
This file is part of GDB.
@ -20,10 +20,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "defs.h"
#include "bfd.h"
#include <time.h> /* For time_t in libbfd.h. */
#include <sys/types.h> /* For time_t, if not in time.h. */
#include "libbfd.h" /* For bfd_elf_find_section */
#include <string.h>
#include "libelf.h"
/*#include "elf/mips.h"*/
#include "symtab.h"
#include "symfile.h"
#include "objfiles.h"
@ -31,7 +30,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "stabsread.h"
#include "gdb-stabs.h"
#include "complaints.h"
#include <string.h>
#include "demangle.h"
/* The struct elfinfo is available only during ELF symbol table and
@ -45,6 +43,7 @@ struct elfinfo {
unsigned int lnsize; /* Size of dwarf line number section */
asection *stabsect; /* Section pointer for .stab section */
asection *stabindexsect; /* Section pointer for .stab.index section */
asection *mdebugsect; /* Section pointer for .mdebug section */
};
/* Various things we might complain about... */
@ -74,7 +73,7 @@ static void
elf_symfile_finish PARAMS ((struct objfile *));
static void
elf_symtab_read PARAMS ((bfd *, CORE_ADDR, struct objfile *));
elf_symtab_read PARAMS ((bfd *, CORE_ADDR, struct objfile *, int));
static void
free_elfinfo PARAMS ((void *));
@ -136,6 +135,10 @@ elf_locate_sections (ignore_abfd, sectp, eip)
{
ei -> stabindexsect = sectp;
}
else if (STREQ (sectp -> name, ".mdebug"))
{
ei -> mdebugsect = sectp;
}
}
#if 0 /* Currently unused */
@ -185,6 +188,9 @@ record_minimal_symbol_and_info (name, address, ms_type, info, objfile)
case mst_text:
case mst_file_text:
section = SECT_OFF_TEXT;
#ifdef SMASH_TEXT_ADDRESS
SMASH_TEXT_ADDRESS (address);
#endif
break;
case mst_data:
case mst_file_data:
@ -200,7 +206,8 @@ record_minimal_symbol_and_info (name, address, ms_type, info, objfile)
}
name = obsavestring (name, strlen (name), &objfile -> symbol_obstack);
prim_record_minimal_symbol_and_info (name, address, ms_type, info, section);
prim_record_minimal_symbol_and_info (name, address, ms_type, info, section,
objfile);
}
/*
@ -230,16 +237,17 @@ DESCRIPTION
*/
static void
elf_symtab_read (abfd, addr, objfile)
elf_symtab_read (abfd, addr, objfile, dynamic)
bfd *abfd;
CORE_ADDR addr;
struct objfile *objfile;
int dynamic;
{
unsigned int storage_needed;
long storage_needed;
asymbol *sym;
asymbol **symbol_table;
unsigned int number_of_symbols;
unsigned int i;
long number_of_symbols;
long i;
int index;
struct cleanup *back_to;
CORE_ADDR symaddr;
@ -253,13 +261,35 @@ elf_symtab_read (abfd, addr, objfile)
struct dbx_symfile_info *dbx = (struct dbx_symfile_info *)
objfile->sym_stab_info;
unsigned long size;
storage_needed = get_symtab_upper_bound (abfd);
int stripped = (bfd_get_symcount (abfd) == 0);
if (dynamic)
{
storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd);
/* Nothing to be done if there is no dynamic symtab. */
if (storage_needed < 0)
return;
}
else
{
storage_needed = bfd_get_symtab_upper_bound (abfd);
if (storage_needed < 0)
error ("Can't read symbols from %s: %s", bfd_get_filename (abfd),
bfd_errmsg (bfd_get_error ()));
}
if (storage_needed > 0)
{
symbol_table = (asymbol **) xmalloc (storage_needed);
back_to = make_cleanup (free, symbol_table);
number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
if (dynamic)
number_of_symbols = bfd_canonicalize_dynamic_symtab (abfd,
symbol_table);
else
number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
if (number_of_symbols < 0)
error ("Can't read symbols from %s: %s", bfd_get_filename (abfd),
bfd_errmsg (bfd_get_error ()));
for (i = 0; i < number_of_symbols; i++)
{
sym = symbol_table[i];
@ -269,6 +299,15 @@ elf_symtab_read (abfd, addr, objfile)
that are null strings (may happen). */
continue;
}
/* If it is a nonstripped executable, do not enter dynamic
symbols, as the dynamic symbol table is usually a subset
of the main symbol table.
On Irix 5 however, the symbols for the procedure linkage
table entries have meaningful values only in the dynamic
symbol table, so we always examine undefined symbols. */
if (dynamic && !stripped && sym -> section != &bfd_und_section)
continue;
if (sym -> flags & BSF_FILE)
{
/* STT_FILE debugging symbol that helps stabs-in-elf debugging.
@ -296,9 +335,52 @@ elf_symtab_read (abfd, addr, objfile)
/* For non-absolute symbols, use the type of the section
they are relative to, to intuit text/data. Bfd provides
no way of figuring this out for absolute symbols. */
if (sym -> section == &bfd_abs_section)
if (sym -> section == &bfd_und_section
&& (sym -> flags & BSF_GLOBAL)
&& (sym -> flags & BSF_FUNCTION))
{
ms_type = mst_abs;
/* Symbol is a reference to a function defined in
a shared library.
If its value is non zero then it is usually the
absolute address of the corresponding entry in
the procedure linkage table.
If its value is zero then the dynamic linker has to
resolve the symbol. We are unable to find any
meaningful address for this symbol in the
executable file, so we skip it.
Irix 5 has a zero value for all shared library functions
in the main symbol table, but the dynamic symbol table
provides the right values. */
ms_type = mst_solib_trampoline;
symaddr = sym -> value;
if (symaddr == 0)
continue;
symaddr += addr;
}
else if (sym -> section == &bfd_abs_section)
{
/* This is a hack to get the minimal symbol type
right for Irix 5, which has absolute adresses
with special section indices for dynamic symbols. */
unsigned short shndx =
((elf_symbol_type *) sym)->internal_elf_sym.st_shndx;
switch (shndx)
{
#if 0
case SHN_MIPS_TEXT:
ms_type = mst_text;
break;
case SHN_MIPS_DATA:
ms_type = mst_data;
break;
case SHN_MIPS_ACOMMON:
ms_type = mst_bss;
break;
#endif
default:
ms_type = mst_abs;
}
}
else if (sym -> section -> flags & SEC_CODE)
{
@ -306,7 +388,10 @@ elf_symtab_read (abfd, addr, objfile)
{
ms_type = mst_text;
}
else if (sym->name[0] == '.' && sym->name[1] == 'L')
else if ((sym->name[0] == '.' && sym->name[1] == 'L')
|| ((sym -> flags & BSF_LOCAL)
&& sym->name[0] == 'L'
&& sym->name[1] == 'L'))
/* Looks like a compiler-generated label. Skip it.
The assembler should be skipping these (to keep
executables small), but apparently with gcc on the
@ -447,7 +532,8 @@ elf_symtab_read (abfd, addr, objfile)
format to look for: FIXME!!!
dwarf_build_psymtabs() builds psymtabs for DWARF symbols;
elfstab_build_psymtabs() handles STABS symbols.
elfstab_build_psymtabs() handles STABS symbols;
mdebug_build_psymtabs() handles ECOFF debugging information.
Note that ELF files have a "minimal" symbol table, which looks a lot
like a COFF symbol table, but has only the minimal information necessary
@ -483,7 +569,11 @@ elf_symfile_read (objfile, section_offsets, mainline)
/* FIXME, should take a section_offsets param, not just an offset. */
offset = ANOFFSET (section_offsets, 0);
elf_symtab_read (abfd, offset, objfile);
elf_symtab_read (abfd, offset, objfile, 0);
/* Add the dynamic symbols. */
elf_symtab_read (abfd, offset, objfile, 1);
/* Now process debugging information, which is contained in
special ELF sections. We first have to find them... */
@ -499,32 +589,32 @@ elf_symfile_read (objfile, section_offsets, mainline)
}
if (ei.stabsect)
{
/* STABS sections */
asection *str_sect;
/* FIXME: Sun didn't really know how to implement this well.
They made .stab sections that don't point to the .stabstr
section with the sh_link field. BFD doesn't make string table
sections visible to the caller. So we have to search the
ELF section table, not the BFD section table, for the string
table. */
struct elf32_internal_shdr *elf_sect;
/* Stab sections have an associated string table that looks like
a separate section. */
str_sect = bfd_get_section_by_name (abfd, ".stabstr");
elf_sect = bfd_elf_find_section (abfd, ".stabstr");
if (elf_sect)
/* FIXME should probably warn about a stab section without a stabstr. */
if (str_sect)
elfstab_build_psymtabs (objfile,
section_offsets,
mainline,
ei.stabsect->filepos, /* .stab offset */
bfd_get_section_size_before_reloc (ei.stabsect),/* .stab size */
(file_ptr) elf_sect->sh_offset, /* .stabstr offset */
elf_sect->sh_size); /* .stabstr size */
section_offsets,
mainline,
ei.stabsect->filepos,
bfd_section_size (abfd, ei.stabsect),
str_sect->filepos,
bfd_section_size (abfd, str_sect));
}
if (!have_partial_symbols ())
if (ei.mdebugsect)
{
wrap_here ("");
printf_filtered ("(no debugging symbols found)...");
wrap_here ("");
const struct ecoff_debug_swap *swap;
/* .mdebug section, presumably holding ECOFF debugging
information. */
swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
if (swap)
elfmdebug_build_psymtabs (objfile, swap, ei.mdebugsect,
section_offsets);
}
/* Install any minimal symbols that have been collected as the current
@ -615,15 +705,16 @@ elf_symfile_offsets (objfile, addr)
{
struct section_offsets *section_offsets;
int i;
objfile->num_sections = SECT_OFF_MAX;
section_offsets = (struct section_offsets *)
obstack_alloc (&objfile -> psymbol_obstack,
sizeof (struct section_offsets) +
sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
sizeof (struct section_offsets)
+ sizeof (section_offsets->offsets) * (SECT_OFF_MAX-1));
for (i = 0; i < SECT_OFF_MAX; i++)
ANOFFSET (section_offsets, i) = addr;
return section_offsets;
}
@ -694,26 +785,11 @@ elfstab_offset_sections (objfile, pst)
complain (&stab_info_mismatch_complaint, filename);
}
/* Register that we are able to handle ELF object file formats and DWARF
debugging formats.
Unlike other object file formats, where the debugging information format
is implied by the object file format, the ELF object file format and the
DWARF debugging information format are two distinct, and potentially
separate entities. I.E. it is perfectly possible to have ELF objects
with debugging formats other than DWARF. And it is conceivable that the
DWARF debugging format might be used with another object file format,
like COFF, by simply using COFF's custom section feature.
GDB, and to a lesser extent BFD, should support the notion of separate
object file formats and debugging information formats. For now, we just
use "elf" in the same sense as "a.out" or "coff", to imply both the ELF
object file format and the DWARF debugging format. */
/* Register that we are able to handle ELF object file formats. */
static struct sym_fns elf_sym_fns =
{
"elf", /* sym_name: name or name prefix of BFD target type */
3, /* sym_namelen: number of significant sym_name chars */
bfd_target_elf_flavour,
elf_new_init, /* sym_new_init: init anything gbl to entire symtab */
elf_symfile_init, /* sym_init: read initial info, setup for sym_read() */
elf_symfile_read, /* sym_read: read a symbol file into symtab */

View File

@ -21,7 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "defs.h"
#include "environ.h"
#include <string.h>
#include "defs.h" /* For strsave(). */
#include "gdbcore.h"
/* Return a new environment object. */
@ -64,6 +64,9 @@ init_environ (e)
extern char **environ;
register int i;
if (environ == NULL)
return;
for (i = 0; environ[i]; i++) /*EMPTY*/;
if (e->allocated < i)
@ -149,23 +152,16 @@ set_in_environ (e, var, value)
strcat (s, value);
vector[i] = s;
/* Certain variables get exported back to the parent (e.g. our)
environment, too. FIXME: this is a hideous hack and should not be
allowed to live. What if we want to change the environment we pass to
the program without affecting GDB's behavior? */
if (STREQ(var, "PATH")) /* Object file location */
{
putenv (strsave (s));
}
/* This used to handle setting the PATH and GNUTARGET variables
specially. The latter has been replaced by "set gnutarget"
(which has worked since GDB 4.11). The former affects searching
the PATH to find SHELL, and searching the PATH to find the
argument of "symbol-file" or "exec-file". Maybe we should have
some kind of "set exec-path" for that. But in any event, having
"set env" affect anything besides the inferior is a bad idea.
What if we want to change the environment we pass to the program
without afecting GDB's behavior? */
/* This is a compatibility hack, since GDB 4.10 and older didn't have
`set gnutarget'. Eventually it should go away, so that (for example)
you can debug objdump's handling of GNUTARGET without affecting GDB's
behavior. */
if (STREQ (var, "GNUTARGET"))
{
set_gnutarget (value);
}
return;
}

View File

@ -1,5 +1,6 @@
/* Evaluate expressions for GDB.
Copyright 1986, 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994
Free Software Foundation, Inc.
This file is part of GDB.
@ -18,12 +19,14 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "defs.h"
#include <string.h>
#include "symtab.h"
#include "gdbtypes.h"
#include "value.h"
#include "expression.h"
#include "target.h"
#include "frame.h"
#include "demangle.h"
#include "language.h" /* For CAST_IS_CONVERSION */
/* Values of NOSIDE argument to eval_subexp. */
@ -43,18 +46,18 @@ enum noside
/* Prototypes for local functions. */
static value
static value_ptr
evaluate_subexp_for_sizeof PARAMS ((struct expression *, int *));
static value
static value_ptr
evaluate_subexp_with_coercion PARAMS ((struct expression *, int *,
enum noside));
static value
static value_ptr
evaluate_subexp_for_address PARAMS ((struct expression *, int *,
enum noside));
static value
static value_ptr
evaluate_subexp PARAMS ((struct type *, struct expression *, int *,
enum noside));
@ -93,12 +96,12 @@ parse_and_eval_address_1 (expptr)
return addr;
}
value
value_ptr
parse_and_eval (exp)
char *exp;
{
struct expression *expr = parse_expression (exp);
register value val;
register value_ptr val;
register struct cleanup *old_chain
= make_cleanup (free_current_contents, &expr);
@ -111,12 +114,12 @@ parse_and_eval (exp)
in the string EXPP as an expression, evaluate it, and return the value.
EXPP is advanced to point to the comma. */
value
value_ptr
parse_to_comma_and_eval (expp)
char **expp;
{
struct expression *expr = parse_exp_1 (expp, (struct block *) 0, 1);
register value val;
register value_ptr val;
register struct cleanup *old_chain
= make_cleanup (free_current_contents, &expr);
@ -130,12 +133,7 @@ parse_to_comma_and_eval (expp)
See expression.h for info on the format of an expression. */
static value evaluate_subexp ();
static value evaluate_subexp_for_address ();
static value evaluate_subexp_for_sizeof ();
static value evaluate_subexp_with_coercion ();
value
value_ptr
evaluate_expression (exp)
struct expression *exp;
{
@ -146,7 +144,7 @@ evaluate_expression (exp)
/* Evaluate an expression, avoiding all memory references
and getting a value whose type alone is correct. */
value
value_ptr
evaluate_type (exp)
struct expression *exp;
{
@ -154,7 +152,7 @@ evaluate_type (exp)
return evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_AVOID_SIDE_EFFECTS);
}
static value
static value_ptr
evaluate_subexp (expect_type, exp, pos, noside)
struct type *expect_type;
register struct expression *exp;
@ -164,10 +162,10 @@ evaluate_subexp (expect_type, exp, pos, noside)
enum exp_opcode op;
int tem, tem2, tem3;
register int pc, pc2 = 0, oldpos;
register value arg1 = NULL, arg2 = NULL, arg3;
register value_ptr arg1 = NULL, arg2 = NULL, arg3;
struct type *type;
int nargs;
value *argvec;
value_ptr *argvec;
pc = (*pos)++;
op = exp->elts[pc].opcode;
@ -263,7 +261,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
tem2 = longest_to_int (exp->elts[pc + 1].longconst);
tem3 = longest_to_int (exp->elts[pc + 2].longconst);
nargs = tem3 - tem2 + 1;
argvec = (value *) alloca (sizeof (value) * nargs);
argvec = (value_ptr *) alloca (sizeof (value_ptr) * nargs);
for (tem = 0; tem < nargs; tem++)
{
/* Ensure that array expressions are coerced into pointer objects. */
@ -341,7 +339,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
for (j = TYPE_FN_FIELDLIST_LENGTH (basetype, i) - 1; j >= 0; --j)
if (TYPE_FN_FIELD_VOFFSET (f, j) == fnoffset)
{
value temp = value_ind (arg2);
value_ptr temp = value_ind (arg2);
arg1 = value_virtual_fn_field (&temp, f, j, domain_type, 0);
arg2 = value_addr (temp);
goto got_it;
@ -404,7 +402,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
}
/* Allocate arg vector, including space for the function to be
called in argvec[0] and a terminating NULL */
argvec = (value *) alloca (sizeof (value) * (nargs + 2));
argvec = (value_ptr *) alloca (sizeof (value_ptr) * (nargs + 2));
for (; tem <= nargs; tem++)
/* Ensure that array expressions are coerced into pointer objects. */
argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
@ -415,17 +413,25 @@ evaluate_subexp (expect_type, exp, pos, noside)
if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR)
{
int static_memfuncp;
value temp = arg2;
value_ptr temp = arg2;
char tstr[64];
argvec[1] = arg2;
argvec[0] =
value_struct_elt (&temp, argvec+1, &exp->elts[pc2 + 2].string,
argvec[0] = 0;
strcpy(tstr, &exp->elts[pc2+2].string);
if (!argvec[0])
{
temp = arg2;
argvec[0] =
value_struct_elt (&temp, argvec+1, tstr,
&static_memfuncp,
op == STRUCTOP_STRUCT
? "structure" : "structure pointer");
arg2 = value_from_longest (lookup_pointer_type (VALUE_TYPE (temp)),
VALUE_ADDRESS (temp)+VALUE_OFFSET (temp));
}
arg2 = value_from_longest (lookup_pointer_type(VALUE_TYPE (temp)),
VALUE_ADDRESS (temp)+VALUE_OFFSET (temp));
argvec[1] = arg2;
if (static_memfuncp)
{
argvec[1] = argvec[0];
@ -473,9 +479,9 @@ evaluate_subexp (expect_type, exp, pos, noside)
lval_memory);
else
{
value temp = arg1;
return value_struct_elt (&temp, (value *)0, &exp->elts[pc + 2].string,
(int *) 0, "structure");
value_ptr temp = arg1;
return value_struct_elt (&temp, NULL, &exp->elts[pc + 2].string,
NULL, "structure");
}
case STRUCTOP_PTR:
@ -491,9 +497,9 @@ evaluate_subexp (expect_type, exp, pos, noside)
lval_memory);
else
{
value temp = arg1;
return value_struct_elt (&temp, (value *)0, &exp->elts[pc + 2].string,
(int *) 0, "structure pointer");
value_ptr temp = arg1;
return value_struct_elt (&temp, NULL, &exp->elts[pc + 2].string,
NULL, "structure pointer");
}
case STRUCTOP_MEMBER:
@ -623,6 +629,13 @@ evaluate_subexp (expect_type, exp, pos, noside)
return value_x_binop (arg1, arg2, op, OP_NULL);
else
return value_subscript (arg1, arg2);
case BINOP_IN:
arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
return value_in (arg1, arg2);
case MULTI_SUBSCRIPT:
(*pos) += 2;
@ -1028,7 +1041,7 @@ GDB does not (yet) know how to evaluated that kind of expression");
NOSIDE may be EVAL_AVOID_SIDE_EFFECTS;
then only the type of the result need be correct. */
static value
static value_ptr
evaluate_subexp_for_address (exp, pos, noside)
register struct expression *exp;
register int *pos;
@ -1086,7 +1099,7 @@ evaluate_subexp_for_address (exp, pos, noside)
default_case:
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
value x = evaluate_subexp (NULL_TYPE, exp, pos, noside);
value_ptr x = evaluate_subexp (NULL_TYPE, exp, pos, noside);
if (VALUE_LVAL (x) == lval_memory)
return value_zero (lookup_pointer_type (VALUE_TYPE (x)),
not_lval);
@ -1110,7 +1123,7 @@ evaluate_subexp_for_address (exp, pos, noside)
*/
static value
static value_ptr
evaluate_subexp_with_coercion (exp, pos, noside)
register struct expression *exp;
register int *pos;
@ -1118,7 +1131,7 @@ evaluate_subexp_with_coercion (exp, pos, noside)
{
register enum exp_opcode op;
register int pc;
register value val;
register value_ptr val;
struct symbol *var;
pc = (*pos);
@ -1149,14 +1162,14 @@ evaluate_subexp_with_coercion (exp, pos, noside)
and return a value for the size of that subexpression.
Advance *POS over the subexpression. */
static value
static value_ptr
evaluate_subexp_for_sizeof (exp, pos)
register struct expression *exp;
register int *pos;
{
enum exp_opcode op;
register int pc;
value val;
value_ptr val;
pc = (*pos);
op = exp->elts[pc].opcode;

View File

@ -1,5 +1,5 @@
/* Work with executable files, for GDB.
Copyright 1988, 1989, 1991, 1992 Free Software Foundation, Inc.
Copyright 1988, 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This file is part of GDB.
@ -22,6 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "inferior.h"
#include "target.h"
#include "gdbcmd.h"
#include "language.h"
#ifdef USG
#include <sys/types.h>
@ -148,15 +149,25 @@ exec_file_command (args, from_tty)
exec_bfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan);
if (!exec_bfd)
error ("Could not open `%s' as an executable file: %s",
scratch_pathname, bfd_errmsg (bfd_error));
scratch_pathname, bfd_errmsg (bfd_get_error ()));
if (!bfd_check_format (exec_bfd, bfd_object))
error ("\"%s\": not in executable format: %s.",
scratch_pathname, bfd_errmsg (bfd_error));
{
/* Make sure to close exec_bfd, or else "run" might try to use
it. */
exec_close (0);
error ("\"%s\": not in executable format: %s.",
scratch_pathname, bfd_errmsg (bfd_get_error ()));
}
if (build_section_table (exec_bfd, &exec_ops.to_sections,
&exec_ops.to_sections_end))
error ("Can't find the file sections in `%s': %s",
exec_bfd->filename, bfd_errmsg (bfd_error));
{
/* Make sure to close exec_bfd, or else "run" might try to use
it. */
exec_close (0);
error ("Can't find the file sections in `%s': %s",
exec_bfd->filename, bfd_errmsg (bfd_get_error ()));
}
#ifdef NEED_TEXT_START_END
@ -173,7 +184,7 @@ exec_file_command (args, from_tty)
text_start = ~(CORE_ADDR)0;
text_end = (CORE_ADDR)0;
for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++)
if (bfd_get_section_flags (p->bfd, p->sec_ptr)
if (bfd_get_section_flags (p->bfd, p->the_bfd_section)
& (SEC_CODE | SEC_READONLY))
{
if (text_start > p->addr)
@ -193,7 +204,7 @@ exec_file_command (args, from_tty)
(*exec_file_display_hook) (filename);
}
else if (from_tty)
printf ("No exec file now.\n");
printf_unfiltered ("No exec file now.\n");
}
/* Set both the exec file and the symbol file, in one command.
@ -226,13 +237,12 @@ add_to_section_table (abfd, asect, table_pp_char)
flagword aflag;
aflag = bfd_get_section_flags (abfd, asect);
/* FIXME, we need to handle BSS segment here...it alloc's but doesn't load */
if (!(aflag & SEC_LOAD))
if (!(aflag & SEC_ALLOC))
return;
if (0 == bfd_section_size (abfd, asect))
return;
(*table_pp)->bfd = abfd;
(*table_pp)->sec_ptr = asect;
(*table_pp)->the_bfd_section = asect;
(*table_pp)->addr = bfd_section_vma (abfd, asect);
(*table_pp)->endaddr = (*table_pp)->addr + bfd_section_size (abfd, asect);
(*table_pp)++;
@ -304,8 +314,8 @@ xfer_memory (memaddr, myaddr, len, write, target)
if (p->endaddr >= memend)
{
/* Entire transfer is within this section. */
res = xfer_fn (p->bfd, p->sec_ptr, myaddr, memaddr - p->addr, len);
return (res != false)? len: 0;
res = xfer_fn (p->bfd, p->the_bfd_section, myaddr, memaddr - p->addr, len);
return (res != 0) ? len : 0;
}
else if (p->endaddr <= memaddr)
{
@ -316,8 +326,8 @@ xfer_memory (memaddr, myaddr, len, write, target)
{
/* This section overlaps the transfer. Just do half. */
len = p->endaddr - memaddr;
res = xfer_fn (p->bfd, p->sec_ptr, myaddr, memaddr - p->addr, len);
return (res != false)? len: 0;
res = xfer_fn (p->bfd, p->the_bfd_section, myaddr, memaddr - p->addr, len);
return (res != 0) ? len : 0;
}
else if (p->addr < nextsectaddr)
nextsectaddr = p->addr;
@ -354,20 +364,27 @@ print_section_info (t, abfd)
printf_filtered ("\t`%s', ", bfd_get_filename(abfd));
wrap_here (" ");
printf_filtered ("file type %s.\n", bfd_get_target(abfd));
printf_filtered ("\tEntry point: %s\n",
local_hex_string ((unsigned long) bfd_get_start_address (exec_bfd)));
for (p = t->to_sections; p < t->to_sections_end; p++) {
printf_filtered ("\t%s", local_hex_string_custom ((unsigned long) p->addr, "08l"));
printf_filtered (" - %s", local_hex_string_custom ((unsigned long) p->endaddr, "08l"));
if (info_verbose)
printf_filtered (" @ %s",
local_hex_string_custom ((unsigned long) p->sec_ptr->filepos, "08l"));
printf_filtered (" is %s", bfd_section_name (p->bfd, p->sec_ptr));
if (p->bfd != abfd) {
printf_filtered (" in %s", bfd_get_filename (p->bfd));
if (abfd == exec_bfd)
{
printf_filtered ("\tEntry point: ");
print_address_numeric (bfd_get_start_address (abfd), 1, gdb_stdout);
printf_filtered ("\n");
}
for (p = t->to_sections; p < t->to_sections_end; p++)
{
/* FIXME-32x64 need a print_address_numeric with field width */
printf_filtered ("\t%s", local_hex_string_custom ((unsigned long) p->addr, "08l"));
printf_filtered (" - %s", local_hex_string_custom ((unsigned long) p->endaddr, "08l"));
if (info_verbose)
printf_filtered (" @ %s",
local_hex_string_custom ((unsigned long) p->the_bfd_section->filepos, "08l"));
printf_filtered (" is %s", bfd_section_name (p->bfd, p->the_bfd_section));
if (p->bfd != abfd)
{
printf_filtered (" in %s", bfd_get_filename (p->bfd));
}
printf_filtered ("\n");
}
printf_filtered ("\n");
}
}
static void
@ -400,8 +417,8 @@ set_section_command (args, from_tty)
secaddr = parse_and_eval_address (args);
for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++) {
if (!strncmp (secname, bfd_section_name (exec_bfd, p->sec_ptr), seclen)
&& bfd_section_name (exec_bfd, p->sec_ptr)[seclen] == '\0') {
if (!strncmp (secname, bfd_section_name (exec_bfd, p->the_bfd_section), seclen)
&& bfd_section_name (exec_bfd, p->the_bfd_section)[seclen] == '\0') {
offset = secaddr - p->addr;
p->addr += offset;
p->endaddr += offset;

View File

@ -28,15 +28,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Prototypes for local functions */
static void
print_subexp PARAMS ((struct expression *, int *, FILE *, enum precedence));
print_subexp PARAMS ((struct expression *, int *, GDB_FILE *, enum precedence));
static void
print_simple_m2_func PARAMS ((char *, struct expression *, int *, FILE *));
print_simple_m2_func PARAMS ((char *, struct expression *, int *, GDB_FILE *));
void
print_expression (exp, stream)
struct expression *exp;
FILE *stream;
GDB_FILE *stream;
{
int pc = 0;
print_subexp (exp, &pc, stream, PREC_NULL);
@ -51,7 +51,7 @@ static void
print_subexp (exp, pos, stream, prec)
register struct expression *exp;
register int *pos;
FILE *stream;
GDB_FILE *stream;
enum precedence prec;
{
register unsigned tem;
@ -64,7 +64,7 @@ print_subexp (exp, pos, stream, prec)
enum precedence myprec = PREC_NULL;
/* Set to 1 for a right-associative operator. */
int assoc = 0;
value val;
value_ptr val;
char *tempstr = NULL;
op_print_tab = exp->language_defn->la_op_print_tab;
@ -340,23 +340,23 @@ print_subexp (exp, pos, stream, prec)
(*pos) += 2;
nargs = longest_to_int (exp->elts[pc + 1].longconst);
print_subexp (exp, pos, stream, PREC_SUFFIX);
fprintf (stream, " [");
fprintf_unfiltered (stream, " [");
for (tem = 0; tem < nargs; tem++)
{
if (tem != 0)
fprintf (stream, ", ");
fprintf_unfiltered (stream, ", ");
print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
}
fprintf (stream, "]");
fprintf_unfiltered (stream, "]");
return;
case BINOP_VAL:
(*pos)+=2;
fprintf(stream,"VAL(");
fprintf_unfiltered(stream,"VAL(");
type_print(exp->elts[pc+1].type,"",stream,0);
fprintf(stream,",");
fprintf_unfiltered(stream,",");
print_subexp(exp,pos,stream,PREC_PREFIX);
fprintf(stream,")");
fprintf_unfiltered(stream,")");
return;
case UNOP_CAP:
@ -466,11 +466,11 @@ print_simple_m2_func(s,exp,pos,stream)
char *s;
register struct expression *exp;
register int *pos;
FILE *stream;
GDB_FILE *stream;
{
fprintf(stream,"%s(",s);
fprintf_unfiltered(stream,"%s(",s);
print_subexp(exp,pos,stream,PREC_PREFIX);
fprintf(stream,")");
fprintf_unfiltered(stream,")");
}
/* Return the operator corresponding to opcode OP as
@ -498,7 +498,7 @@ op_string(op)
void
dump_expression (exp, stream, note)
struct expression *exp;
FILE *stream;
GDB_FILE *stream;
char *note;
{
int elt;
@ -506,8 +506,9 @@ dump_expression (exp, stream, note)
char *eltscan;
int eltsize;
fprintf_filtered (stream, "Dump of expression @ 0x%lx, %s:\n",
(unsigned long) exp, note);
fprintf_filtered (stream, "Dump of expression @ ");
gdb_print_address (exp, stream);
fprintf_filtered (stream, ", %s:\n", note);
fprintf_filtered (stream, "\tLanguage %s, %d elements, %d bytes each.\n",
exp->language_defn->la_name, exp -> nelts,
sizeof (union exp_element));

View File

@ -104,6 +104,9 @@ enum exp_opcode
the second operand with itself that many times. */
BINOP_CONCAT,
/* For Chill and Pascal. */
BINOP_IN, /* Returns 1 iff ARG1 IN ARG2. */
/* This must be the highest BINOP_ value, for expprint.c. */
BINOP_END,
@ -292,7 +295,7 @@ extern struct block *innermost_block;
/* From expprint.c */
extern void
print_expression PARAMS ((struct expression *, FILE *));
print_expression PARAMS ((struct expression *, GDB_FILE *));
extern char *
op_string PARAMS ((enum exp_opcode));
@ -304,7 +307,7 @@ op_string PARAMS ((enum exp_opcode));
#ifdef DEBUG_EXPRESSIONS
extern void
dump_expression PARAMS ((struct expression *, FILE *, char *));
dump_expression PARAMS ((struct expression *, GDB_FILE *, char *));
#define DUMP_EXPRESSION(exp,file,note) dump_expression ((exp), (file), (note))
#else
#define DUMP_EXPRESSION(exp,file,note) /* Null expansion */

View File

@ -168,6 +168,90 @@ store_address (addr, len, val)
store_unsigned_integer (addr, len, (LONGEST)val);
}
/* Swap LEN bytes at BUFFER between target and host byte-order. This is
the wrong way to do byte-swapping because it assumes that you have a way
to have a host variable of exactly the right size. Once extract_floating
and store_floating have been fixed, this can go away. */
#if TARGET_BYTE_ORDER == HOST_BYTE_ORDER
#define SWAP_TARGET_AND_HOST(buffer,len)
#else /* Target and host byte order differ. */
#define SWAP_TARGET_AND_HOST(buffer,len) \
{ \
char tmp; \
char *p = (char *)(buffer); \
char *q = ((char *)(buffer)) + len - 1; \
for (; p < q; p++, q--) \
{ \
tmp = *q; \
*q = *p; \
*p = tmp; \
} \
}
#endif /* Target and host byte order differ. */
/* There are many problems with floating point cross-debugging.
1. These routines only handle byte-swapping, not conversion of
formats. So if host is IEEE floating and target is VAX floating,
or vice-versa, it loses. This means that we can't (yet) use these
routines for extendeds. Extendeds are handled by
REGISTER_CONVERTIBLE. What we want is to use floatformat.h, but that
doesn't yet handle VAX floating at all.
2. We can't deal with it if there is more than one floating point
format in use. This has to be fixed at the unpack_double level.
3. We probably should have a LONGEST_DOUBLE or DOUBLEST or whatever
we want to call it which is long double where available. */
double
extract_floating (addr, len)
PTR addr;
int len;
{
if (len == sizeof (float))
{
float retval;
memcpy (&retval, addr, sizeof (retval));
SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
return retval;
}
else if (len == sizeof (double))
{
double retval;
memcpy (&retval, addr, sizeof (retval));
SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
return retval;
}
else
{
error ("Can't deal with a floating point number of %d bytes.", len);
}
}
void
store_floating (addr, len, val)
PTR addr;
int len;
double val;
{
if (len == sizeof (float))
{
float floatval = val;
SWAP_TARGET_AND_HOST (&floatval, sizeof (floatval));
memcpy (addr, &floatval, sizeof (floatval));
}
else if (len == sizeof (double))
{
SWAP_TARGET_AND_HOST (&val, sizeof (val));
memcpy (addr, &val, sizeof (val));
}
else
{
error ("Can't deal with a floating point number of %d bytes.", len);
}
}
#if !defined (GET_SAVED_REGISTER)
/* Return the address in which frame FRAME's value of register REGNUM
@ -332,29 +416,38 @@ read_relative_register_raw_bytes (regnum, myaddr)
in its virtual format, with the type specified by
REGISTER_VIRTUAL_TYPE. */
value
value_ptr
value_of_register (regnum)
int regnum;
{
CORE_ADDR addr;
int optim;
register value val;
register value_ptr reg_val;
char raw_buffer[MAX_REGISTER_RAW_SIZE];
char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
enum lval_type lval;
get_saved_register (raw_buffer, &optim, &addr,
selected_frame, regnum, &lval);
REGISTER_CONVERT_TO_VIRTUAL (regnum, raw_buffer, virtual_buffer);
val = allocate_value (REGISTER_VIRTUAL_TYPE (regnum));
memcpy (VALUE_CONTENTS_RAW (val), virtual_buffer,
REGISTER_VIRTUAL_SIZE (regnum));
VALUE_LVAL (val) = lval;
VALUE_ADDRESS (val) = addr;
VALUE_REGNO (val) = regnum;
VALUE_OPTIMIZED_OUT (val) = optim;
return val;
reg_val = allocate_value (REGISTER_VIRTUAL_TYPE (regnum));
/* Convert raw data to virtual format if necessary. */
#ifdef REGISTER_CONVERTIBLE
if (REGISTER_CONVERTIBLE (regnum))
{
REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum),
raw_buffer, VALUE_CONTENTS_RAW (reg_val));
}
else
#endif
memcpy (VALUE_CONTENTS_RAW (reg_val), raw_buffer,
REGISTER_RAW_SIZE (regnum));
VALUE_LVAL (reg_val) = lval;
VALUE_ADDRESS (reg_val) = addr;
VALUE_REGNO (reg_val) = regnum;
VALUE_OPTIMIZED_OUT (reg_val) = optim;
return reg_val;
}
/* Low level examining and depositing of registers.
@ -372,12 +465,21 @@ char registers[REGISTER_BYTES + /* SLOP */ 256];
/* Nonzero if that register has been fetched. */
char register_valid[NUM_REGS];
/* The thread/process associated with the current set of registers. For now,
-1 is special, and means `no current process'. */
int registers_pid = -1;
/* Indicate that registers may have changed, so invalidate the cache. */
void
registers_changed ()
{
int i;
for (i = 0; i < NUM_REGS; i++)
int numregs = ARCH_NUM_REGS;
registers_pid = -1;
for (i = 0; i < numregs; i++)
register_valid[i] = 0;
}
@ -386,7 +488,8 @@ void
registers_fetched ()
{
int i;
for (i = 0; i < NUM_REGS; i++)
int numregs = ARCH_NUM_REGS;
for (i = 0; i < numregs; i++)
register_valid[i] = 1;
}
@ -401,8 +504,16 @@ read_register_bytes (regbyte, myaddr, len)
int len;
{
/* Fetch all registers. */
int i;
for (i = 0; i < NUM_REGS; i++)
int i, numregs;
if (registers_pid != inferior_pid)
{
registers_changed ();
registers_pid = inferior_pid;
}
numregs = ARCH_NUM_REGS;
for (i = 0; i < numregs; i++)
if (!register_valid[i])
{
target_fetch_registers (-1);
@ -421,6 +532,12 @@ read_register_gen (regno, myaddr)
int regno;
char *myaddr;
{
if (registers_pid != inferior_pid)
{
registers_changed ();
registers_pid = inferior_pid;
}
if (!register_valid[regno])
target_fetch_registers (regno);
memcpy (myaddr, &registers[REGISTER_BYTE (regno)],
@ -436,6 +553,12 @@ write_register_bytes (regbyte, myaddr, len)
char *myaddr;
int len;
{
if (registers_pid != inferior_pid)
{
registers_changed ();
registers_pid = inferior_pid;
}
/* Make sure the entire registers array is valid. */
read_register_bytes (0, (char *)NULL, REGISTER_BYTES);
memcpy (&registers[regbyte], myaddr, len);
@ -449,6 +572,12 @@ CORE_ADDR
read_register (regno)
int regno;
{
if (registers_pid != inferior_pid)
{
registers_changed ();
registers_pid = inferior_pid;
}
if (!register_valid[regno])
target_fetch_registers (regno);
@ -456,6 +585,27 @@ read_register (regno)
REGISTER_RAW_SIZE(regno));
}
CORE_ADDR
read_register_pid (regno, pid)
int regno, pid;
{
int save_pid;
CORE_ADDR retval;
if (pid == inferior_pid)
return read_register (regno);
save_pid = inferior_pid;
inferior_pid = pid;
retval = read_register (regno);
inferior_pid = save_pid;
return retval;
}
/* Registers we shouldn't try to store. */
#if !defined (CANNOT_STORE_REGISTER)
#define CANNOT_STORE_REGISTER(regno) 0
@ -477,6 +627,12 @@ write_register (regno, val)
if (CANNOT_STORE_REGISTER (regno))
return;
if (registers_pid != inferior_pid)
{
registers_changed ();
registers_pid = inferior_pid;
}
size = REGISTER_RAW_SIZE(regno);
buf = alloca (size);
store_signed_integer (buf, size, (LONGEST) val);
@ -484,11 +640,9 @@ write_register (regno, val)
/* If we have a valid copy of the register, and new value == old value,
then don't bother doing the actual store. */
if (register_valid [regno])
{
if (memcmp (&registers[REGISTER_BYTE (regno)], buf, size) == 0)
return;
}
if (register_valid [regno]
&& memcmp (&registers[REGISTER_BYTE (regno)], buf, size) == 0)
return;
target_prepare_to_store ();
@ -499,6 +653,29 @@ write_register (regno, val)
target_store_registers (regno);
}
void
write_register_pid (regno, val, pid)
int regno;
LONGEST val;
int pid;
{
int save_pid;
if (pid == inferior_pid)
{
write_register (regno, val);
return;
}
save_pid = inferior_pid;
inferior_pid = pid;
write_register (regno, val);
inferior_pid = save_pid;
}
/* Record that register REGNO contains VAL.
This is used when the value is obtained from the inferior or core dump,
so there is no need to store the value there. */
@ -508,6 +685,12 @@ supply_register (regno, val)
int regno;
char *val;
{
if (registers_pid != inferior_pid)
{
registers_changed ();
registers_pid = inferior_pid;
}
register_valid[regno] = 1;
memcpy (&registers[REGISTER_BYTE (regno)], val, REGISTER_RAW_SIZE (regno));
@ -517,6 +700,111 @@ supply_register (regno, val)
CLEAN_UP_REGISTER_VALUE(regno, &registers[REGISTER_BYTE(regno)]);
#endif
}
/* This routine is getting awfully cluttered with #if's. It's probably
time to turn this into READ_PC and define it in the tm.h file.
Ditto for write_pc. */
CORE_ADDR
read_pc ()
{
#ifdef TARGET_READ_PC
return TARGET_READ_PC (inferior_pid);
#else
return ADDR_BITS_REMOVE ((CORE_ADDR) read_register_pid (PC_REGNUM, inferior_pid));
#endif
}
CORE_ADDR
read_pc_pid (pid)
int pid;
{
#ifdef TARGET_READ_PC
return TARGET_READ_PC (pid);
#else
return ADDR_BITS_REMOVE ((CORE_ADDR) read_register_pid (PC_REGNUM, pid));
#endif
}
void
write_pc (val)
CORE_ADDR val;
{
#ifdef TARGET_WRITE_PC
TARGET_WRITE_PC (val, inferior_pid);
#else
write_register_pid (PC_REGNUM, (long) val, inferior_pid);
#ifdef NPC_REGNUM
write_register_pid (NPC_REGNUM, (long) val + 4, inferior_pid);
#ifdef NNPC_REGNUM
write_register_pid (NNPC_REGNUM, (long) val + 8, inferior_pid);
#endif
#endif
#endif
}
void
write_pc_pid (val, pid)
CORE_ADDR val;
int pid;
{
#ifdef TARGET_WRITE_PC
TARGET_WRITE_PC (val, pid);
#else
write_register_pid (PC_REGNUM, (long) val, pid);
#ifdef NPC_REGNUM
write_register_pid (NPC_REGNUM, (long) val + 4, pid);
#ifdef NNPC_REGNUM
write_register_pid (NNPC_REGNUM, (long) val + 8, pid);
#endif
#endif
#endif
}
/* Cope with strage ways of getting to the stack and frame pointers */
CORE_ADDR
read_sp ()
{
#ifdef TARGET_READ_SP
return TARGET_READ_SP ();
#else
return read_register (SP_REGNUM);
#endif
}
void
write_sp (val)
CORE_ADDR val;
{
#ifdef TARGET_WRITE_SP
TARGET_WRITE_SP (val);
#else
write_register (SP_REGNUM, val);
#endif
}
CORE_ADDR
read_fp ()
{
#ifdef TARGET_READ_FP
return TARGET_READ_FP ();
#else
return read_register (FP_REGNUM);
#endif
}
void
write_fp (val)
CORE_ADDR val;
{
#ifdef TARGET_WRITE_FP
TARGET_WRITE_FP (val);
#else
write_register (FP_REGNUM, val);
#endif
}
/* Will calling read_var_value or locate_var_value on SYM end
up caring what frame it is being evaluated relative to? SYM must
@ -555,6 +843,7 @@ symbol_read_needs_frame (sym)
case LOC_OPTIMIZED_OUT:
return 0;
}
return 1;
}
/* Given a struct symbol for a variable,
@ -563,12 +852,12 @@ symbol_read_needs_frame (sym)
If the variable cannot be found, return a zero pointer.
If FRAME is NULL, use the selected_frame. */
value
value_ptr
read_var_value (var, frame)
register struct symbol *var;
FRAME frame;
{
register value v;
register value_ptr v;
struct frame_info *fi;
struct type *type = SYMBOL_TYPE (var);
CORE_ADDR addr;
@ -672,15 +961,17 @@ read_var_value (var, frame)
return 0;
b = get_frame_block (frame);
v = value_from_register (type, SYMBOL_VALUE (var), frame);
if (SYMBOL_CLASS (var) == LOC_REGPARM_ADDR)
{
addr = *(CORE_ADDR *)VALUE_CONTENTS (v);
addr =
value_as_pointer (value_from_register (lookup_pointer_type (type),
SYMBOL_VALUE (var),
frame));
VALUE_LVAL (v) = lval_memory;
}
else
return v;
return value_from_register (type, SYMBOL_VALUE (var), frame);
}
break;
@ -702,17 +993,16 @@ read_var_value (var, frame)
/* Return a value of type TYPE, stored in register REGNUM, in frame
FRAME. */
value
value_ptr
value_from_register (type, regnum, frame)
struct type *type;
int regnum;
FRAME frame;
{
char raw_buffer [MAX_REGISTER_RAW_SIZE];
char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
CORE_ADDR addr;
int optim;
value v = allocate_value (type);
value_ptr v = allocate_value (type);
int len = TYPE_LENGTH (type);
char *value_bytes = 0;
int value_bytes_copied = 0;
@ -878,36 +1168,17 @@ value_from_register (type, regnum, frame)
VALUE_OPTIMIZED_OUT (v) = optim;
VALUE_LVAL (v) = lval;
VALUE_ADDRESS (v) = addr;
/* Convert raw data to virtual format if necessary. */
/* Convert the raw contents to virtual contents.
(Just copy them if the formats are the same.) */
REGISTER_CONVERT_TO_VIRTUAL (regnum, raw_buffer, virtual_buffer);
#ifdef REGISTER_CONVERTIBLE
if (REGISTER_CONVERTIBLE (regnum))
{
/* When the raw and virtual formats differ, the virtual format
corresponds to a specific data type. If we want that type,
copy the data into the value.
Otherwise, do a type-conversion. */
if (type != REGISTER_VIRTUAL_TYPE (regnum))
{
/* eg a variable of type `float' in a 68881 register
with raw type `extended' and virtual type `double'.
Fetch it as a `double' and then convert to `float'. */
/* FIXME: This value will be not_lval, which means we can't assign
to it. Probably the right fix is to do the cast on a temporary
value, and just copy the VALUE_CONTENTS over. */
v = allocate_value (REGISTER_VIRTUAL_TYPE (regnum));
memcpy (VALUE_CONTENTS_RAW (v), virtual_buffer,
REGISTER_VIRTUAL_SIZE (regnum));
v = value_cast (type, v);
}
else
memcpy (VALUE_CONTENTS_RAW (v), virtual_buffer, len);
REGISTER_CONVERT_TO_VIRTUAL (regnum, type,
raw_buffer, VALUE_CONTENTS_RAW (v));
}
else
#endif
{
/* Raw and virtual formats are the same for this register. */
@ -919,7 +1190,7 @@ value_from_register (type, regnum, frame)
}
#endif
memcpy (VALUE_CONTENTS_RAW (v), virtual_buffer + VALUE_OFFSET (v), len);
memcpy (VALUE_CONTENTS_RAW (v), raw_buffer + VALUE_OFFSET (v), len);
}
return v;
@ -930,14 +1201,14 @@ value_from_register (type, regnum, frame)
return a (pointer to a) struct value containing the properly typed
address. */
value
value_ptr
locate_var_value (var, frame)
register struct symbol *var;
FRAME frame;
{
CORE_ADDR addr = 0;
struct type *type = SYMBOL_TYPE (var);
value lazy_value;
value_ptr lazy_value;
/* Evaluate it first; if the result is a memory address, we're fine.
Lazy evaluation pays off here. */

View File

@ -1,5 +1,5 @@
/* Fork a Unix child process, and set up to debug it, for GDB.
Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
Contributed by Cygnus Support.
This file is part of GDB.
@ -19,48 +19,43 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "defs.h"
#include <string.h>
#include "frame.h" /* required by inferior.h */
#include "inferior.h"
#include "target.h"
#include "wait.h"
#include "gdbcore.h"
#include "terminal.h"
#include "thread.h"
#include <signal.h>
#ifdef SET_STACK_LIMIT_HUGE
#include <sys/time.h>
#include <sys/resource.h>
extern int original_stack_limit;
#endif /* SET_STACK_LIMIT_HUGE */
extern char **environ;
/* Start an inferior Unix child process and sets inferior_pid to its pid.
EXEC_FILE is the file to run.
ALLARGS is a string containing the arguments to the program.
ENV is the environment vector to pass. Errors reported with error(). */
#ifndef SHELL_FILE
#define SHELL_FILE "/bin/sh"
#endif
/* Start an inferior Unix child process and sets inferior_pid to its pid.
EXEC_FILE is the file to run.
ALLARGS is a string containing the arguments to the program.
ENV is the environment vector to pass. SHELL_FILE is the shell file,
or NULL if we should pick one. Errors reported with error(). */
void
fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun)
fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun,
shell_file)
char *exec_file;
char *allargs;
char **env;
void (*traceme_fun) PARAMS ((void));
void (*init_trace_fun) PARAMS ((int));
char *shell_file;
{
int pid;
char *shell_command;
char *shell_file;
static char default_shell_file[] = SHELL_FILE;
int len;
int pending_execs;
int terminal_initted;
/* Set debug_fork then attach to the child while it sleeps, to debug. */
static int debug_fork = 0;
/* This is set to the result of setpgrp, which if vforked, will be visible
@ -76,9 +71,11 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun)
/* The user might want tilde-expansion, and in general probably wants
the program to behave the same way as if run from
his/her favorite shell. So we let the shell run it for us.
FIXME, this should probably search the local environment (as
modified by the setenv command), not the env gdb inherited. */
shell_file = getenv ("SHELL");
FIXME-maybe, we might want a "set shell" command so the user can change
the shell from within GDB (if so, change callers which pass in a non-NULL
shell_file too). */
if (shell_file == NULL)
shell_file = getenv ("SHELL");
if (shell_file == NULL)
shell_file = default_shell_file;
@ -171,8 +168,8 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun)
output prior to doing a fork, to avoid the possibility of both the
parent and child flushing the same data after the fork. */
fflush (stdout);
fflush (stderr);
gdb_flush (gdb_stdout);
gdb_flush (gdb_stderr);
#if defined(USG) && !defined(HAVE_VFORK)
pid = fork ();
@ -196,17 +193,6 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun)
if (debug_setpgrp == -1)
perror("setpgrp failed in child");
#ifdef SET_STACK_LIMIT_HUGE
/* Reset the stack limit back to what it was. */
{
struct rlimit rlim;
getrlimit (RLIMIT_STACK, &rlim);
rlim.rlim_cur = original_stack_limit;
setrlimit (RLIMIT_STACK, &rlim);
}
#endif /* SET_STACK_LIMIT_HUGE */
/* Ask the tty subsystem to switch to the one we specified earlier
(or to share the current terminal, if none was specified). */
@ -229,9 +215,9 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun)
environ = env;
execlp (shell_file, shell_file, "-c", shell_command, (char *)0);
fprintf (stderr, "Cannot exec %s: %s.\n", shell_file,
fprintf_unfiltered (gdb_stderr, "Cannot exec %s: %s.\n", shell_file,
safe_strerror (errno));
fflush (stderr);
gdb_flush (gdb_stderr);
_exit (0177);
}
@ -240,37 +226,47 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun)
init_thread_list();
inferior_pid = pid; /* Needed for wait_for_inferior stuff below */
/* Now that we have a child process, make it our target, and
initialize anything target-vector-specific that needs initializing. */
(*init_trace_fun)(pid);
/* We are now in the child process of interest, having exec'd the
correct program, and are poised at the first instruction of the
new program. */
#ifdef SOLIB_CREATE_INFERIOR_HOOK
SOLIB_CREATE_INFERIOR_HOOK (pid);
#endif
}
/* Accept NTRAPS traps from the inferior. */
void
startup_inferior (ntraps)
int ntraps;
{
int pending_execs = ntraps;
int terminal_initted;
/* The process was started by the fork that created it,
but it will have stopped one instruction after execing the shell.
Here we must get it up to actual execution of the real program. */
inferior_pid = pid; /* Needed for wait_for_inferior stuff below */
clear_proceed_status ();
/* We will get a trace trap after one instruction.
Continue it automatically. Eventually (after shell does an exec)
it will get another trace trap. Then insert breakpoints and continue. */
#ifdef START_INFERIOR_TRAPS_EXPECTED
pending_execs = START_INFERIOR_TRAPS_EXPECTED;
#else
pending_execs = 2;
#endif
init_wait_for_inferior ();
terminal_initted = 0;
#ifdef STARTUP_INFERIOR
STARTUP_INFERIOR (pending_execs);
#else
while (1)
{
stop_soon_quietly = 1; /* Make wait_for_inferior be quiet */
wait_for_inferior ();
if (stop_signal != SIGTRAP)
if (stop_signal != TARGET_SIGNAL_TRAP)
{
/* Let shell child handle its own signals in its own way */
/* FIXME, what if child has exit()ed? Must exit loop somehow */
@ -296,15 +292,9 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun)
}
if (0 == --pending_execs)
break;
resume (0, 0); /* Just make it go on */
resume (0, TARGET_SIGNAL_0); /* Just make it go on */
}
}
#endif /* STARTUP_INFERIOR */
stop_soon_quietly = 0;
/* We are now in the child process of interest, having exec'd the
correct program, and are poised at the first instruction of the
new program. */
#ifdef SOLIB_CREATE_INFERIOR_HOOK
SOLIB_CREATE_INFERIOR_HOOK (pid);
#endif
}

View File

@ -217,7 +217,7 @@ extern struct block * block_for_pc PARAMS ((CORE_ADDR));
extern int frameless_look_for_prologue PARAMS ((FRAME));
extern void print_frame_args PARAMS ((struct symbol *, struct frame_info *,
int, FILE *));
int, GDB_FILE *));
extern FRAME find_relative_frame PARAMS ((FRAME, int*));
@ -233,6 +233,8 @@ extern CORE_ADDR find_saved_register PARAMS ((FRAME, int));
extern FRAME block_innermost_frame PARAMS ((struct block *));
extern FRAME find_frame_addr_in_frame_chain PARAMS ((FRAME_ADDR));
extern CORE_ADDR sigtramp_saved_pc PARAMS ((FRAME));
#endif /* !defined (FRAME_H) */

View File

@ -15,10 +15,20 @@ 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. */
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: freebsd-nat.c,v 1.3 1994/05/18 12:43:13 pk Exp $
*/
#include <sys/types.h>
#include <sys/param.h>
#include <signal.h>
#include <sys/user.h>
#include <machine/reg.h>
#include <machine/frame.h>
#include <sys/ptrace.h>
#include "defs.h"
#include <machine/reg.h>
/* this table must line up with REGISTER_NAMES in tm-i386.h */
/* symbols like 'tEAX' come from <machine/reg.h> */
@ -28,14 +38,7 @@ static int tregmap[] =
tESP, tEBP, tESI, tEDI,
tEIP, tEFLAGS, tCS, tSS
};
#ifdef sEAX
static int sregmap[] =
{
sEAX, sECX, sEDX, sEBX,
sESP, sEBP, sESI, sEDI,
sEIP, sEFLAGS, sCS, sSS
};
#endif
/* blockend is the value of u.u_ar0, and points to the
place where ES is stored. */
@ -44,45 +47,14 @@ i386_register_u_addr (blockend, regnum)
int blockend;
int regnum;
{
/* The following condition is a kludge to get at the proper register map
depending upon the state of pcb_flag.
The proper condition would be
if (u.u_pcb.pcb_flag & FM_TRAP)
but that would require a ptrace call here and wouldn't work
for corefiles. */
#ifdef sEAX
if (blockend < 0x1fcc)
return (blockend + 4 * tregmap[regnum]);
else
return (blockend + 4 * sregmap[regnum]);
#else
return (blockend + 4 * tregmap[regnum]);
#endif
}
#ifdef FLOAT_INFO
#include <sys/param.h>
#include <sys/dir.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <a.out.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/uio.h>
#define curpcb Xcurpcb /* XXX avoid leaking declaration from pcb.h */
#include <sys/user.h>
#undef curpcb
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/ptrace.h>
#define fpstate save87
#define U_FPSTATE(u) u.u_pcb.pcb_savefpu
static void
i387_to_double (from, to)
char *from;
char *to;
@ -113,6 +85,7 @@ i387_to_double (from, to)
asm ("popl %eax"); /* flush saved copy */
}
static void
double_to_i387 (from, to)
char *from;
char *to;
@ -209,7 +182,7 @@ print_387_status_word (status)
printf ("top %d\n", (status >> 11) & 7);
}
static
static void
print_387_status (status, ep)
unsigned short status;
struct env387 *ep;
@ -271,6 +244,7 @@ print_387_status (status, ep)
}
}
void
i386_float_info ()
{
struct user u; /* just for address computations */
@ -320,4 +294,319 @@ i386_float_info ()
print_387_status (0, (struct env387 *)buf);
}
void
clear_regs()
{
return;
}
#ifdef KERNEL_DEBUG
#include <sys/proc.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <machine/vmparam.h>
#include <machine/pcb.h>
#define KERNOFF ((unsigned)KERNBASE)
#define INKERNEL(x) ((x) >= KERNOFF)
static CORE_ADDR sbr;
static CORE_ADDR curpcb;
static CORE_ADDR kstack;
static int found_pcb;
static int devmem;
static int kfd;
static struct pcb pcb;
int read_pcb (int, CORE_ADDR);
static CORE_ADDR kvtophys (int, CORE_ADDR);
static physrd(int, u_int, char*, int);
extern CORE_ADDR ksym_lookup(const char *);
/* substitutes for the stuff in libkvm which doesn't work */
/* most of this was taken from the old kgdb */
/* we don't need all this stuff, but the call should look the same */
kvm_open (efile, cfile, sfile, perm, errout)
char *efile;
char *cfile;
void *sfile;
int perm;
int errout;
{
struct stat stb;
CORE_ADDR addr;
int cfd;
if ((cfd = open(cfile, perm, 0)) < 0)
return (cfd);
fstat(cfd, &stb);
if ((stb.st_mode & S_IFMT) == S_IFCHR && stb.st_rdev == makedev(2, 0)) {
devmem = 1;
kfd = open ("/dev/kmem", perm, 0);
}
physrd(cfd, ksym_lookup("IdlePTD") - KERNOFF, (char*)&sbr, sizeof sbr);
printf("IdlePTD %x\n", sbr);
curpcb = ksym_lookup("curpcb") - KERNOFF;
physrd(cfd, curpcb, (char*)&curpcb, sizeof curpcb);
kstack = ksym_lookup("kstack");
found_pcb = 1; /* for vtophys */
if (!devmem)
read_pcb(cfd, ksym_lookup("dumppcb") - KERNOFF);
else
read_pcb(cfd, kvtophys(cfd, kstack));
return (cfd);
}
kvm_close (fd)
{
return (close (fd));
}
kvm_write(core_kd, memaddr, myaddr, len)
CORE_ADDR memaddr;
char *myaddr;
{
int cc;
if (devmem) {
if (kfd > 0) {
/*
* Just like kvm_read, only we write.
*/
errno = 0;
if (lseek(kfd, (off_t)memaddr, 0) < 0 && errno != 0) {
error("kvm_write:invalid address (%x)", memaddr);
return (0);
}
cc = write(kfd, myaddr, len);
if (cc < 0) {
error("kvm_write:write failed");
return (0);
} else if (cc < len)
error("kvm_write:short write");
return (cc);
} else
return (0);
} else {
printf("kvm_write not implemented for dead kernels\n");
return (0);
}
/* NOTREACHED */
}
kvm_read(core_kd, memaddr, myaddr, len)
CORE_ADDR memaddr;
char *myaddr;
{
return (kernel_core_file_hook (core_kd, memaddr, myaddr, len));
}
kvm_uread(core_kd, p, memaddr, myaddr, len)
register struct proc *p;
CORE_ADDR memaddr;
char *myaddr;
{
register char *cp;
char procfile[MAXPATHLEN];
ssize_t amount;
int fd;
if (devmem) {
cp = myaddr;
sprintf(procfile, "/proc/%d/mem", p->p_pid);
fd = open(procfile, O_RDONLY, 0);
if (fd < 0) {
error("cannot open %s", procfile);
close(fd);
return (0);
}
while (len > 0) {
if (lseek(fd, memaddr, 0) == -1 && errno != 0) {
error("invalid address (%x) in %s",
memaddr, procfile);
break;
}
amount = read(fd, cp, len);
if (amount < 0) {
error("error reading %s", procfile);
break;
}
cp += amount;
memaddr += amount;
len -= amount;
}
close(fd);
return (ssize_t)(cp - myaddr);
} else {
return (kernel_core_file_hook (core_kd, memaddr, myaddr, len));
}
}
static
physrd(cfd, addr, dat, len)
u_int addr;
char *dat;
{
if (lseek(cfd, (off_t)addr, L_SET) == -1)
return (-1);
return (read(cfd, dat, len));
}
static CORE_ADDR
kvtophys (fd, addr)
CORE_ADDR addr;
{
CORE_ADDR v;
struct pte pte;
static CORE_ADDR PTD = -1;
CORE_ADDR current_ptd;
/*if (devmem && kfd > 0)
return (addr);
/*
* If we're looking at the kernel stack,
* munge the address to refer to the user space mapping instead;
* that way we get the requested process's kstack, not the running one.
*/
if (addr >= kstack && addr < kstack + ctob(UPAGES))
addr = (addr - kstack) + curpcb;
/*
* We may no longer have a linear system page table...
*
* Here's the scoop. IdlePTD contains the physical address
* of a page table directory that always maps the kernel.
* IdlePTD is in memory that is mapped 1-to-1, so we can
* find it easily given its 'virtual' address from ksym_lookup().
* For hysterical reasons, the value of IdlePTD is stored in sbr.
*
* To look up a kernel address, we first convert it to a 1st-level
* address and look it up in IdlePTD. This gives us the physical
* address of a page table page; we extract the 2nd-level part of
* VA and read the 2nd-level pte. Finally, we add the offset part
* of the VA into the physical address from the pte and return it.
*
* User addresses are a little more complicated. If we don't have
* a current PCB from read_pcb(), we use PTD, which is the (fixed)
* virtual address of the current ptd. Since it's NOT in 1-to-1
* kernel space, we must look it up using IdlePTD. If we do have
* a pcb, we get the ptd from pcb_ptd.
*/
if (INKERNEL(addr))
current_ptd = sbr;
else if (found_pcb == 0) {
if (PTD == -1)
PTD = kvtophys(fd, ksym_lookup("PTD"));
current_ptd = PTD;
} else
current_ptd = pcb.pcb_ptd;
/*
* Read the first-level page table (ptd).
*/
v = current_ptd + ((unsigned)addr >> PD_SHIFT) * sizeof pte;
if (physrd(fd, v, (char *)&pte, sizeof pte) < 0 || pte.pg_v == 0)
return (~0);
/*
* Read the second-level page table.
*/
v = i386_ptob(pte.pg_pfnum) + ((addr&PT_MASK) >> PG_SHIFT) * sizeof pte;
if (physrd(fd, v, (char *) &pte, sizeof(pte)) < 0 || pte.pg_v == 0)
return (~0);
addr = i386_ptob(pte.pg_pfnum) + (addr & PGOFSET);
#if 0
printf("vtophys(%x) -> %x\n", oldaddr, addr);
#endif
return (addr);
}
read_pcb (fd, uaddr)
CORE_ADDR uaddr;
{
int i;
int *pcb_regs = (int *)&pcb;
int eip;
if (physrd(fd, uaddr, (char *)&pcb, sizeof pcb) < 0) {
error("cannot read pcb at %x\n", uaddr);
return (-1);
}
printf("current pcb at %x\n", uaddr);
/*
* get the register values out of the sys pcb and
* store them where `read_register' will find them.
*/
for (i = 0; i < 8; ++i)
supply_register(i, &pcb_regs[i+10]);
supply_register(8, &pcb_regs[8]); /* eip */
supply_register(9, &pcb_regs[9]); /* eflags */
for (i = 10; i < 13; ++i) /* cs, ss, ds */
supply_register(i, &pcb_regs[i+9]);
supply_register(13, &pcb_regs[18]); /* es */
for (i = 14; i < 16; ++i) /* fs, gs */
supply_register(i, &pcb_regs[i+8]);
#if 0 /* doesn't work ??? */
/* Hmm... */
if (target_read_memory(pcb_regs[5+10]+4, &eip, sizeof eip, 0))
error("Cannot read PC.");
supply_register(8, &eip); /* eip */
#endif
/* XXX 80387 registers? */
}
/*
* read len bytes from kernel virtual address 'addr' into local
* buffer 'buf'. Return numbert of bytes if read ok, 0 otherwise. On read
* errors, portion of buffer not read is zeroed.
*/
kernel_core_file_hook(fd, addr, buf, len)
CORE_ADDR addr;
char *buf;
int len;
{
int i;
CORE_ADDR paddr;
register char *cp;
int cc;
cp = buf;
while (len > 0) {
paddr = kvtophys(fd, addr);
if (paddr == ~0) {
bzero(buf, len);
break;
}
/* we can't read across a page boundary */
i = min(len, NBPG - (addr & PGOFSET));
if ((cc = physrd(fd, paddr, cp, i)) <= 0) {
bzero(cp, len);
return (cp - buf);
}
cp += cc;
addr += cc;
len -= cc;
}
return (cp - buf);
}
#endif /* KERNEL_DEBUG */

View File

@ -1,6 +1,6 @@
.\" Copyright (c) 1991 Free Software Foundation
.\" See section COPYING for conditions for redistribution
.\" $Id: gdb.1,v 1.1.1.1 1993/10/30 21:59:13 jkh Exp $
.\" $Id: gdb.1,v 1.1 1994/01/28 12:39:43 pk Exp $
.TH gdb 1 "4nov1991" "GNU Tools" "GNU Tools"
.SH NAME
gdb \- The GNU Debugger

View File

@ -64,11 +64,18 @@ read_memory_integer PARAMS ((CORE_ADDR memaddr, int len));
extern unsigned LONGEST
read_memory_unsigned_integer PARAMS ((CORE_ADDR memaddr, int len));
/* If this is prototyped, need to deal with void* vs. char*. */
/* This takes a char *, not void *. This is probably right, because
passing in an int * or whatever is wrong with respect to
byteswapping, alignment, different sizes for host vs. target types,
etc. */
extern void
write_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len));
extern void write_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, int len));
extern void generic_search PARAMS ((int len, char *data, char *mask,
CORE_ADDR startaddr, int increment,
CORE_ADDR lorange, CORE_ADDR hirange,
CORE_ADDR *addr_found, char *data_found));
/* Hook for `exec_file_command' command to call. */
extern void (*exec_file_display_hook) PARAMS ((char *filename));
@ -113,6 +120,9 @@ extern CORE_ADDR kernel_u_addr;
/* The target vector for core files */
extern struct target_ops core_ops;
#ifdef KERNEL_DEBUG
extern struct target_ops kcore_ops;
#endif
/* target vector functions called directly from elsewhere */
void

View File

@ -348,6 +348,53 @@ create_range_type (result_type, index_type, low_bound, high_bound)
return (result_type);
}
/* A lot of code assumes that the "index type" of an array/string/
set/bitstring is specifically a range type, though in some languages
it can be any discrete type. */
struct type *
force_to_range_type (type)
struct type *type;
{
switch (TYPE_CODE (type))
{
case TYPE_CODE_RANGE:
return type;
case TYPE_CODE_ENUM:
{
int low_bound = TYPE_FIELD_BITPOS (type, 0);
int high_bound = TYPE_FIELD_BITPOS (type, TYPE_NFIELDS (type) - 1);
struct type *range_type =
create_range_type (NULL, type, low_bound, high_bound);
TYPE_NAME (range_type) = TYPE_NAME (range_type);
TYPE_DUMMY_RANGE (range_type) = 1;
return range_type;
}
case TYPE_CODE_BOOL:
{
struct type *range_type = create_range_type (NULL, type, 0, 1);
TYPE_NAME (range_type) = TYPE_NAME (range_type);
TYPE_DUMMY_RANGE (range_type) = 1;
return range_type;
}
case TYPE_CODE_CHAR:
{
struct type *range_type = create_range_type (NULL, type, 0, 255);
TYPE_NAME (range_type) = TYPE_NAME (range_type);
TYPE_DUMMY_RANGE (range_type) = 1;
return range_type;
}
default:
{
static struct complaint msg =
{ "array index type must be a discrete type", 0, 0};
complain (&msg);
return create_range_type (NULL, builtin_type_int, 0, 0);
}
}
}
/* Create an array type using either a blank type supplied in RESULT_TYPE,
or creating a new type, inheriting the objfile from RANGE_TYPE.
@ -367,23 +414,15 @@ create_array_type (result_type, element_type, range_type)
int low_bound;
int high_bound;
if (TYPE_CODE (range_type) != TYPE_CODE_RANGE)
{
/* FIXME: We only handle range types at the moment. Complain and
create a dummy range type to use. */
warning ("internal error: array index type must be a range type");
range_type = lookup_fundamental_type (TYPE_OBJFILE (range_type),
FT_INTEGER);
range_type = create_range_type ((struct type *) NULL, range_type, 0, 0);
}
range_type = force_to_range_type (range_type);
if (result_type == NULL)
{
result_type = alloc_type (TYPE_OBJFILE (range_type));
}
TYPE_CODE (result_type) = TYPE_CODE_ARRAY;
TYPE_TARGET_TYPE (result_type) = element_type;
low_bound = TYPE_FIELD_BITPOS (range_type, 0);
high_bound = TYPE_FIELD_BITPOS (range_type, 1);
low_bound = TYPE_LOW_BOUND (range_type);
high_bound = TYPE_HIGH_BOUND (range_type);
TYPE_LENGTH (result_type) =
TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
TYPE_NFIELDS (result_type) = 1;
@ -417,6 +456,37 @@ create_string_type (result_type, range_type)
return (result_type);
}
struct type *
create_set_type (result_type, domain_type)
struct type *result_type;
struct type *domain_type;
{
int low_bound, high_bound, bit_length;
if (result_type == NULL)
{
result_type = alloc_type (TYPE_OBJFILE (domain_type));
}
domain_type = force_to_range_type (domain_type);
TYPE_CODE (result_type) = TYPE_CODE_SET;
TYPE_NFIELDS (result_type) = 1;
TYPE_FIELDS (result_type) = (struct field *)
TYPE_ALLOC (result_type, 1 * sizeof (struct field));
memset (TYPE_FIELDS (result_type), 0, sizeof (struct field));
TYPE_FIELD_TYPE (result_type, 0) = domain_type;
low_bound = TYPE_LOW_BOUND (domain_type);
high_bound = TYPE_HIGH_BOUND (domain_type);
bit_length = high_bound - low_bound + 1;
if (bit_length <= TARGET_CHAR_BIT)
TYPE_LENGTH (result_type) = 1;
else if (bit_length <= TARGET_SHORT_BIT)
TYPE_LENGTH (result_type) = TARGET_SHORT_BIT / TARGET_CHAR_BIT;
else
TYPE_LENGTH (result_type)
= ((bit_length + TARGET_INT_BIT - 1) / TARGET_INT_BIT)
* TARGET_CHAR_BIT;
return (result_type);
}
/* Smash TYPE to be a type of members of DOMAIN with type TO_TYPE.
A MEMBER is a wierd thing -- it amounts to a typed offset into
a struct, e.g. "an int at offset 8". A MEMBER TYPE doesn't
@ -685,7 +755,7 @@ lookup_struct_elt_type (type, name, noerr)
{
int i;
if (TYPE_CODE (type) == TYPE_CODE_PTR ||
while (TYPE_CODE (type) == TYPE_CODE_PTR ||
TYPE_CODE (type) == TYPE_CODE_REF)
type = TYPE_TARGET_TYPE (type);
@ -693,9 +763,9 @@ lookup_struct_elt_type (type, name, noerr)
TYPE_CODE (type) != TYPE_CODE_UNION)
{
target_terminal_ours ();
fflush (stdout);
fprintf (stderr, "Type ");
type_print (type, "", stderr, -1);
gdb_flush (gdb_stdout);
fprintf_unfiltered (gdb_stderr, "Type ");
type_print (type, "", gdb_stderr, -1);
error (" is not a structure or union type.");
}
@ -743,11 +813,11 @@ lookup_struct_elt_type (type, name, noerr)
}
target_terminal_ours ();
fflush (stdout);
fprintf (stderr, "Type ");
type_print (type, "", stderr, -1);
fprintf (stderr, " has no component named ");
fputs_filtered (name, stderr);
gdb_flush (gdb_stdout);
fprintf_unfiltered (gdb_stderr, "Type ");
type_print (type, "", gdb_stderr, -1);
fprintf_unfiltered (gdb_stderr, " has no component named ");
fputs_filtered (name, gdb_stderr);
error (".");
return (struct type *)-1; /* For lint */
}
@ -790,13 +860,14 @@ fill_in_vptr_fieldno (type)
If this is a stubbed struct (i.e. declared as struct foo *), see if
we can find a full definition in some other file. If so, copy this
definition, so we can use it in future. If not, set a flag so we
don't waste too much time in future. (FIXME, this doesn't seem
to be happening...)
definition, so we can use it in future. There used to be a comment (but
not any code) that if we don't find a full definition, we'd set a flag
so we don't spend time in the future checking the same type. That would
be a mistake, though--we might load in more symbols which contain a
full definition for the type.
This used to be coded as a macro, but I don't think it is called
often enough to merit such treatment.
*/
often enough to merit such treatment. */
struct complaint stub_noname_complaint =
{"stub type has NULL name", 0, 0};
@ -822,7 +893,31 @@ check_stub_type (type)
(struct symtab **) NULL);
if (sym)
{
memcpy ((char *)type, (char *)SYMBOL_TYPE(sym), sizeof (struct type));
memcpy ((char *)type,
(char *)SYMBOL_TYPE(sym),
sizeof (struct type));
}
}
if (TYPE_FLAGS (type) & TYPE_FLAG_TARGET_STUB)
{
struct type *range_type;
check_stub_type (TYPE_TARGET_TYPE (type));
if (!(TYPE_FLAGS (TYPE_TARGET_TYPE (type)) & TYPE_FLAG_STUB)
&& TYPE_CODE (type) == TYPE_CODE_ARRAY
&& TYPE_NFIELDS (type) == 1
&& (TYPE_CODE (range_type = TYPE_FIELD_TYPE (type, 0))
== TYPE_CODE_RANGE))
{
/* Now recompute the length of the array type, based on its
number of elements and the target type's length. */
TYPE_LENGTH (type) =
((TYPE_FIELD_BITPOS (range_type, 1)
- TYPE_FIELD_BITPOS (range_type, 0)
+ 1)
* TYPE_LENGTH (TYPE_TARGET_TYPE (type)));
TYPE_FLAGS (type) &= ~TYPE_FLAG_TARGET_STUB;
}
}
}
@ -884,6 +979,7 @@ check_stub_method (type, i, j)
argtypes = (struct type **)
TYPE_ALLOC (type, (argcount + 2) * sizeof (struct type *));
p = argtypetext;
/* FIXME: This is wrong for static member functions. */
argtypes[0] = lookup_pointer_type (type);
argcount = 1;
@ -894,9 +990,13 @@ check_stub_method (type, i, j)
{
if (depth <= 0 && (*p == ',' || *p == ')'))
{
argtypes[argcount] =
parse_and_eval_type (argtypetext, p - argtypetext);
argcount += 1;
/* Avoid parsing of ellipsis, they will be handled below. */
if (strncmp (argtypetext, "...", p - argtypetext) != 0)
{
argtypes[argcount] =
parse_and_eval_type (argtypetext, p - argtypetext);
argcount += 1;
}
argtypetext = p + 1;
}
@ -1046,6 +1146,17 @@ lookup_fundamental_type (objfile, typeid)
return (*typep);
}
int
can_dereference (t)
struct type *t;
{
/* FIXME: Should we return true for references as well as pointers? */
return
(t != NULL
&& TYPE_CODE (t) == TYPE_CODE_PTR
&& TYPE_CODE (TYPE_TARGET_TYPE (t)) != TYPE_CODE_VOID);
}
#if MAINTENANCE_CMDS
static void
@ -1105,33 +1216,46 @@ dump_fn_fieldlists (type, spaces)
int overload_idx;
struct fn_field *f;
printfi_filtered (spaces, "fn_fieldlists 0x%lx\n",
(unsigned long) TYPE_FN_FIELDLISTS (type));
printfi_filtered (spaces, "fn_fieldlists ");
gdb_print_address (TYPE_FN_FIELDLISTS (type), gdb_stdout);
printf_filtered ("\n");
for (method_idx = 0; method_idx < TYPE_NFN_FIELDS (type); method_idx++)
{
f = TYPE_FN_FIELDLIST1 (type, method_idx);
printfi_filtered (spaces + 2, "[%d] name '%s' (0x%lx) length %d\n",
printfi_filtered (spaces + 2, "[%d] name '%s' (",
method_idx,
TYPE_FN_FIELDLIST_NAME (type, method_idx),
(unsigned long) TYPE_FN_FIELDLIST_NAME (type, method_idx),
TYPE_FN_FIELDLIST_LENGTH (type, method_idx));
TYPE_FN_FIELDLIST_NAME (type, method_idx));
gdb_print_address (TYPE_FN_FIELDLIST_NAME (type, method_idx),
gdb_stdout);
printf_filtered (") length %d\n",
TYPE_FN_FIELDLIST_LENGTH (type, method_idx));
for (overload_idx = 0;
overload_idx < TYPE_FN_FIELDLIST_LENGTH (type, method_idx);
overload_idx++)
{
printfi_filtered (spaces + 4, "[%d] physname '%s' (0x%lx)\n",
printfi_filtered (spaces + 4, "[%d] physname '%s' (",
overload_idx,
TYPE_FN_FIELD_PHYSNAME (f, overload_idx),
(unsigned long) TYPE_FN_FIELD_PHYSNAME (f, overload_idx));
printfi_filtered (spaces + 8, "type 0x%lx\n",
(unsigned long) TYPE_FN_FIELD_TYPE (f, overload_idx));
TYPE_FN_FIELD_PHYSNAME (f, overload_idx));
gdb_print_address (TYPE_FN_FIELD_PHYSNAME (f, overload_idx),
gdb_stdout);
printf_filtered (")\n");
printfi_filtered (spaces + 8, "type ");
gdb_print_address (TYPE_FN_FIELD_TYPE (f, overload_idx), gdb_stdout);
printf_filtered ("\n");
recursive_dump_type (TYPE_FN_FIELD_TYPE (f, overload_idx),
spaces + 8 + 2);
printfi_filtered (spaces + 8, "args 0x%lx\n",
(unsigned long) TYPE_FN_FIELD_ARGS (f, overload_idx));
printfi_filtered (spaces + 8, "args ");
gdb_print_address (TYPE_FN_FIELD_ARGS (f, overload_idx), gdb_stdout);
printf_filtered ("\n");
print_arg_types (TYPE_FN_FIELD_ARGS (f, overload_idx), spaces);
printfi_filtered (spaces + 8, "fcontext 0x%lx\n",
(unsigned long) TYPE_FN_FIELD_FCONTEXT (f, overload_idx));
printfi_filtered (spaces + 8, "fcontext ");
gdb_print_address (TYPE_FN_FIELD_FCONTEXT (f, overload_idx),
gdb_stdout);
printf_filtered ("\n");
printfi_filtered (spaces + 8, "is_const %d\n",
TYPE_FN_FIELD_CONST (f, overload_idx));
printfi_filtered (spaces + 8, "is_volatile %d\n",
@ -1161,9 +1285,11 @@ print_cplus_stuff (type, spaces)
TYPE_NFN_FIELDS_TOTAL (type));
if (TYPE_N_BASECLASSES (type) > 0)
{
printfi_filtered (spaces, "virtual_field_bits (%d bits at *0x%lx)",
TYPE_N_BASECLASSES (type),
(unsigned long) TYPE_FIELD_VIRTUAL_BITS (type));
printfi_filtered (spaces, "virtual_field_bits (%d bits at *",
TYPE_N_BASECLASSES (type));
gdb_print_address (TYPE_FIELD_VIRTUAL_BITS (type), gdb_stdout);
printf_filtered (")");
print_bit_vector (TYPE_FIELD_VIRTUAL_BITS (type),
TYPE_N_BASECLASSES (type));
puts_filtered ("\n");
@ -1172,18 +1298,20 @@ print_cplus_stuff (type, spaces)
{
if (TYPE_FIELD_PRIVATE_BITS (type) != NULL)
{
printfi_filtered (spaces, "private_field_bits (%d bits at *0x%lx)",
TYPE_NFIELDS (type),
(unsigned long) TYPE_FIELD_PRIVATE_BITS (type));
printfi_filtered (spaces, "private_field_bits (%d bits at *",
TYPE_NFIELDS (type));
gdb_print_address (TYPE_FIELD_PRIVATE_BITS (type), gdb_stdout);
printf_filtered (")");
print_bit_vector (TYPE_FIELD_PRIVATE_BITS (type),
TYPE_NFIELDS (type));
puts_filtered ("\n");
}
if (TYPE_FIELD_PROTECTED_BITS (type) != NULL)
{
printfi_filtered (spaces, "protected_field_bits (%d bits at *0x%lx)",
TYPE_NFIELDS (type),
(unsigned long) TYPE_FIELD_PROTECTED_BITS (type));
printfi_filtered (spaces, "protected_field_bits (%d bits at *",
TYPE_NFIELDS (type));
gdb_print_address (TYPE_FIELD_PROTECTED_BITS (type), gdb_stdout);
printf_filtered (")");
print_bit_vector (TYPE_FIELD_PROTECTED_BITS (type),
TYPE_NFIELDS (type));
puts_filtered ("\n");
@ -1202,14 +1330,20 @@ recursive_dump_type (type, spaces)
{
int idx;
printfi_filtered (spaces, "type node 0x%lx\n", (unsigned long)type);
printfi_filtered (spaces, "name '%s' (0x%lx)\n",
TYPE_NAME (type) ? TYPE_NAME (type) : "<NULL>",
(unsigned long)TYPE_NAME (type));
printfi_filtered (spaces, "type node ");
gdb_print_address (type, gdb_stdout);
printf_filtered ("\n");
printfi_filtered (spaces, "name '%s' (",
TYPE_NAME (type) ? TYPE_NAME (type) : "<NULL>");
gdb_print_address (TYPE_NAME (type), gdb_stdout);
printf_filtered (")\n");
if (TYPE_TAG_NAME (type) != NULL)
printfi_filtered (spaces, "tagname '%s' (0x%lx)\n",
TYPE_TAG_NAME (type),
(unsigned long)TYPE_TAG_NAME (type));
{
printfi_filtered (spaces, "tagname '%s' (",
TYPE_TAG_NAME (type));
gdb_print_address (TYPE_TAG_NAME (type), gdb_stdout);
printf_filtered (")\n");
}
printfi_filtered (spaces, "code 0x%x ", TYPE_CODE (type));
switch (TYPE_CODE (type))
{
@ -1276,54 +1410,59 @@ recursive_dump_type (type, spaces)
}
puts_filtered ("\n");
printfi_filtered (spaces, "length %d\n", TYPE_LENGTH (type));
printfi_filtered (spaces, "objfile 0x%lx\n",
(unsigned long) TYPE_OBJFILE (type));
printfi_filtered (spaces, "target_type 0x%lx\n",
(unsigned long) TYPE_TARGET_TYPE (type));
printfi_filtered (spaces, "objfile ");
gdb_print_address (TYPE_OBJFILE (type), gdb_stdout);
printf_filtered ("\n");
printfi_filtered (spaces, "target_type ");
gdb_print_address (TYPE_TARGET_TYPE (type), gdb_stdout);
printf_filtered ("\n");
if (TYPE_TARGET_TYPE (type) != NULL)
{
recursive_dump_type (TYPE_TARGET_TYPE (type), spaces + 2);
}
printfi_filtered (spaces, "pointer_type 0x%lx\n",
(unsigned long) TYPE_POINTER_TYPE (type));
printfi_filtered (spaces, "reference_type 0x%lx\n",
(unsigned long) TYPE_REFERENCE_TYPE (type));
printfi_filtered (spaces, "function_type 0x%lx\n",
(unsigned long) TYPE_FUNCTION_TYPE (type));
printfi_filtered (spaces, "pointer_type ");
gdb_print_address (TYPE_POINTER_TYPE (type), gdb_stdout);
printf_filtered ("\n");
printfi_filtered (spaces, "reference_type ");
gdb_print_address (TYPE_REFERENCE_TYPE (type), gdb_stdout);
printf_filtered ("\n");
printfi_filtered (spaces, "function_type ");
gdb_print_address (TYPE_FUNCTION_TYPE (type), gdb_stdout);
printf_filtered ("\n");
printfi_filtered (spaces, "flags 0x%x", TYPE_FLAGS (type));
if (TYPE_FLAGS (type) & TYPE_FLAG_UNSIGNED)
{
puts_filtered (" TYPE_FLAG_UNSIGNED");
}
if (TYPE_FLAGS (type) & TYPE_FLAG_SIGNED)
{
puts_filtered (" TYPE_FLAG_SIGNED");
}
if (TYPE_FLAGS (type) & TYPE_FLAG_STUB)
{
puts_filtered (" TYPE_FLAG_STUB");
}
puts_filtered ("\n");
printfi_filtered (spaces, "nfields %d 0x%lx\n", TYPE_NFIELDS (type),
(unsigned long) TYPE_FIELDS (type));
printfi_filtered (spaces, "nfields %d ", TYPE_NFIELDS (type));
gdb_print_address (TYPE_FIELDS (type), gdb_stdout);
puts_filtered ("\n");
for (idx = 0; idx < TYPE_NFIELDS (type); idx++)
{
printfi_filtered (spaces + 2,
"[%d] bitpos %d bitsize %d type 0x%lx name '%s' (0x%lx)\n",
"[%d] bitpos %d bitsize %d type ",
idx, TYPE_FIELD_BITPOS (type, idx),
TYPE_FIELD_BITSIZE (type, idx),
(unsigned long) TYPE_FIELD_TYPE (type, idx),
TYPE_FIELD_NAME (type, idx) != NULL
? TYPE_FIELD_NAME (type, idx)
: "<NULL>",
(unsigned long) TYPE_FIELD_NAME (type, idx));
TYPE_FIELD_BITSIZE (type, idx));
gdb_print_address (TYPE_FIELD_TYPE (type, idx), gdb_stdout);
printf_filtered (" name '%s' (",
TYPE_FIELD_NAME (type, idx) != NULL
? TYPE_FIELD_NAME (type, idx)
: "<NULL>");
gdb_print_address (TYPE_FIELD_NAME (type, idx), gdb_stdout);
printf_filtered (")\n");
if (TYPE_FIELD_TYPE (type, idx) != NULL)
{
recursive_dump_type (TYPE_FIELD_TYPE (type, idx), spaces + 4);
}
}
printfi_filtered (spaces, "vptr_basetype 0x%lx\n",
(unsigned long) TYPE_VPTR_BASETYPE (type));
printfi_filtered (spaces, "vptr_basetype ");
gdb_print_address (TYPE_VPTR_BASETYPE (type), gdb_stdout);
puts_filtered ("\n");
if (TYPE_VPTR_BASETYPE (type) != NULL)
{
recursive_dump_type (TYPE_VPTR_BASETYPE (type), spaces + 2);
@ -1333,14 +1472,16 @@ recursive_dump_type (type, spaces)
{
case TYPE_CODE_METHOD:
case TYPE_CODE_FUNC:
printfi_filtered (spaces, "arg_types 0x%lx\n",
(unsigned long) TYPE_ARG_TYPES (type));
printfi_filtered (spaces, "arg_types ");
gdb_print_address (TYPE_ARG_TYPES (type), gdb_stdout);
puts_filtered ("\n");
print_arg_types (TYPE_ARG_TYPES (type), spaces);
break;
case TYPE_CODE_STRUCT:
printfi_filtered (spaces, "cplus_stuff 0x%lx\n",
(unsigned long) TYPE_CPLUS_SPECIFIC (type));
printfi_filtered (spaces, "cplus_stuff ");
gdb_print_address (TYPE_CPLUS_SPECIFIC (type), gdb_stdout);
puts_filtered ("\n");
print_cplus_stuff (type, spaces);
break;
@ -1348,8 +1489,8 @@ recursive_dump_type (type, spaces)
/* We have to pick one of the union types to be able print and test
the value. Pick cplus_struct_type, even though we know it isn't
any particular one. */
printfi_filtered (spaces, "type_specific 0x%lx",
(unsigned long) TYPE_CPLUS_SPECIFIC (type));
printfi_filtered (spaces, "type_specific ");
gdb_print_address (TYPE_CPLUS_SPECIFIC (type), gdb_stdout);
if (TYPE_CPLUS_SPECIFIC (type) != NULL)
{
printf_filtered (" (unknown data form)");
@ -1375,7 +1516,7 @@ _initialize_gdbtypes ()
"char", (struct objfile *) NULL);
builtin_type_signed_char =
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_SIGNED,
0,
"signed char", (struct objfile *) NULL);
builtin_type_unsigned_char =
init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,

View File

@ -21,9 +21,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (GDBTYPES_H)
#define GDBTYPES_H 1
/* When gdb creates fundamental types, it uses one of the following
type identifiers. The identifiers are used to index a vector of
pointers to any types that are created. */
/* Codes for `fundamental types'. This is a monstrosity based on the
bogus notion that there are certain compiler-independent
`fundamental types'. None of these is well-defined (how big is
FT_SHORT? Does it depend on the language? How does the
language-specific code know which type to correlate to FT_SHORT?) */
#define FT_VOID 0
#define FT_BOOLEAN 1
@ -84,13 +86,25 @@ enum type_code
of GDB which bogusly assume that TYPE_CODE_FLT can mean complex. */
TYPE_CODE_FLT,
/* Void type (values zero length; the length field is ignored). */
/* Void type. The length field specifies the length (probably always
one) which is used in pointer arithmetic involving pointers to
this type, but actually dereferencing such a pointer is invalid;
a void type has no length and no actual representation in memory
or registers. A pointer to a void type is a generic pointer. */
TYPE_CODE_VOID,
TYPE_CODE_SET, /* Pascal sets */
TYPE_CODE_RANGE, /* Range (integers within spec'd bounds) */
TYPE_CODE_STRING, /* String types, distinct from array of char */
TYPE_CODE_BITSTRING, /* String of bits, distinct from bool array */
/* A string type which is like an array of character but prints
differently (at least for CHILL). It does not contain a length
field as Pascal strings (for many Pascals, anyway) do; if we want
to deal with such strings, we should use a new type code. */
TYPE_CODE_STRING,
/* String of bits; like TYPE_CODE_SET but prints differently (at least
for CHILL). */
TYPE_CODE_BITSTRING,
/* Unknown type. The length field is valid if we were able to
deduce that much about the type, or 0 if we don't even know that. */
@ -101,33 +115,40 @@ enum type_code
TYPE_CODE_METHOD, /* Method type */
TYPE_CODE_REF, /* C++ Reference types */
/* Modula-2 */
TYPE_CODE_CHAR, /* *real* character type */
TYPE_CODE_BOOL /* BOOLEAN type */
/* Boolean type. 0 is false, 1 is true, and other values are non-boolean
(e.g. FORTRAN "logical" used as unsigned int). */
TYPE_CODE_BOOL
};
/* For now allow source to use TYPE_CODE_CLASS for C++ classes, as an
alias for TYPE_CODE_STRUCT. Eventually these should probably be
officially distinct types within gdb. */
alias for TYPE_CODE_STRUCT. This is for DWARF, which has a distinct
"class" attribute. Perhaps we should actually have a separate TYPE_CODE
so that we can print "class" or "struct" depending on what the debug
info said. It's not clear we should bother. */
#define TYPE_CODE_CLASS TYPE_CODE_STRUCT
/* Some bits for the type's flags word. */
/* Explicitly unsigned integer type */
/* Unsigned integer type. If this is not set for a TYPE_CODE_INT, the
type is signed. */
#define TYPE_FLAG_UNSIGNED (1 << 0)
/* Explicitly signed integer type */
#define TYPE_FLAG_SIGNED (1 << 1)
/* This appears in a type's flags word if it is a stub type (e.g., if
someone referenced a type that wasn't defined in a source file
via (struct sir_not_appearing_in_this_film *)). */
#define TYPE_FLAG_STUB (1 << 2)
/* The target type of this type is a stub type, and this type needs to
be updated if it gets un-stubbed in check_stub_type. Currently only
used for arrays, in which TYPE_LENGTH of the array gets set based
on the TYPE_LENGTH of the target type. */
#define TYPE_FLAG_TARGET_STUB (1 << 3)
struct type
{
@ -347,6 +368,11 @@ struct cplus_struct_type
B_TYPE *protected_field_bits;
/* for classes with fields to be ignored, either this is optimized out
or this field has length 0 */
B_TYPE *ignore_field_bits;
/* For classes, structures, and unions, a description of each field,
which consists of an overloaded name, followed by the types of
arguments that the method expects, and then the name after it
@ -389,7 +415,8 @@ struct cplus_struct_type
/* The argument list. Only valid if is_stub is clear. Contains
the type of each argument, including `this', and ending with
a NULL pointer after the last argument. */
a NULL pointer after the last argument. Should not contain
a `this' pointer for static member functions. */
struct type **args;
@ -453,6 +480,12 @@ allocate_cplus_struct_type PARAMS ((struct type *));
#define TYPE_NFIELDS(thistype) (thistype)->nfields
#define TYPE_FIELDS(thistype) (thistype)->fields
#define TYPE_LOW_BOUND(range_type) TYPE_FIELD_BITPOS (range_type, 0)
#define TYPE_HIGH_BOUND(range_type) TYPE_FIELD_BITPOS (range_type, 1)
/* If TYPE_DUMMY_RANGE is true for a range type, it was allocated
by force_to_range_type. */
#define TYPE_DUMMY_RANGE(type) ((type)->vptr_fieldno)
/* C++ */
#define TYPE_VPTR_BASETYPE(thistype) (thistype)->vptr_basetype
@ -484,12 +517,16 @@ allocate_cplus_struct_type PARAMS ((struct type *));
TYPE_CPLUS_SPECIFIC(thistype)->private_field_bits
#define TYPE_FIELD_PROTECTED_BITS(thistype) \
TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits
#define TYPE_FIELD_IGNORE_BITS(thistype) \
TYPE_CPLUS_SPECIFIC(thistype)->ignore_field_bits
#define TYPE_FIELD_VIRTUAL_BITS(thistype) \
TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits
#define SET_TYPE_FIELD_PRIVATE(thistype, n) \
B_SET (TYPE_CPLUS_SPECIFIC(thistype)->private_field_bits, (n))
#define SET_TYPE_FIELD_PROTECTED(thistype, n) \
B_SET (TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits, (n))
#define SET_TYPE_FIELD_IGNORE(thistype, n) \
B_SET (TYPE_CPLUS_SPECIFIC(thistype)->ignore_field_bits, (n))
#define SET_TYPE_FIELD_VIRTUAL(thistype, n) \
B_SET (TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n))
#define TYPE_FIELD_PRIVATE(thistype, n) \
@ -498,6 +535,9 @@ allocate_cplus_struct_type PARAMS ((struct type *));
#define TYPE_FIELD_PROTECTED(thistype, n) \
(TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits == NULL ? 0 \
: B_TST(TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits, (n)))
#define TYPE_FIELD_IGNORE(thistype, n) \
(TYPE_CPLUS_SPECIFIC(thistype)->ignore_field_bits == NULL ? 0 \
: B_TST(TYPE_CPLUS_SPECIFIC(thistype)->ignore_field_bits, (n)))
#define TYPE_FIELD_VIRTUAL(thistype, n) \
B_TST(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n))
@ -565,20 +605,6 @@ extern struct type *builtin_type_chill_long;
extern struct type *builtin_type_chill_ulong;
extern struct type *builtin_type_chill_real;
/* CC_HAS_LONG_LONG is defined if the host has "long long". */
#ifdef CC_HAS_LONG_LONG
#define BUILTIN_TYPE_LONGEST builtin_type_long_long
#define BUILTIN_TYPE_UNSIGNED_LONGEST builtin_type_unsigned_long_long
#else /* not CC_HAS_LONG_LONG. */
#define BUILTIN_TYPE_LONGEST builtin_type_long
#define BUILTIN_TYPE_UNSIGNED_LONGEST builtin_type_unsigned_long
#endif /* not CC_HAS_LONG_LONG. */
/* Maximum and minimum values of built-in types */
#define MAX_OF_TYPE(t) \
@ -655,6 +681,9 @@ create_array_type PARAMS ((struct type *, struct type *, struct type *));
extern struct type *
create_string_type PARAMS ((struct type *, struct type *));
extern struct type *
create_set_type PARAMS ((struct type *, struct type *));
extern struct type *
lookup_unsigned_typename PARAMS ((char *));
@ -695,7 +724,9 @@ extern void recursive_dump_type PARAMS ((struct type *, int));
/* printcmd.c */
extern void
print_scalar_formatted PARAMS ((char *, struct type *, int, int, FILE *));
print_scalar_formatted PARAMS ((char *, struct type *, int, int, GDB_FILE *));
extern int can_dereference PARAMS ((struct type *));
#if MAINTENANCE_CMDS
extern void maintenance_print_type PARAMS ((char *, int));

View File

@ -1,5 +1,5 @@
/* Print i386 instructions for GDB, the GNU debugger.
Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
Copyright (C) 1988, 1989, 1991, 1993, 1994 Free Software Foundation, Inc.
This file is part of GDB.
@ -33,12 +33,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
*/
#include "dis-asm.h"
#include "sysdep.h"
#define MAXLEN 20
#include <setjmp.h>
struct private
struct dis_private
{
/* Points to first byte not fetched. */
bfd_byte *max_fetched;
@ -51,7 +52,7 @@ struct private
to ADDR (exclusive) are valid. Returns 1 for success, longjmps
on error. */
#define FETCH_DATA(info, addr) \
((addr) <= ((struct private *)(info->private_data))->max_fetched \
((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
? 1 : fetch_data ((info), (addr)))
static int
@ -60,7 +61,7 @@ fetch_data (info, addr)
bfd_byte *addr;
{
int status;
struct private *priv = (struct private *)info->private_data;
struct dis_private *priv = (struct dis_private *)info->private_data;
bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
status = (*info->read_memory_func) (start,
@ -415,8 +416,8 @@ struct dis386 dis386[] = {
{ "stosS", Yv, eAX },
{ "lodsb", AL, Xb },
{ "lodsS", eAX, Xv },
{ "scasb", AL, Xb },
{ "scasS", eAX, Xv },
{ "scasb", AL, Yb },
{ "scasS", eAX, Yv },
/* b0 */
{ "movb", AL, Ib },
{ "movb", CL, Ib },
@ -977,7 +978,7 @@ print_insn_i386 (pc, info)
char *first, *second, *third;
int needcomma;
struct private priv;
struct dis_private priv;
bfd_byte *inbuf = priv.the_buffer;
info->private_data = (PTR) &priv;
@ -1045,11 +1046,17 @@ print_insn_i386 (pc, info)
else
dp = &dis386[*codep];
codep++;
/* Fetch the mod/reg/rm byte. FIXME: We should be only fetching
this if we need it. As it is, this code loses if there is a
one-byte instruction (without a mod/reg/rm byte) at the end of
the address space. */
FETCH_DATA (info, codep + 1);
mod = (*codep >> 6) & 3;
reg = (*codep >> 3) & 7;
rm = *codep & 7;
if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
{
dofloat ();

View File

@ -27,7 +27,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
int
print_insn (memaddr, stream)
CORE_ADDR memaddr;
FILE *stream;
GDB_FILE *stream;
{
disassemble_info info;

View File

@ -1,5 +1,5 @@
/* Intel 386 target-dependent stuff.
Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
Copyright (C) 1988, 1989, 1991, 1994 Free Software Foundation, Inc.
This file is part of GDB.
@ -22,6 +22,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "inferior.h"
#include "gdbcore.h"
#include "target.h"
#include "floatformat.h"
#include "symtab.h"
static long
i386_get_frame_setup PARAMS ((int));
@ -430,7 +432,12 @@ i386_frame_find_saved_regs (fip, fsrp)
op = codestream_get ();
if (op < 0x50 || op > 0x57)
break;
#ifdef I386_REGNO_TO_SYMMETRY
/* Dynix uses different internal numbering. Ick. */
fsrp->regs[I386_REGNO_TO_SYMMETRY(op - 0x50)] = adr;
#else
fsrp->regs[op - 0x50] = adr;
#endif
adr -= 4;
}
}
@ -447,6 +454,10 @@ i386_skip_prologue (pc)
{
unsigned char op;
int i;
static unsigned char pic_pat[6] = { 0xe8, 0, 0, 0, 0, /* call 0x0 */
0x5b, /* popl %ebx */
};
CORE_ADDR pos;
if (i386_get_frame_setup (pc) < 0)
return (pc);
@ -464,6 +475,54 @@ i386_skip_prologue (pc)
break;
codestream_get ();
}
/* The native cc on SVR4 in -K PIC mode inserts the following code to get
the address of the global offset table (GOT) into register %ebx.
call 0x0
popl %ebx
movl %ebx,x(%ebp) (optional)
addl y,%ebx
This code is with the rest of the prologue (at the end of the
function), so we have to skip it to get to the first real
instruction at the start of the function. */
pos = codestream_tell ();
for (i = 0; i < 6; i++)
{
op = codestream_get ();
if (pic_pat [i] != op)
break;
}
if (i == 6)
{
unsigned char buf[4];
long delta = 6;
op = codestream_get ();
if (op == 0x89) /* movl %ebx, x(%ebp) */
{
op = codestream_get ();
if (op == 0x5d) /* one byte offset from %ebp */
{
delta += 3;
codestream_read (buf, 1);
}
else if (op == 0x9d) /* four byte offset from %ebp */
{
delta += 6;
codestream_read (buf, 4);
}
else /* unexpected instruction */
delta = -1;
op = codestream_get ();
}
/* addl y,%ebx */
if (delta > 0 && op == 0x81 && codestream_get () == 0xc3)
{
pos += delta + 6;
}
}
codestream_seek (pos);
i386_follow_jump ();
@ -565,27 +624,12 @@ i386_extract_return_value(type, regbuf, valbuf)
{
if (TYPE_CODE_FLT == TYPE_CODE(type))
{
extern struct ext_format ext_format_i387;
double d;
/* 387 %st(0), gcc uses this */
ieee_extended_to_double (&ext_format_i387,
&regbuf[REGISTER_BYTE(FP0_REGNUM)],
&d);
switch (TYPE_LENGTH(type))
{
case 4: /* float */
{
float f = (float) d;
memcpy (valbuf, &f, 4);
break;
}
case 8: /* double */
memcpy (valbuf, &d, 8);
break;
default:
error("Unknown floating point size");
break;
}
floatformat_to_double (&floatformat_i387_ext,
&regbuf[REGISTER_BYTE(FP0_REGNUM)],
&d);
store_floating (valbuf, TYPE_LENGTH (type), d);
}
else
{
@ -593,3 +637,32 @@ i386_extract_return_value(type, regbuf, valbuf)
}
}
#endif /* I386_AIX_TARGET */
#ifdef I386V4_SIGTRAMP_SAVED_PC
/* Get saved user PC for sigtramp from the pushed ucontext on the stack
for all three variants of SVR4 sigtramps. */
CORE_ADDR
i386v4_sigtramp_saved_pc (frame)
FRAME frame;
{
CORE_ADDR saved_pc_offset = 4;
char *name = NULL;
find_pc_partial_function (frame->pc, &name,
(CORE_ADDR *)NULL,(CORE_ADDR *)NULL);
if (name)
{
if (STREQ (name, "_sigreturn"))
saved_pc_offset = 132 + 14 * 4;
else if (STREQ (name, "_sigacthandler"))
saved_pc_offset = 80 + 14 * 4;
else if (STREQ (name, "sigvechandler"))
saved_pc_offset = 120 + 14 * 4;
}
if (frame->next)
return read_memory_integer (frame->next->frame + saved_pc_offset, 4);
return read_memory_integer (read_register (SP_REGNUM) + saved_pc_offset, 4);
}
#endif /* I386V4_SIGTRAMP_SAVED_PC */

View File

@ -30,6 +30,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "gdbcmd.h"
#include "gdbcore.h"
#include "target.h"
#include "language.h"
static void
continue_command PARAMS ((char *, int));
@ -127,7 +128,7 @@ int inferior_pid;
/* Last signal that the inferior received (why it stopped). */
int stop_signal;
enum target_signal stop_signal;
/* Address at which inferior stopped. */
@ -221,12 +222,22 @@ Start it from the beginning? "))
target_kill ();
}
clear_breakpoint_hit_counts ();
exec_file = (char *) get_exec_file (0);
/* The exec file is re-read every time we do a generic_mourn_inferior, so
we just have to worry about the symbol file. */
reread_symbols ();
/* We keep symbols from add-symbol-file, on the grounds that the
user might want to add some symbols before running the program
(right?). But sometimes (dynamic loading where the user manually
introduces the new symbols with add-symbol-file), the code which
the symbols describe does not persist between runs. Currently
the user has to manually nuke all symbols between runs if they
want them to go away (PR 2207). This is probably reasonable. */
if (args)
{
char *cmd;
@ -243,7 +254,7 @@ Start it from the beginning? "))
puts_filtered(" ");
puts_filtered(inferior_args);
puts_filtered("\n");
fflush (stdout);
gdb_flush (gdb_stdout);
}
target_create_inferior (exec_file, inferior_args,
@ -286,7 +297,7 @@ continue_command (proc_count_exp, from_tty)
clear_proceed_status ();
proceed ((CORE_ADDR) -1, -1, 0);
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
}
/* Step until outside of current statement. */
@ -373,7 +384,7 @@ step_1 (skip_subroutines, single_inst, count_string)
printf_filtered ("\
Single stepping until exit from function %s, \n\
which has no line number information.\n", name);
fflush (stdout);
gdb_flush (gdb_stdout);
}
}
else
@ -391,7 +402,7 @@ which has no line number information.\n", name);
step_over_calls = 1;
step_multi = (count > 1);
proceed ((CORE_ADDR) -1, -1, 1);
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
if (! stop_step)
break;
@ -455,11 +466,14 @@ jump_command (arg, from_tty)
addr = sal.pc;
if (from_tty)
printf_filtered ("Continuing at %s.\n",
local_hex_string((unsigned long) addr));
{
printf_filtered ("Continuing at ");
print_address_numeric (addr, 1, gdb_stdout);
printf_filtered (".\n");
}
clear_proceed_status ();
proceed (addr, 0, 0);
proceed (addr, TARGET_SIGNAL_0, 0);
}
/* Continue program giving it specified signal. */
@ -469,7 +483,7 @@ signal_command (signum_exp, from_tty)
char *signum_exp;
int from_tty;
{
register int signum;
enum target_signal oursig;
dont_repeat (); /* Too dangerous. */
ERROR_NO_INFERIOR;
@ -480,25 +494,36 @@ signal_command (signum_exp, from_tty)
/* It would be even slicker to make signal names be valid expressions,
(the type could be "enum $signal" or some such), then the user could
assign them to convenience variables. */
signum = strtosigno (signum_exp);
oursig = target_signal_from_name (signum_exp);
if (signum == 0)
/* Not found as a name, try it as an expression. */
signum = parse_and_eval_address (signum_exp);
if (oursig == TARGET_SIGNAL_UNKNOWN)
{
/* Not found as a name, try it as an expression. */
/* The numeric signal refers to our own internal signal numbering
from target.h, not to host/target signal number. This is a
feature; users really should be using symbolic names anyway,
and the common ones like SIGHUP, SIGINT, SIGALRM, etc. will
work right anyway. */
int signum = parse_and_eval_address (signum_exp);
if (signum < 0
|| signum >= (int)TARGET_SIGNAL_LAST
|| signum == (int)TARGET_SIGNAL_UNKNOWN
|| signum == (int)TARGET_SIGNAL_DEFAULT)
error ("Invalid signal number %d.", signum);
oursig = signum;
}
if (from_tty)
{
char *signame = strsigno (signum);
printf_filtered ("Continuing with signal ");
if (signame == NULL || signum == 0)
printf_filtered ("%d.\n", signum);
if (oursig == TARGET_SIGNAL_0)
printf_filtered ("Continuing with no signal.\n");
else
/* Do we need to print the number as well as the name? */
printf_filtered ("%s (%d).\n", signame, signum);
printf_filtered ("Continuing with signal %s.\n",
target_signal_to_name (oursig));
}
clear_proceed_status ();
proceed (stop_pc, signum, 0);
proceed (stop_pc, oursig, 0);
}
/* Call breakpoint_auto_delete on the current contents of the bpstat
@ -552,7 +577,7 @@ run_stack_dummy (addr, buffer)
#if CALL_DUMMY_LOCATION != AT_ENTRY_POINT
sal.pc = addr - CALL_DUMMY_START_OFFSET + CALL_DUMMY_BREAKPOINT_OFFSET;
#else
sal.pc = entry_point_address ();
sal.pc = CALL_DUMMY_ADDRESS ();
#endif
sal.symtab = NULL;
sal.line = 0;
@ -583,7 +608,7 @@ run_stack_dummy (addr, buffer)
#endif /* CALL_DUMMY_BREAKPOINT_OFFSET. */
proceed_to_finish = 1; /* We want stop_registers, please... */
proceed (addr, 0, 0);
proceed (addr, TARGET_SIGNAL_0, 0);
discard_cleanups (old_cleanups);
@ -601,8 +626,8 @@ run_stack_dummy (addr, buffer)
Note that eventually this command should probably be changed so
that only source lines are printed out when we hit the breakpoint
we set. I'm going to postpone this until after a hopeful rewrite
of wait_for_inferior and the proceed status code. -- randy */
we set. This may involve changes to wait_for_inferior and the
proceed status code. */
/* ARGSUSED */
static void
@ -648,7 +673,7 @@ until_next_command (from_tty)
step_multi = 0; /* Only one call to proceed */
proceed ((CORE_ADDR) -1, -1, 1);
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
}
static void
@ -714,14 +739,14 @@ finish_command (arg, from_tty)
}
proceed_to_finish = 1; /* We want stop_registers, please... */
proceed ((CORE_ADDR) -1, -1, 0);
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
/* Did we stop at our breakpoint? */
if (bpstat_find_breakpoint(stop_bpstat, breakpoint) != NULL
&& function != 0)
{
struct type *value_type;
register value val;
register value_ptr val;
CORE_ADDR funcaddr;
value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function));
@ -740,7 +765,7 @@ finish_command (arg, from_tty)
BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function))));
printf_filtered ("Value returned is $%d = ", record_latest_value (val));
value_print (val, stdout, 0, Val_no_prettyprint);
value_print (val, gdb_stdout, 0, Val_no_prettyprint);
printf_filtered ("\n");
}
do_cleanups(old_chain);
@ -779,21 +804,12 @@ program_info (args, from_tty)
num = bpstat_num (&bs);
}
}
else if (stop_signal)
else if (stop_signal != TARGET_SIGNAL_0)
{
#ifdef PRINT_RANDOM_SIGNAL
PRINT_RANDOM_SIGNAL (stop_signal);
#else
char *signame = strsigno (stop_signal);
printf_filtered ("It stopped with signal ");
if (signame == NULL)
printf_filtered ("%d", stop_signal);
else
/* Do we need to print the number as well as the name? */
printf_filtered ("%s (%d)", signame, stop_signal);
printf_filtered (", %s.\n", safe_strsignal (stop_signal));
#endif
}
printf_filtered ("It stopped with signal %s, %s.\n",
target_signal_to_name (stop_signal),
target_signal_to_string (stop_signal));
}
if (!from_tty)
printf_filtered ("Type \"info stack\" or \"info registers\" for more information.\n");
@ -946,82 +962,6 @@ path_command (dirname, from_tty)
path_info ((char *)NULL, from_tty);
}
/* This routine is getting awfully cluttered with #if's. It's probably
time to turn this into READ_PC and define it in the tm.h file.
Ditto for write_pc. */
CORE_ADDR
read_pc ()
{
#ifdef TARGET_READ_PC
return TARGET_READ_PC ();
#else
return ADDR_BITS_REMOVE ((CORE_ADDR) read_register (PC_REGNUM));
#endif
}
void
write_pc (val)
CORE_ADDR val;
{
#ifdef TARGET_WRITE_PC
TARGET_WRITE_PC (val);
#else
write_register (PC_REGNUM, (long) val);
#ifdef NPC_REGNUM
write_register (NPC_REGNUM, (long) val + 4);
#ifdef NNPC_REGNUM
write_register (NNPC_REGNUM, (long) val + 8);
#endif
#endif
#endif
}
/* Cope with strage ways of getting to the stack and frame pointers */
CORE_ADDR
read_sp ()
{
#ifdef TARGET_READ_SP
return TARGET_READ_SP ();
#else
return read_register (SP_REGNUM);
#endif
}
void
write_sp (val)
CORE_ADDR val;
{
#ifdef TARGET_WRITE_SP
TARGET_WRITE_SP (val);
#else
write_register (SP_REGNUM, val);
#endif
}
CORE_ADDR
read_fp ()
{
#ifdef TARGET_READ_FP
return TARGET_READ_FP ();
#else
return read_register (FP_REGNUM);
#endif
}
void
write_fp (val)
CORE_ADDR val;
{
#ifdef TARGET_WRITE_FP
TARGET_WRITE_FP (val);
#else
write_register (FP_REGNUM, val);
#endif
}
const char * const reg_names[] = REGISTER_NAMES;
/* Print out the machine register regnum. If regnum is -1,
@ -1036,15 +976,18 @@ const char * const reg_names[] = REGISTER_NAMES;
to provide that format. */
#if !defined (DO_REGISTERS_INFO)
#define DO_REGISTERS_INFO(regnum, fp) do_registers_info(regnum, fp)
static void
do_registers_info (regnum, fpregs)
int regnum;
int fpregs;
{
register int i;
int numregs = ARCH_NUM_REGS;
for (i = 0; i < NUM_REGS; i++)
for (i = 0; i < numregs; i++)
{
char raw_buffer[MAX_REGISTER_RAW_SIZE];
char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
@ -1058,17 +1001,27 @@ do_registers_info (regnum, fpregs)
continue;
}
fputs_filtered (reg_names[i], stdout);
print_spaces_filtered (15 - strlen (reg_names[i]), stdout);
fputs_filtered (reg_names[i], gdb_stdout);
print_spaces_filtered (15 - strlen (reg_names[i]), gdb_stdout);
/* Get the data in raw format, then convert also to virtual format. */
/* Get the data in raw format. */
if (read_relative_register_raw_bytes (i, raw_buffer))
{
printf_filtered ("Invalid register contents\n");
continue;
}
REGISTER_CONVERT_TO_VIRTUAL (i, raw_buffer, virtual_buffer);
/* Convert raw data to virtual format if necessary. */
#ifdef REGISTER_CONVERTIBLE
if (REGISTER_CONVERTIBLE (i))
{
REGISTER_CONVERT_TO_VIRTUAL (i, REGISTER_VIRTUAL_TYPE (i),
raw_buffer, virtual_buffer);
}
else
#endif
memcpy (virtual_buffer, raw_buffer,
REGISTER_VIRTUAL_SIZE (i));
/* If virtual format is floating, print it that way, and in raw hex. */
if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT
@ -1077,7 +1030,7 @@ do_registers_info (regnum, fpregs)
register int j;
val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0,
stdout, 0, 1, 0, Val_pretty_default);
gdb_stdout, 0, 1, 0, Val_pretty_default);
printf_filtered ("\t(raw 0x");
for (j = 0; j < REGISTER_RAW_SIZE (i); j++)
@ -1100,10 +1053,10 @@ do_registers_info (regnum, fpregs)
else
{
val_print (REGISTER_VIRTUAL_TYPE (i), raw_buffer, 0,
stdout, 'x', 1, 0, Val_pretty_default);
gdb_stdout, 'x', 1, 0, Val_pretty_default);
printf_filtered ("\t");
val_print (REGISTER_VIRTUAL_TYPE (i), raw_buffer, 0,
stdout, 0, 1, 0, Val_pretty_default);
gdb_stdout, 0, 1, 0, Val_pretty_default);
}
/* The SPARC wants to print even-numbered float regs as doubles
@ -1122,7 +1075,7 @@ registers_info (addr_exp, fpregs)
char *addr_exp;
int fpregs;
{
int regnum;
int regnum, numregs;
register char *end;
if (!target_has_registers)
@ -1141,13 +1094,14 @@ registers_info (addr_exp, fpregs)
end = addr_exp;
while (*end != '\0' && *end != ' ' && *end != '\t')
++end;
for (regnum = 0; regnum < NUM_REGS; regnum++)
numregs = ARCH_NUM_REGS;
for (regnum = 0; regnum < numregs; regnum++)
if (!strncmp (addr_exp, reg_names[regnum], end - addr_exp)
&& strlen (reg_names[regnum]) == end - addr_exp)
goto found;
if (*addr_exp >= '0' && *addr_exp <= '9')
regnum = atoi (addr_exp); /* Take a number */
if (regnum >= NUM_REGS) /* Bad name, or bad number */
if (regnum >= numregs) /* Bad name, or bad number */
error ("%.*s: invalid register", end - addr_exp, addr_exp);
found:
@ -1221,7 +1175,12 @@ attach_command (args, from_tty)
clear_proceed_status ();
stop_soon_quietly = 1;
#ifndef MACH
/* Mach 3 does not generate any traps when attaching to inferior,
and to set up frames we can do this. */
wait_for_inferior ();
#endif
#ifdef SOLIB_ADD
/* Add shared library symbols from the newly attached process, if any. */
@ -1248,6 +1207,8 @@ detach_command (args, from_tty)
int from_tty;
{
dont_repeat (); /* Not for the faint of heart */
if (remove_breakpoints ())
printf("detach_command: couldn't remove all breakpoints!\n");
target_detach (args, from_tty);
}
@ -1271,7 +1232,7 @@ unset_command (args, from_tty)
int from_tty;
{
printf_filtered ("\"unset\" must be followed by the name of an unset subcommand.\n");
help_list (unsetlist, "unset ", -1, stdout);
help_list (unsetlist, "unset ", -1, gdb_stdout);
}
void

Some files were not shown because too many files have changed in this diff Show More