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:
parent
981b2b037a
commit
16d72e1e9b
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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) \
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1 +1 @@
|
||||
4.11
|
||||
4.13
|
||||
|
@ -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' \
|
||||
|
@ -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
|
||||
|
@ -1 +1 @@
|
||||
2.2
|
||||
cygnus-2.3
|
||||
|
@ -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 */
|
||||
|
@ -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
@ -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;
|
||||
|
@ -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
@ -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
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
@ -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;
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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) */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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 *,
|
||||
|
@ -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
@ -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;
|
||||
|
@ -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 ();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 |
|
||||
|
@ -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
@ -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. */
|
||||
|
||||
|
@ -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++
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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));
|
||||
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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) */
|
||||
|
@ -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 */
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 *,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 = {
|
||||
|
@ -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;
|
||||
{
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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 */
|
||||
|
@ -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, ®isters[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 (®isters[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 (®isters[REGISTER_BYTE (regno)], buf, size) == 0)
|
||||
return;
|
||||
}
|
||||
if (register_valid [regno]
|
||||
&& memcmp (®isters[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 (®isters[REGISTER_BYTE (regno)], val, REGISTER_RAW_SIZE (regno));
|
||||
|
||||
@ -517,6 +700,111 @@ supply_register (regno, val)
|
||||
CLEAN_UP_REGISTER_VALUE(regno, ®isters[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. */
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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) */
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
|
@ -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 ();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
®buf[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,
|
||||
®buf[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 */
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user